00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ThePEG_ClassDescription_H
00010 #define ThePEG_ClassDescription_H
00011
00012 #include "ThePEG/Config/ThePEG.h"
00013 #include "ClassDescription.fh"
00014 #include "ThePEG/Utilities/Named.h"
00015 #include "ThePEG/Persistency/PersistentOStream.fh"
00016 #include "ThePEG/Persistency/PersistentIStream.fh"
00017 #include "ClassTraits.h"
00018 #include "DescriptionList.h"
00019
00020 namespace ThePEG {
00021
00063 class ClassDescriptionBase: public Named {
00064
00065 public:
00066
00068 typedef vector<const ClassDescriptionBase *> DescriptionVector;
00069
00070 protected:
00071
00081 ClassDescriptionBase(string newName,
00082 const type_info & newInfo,
00083 int newVersion,
00084 string newLibrary,
00085 bool abst)
00086 : Named(newName), theVersion(newVersion), theLibrary(newLibrary),
00087 theInfo(newInfo), isAbstract(abst), done(false) {}
00088
00089 public:
00090
00094 virtual ~ClassDescriptionBase();
00095
00099 const type_info & info() const { return theInfo; }
00100
00104 int version() const { return theVersion; }
00105
00110 string library() const { return theLibrary; }
00111
00115 bool check() const { return done; }
00116
00121 const DescriptionVector & descriptions() const { return theBaseClasses; }
00122
00126 virtual void setup() = 0;
00127
00131 virtual BPtr create() const = 0;
00132
00139 virtual void output(tcBPtr b, PersistentOStream & os) const = 0;
00140
00148 virtual void input(tBPtr b, PersistentIStream & is, int oldVersion) const = 0;
00149
00154 bool isA(const ClassDescriptionBase & base) const;
00155
00159 bool abstract() const { return isAbstract; }
00160
00161 protected:
00162
00169 void baseClasses(DescriptionVector::iterator first,
00170 DescriptionVector::iterator last)
00171 {
00172 theBaseClasses = DescriptionVector(first, last);
00173 done = true;
00174 }
00175
00176 private:
00177
00181 int theVersion;
00182
00186 string theLibrary;
00187
00191 const type_info & theInfo;
00192
00196 DescriptionVector theBaseClasses;
00197
00201 bool isAbstract;
00202
00206 bool done;
00207
00208 };
00209
00214 template <typename T, int IBase,
00215 typename B = typename BaseClassTrait<T,IBase>::NthBase>
00216 struct ClassDescriptionHelper {
00218 static void addBases(vector<const ClassDescriptionBase *> & c){
00219 const ClassDescriptionBase * b = DescriptionList::find(typeid(B));
00220 if ( !b ) return;
00221 c.push_back(b);
00222 ClassDescriptionHelper<T,IBase+1>::addBases(c);
00223 }
00224 };
00225
00232 template <typename T, int IBase>
00233 struct ClassDescriptionHelper<T, IBase, int> {
00235 static void addBases(vector<const ClassDescriptionBase *> & ) {}
00236 };
00237
00244 template <typename T>
00245 class ClassDescriptionTBase: public ClassDescriptionBase {
00246
00247 public:
00248
00250 typedef ClassTraits<T> Traits;
00251
00252 public:
00253
00258 ClassDescriptionTBase(bool abst)
00259 : ClassDescriptionBase(Traits::className(), typeid(T), Traits::version(),
00260 Traits::library(), abst)
00261 {
00262 DescriptionList::Register(*this);
00263 T::Init();
00264 }
00265
00266
00270 virtual ~ClassDescriptionTBase() {}
00271
00275 virtual void setup() {
00276 DescriptionVector bases;
00277 ClassDescriptionHelper<T,1>::addBases(bases);
00278 baseClasses(bases.begin(), bases.end());
00279 }
00280
00281 };
00282
00287 template <typename T>
00288 class AbstractClassDescription: public ClassDescriptionTBase<T> {
00289
00290 public:
00291
00293 typedef ClassTraits<T> Traits;
00294
00295 public:
00296
00300 AbstractClassDescription() : ClassDescriptionTBase<T>(true) {}
00301
00306 virtual BPtr create() const {
00307 throw std::logic_error("Tried to instantiate virtual class " + Named::name());
00308 }
00309
00316 virtual void output(tcBPtr b, PersistentOStream & os) const {
00317 Traits::output(Traits::cast(b), os);
00318 }
00319
00327 virtual void input(tBPtr b, PersistentIStream & is,
00328 int oldVersion) const {
00329 Traits::input(Traits::cast(b), is, oldVersion);
00330 }
00331
00332 };
00333
00338 template <typename T>
00339 class ClassDescription: public ClassDescriptionTBase<T> {
00340
00341 public:
00342
00344 typedef ClassTraits<T> Traits;
00345
00346 public:
00347
00351 ClassDescription() : ClassDescriptionTBase<T>(false) {}
00352
00356 virtual BPtr create() const { return Traits::create(); }
00357
00364 virtual void output(tcBPtr b, PersistentOStream & os) const {
00365 Traits::output(Traits::cast(b), os);
00366 }
00367
00375 virtual void input(tBPtr b, PersistentIStream & is,
00376 int oldVersion) const {
00377 Traits::input(Traits::cast(b), is, oldVersion);
00378 }
00379
00380 };
00381
00386 template <typename T>
00387 class NoPIOClassDescription: public ClassDescriptionTBase<T> {
00388
00389 public:
00390
00392 typedef ClassTraits<T> Traits;
00393
00394 public:
00395
00399 NoPIOClassDescription() : ClassDescriptionTBase<T>(false) {}
00400
00404 virtual BPtr create() const { return Traits::create(); }
00405
00409 virtual void output(tcBPtr, PersistentOStream &) const {}
00410
00414 virtual void input(tBPtr, PersistentIStream &, int) const {}
00415
00416 };
00417
00422 template <typename T>
00423 class AbstractNoPIOClassDescription: public ClassDescriptionTBase<T> {
00424
00425 public:
00426
00428 typedef ClassTraits<T> Traits;
00429
00430 public:
00431
00435 AbstractNoPIOClassDescription() : ClassDescriptionTBase<T>(true) {}
00436
00441 virtual BPtr create() const {
00442 throw std::logic_error("Tried to instantiate virtual class " + Named::name());
00443 }
00444
00448 virtual void output(tcBPtr, PersistentOStream & ) const {}
00449
00453 virtual void input(tBPtr, PersistentIStream &, int) const {}
00454
00455 };
00456
00457 }
00458
00459 #define ThePEG_DECLARE_CLASS_DESCRIPTION(Class) \
00460 \
00461 static ClassDescription<Class> init ## Class \
00462
00463 #define ThePEG_DECLARE_ABSTRACT_CLASS_DESCRIPTION(Class) \
00464 \
00465 static AbstractClassDescription<Class> init ## Class \
00466
00467 #define ThePEG_DECLARE_NOPIO_CLASS_DESCRIPTION(Class) \
00468 \
00469 static NoPIOClassDescription<Class> init ## Class \
00470
00471 #define ThePEG_DECLARE_ABSTRACT_NOPIO_CLASS_DESCRIPTION(Class) \
00472 \
00473 static AbstractNoPIOClassDescription<Class> init ## Class \
00474
00475 #define ThePEG_IMPLEMENT_CLASS_DESCRIPTION(Class) \
00476 ClassDescription<Class> Class::init ## Class \
00477
00478 #define ThePEG_IMPLEMENT_ABSTRACT_CLASS_DESCRIPTION(Class) \
00479 AbstractClassDescription<Class> Class::init ## Class \
00480
00481 #define ThePEG_IMPLEMENT_NOPIO_CLASS_DESCRIPTION(Class) \
00482 NoPIOClassDescription<Class> Class::init ## Class \
00483
00484 #define ThePEG_IMPLEMENT_ABSTRACT_NOPIO_CLASS_DESCRIPTION(Class) \
00485 AbstractNoPIOClassDescription<Class> Class::init ## Class \
00486
00487 #endif