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     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:

Generated at Mon Dec 3 23:23:34 2007 for MPQC 2.3.1 using the documentation package Doxygen 1.5.2.