- Main Page
- Related Pages
- Classes
- Files

- File List

# class.h

    00001 //
    00002 // class.h
    00003 //
    00004 // Copyright (C) 1996 Limit Point Systems, Inc.
    00005 //
    00006 // Author: Curtis Janssen <cljanss@limitpt.com>
    00007 // Maintainer: LPS
    00008 //
    00009 // This file is part of the SC Toolkit.
    00010 //
    00011 // The SC Toolkit is free software; you can redistribute it and/or modify
    00012 // it under the terms of the GNU Library General Public License as published by
    00013 // the Free Software Foundation; either version 2, or (at your option)
    00014 // any later version.
    00015 //
    00016 // The SC Toolkit is distributed in the hope that it will be useful,
    00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00019 // GNU Library General Public License for more details.
    00020 //
    00021 // You should have received a copy of the GNU Library General Public License
    00022 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
    00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    00024 //
    00025 // The U.S. Government is granted a limited license as per AL 91-7.
    00026 //
    00027
    00028 #ifdef __GNUG__
    00029 #pragma interface
    00030 #endif
    00031
    00032 #ifndef _util_class_class_h
    00033 #define _util_class_class_h
    00034
    00035 #include <map>
    00036 #include <set>
    00037 #include <string>
    00038
    00039 #include <stdio.h>
    00040 #include <string.h>
    00041 #include <stdarg.h>
    00042 #include <iostream>
    00043 #include <iomanip>
    00044 #include <typeinfo>
    00045 #include <util/ref/ref.h>
    00046 #include <util/misc/exenv.h>
    00047
    00048 namespace sc {
    00049
    00050 template <class T, class C>
    00051 class DescribedMemberDatum {
    00052   private:
    00053     T C::*member_;
    00054   public:
    00055     DescribedMemberDatum(T C::*member): member_(member) {}
    00056     //T &member(C *c) { return c->*member_; }
    00057 };
    00058
    00059 class DescribedClass;
    00060 class ClassDesc;
    00061 typedef ClassDesc* ClassDescP;
    00062 typedef const ClassDesc* CClassDescP;
    00063
    00064 class ClassDesc;
    00065
    00067 class ParentClass
    00068 {
    00069   public:
    00070     enum Access { Private, Protected, Public };
    00071   private:
    00072     Access _access;
    00073     int _is_virtual;
    00074     ClassDesc* _classdesc;
    00075   public:
    00076     ParentClass(ClassDesc*,Access access = Private,int is_virtual = 0);
    00077     ParentClass(const ParentClass&);
    00078     ~ParentClass();
    00079     int is_virtual() const;
    00080     Access access() const { return _access; }
    00081     const ClassDesc* classdesc() const;
    00082     void change_classdesc(ClassDesc*n);
    00083 };
    00084
    00086 class ParentClasses
    00087 {
    00088   private:
    00089     int _n;
    00090     ParentClass** _classes;
    00091     void add(ParentClass*);
    00092     // do not allow copy constructor or assignment
    00093     ParentClasses(const ParentClasses&);
    00094     void operator=(const ParentClasses&);
    00095   public:
    00096     ParentClasses();
    00097     void init(const char*);
    00098     ~ParentClasses();
    00099     ParentClass& parent(int i) { return *_classes[i]; }
    00100     const ParentClass& parent(int i) const { return *_classes[i]; }
    00101     ParentClass& operator[](int i) { return *_classes[i]; }
    00102     const ParentClass& operator[](int i) const { return *_classes[i]; }
    00103     int n() const { return _n; }
    00104     void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
    00105 };
    00106
    00107
    00108 class KeyVal;
    00109 class StateIn;
    00110
    00113 template <class T>
    00114 DescribedClass* create()
    00115 {
    00116   return new T;
    00117 }
    00118
    00121 template <class T>
    00122 DescribedClass* create(const Ref<KeyVal>& keyval)
    00123 {
    00124   return new T(keyval);
    00125 }
    00126
    00129 template <class T>
    00130 DescribedClass* create(StateIn& statein)
    00131 {
    00132   return new T(statein);
    00133 }
    00134
    00135 class type_info_key {
    00136   private:
    00137     const std::type_info *ti_;
    00138   public:
    00139     type_info_key(): ti_(0) {}
    00140     type_info_key(const std::type_info *ti): ti_(ti) {}
    00141     type_info_key& operator=(const type_info_key&);
    00142     int operator==(const type_info_key&) const;
    00143     int operator<(const type_info_key&) const;
    00144     int cmp(const type_info_key&) const;
    00145 };
    00146
    00158 class ClassDesc: public Identity {
    00159     friend class ParentClasses;
    00160   private:
    00161     static std::map<std::string,ClassDescP> *all_;
    00162     static std::map<type_info_key,ClassDescP> *type_info_all_;
    00163     static char * classlib_search_path_;
    00164     static std::set<std::string> *unresolved_parents_;
    00165
    00166     char* classname_;
    00167     int version_;
    00168     ParentClasses parents_;
    00169     std::set<std::string> *children_;
    00170     DescribedClass* (*ctor_)();
    00171     DescribedClass* (*keyvalctor_)(const Ref<KeyVal>&);
    00172     DescribedClass* (*stateinctor_)(StateIn&);
    00173     const std::type_info *ti_;
    00174
    00175     void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
    00176
    00177     // do not allow copy constructor or assignment
    00178     ClassDesc(const ClassDesc&);
    00179     void operator=(const ClassDesc&);
    00180
    00181     // this is used for temporary parent class descriptors
    00182     ClassDesc(const char*);
    00183     void init(const char*,int=1,const char* p=0,
    00184               const std::type_info *ti=0,
    00185               DescribedClass* (*ctor)()=0,
    00186               DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
    00187               DescribedClass* (*stateinctor)(StateIn&)=0);
    00188   public:
    00189     ClassDesc(const std::type_info&, const char*,int=1,const char* p=0,
    00190               DescribedClass* (*ctor)()=0,
    00191               DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
    00192               DescribedClass* (*stateinctor)(StateIn&)=0);
    00193     ~ClassDesc();
    00194
    00195     static std::map<std::string,ClassDescP>& all();
    00196     const ParentClasses& parents() const { return parents_; }
    00197
    00199     static void list_all_classes();
    00202     static ClassDesc* name_to_class_desc(const char*);
    00204     static ClassDesc *class_desc(const std::type_info &);
    00206     const char* name() const { return classname_; }
    00208     int version() const { return version_; }
    00210     DescribedClass* create_described_class() const;
    00218     virtual DescribedClass* create() const;
    00224     virtual DescribedClass* create(const Ref<KeyVal>&) const;
    00230     virtual DescribedClass* create(StateIn&) const;
    00231
    00234     static int load_class(const char* classname);
    00235 };
    00236
    00244 class DescribedClass : public RefCount {
    00245   public:
    00246     DescribedClass();
    00247     DescribedClass(const DescribedClass&);
    00248     DescribedClass& operator=(const DescribedClass&);
    00249     virtual ~DescribedClass();
    00252     ClassDesc* class_desc() const throw();
    00254     const char* class_name() const;
    00256     int class_version() const;
    00258     virtual void print(std::ostream& = ExEnv::out0()) const;
    00259   };
    00260
    00262 template <class T>
    00263 inline ClassDesc *
    00264 class_desc()
    00265 {
    00266   return ClassDesc::class_desc(typeid(T));
    00267 }
    00268
    00271 inline ClassDesc *
    00272 class_desc(DescribedClass *d)
    00273 {
    00274   return ClassDesc::class_desc(typeid(*d));
    00275 }
    00276
    00279 template<class T>
    00280 inline T
    00281 require_dynamic_cast(DescribedClass*p,const char * errmsg,...)
    00282 {
    00283   T t = dynamic_cast<T>(p);
    00284   if (p && !t) {
    00285       va_list args;
    00286       va_start(args,errmsg);
    00287       fprintf(stderr,"A required dynamic_cast failed in: ");
    00288       vfprintf(stderr,errmsg,args);
    00289       fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
    00290               typeid(T).name(),p->class_desc()->name());
    00291       fflush(stderr);
    00292       va_end(args);
    00293       abort();
    00294   }
    00295   return t;
    00296 }
    00297
    00300 template<class T>
    00301 inline T
    00302 require_dynamic_cast(const DescribedClass*p,const char * errmsg,...)
    00303 {
    00304   T t = dynamic_cast<T>(p);
    00305   if (p && !t) {
    00306       va_list args;
    00307       va_start(args,errmsg);
    00308       fprintf(stderr,"A required dynamic_cast failed in: ");
    00309       vfprintf(stderr,errmsg,args);
    00310       fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
    00311               typeid(T).name(),p->class_desc()->name());
    00312       fflush(stderr);
    00313       va_end(args);
    00314       abort();
    00315   }
    00316   return t;
    00317 }
    00318
    00321 template <class A>
    00322 class ForceLinkBase {
    00323   public:
    00324     ForceLinkBase() {};
    00325     virtual ~ForceLinkBase() {};
    00326     virtual DescribedClass *create(A) = 0;
    00327 };
    00328
    00338 template <class T, class A = const Ref<KeyVal> &>
    00339 class ForceLink: public ForceLinkBase<A> {
    00340   public:
    00341     ForceLink() {};
    00342     virtual ~ForceLink() {};
    00343     DescribedClass *create(A a) { return new T(a); }
    00344 };
    00345
    00346 }
    00347
    00348 #endif
    00349
    00350 // Local Variables:
    00351 // mode: c++
    00352 // c-file-style: "CLJ"
    00353 // End: