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 <stdio.h>
00036 #include <string.h>
00037 #include <stdarg.h>
00038 #include <iostream>
00039 #include <iomanip>
00040 #include <typeinfo>
00041 #include <util/ref/ref.h>
00042 #include <util/container/avlset.h>
00043 #include <util/container/avlmap.h>
00044 #include <util/misc/exenv.h>
00045
00046 template <class T, class C>
00047 class DescribedMemberDatum {
00048 private:
00049 T C::*member_;
00050 public:
00051 DescribedMemberDatum(T C::*member): member_(member) {}
00052
00053 };
00054
00055 class DescribedClass;
00056 class ClassDesc;
00057 typedef ClassDesc* ClassDescP;
00058 typedef const ClassDesc* CClassDescP;
00059
00061 class ClassKey {
00062 private:
00063 char* classname_;
00064 public:
00065 ClassKey();
00066 ClassKey(const char* name);
00067 ClassKey(const ClassKey&);
00068 ~ClassKey();
00069 ClassKey& operator=(const ClassKey&);
00070 int operator==(const ClassKey& ck) const;
00071 int operator<(const ClassKey& ck) const;
00072 int hash() const;
00073 int cmp(const ClassKey&ck) const;
00074 char* name() const;
00075 };
00076
00077 class ClassDesc;
00078
00080 class ParentClass
00081 {
00082 public:
00083 enum Access { Private, Protected, Public };
00084 private:
00085 Access _access;
00086 int _is_virtual;
00087 ClassDesc* _classdesc;
00088 public:
00089 ParentClass(ClassDesc*,Access access = Private,int is_virtual = 0);
00090 ParentClass(const ParentClass&);
00091 ~ParentClass();
00092 int is_virtual() const;
00093 Access access() const { return _access; }
00094 const ClassDesc* classdesc() const;
00095 void change_classdesc(ClassDesc*n);
00096 };
00097
00099 class ParentClasses
00100 {
00101 private:
00102 int _n;
00103 ParentClass** _classes;
00104 void add(ParentClass*);
00105
00106 ParentClasses(const ParentClasses&);
00107 void operator=(const ParentClasses&);
00108 public:
00109 ParentClasses();
00110 void init(const char*);
00111 ~ParentClasses();
00112 ParentClass& parent(int i) { return *_classes[i]; }
00113 const ParentClass& parent(int i) const { return *_classes[i]; }
00114 ParentClass& operator[](int i) { return *_classes[i]; }
00115 const ParentClass& operator[](int i) const { return *_classes[i]; }
00116 int n() const { return _n; }
00117 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00118 };
00119
00120
00121 class KeyVal;
00122 class StateIn;
00123
00126 template <class T>
00127 DescribedClass* create()
00128 {
00129 return new T;
00130 }
00131
00134 template <class T>
00135 DescribedClass* create(const Ref<KeyVal>& keyval)
00136 {
00137 return new T(keyval);
00138 }
00139
00142 template <class T>
00143 DescribedClass* create(StateIn& statein)
00144 {
00145 return new T(statein);
00146 }
00147
00148 class type_info_key {
00149 private:
00150 const std::type_info *ti_;
00151 public:
00152 type_info_key(): ti_(0) {}
00153 type_info_key(const std::type_info *ti): ti_(ti) {}
00154 type_info_key& operator=(const type_info_key&);
00155 int operator==(const type_info_key&) const;
00156 int operator<(const type_info_key&) const;
00157 int cmp(const type_info_key&) const;
00158 };
00159
00171 class ClassDesc: public Identity {
00172 friend class ParentClasses;
00173 private:
00174 static AVLMap<ClassKey,ClassDescP> *all_;
00175 static AVLMap<type_info_key,ClassDescP> *type_info_all_;
00176 static char * classlib_search_path_;
00177 static AVLSet<ClassKey> *unresolved_parents_;
00178
00179 char* classname_;
00180 int version_;
00181 ParentClasses parents_;
00182 AVLSet<ClassKey> *children_;
00183 DescribedClass* (*ctor_)();
00184 DescribedClass* (*keyvalctor_)(const Ref<KeyVal>&);
00185 DescribedClass* (*stateinctor_)(StateIn&);
00186
00187 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00188
00189
00190 ClassDesc(const ClassDesc&);
00191 void operator=(const ClassDesc&);
00192
00193
00194 ClassDesc(const char*);
00195 void init(const char*,int=1,const char* p=0,
00196 DescribedClass* (*ctor)()=0,
00197 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00198 DescribedClass* (*stateinctor)(StateIn&)=0);
00199 public:
00200 ClassDesc(const std::type_info&, const char*,int=1,const char* p=0,
00201 DescribedClass* (*ctor)()=0,
00202 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00203 DescribedClass* (*stateinctor)(StateIn&)=0);
00204 ~ClassDesc();
00205
00206 static AVLMap<ClassKey,ClassDescP>& all();
00207 const ParentClasses& parents() const { return parents_; }
00208
00210 static void list_all_classes();
00213 static ClassDesc* name_to_class_desc(const char*);
00215 static ClassDesc *class_desc(const std::type_info &);
00217 const char* name() const { return classname_; }
00219 int version() const { return version_; }
00221 DescribedClass* create_described_class() const;
00229 virtual DescribedClass* create() const;
00235 virtual DescribedClass* create(const Ref<KeyVal>&) const;
00241 virtual DescribedClass* create(StateIn&) const;
00242
00245 static int load_class(const char* classname);
00246 };
00247
00255 class DescribedClass : public RefCount {
00256 public:
00257 DescribedClass();
00258 DescribedClass(const DescribedClass&);
00259 DescribedClass& operator=(const DescribedClass&);
00260 virtual ~DescribedClass();
00263 ClassDesc* class_desc() const;
00265 const char* class_name() const;
00267 int class_version() const;
00269 virtual void print(std::ostream& = ExEnv::out()) const;
00270 };
00271
00273 template <class T>
00274 inline ClassDesc *
00275 class_desc()
00276 {
00277 return ClassDesc::class_desc(typeid(T));
00278 }
00279
00282 inline ClassDesc *
00283 class_desc(DescribedClass *d)
00284 {
00285 return ClassDesc::class_desc(typeid(*d));
00286 }
00287
00290 template<class T>
00291 inline T
00292 require_dynamic_cast(DescribedClass*p,const char * errmsg,...)
00293 {
00294 T t = dynamic_cast<T>(p);
00295 if (p && !t) {
00296 va_list args;
00297 va_start(args,errmsg);
00298 fprintf(stderr,"A required dynamic_cast failed in: ");
00299 vfprintf(stderr,errmsg,args);
00300 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00301 typeid(T).name(),typeid(p).name());
00302 fflush(stderr);
00303 va_end(args);
00304 abort();
00305 }
00306 return t;
00307 }
00308
00311 template<class T>
00312 inline T
00313 require_dynamic_cast(const DescribedClass*p,const char * errmsg,...)
00314 {
00315 T t = dynamic_cast<T>(p);
00316 if (p && !t) {
00317 va_list args;
00318 va_start(args,errmsg);
00319 fprintf(stderr,"A required dynamic_cast failed in: ");
00320 vfprintf(stderr,errmsg,args);
00321 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00322 typeid(T).name(),typeid(p).name());
00323 fflush(stderr);
00324 va_end(args);
00325 abort();
00326 }
00327 return t;
00328 }
00329
00332 template <class A>
00333 class ForceLinkBase {
00334 public:
00335 virtual ~ForceLinkBase() {};
00336 virtual DescribedClass *create(A) = 0;
00337 };
00338
00348 template <class T, class A = const Ref<KeyVal> &>
00349 class ForceLink: public ForceLinkBase<A> {
00350 public:
00351 DescribedClass *create(A a) { return new T(a); }
00352 };
00353
00354 #endif
00355
00356
00357
00358
00359