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 class DescribedClass;
00051 class ClassDesc;
00052 typedef ClassDesc* ClassDescP;
00053 typedef const ClassDesc* CClassDescP;
00054
00055 class ClassDesc;
00056
00058 class ParentClass
00059 {
00060 public:
00061 enum Access { Private, Protected, Public };
00062 private:
00063 Access _access;
00064 int _is_virtual;
00065 ClassDesc* _classdesc;
00066 public:
00067 ParentClass(ClassDesc*,Access access = Private,int is_virtual = 0);
00068 ParentClass(const ParentClass&);
00069 ~ParentClass();
00070 int is_virtual() const;
00071 Access access() const { return _access; }
00072 const ClassDesc* classdesc() const;
00073 void change_classdesc(ClassDesc*n);
00074 };
00075
00077 class ParentClasses
00078 {
00079 private:
00080 int _n;
00081 ParentClass** _classes;
00082 void add(ParentClass*);
00083
00084 ParentClasses(const ParentClasses&);
00085 void operator=(const ParentClasses&);
00086 public:
00087 ParentClasses();
00088 void init(const char*);
00089 ~ParentClasses();
00090 ParentClass& parent(int i) { return *_classes[i]; }
00091 const ParentClass& parent(int i) const { return *_classes[i]; }
00092 ParentClass& operator[](int i) { return *_classes[i]; }
00093 const ParentClass& operator[](int i) const { return *_classes[i]; }
00094 int n() const { return _n; }
00095 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00096 };
00097
00098
00099 class KeyVal;
00100 class StateIn;
00101
00104 template <class T>
00105 DescribedClass* create()
00106 {
00107 return new T;
00108 }
00109
00112 template <class T>
00113 DescribedClass* create(const Ref<KeyVal>& keyval)
00114 {
00115 return new T(keyval);
00116 }
00117
00120 template <class T>
00121 DescribedClass* create(StateIn& statein)
00122 {
00123 return new T(statein);
00124 }
00125
00126 class type_info_key {
00127 private:
00128 const std::type_info *ti_;
00129 public:
00130 type_info_key(): ti_(0) {}
00131 type_info_key(const std::type_info *ti): ti_(ti) {}
00132 type_info_key& operator=(const type_info_key&);
00133 int operator==(const type_info_key&) const;
00134 int operator<(const type_info_key&) const;
00135 int cmp(const type_info_key&) const;
00136 };
00137
00149 class ClassDesc: public Identity {
00150 friend class ParentClasses;
00151 private:
00152 static std::map<std::string,ClassDescP> *all_;
00153 static std::map<type_info_key,ClassDescP> *type_info_all_;
00154 static char * classlib_search_path_;
00155 static std::set<std::string> *unresolved_parents_;
00156
00157 char* classname_;
00158 int version_;
00159 ParentClasses parents_;
00160 std::set<std::string> *children_;
00161 DescribedClass* (*ctor_)();
00162 DescribedClass* (*keyvalctor_)(const Ref<KeyVal>&);
00163 DescribedClass* (*stateinctor_)(StateIn&);
00164 const std::type_info *ti_;
00165
00166 void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00167
00168
00169 ClassDesc(const ClassDesc&);
00170 void operator=(const ClassDesc&);
00171
00172
00173 ClassDesc(const char*);
00174 void init(const char*,int=1,const char* p=0,
00175 const std::type_info *ti=0,
00176 DescribedClass* (*ctor)()=0,
00177 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00178 DescribedClass* (*stateinctor)(StateIn&)=0);
00179 public:
00180 ClassDesc(const std::type_info&, const char*,int=1,const char* p=0,
00181 DescribedClass* (*ctor)()=0,
00182 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00183 DescribedClass* (*stateinctor)(StateIn&)=0);
00184 ~ClassDesc();
00185
00186 static std::map<std::string,ClassDescP>& all();
00187 const ParentClasses& parents() const { return parents_; }
00188
00190 static void list_all_classes();
00193 static ClassDesc* name_to_class_desc(const char*);
00195 static ClassDesc *class_desc(const std::type_info &);
00197 const char* name() const { return classname_; }
00199 int version() const { return version_; }
00201 DescribedClass* create_described_class() const;
00209 virtual DescribedClass* create() const;
00215 virtual DescribedClass* create(const Ref<KeyVal>&) const;
00221 virtual DescribedClass* create(StateIn&) const;
00222
00225 static int load_class(const char* classname);
00226 };
00227
00235 class DescribedClass : public RefCount {
00236 public:
00237 DescribedClass();
00238 DescribedClass(const DescribedClass&);
00239 DescribedClass& operator=(const DescribedClass&);
00240 virtual ~DescribedClass();
00243 ClassDesc* class_desc() const throw();
00245 const char* class_name() const;
00247 int class_version() const;
00249 virtual void print(std::ostream& = ExEnv::out0()) const;
00250 };
00251
00253 template <class T>
00254 inline ClassDesc *
00255 class_desc()
00256 {
00257 return ClassDesc::class_desc(typeid(T));
00258 }
00259
00262 inline ClassDesc *
00263 class_desc(DescribedClass *d)
00264 {
00265 return ClassDesc::class_desc(typeid(*d));
00266 }
00267
00270 template<class T>
00271 inline T
00272 require_dynamic_cast(DescribedClass*p,const char * errmsg,...)
00273 {
00274 T t = dynamic_cast<T>(p);
00275 if (p && !t) {
00276 va_list args;
00277 va_start(args,errmsg);
00278 fprintf(stderr,"A required dynamic_cast failed in: ");
00279 vfprintf(stderr,errmsg,args);
00280 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00281 typeid(T).name(),p->class_desc()->name());
00282 fflush(stderr);
00283 va_end(args);
00284 abort();
00285 }
00286 return t;
00287 }
00288
00291 template<class T>
00292 inline T
00293 require_dynamic_cast(const DescribedClass*p,const char * errmsg,...)
00294 {
00295 T t = dynamic_cast<T>(p);
00296 if (p && !t) {
00297 va_list args;
00298 va_start(args,errmsg);
00299 fprintf(stderr,"A required dynamic_cast failed in: ");
00300 vfprintf(stderr,errmsg,args);
00301 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00302 typeid(T).name(),p->class_desc()->name());
00303 fflush(stderr);
00304 va_end(args);
00305 abort();
00306 }
00307 return t;
00308 }
00309
00312 template <class A>
00313 class ForceLinkBase {
00314 public:
00315 ForceLinkBase() {};
00316 virtual ~ForceLinkBase() {};
00317 virtual DescribedClass *create(A) = 0;
00318 };
00319
00329 template <class T, class A = const Ref<KeyVal> &>
00330 class ForceLink: public ForceLinkBase<A> {
00331 public:
00332 ForceLink() {};
00333 virtual ~ForceLink() {};
00334 DescribedClass *create(A a) { return new T(a); }
00335 };
00336
00337 }
00338
00339 #endif
00340
00341
00342
00343
00344