Main Page   Class Hierarchy   Compound List   File List   Compound 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 <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 template <class T, class C>
00047 class DescribedMemberDatum {
00048   private:
00049     T C::*member_;
00050   public:
00051     DescribedMemberDatum(T C::*member): member_(member) {}
00052     //T &member(C *c) { return c->*member_; }
00053 };
00054 
00055 class DescribedClass;
00056 class ClassDesc;
00057 typedef ClassDesc* ClassDescP;
00058 typedef const ClassDesc* CClassDescP;
00059 
00061 class ClassKey {
00062   private:
00063     char* classname_;
00064   public:
00065     ClassKey();
00066     ClassKey(const char* name);
00067     ClassKey(const ClassKey&);
00068     ~ClassKey();
00069     ClassKey& operator=(const ClassKey&);
00070     int operator==(const ClassKey& ck) const;
00071     int operator<(const ClassKey& ck) const;
00072     int hash() const;
00073     int cmp(const ClassKey&ck) const;
00074     char* name() const;
00075   };
00076 
00077 class ClassDesc;
00078 
00080 class ParentClass
00081 {
00082   public:
00083     enum Access { Private, Protected, Public };
00084   private:
00085     Access _access;
00086     int _is_virtual;
00087     ClassDesc* _classdesc;
00088   public:
00089     ParentClass(ClassDesc*,Access access = Private,int is_virtual = 0);
00090     ParentClass(const ParentClass&);
00091     ~ParentClass();
00092     int is_virtual() const;
00093     Access access() const { return _access; }
00094     const ClassDesc* classdesc() const;
00095     void change_classdesc(ClassDesc*n);
00096 };
00097 
00099 class ParentClasses
00100 {
00101   private:
00102     int _n;
00103     ParentClass** _classes;
00104     void add(ParentClass*);
00105     // do not allow copy constructor or assignment
00106     ParentClasses(const ParentClasses&);
00107     void operator=(const ParentClasses&);
00108   public:
00109     ParentClasses();
00110     void init(const char*);
00111     ~ParentClasses();
00112     ParentClass& parent(int i) { return *_classes[i]; }
00113     const ParentClass& parent(int i) const { return *_classes[i]; }
00114     ParentClass& operator[](int i) { return *_classes[i]; }
00115     const ParentClass& operator[](int i) const { return *_classes[i]; }
00116     int n() const { return _n; }
00117     void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00118 };
00119     
00120 
00121 class KeyVal;
00122 class StateIn;
00123 
00126 template <class T>
00127 DescribedClass* create()
00128 {
00129   return new T;
00130 }
00131 
00134 template <class T>
00135 DescribedClass* create(const Ref<KeyVal>& keyval)
00136 {
00137   return new T(keyval);
00138 }
00139 
00142 template <class T>
00143 DescribedClass* create(StateIn& statein)
00144 {
00145   return new T(statein);
00146 }
00147 
00148 class type_info_key {
00149   private:
00150     const std::type_info *ti_;
00151   public:
00152     type_info_key(): ti_(0) {}
00153     type_info_key(const std::type_info *ti): ti_(ti) {}
00154     type_info_key& operator=(const type_info_key&);
00155     int operator==(const type_info_key&) const;
00156     int operator<(const type_info_key&) const;
00157     int cmp(const type_info_key&) const;
00158 };
00159 
00171 class ClassDesc: public Identity {
00172     friend class ParentClasses;
00173   private:
00174     static AVLMap<ClassKey,ClassDescP> *all_;
00175     static AVLMap<type_info_key,ClassDescP> *type_info_all_;
00176     static char * classlib_search_path_;
00177     static AVLSet<ClassKey> *unresolved_parents_;
00178 
00179     char* classname_;
00180     int version_;
00181     ParentClasses parents_;
00182     AVLSet<ClassKey> *children_;
00183     DescribedClass* (*ctor_)();
00184     DescribedClass* (*keyvalctor_)(const Ref<KeyVal>&);
00185     DescribedClass* (*stateinctor_)(StateIn&);
00186 
00187     void change_parent(ClassDesc*oldcd,ClassDesc*newcd);
00188 
00189     // do not allow copy constructor or assignment
00190     ClassDesc(const ClassDesc&);
00191     void operator=(const ClassDesc&);
00192 
00193     // this is used for temporary parent class descriptors
00194     ClassDesc(const char*);
00195     void init(const char*,int=1,const char* p=0,
00196               DescribedClass* (*ctor)()=0,
00197               DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00198               DescribedClass* (*stateinctor)(StateIn&)=0);
00199   public:
00200     ClassDesc(const std::type_info&, const char*,int=1,const char* p=0,
00201               DescribedClass* (*ctor)()=0,
00202               DescribedClass* (*keyvalctor)(const Ref<KeyVal>&)=0,
00203               DescribedClass* (*stateinctor)(StateIn&)=0);
00204     ~ClassDesc();
00205 
00206     static AVLMap<ClassKey,ClassDescP>& all();
00207     const ParentClasses& parents() const { return parents_; }
00208 
00210     static void list_all_classes();
00213     static ClassDesc* name_to_class_desc(const char*);
00215     static ClassDesc *class_desc(const std::type_info &);
00217     const char* name() const { return classname_; }
00219     int version() const { return version_; }
00221     DescribedClass* create_described_class() const;
00229     virtual DescribedClass* create() const;
00235     virtual DescribedClass* create(const Ref<KeyVal>&) const;
00241     virtual DescribedClass* create(StateIn&) const;
00242 
00245     static int load_class(const char* classname);
00246 };
00247 
00255 class DescribedClass : public RefCount {
00256   public:
00257     DescribedClass();
00258     DescribedClass(const DescribedClass&);
00259     DescribedClass& operator=(const DescribedClass&);
00260     virtual ~DescribedClass();
00263     ClassDesc* class_desc() const;
00265     const char* class_name() const;
00267     int class_version() const;
00269     virtual void print(std::ostream& = ExEnv::out()) const;
00270   };
00271 
00273 template <class T>
00274 inline ClassDesc *
00275 class_desc()
00276 {
00277   return ClassDesc::class_desc(typeid(T));
00278 }
00279 
00282 inline ClassDesc *
00283 class_desc(DescribedClass *d)
00284 {
00285   return ClassDesc::class_desc(typeid(*d));
00286 }
00287 
00290 template<class T>
00291 inline T
00292 require_dynamic_cast(DescribedClass*p,const char * errmsg,...)
00293 {
00294   T t = dynamic_cast<T>(p);
00295   if (p && !t) {
00296       va_list args;
00297       va_start(args,errmsg);
00298       fprintf(stderr,"A required dynamic_cast failed in: ");
00299       vfprintf(stderr,errmsg,args);
00300       fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00301               typeid(T).name(),typeid(p).name());
00302       fflush(stderr);
00303       va_end(args);
00304       abort();
00305   }
00306   return t;
00307 }
00308 
00311 template<class T>
00312 inline T
00313 require_dynamic_cast(const DescribedClass*p,const char * errmsg,...)
00314 {
00315   T t = dynamic_cast<T>(p);
00316   if (p && !t) {
00317       va_list args;
00318       va_start(args,errmsg);
00319       fprintf(stderr,"A required dynamic_cast failed in: ");
00320       vfprintf(stderr,errmsg,args);
00321       fprintf(stderr,"\nwanted type \"%s\" but got \"%s\"\n",
00322               typeid(T).name(),typeid(p).name());
00323       fflush(stderr);
00324       va_end(args);
00325       abort();
00326   }
00327   return t;
00328 }
00329 
00332 template <class A>
00333 class ForceLinkBase {
00334   public:
00335     virtual ~ForceLinkBase() {};
00336     virtual DescribedClass *create(A) = 0;
00337 };
00338 
00348 template <class T, class A = const Ref<KeyVal> &>
00349 class ForceLink: public ForceLinkBase<A> {
00350   public:
00351     DescribedClass *create(A a) { return new T(a); }
00352 };
00353 
00354 #endif
00355 
00356 // Local Variables:
00357 // mode: c++
00358 // c-file-style: "CLJ"
00359 // End:

Generated at Thu Oct 4 18:08:42 2001 for MPQC 2.0.0 using the documentation package Doxygen 1.2.5.