00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
00174
void change_parent(
ClassDesc*oldcd,
ClassDesc*newcd);
00175
00176
00177
ClassDesc(
const ClassDesc&);
00178
void operator=(
const ClassDesc&);
00179
00180
00181
ClassDesc(
const char*);
00182
void init(
const char*,
int=1,
const char* p=0,
00183
DescribedClass* (*ctor)()=0,
00184
DescribedClass* (*keyvalctor)(
const Ref<KeyVal>&)=0,
00185
DescribedClass* (*stateinctor)(
StateIn&)=0);
00186
public:
00187
ClassDesc(
const std::type_info&,
const char*,
int=1,
const char* p=0,
00188
DescribedClass* (*ctor)()=0,
00189
DescribedClass* (*keyvalctor)(
const Ref<KeyVal>&)=0,
00190
DescribedClass* (*stateinctor)(StateIn&)=0);
00191 ~
ClassDesc();
00192
00193
static std::map<std::string,ClassDescP>& all();
00194
const ParentClasses& parents()
const {
return parents_; }
00195
00197
static void list_all_classes();
00200
static ClassDesc* name_to_class_desc(
const char*);
00202
static ClassDesc *class_desc(
const std::type_info &);
00204 const char* name()
const {
return classname_; }
00206 int version()
const {
return version_; }
00208
DescribedClass* create_described_class() const;
00216 virtual
DescribedClass* create() const;
00222 virtual
DescribedClass* create(const
Ref<
KeyVal>&) const;
00228 virtual
DescribedClass* create(StateIn&) const;
00229
00232 static
int load_class(const
char* classname);
00233 };
00234
00242 class
DescribedClass : public
RefCount {
00243
public:
00244
DescribedClass();
00245
DescribedClass(
const DescribedClass&);
00246
DescribedClass& operator=(
const DescribedClass&);
00247
virtual ~
DescribedClass();
00250
ClassDesc* class_desc()
const;
00252
const char* class_name()
const;
00254
int class_version()
const;
00256
virtual void print(std::ostream& = ExEnv::out0())
const;
00257 };
00258
00260
template <
class T>
00261
inline ClassDesc *
00262 class_desc()
00263 {
00264
return ClassDesc::class_desc(
typeid(T));
00265 }
00266
00269
inline ClassDesc *
00270 class_desc(DescribedClass *d)
00271 {
00272
return ClassDesc::class_desc(
typeid(*d));
00273 }
00274
00277
template<
class T>
00278
inline T
00279 require_dynamic_cast(DescribedClass*p,
const char * errmsg,...)
00280 {
00281 T t = dynamic_cast<T>(p);
00282
if (p && !t) {
00283 va_list args;
00284 va_start(args,errmsg);
00285 fprintf(stderr,
"A required dynamic_cast failed in: ");
00286 vfprintf(stderr,errmsg,args);
00287 fprintf(stderr,
"\nwanted type \"%s\" but got \"%s\"\n",
00288
typeid(T).name(),p->class_desc()->name());
00289 fflush(stderr);
00290 va_end(args);
00291 abort();
00292 }
00293
return t;
00294 }
00295
00298
template<
class T>
00299
inline T
00300 require_dynamic_cast(
const DescribedClass*p,
const char * errmsg,...)
00301 {
00302 T t = dynamic_cast<T>(p);
00303
if (p && !t) {
00304 va_list args;
00305 va_start(args,errmsg);
00306 fprintf(stderr,
"A required dynamic_cast failed in: ");
00307 vfprintf(stderr,errmsg,args);
00308 fprintf(stderr,
"\nwanted type \"%s\" but got \"%s\"\n",
00309
typeid(T).name(),p->class_desc()->name());
00310 fflush(stderr);
00311 va_end(args);
00312 abort();
00313 }
00314
return t;
00315 }
00316
00319
template <
class A>
00320 class ForceLinkBase {
00321
public:
00322
virtual ~
ForceLinkBase() {};
00323
virtual DescribedClass *create(A) = 0;
00324 };
00325
00335
template <
class T,
class A = const Ref<KeyVal> &>
00336 class ForceLink:
public ForceLinkBase<A> {
00337
public:
00338
DescribedClass *create(A a) {
return new T(a); }
00339 };
00340
00341 }
00342
00343
#endif
00344
00345
00346
00347
00348