MPQC
2.3.1
|
00001 // 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 <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 //T &member(C *c) { return c->*member_; } 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 // do not allow copy constructor or assignment 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 // do not allow copy constructor or assignment 00178 ClassDesc(const ClassDesc&); 00179 void operator=(const ClassDesc&); 00180 00181 // this is used for temporary parent class descriptors 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 // Local Variables: 00351 // mode: c++ 00352 // c-file-style: "CLJ" 00353 // End: