|
class.h00001 // 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 <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 //T &member(C *c) { return c->*member_; } 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 // do not allow copy constructor or assignment 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 // do not allow copy constructor or assignment 00192 ClassDesc(const ClassDesc&); 00193 void operator=(const ClassDesc&); 00194 00195 // this is used for temporary parent class descriptors 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 // Local Variables: 00361 // mode: c++ 00362 // c-file-style: "CLJ" 00363 // End: Generated at Fri Jan 10 08:14:08 2003 for MPQC 2.1.3 using the documentation package Doxygen 1.2.14. |