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 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     // do not allow copy constructor or assignment
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     // do not allow copy constructor or assignment
00169     ClassDesc(const ClassDesc&);
00170     void operator=(const ClassDesc&);
00171 
00172     // this is used for temporary parent class descriptors
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 // Local Variables:
00342 // mode: c++
00343 // c-file-style: "CLJ"
00344 // End:

Generated at Wed Sep 5 14:02:29 2007 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.5.2.
These pages are hosted on SourceForge.net