00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
00178 ClassDesc(const ClassDesc&);
00179 void operator=(const ClassDesc&);
00180
00181
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
00351
00352
00353