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 namespace sc {
00047
00048 template <class T, class C>
00049 class DescribedMemberDatum {
00050 private:
00051 T C::*member_;
00052 public:
00053 DescribedMemberDatum(T C::*member): member_(member) {}
00054
00055 };
00056
00057 class DescribedClass;
00058 class ClassDesc;
00059 typedef ClassDesc* ClassDescP;
00060 typedef const ClassDesc* CClassDescP;
00061
00063 class ClassKey {
00064 private:
00065 char* classname_;
00066 public:
00067 ClassKey();
00068 ClassKey(const char* name);
00069 ClassKey(const ClassKey&);
00070 ~ClassKey();
00071 ClassKey& operator=(const ClassKey&);
00072 int operator==(const ClassKey& ck) const;
00073 int operator<(const ClassKey& ck) const;
00074 int hash() const;
00075 int cmp(const ClassKey&ck) const;
00076 char* name() const;
00077 };
00078
00079 class ClassDesc;
00080
00082 class ParentClass
00083 {
00084 public:
00085 enum Access { Private, Protected, Public };
00086 private:
00087 Access _access;
00088 int _is_virtual;
00089 ClassDesc* _classdesc;
00090 public:
00091 ParentClass(ClassDesc*,Access access = Private,int is_virtual = 0);
00092 ParentClass(const ParentClass&);
00093 ~ParentClass();
00094 int is_virtual() const;
00095 Access access() const { return _access; }
00096 const ClassDesc* classdesc() const;
00097 void change_classdesc(ClassDesc*n);
00098 };
00099
00101 class ParentClasses
00102 {
00103 private:
00104 int _n;
00105 ParentClass** _classes;
00106 void add(ParentClass*);
00107
00108 ParentClasses(const ParentClasses&);
00109 void operator=(const ParentClasses&);
00110 public:
00111 ParentClasses();
00112 void init(const char*);
00113 ~ParentClasses();
00114 ParentClass& parent(int i) { return *_classes[i]; }
00115 const ParentClass& parent(int i) const { return *_classes[i]; }
00116 ParentClass& operator[](int i) { return *_classes[i]; }
00117 const ParentClass& operator[](int i) const { return *_classes[i]; }
00118 int n() const { return _n; }
00119 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00120 };
00121
00122
00123 class KeyVal;
00124 class StateIn;
00125
00128 template <class T>
00129 DescribedClass* create()
00130 {
00131 return new T;
00132 }
00133
00136 template <class T>
00137 DescribedClass* create(const Ref<KeyVal>& keyval)
00138 {
00139 return new T(keyval);
00140 }
00141
00144 template <class T>
00145 DescribedClass* create(StateIn& statein)
00146 {
00147 return new T(statein);
00148 }
00149
00150 class type_info_key {
00151 private:
00152 const std::type_info *ti_;
00153 public:
00154 type_info_key(): ti_(0) {}
00155 type_info_key(const std::type_info *ti): ti_(ti) {}
00156 type_info_key& operator=(const type_info_key&);
00157 int operator==(const type_info_key&) const;
00158 int operator<(const type_info_key&) const;
00159 int cmp(const type_info_key&) const;
00160 };
00161
00173 class ClassDesc: public Identity {
00174 friend class ParentClasses;
00175 private:
00176 static AVLMap<ClassKey,ClassDescP> *all_;
00177 static AVLMap<type_info_key,ClassDescP> *type_info_all_;
00178 static char * classlib_search_path_;
00179 static AVLSet<ClassKey> *unresolved_parents_;
00180
00181 char* classname_;
00182 int version_;
00183 ParentClasses parents_;
00184 AVLSet<ClassKey> *children_;
00185 DescribedClass* (*ctor_)();
00186 DescribedClass* (*keyvalctor_)(const Ref<KeyVal>&);
00187 DescribedClass* (*stateinctor_)(StateIn&);
00188
00189 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00190
00191
00192 ClassDesc(const ClassDesc&);
00193 void operator=(const ClassDesc&);
00194
00195
00196 ClassDesc(const char*);
00197 void init(const char*,int=1,const char* p=0,
00198 DescribedClass* (*ctor)()=0,
00199 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00200 DescribedClass* (*stateinctor)(StateIn&)=0);
00201 public:
00202 ClassDesc(const std::type_info&, const char*,int=1,const char* p=0,
00203 DescribedClass* (*ctor)()=0,
00204 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00205 DescribedClass* (*stateinctor)(StateIn&)=0);
00206 ~ClassDesc();
00207
00208 static AVLMap<ClassKey,ClassDescP>& all();
00209 const ParentClasses& parents() const { return parents_; }
00210
00212 static void list_all_classes();
00215 static ClassDesc* name_to_class_desc(const char*);
00217 static ClassDesc *class_desc(const std::type_info &);
00219 const char* name() const { return classname_; }
00221 int version() const { return version_; }
00223 DescribedClass* create_described_class() const;
00231 virtual DescribedClass* create() const;
00237 virtual DescribedClass* create(const Ref<KeyVal>&) const;
00243 virtual DescribedClass* create(StateIn&) const;
00244
00247 static int load_class(const char* classname);
00248 };
00249
00257 class DescribedClass : public RefCount {
00258 public:
00259 DescribedClass();
00260 DescribedClass(const DescribedClass&);
00261 DescribedClass& operator=(const DescribedClass&);
00262 virtual ~DescribedClass();
00265 ClassDesc* class_desc() const;
00267 const char* class_name() const;
00269 int class_version() const;
00271 virtual void print(std::ostream& = ExEnv::out0()) const;
00272 };
00273
00275 template <class T>
00276 inline ClassDesc *
00277 class_desc()
00278 {
00279 return ClassDesc::class_desc(typeid(T));
00280 }
00281
00284 inline ClassDesc *
00285 class_desc(DescribedClass *d)
00286 {
00287 return ClassDesc::class_desc(typeid(*d));
00288 }
00289
00292 template<class T>
00293 inline T
00294 require_dynamic_cast(DescribedClass*p,const char * errmsg,...)
00295 {
00296 T t = dynamic_cast<T>(p);
00297 if (p && !t) {
00298 va_list args;
00299 va_start(args,errmsg);
00300 fprintf(stderr,"A required dynamic_cast failed in: ");
00301 vfprintf(stderr,errmsg,args);
00302 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00303 typeid(T).name(),p->class_desc()->name());
00304 fflush(stderr);
00305 va_end(args);
00306 abort();
00307 }
00308 return t;
00309 }
00310
00313 template<class T>
00314 inline T
00315 require_dynamic_cast(const DescribedClass*p,const char * errmsg,...)
00316 {
00317 T t = dynamic_cast<T>(p);
00318 if (p && !t) {
00319 va_list args;
00320 va_start(args,errmsg);
00321 fprintf(stderr,"A required dynamic_cast failed in: ");
00322 vfprintf(stderr,errmsg,args);
00323 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00324 typeid(T).name(),p->class_desc()->name());
00325 fflush(stderr);
00326 va_end(args);
00327 abort();
00328 }
00329 return t;
00330 }
00331
00334 template <class A>
00335 class ForceLinkBase {
00336 public:
00337 virtual ~ForceLinkBase() {};
00338 virtual DescribedClass *create(A) = 0;
00339 };
00340
00350 template <class T, class A = const Ref<KeyVal> &>
00351 class ForceLink: public ForceLinkBase<A> {
00352 public:
00353 DescribedClass *create(A a) { return new T(a); }
00354 };
00355
00356 }
00357
00358 #endif
00359
00360
00361
00362
00363