Google

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

Generated at Fri Jan 10 08:14:08 2003 for MPQC 2.1.3 using the documentation package Doxygen 1.2.14.