Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

class.h

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 00174 void change_parent(ClassDesc*oldcd,ClassDesc*newcd); 00175 00176 // do not allow copy constructor or assignment 00177 ClassDesc(const ClassDesc&); 00178 void operator=(const ClassDesc&); 00179 00180 // this is used for temporary parent class descriptors 00181 ClassDesc(const char*); 00182 void init(const char*,int=1,const char* p=0, 00183 DescribedClass* (*ctor)()=0, 00184 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0, 00185 DescribedClass* (*stateinctor)(StateIn&)=0); 00186 public: 00187 ClassDesc(const std::type_info&, const char*,int=1,const char* p=0, 00188 DescribedClass* (*ctor)()=0, 00189 DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0, 00190 DescribedClass* (*stateinctor)(StateIn&)=0); 00191 ~ClassDesc(); 00192 00193 static std::map<std::string,ClassDescP>& all(); 00194 const ParentClasses& parents() const { return parents_; } 00195 00197 static void list_all_classes(); 00200 static ClassDesc* name_to_class_desc(const char*); 00202 static ClassDesc *class_desc(const std::type_info &); 00204 const char* name() const { return classname_; } 00206 int version() const { return version_; } 00208 DescribedClass* create_described_class() const; 00216 virtual DescribedClass* create() const; 00222 virtual DescribedClass* create(const Ref<KeyVal>&) const; 00228 virtual DescribedClass* create(StateIn&) const; 00229 00232 static int load_class(const char* classname); 00233 }; 00234 00242 class DescribedClass : public RefCount { 00243 public: 00244 DescribedClass(); 00245 DescribedClass(const DescribedClass&); 00246 DescribedClass& operator=(const DescribedClass&); 00247 virtual ~DescribedClass(); 00250 ClassDesc* class_desc() const; 00252 const char* class_name() const; 00254 int class_version() const; 00256 virtual void print(std::ostream& = ExEnv::out0()) const; 00257 }; 00258 00260 template <class T> 00261 inline ClassDesc * 00262 class_desc() 00263 { 00264 return ClassDesc::class_desc(typeid(T)); 00265 } 00266 00269 inline ClassDesc * 00270 class_desc(DescribedClass *d) 00271 { 00272 return ClassDesc::class_desc(typeid(*d)); 00273 } 00274 00277 template<class T> 00278 inline T 00279 require_dynamic_cast(DescribedClass*p,const char * errmsg,...) 00280 { 00281 T t = dynamic_cast<T>(p); 00282 if (p && !t) { 00283 va_list args; 00284 va_start(args,errmsg); 00285 fprintf(stderr,"A required dynamic_cast failed in: "); 00286 vfprintf(stderr,errmsg,args); 00287 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n", 00288 typeid(T).name(),p->class_desc()->name()); 00289 fflush(stderr); 00290 va_end(args); 00291 abort(); 00292 } 00293 return t; 00294 } 00295 00298 template<class T> 00299 inline T 00300 require_dynamic_cast(const DescribedClass*p,const char * errmsg,...) 00301 { 00302 T t = dynamic_cast<T>(p); 00303 if (p && !t) { 00304 va_list args; 00305 va_start(args,errmsg); 00306 fprintf(stderr,"A required dynamic_cast failed in: "); 00307 vfprintf(stderr,errmsg,args); 00308 fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n", 00309 typeid(T).name(),p->class_desc()->name()); 00310 fflush(stderr); 00311 va_end(args); 00312 abort(); 00313 } 00314 return t; 00315 } 00316 00319 template <class A> 00320 class ForceLinkBase { 00321 public: 00322 virtual ~ForceLinkBase() {}; 00323 virtual DescribedClass *create(A) = 0; 00324 }; 00325 00335 template <class T, class A = const Ref<KeyVal> &> 00336 class ForceLink: public ForceLinkBase<A> { 00337 public: 00338 DescribedClass *create(A a) { return new T(a); } 00339 }; 00340 00341 } 00342 00343 #endif 00344 00345 // Local Variables: 00346 // mode: c++ 00347 // c-file-style: "CLJ" 00348 // End:

Generated at Thu Jul 29 19:53:50 2004 for MPQC 2.2.1 using the documentation package Doxygen 1.3.7.