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: