Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:31

0001 // -*- C++ -*-
0002 //
0003 // ClassDescription.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 #ifndef ThePEG_ClassDescription_H
0010 #define ThePEG_ClassDescription_H
0011 
0012 #include "ThePEG/Config/ThePEG.h"
0013 #include "ClassDescription.fh"
0014 #include "ThePEG/Utilities/Named.h"
0015 #include "ThePEG/Persistency/PersistentOStream.fh"
0016 #include "ThePEG/Persistency/PersistentIStream.fh"
0017 #include "ClassTraits.h"
0018 #include "DescriptionList.h"
0019 
0020 namespace ThePEG {
0021 
0022 /**
0023  * ClassDescriptionBase is the base class for all class description
0024  * classes.  ClassDescriptionBase is the non-templated base class for
0025  * the templated ClassDescriptionTBase, ClassDescription,
0026  * AbstractClassDescription, NoPIOClassDescription and
0027  * AbstractNoPIOClassDescription classes. An instantiation of one of
0028  * these classes represents a meta class encapsulating information
0029  * about the template argument class. This information is obtained
0030  * from the templated ClassTraits class which can be specialized for
0031  * any given class should the default information not be
0032  * satisfactory. Information is also obtained from the templated
0033  * BaseClassTraits class which must be specialized for each class
0034  * declaring a typedef for each of its base classes.
0035  *
0036  * The information about a class stored in a
0037  * <code>ClassDescriptionBase</code> objects is the following:<BR> a
0038  * platform-independent class name,<BR> a reference to the
0039  * <code>type_info</code><BR> an integer version number,<BR> a vector
0040  * of <code>ClassDescriptionBase*</code> corresponding to the base
0041  * classes,<BR> methods for reading/writing members of a class from/to
0042  * a PersistentIStream/PersistentOStream and<BR> a method for creating
0043  * an object of a class.
0044  *
0045  * The ClassDescriptionBase objects should be created before main() is
0046  * executed, and shouold therfore be instantiated as static member
0047  * variables. Only one ClassDescriptionBase object shall be
0048  * instantiated for each class to be described. The
0049  * ClassDescriptionBase objects are automatically stored in a purely
0050  * static DescriptionList class.
0051  *
0052  * AbstractClassDescription and AbstractNoPIOClassDescription should
0053  * be used for abstract base classes, while NoPIOClassDescription and
0054  * AbstractNoPIOClassDescription should be used for classes which do
0055  * not have any members which need to be read and written
0056  * persistently.
0057  *
0058  * @see ClassTraits
0059  * @see PersistentIStream
0060  * @see PersistentOStream
0061  * @see DescriptionList
0062  */
0063 class ClassDescriptionBase: public Named {
0064 
0065 public:
0066 
0067   /** A vector of class descriptions. */
0068   typedef vector<const ClassDescriptionBase *> DescriptionVector;
0069 
0070 protected:
0071 
0072   /**
0073    * The constructor used by sub-classes.
0074    * @param newName the platform independent name of the class.
0075    * @param newInfo the type_info object corresponding to the class.
0076    * @param newVersion the implementation version of the class.
0077    * @param newLibrary the name of a file containing the dynamic
0078    * @param abst true if the class is abstract.
0079    * library where the class is implemented.
0080    */
0081   ClassDescriptionBase(string newName, 
0082                const type_info & newInfo,
0083                int newVersion, 
0084                string newLibrary,
0085                bool abst)
0086     : Named(newName), theVersion(newVersion), theLibrary(newLibrary),
0087       theInfo(newInfo), isAbstract(abst), done(false) {}
0088 
0089 public:
0090 
0091   /**
0092    * Empty destructor.
0093    */
0094   virtual ~ClassDescriptionBase();
0095 
0096   /**
0097    * The standart RTTI type_info object for the described class.
0098    */
0099   const type_info & info() const { return theInfo; }
0100 
0101   /**
0102    * The version of the described class.
0103    */
0104   int version() const { return theVersion; }
0105 
0106   /**
0107    * The name of a file containing the dynamic
0108    * library where the class is implemented.
0109    */
0110   string library() const { return theLibrary; }
0111 
0112   /**
0113    * Return true if this object was set up properly.
0114    */
0115   bool check() const { return done; }
0116 
0117   /**
0118    * Return the descriptions of the base classes of the described
0119    * class.
0120    */
0121   const DescriptionVector & descriptions() const { return theBaseClasses; }
0122 
0123   /**
0124    * Set up the base class information for this object.
0125    */
0126   virtual void setup() = 0;
0127 
0128   /**
0129    * Create an object of the described class.
0130    */
0131   virtual BPtr create() const = 0;
0132 
0133   /**
0134    * Output the members of an object of the described class to a
0135    * persistent stream.
0136    * @param b the object to be written.
0137    * @param os the persistent stream.
0138    */
0139   virtual void output(tcBPtr b, PersistentOStream & os) const = 0;
0140 
0141   /**
0142    * Read the members of an object of the described class from a
0143    * persistent stream.
0144    * @param b the object to be read.
0145    * @param is the persistent stream.
0146    * @param oldVersion the version number of the object when it was written.
0147    */
0148   virtual void input(tBPtr b, PersistentIStream & is, int oldVersion) const = 0;
0149 
0150   /**
0151    * Return true if the class described by the argument is a base
0152    * class of the class described by this.
0153    */
0154   bool isA(const ClassDescriptionBase & base) const;
0155 
0156   /**
0157    * Return true if the corresponding class is abstract.
0158    */
0159   bool abstract() const { return isAbstract; }
0160 
0161 protected:
0162 
0163   /**
0164    * Set the base classes.
0165    * @param first an iterator refering to the first base class
0166    * @param last an iterator giving the end of the range of base class
0167    * descriptions.
0168    */
0169   void baseClasses(DescriptionVector::iterator first,
0170            DescriptionVector::iterator last) 
0171   {
0172     theBaseClasses = DescriptionVector(first, last);
0173     done = true;
0174   }
0175 
0176 private:
0177 
0178   /**
0179    * The version of the described class.
0180    */
0181   int theVersion;
0182 
0183   /**
0184    * The library file where this class may be found.
0185    */
0186   string theLibrary;
0187 
0188   /**
0189    * The type_info object for the described class
0190    */
0191   const type_info & theInfo;
0192 
0193   /**
0194    * The vector of base classes.
0195    */
0196   DescriptionVector theBaseClasses;
0197 
0198   /**
0199    * True if this class is abstract.
0200    */
0201   bool isAbstract;
0202 
0203   /**
0204    * True if this object was set up properly.
0205    */
0206   bool done;
0207 
0208 };
0209 
0210 /**
0211  * A helper class for tracing the base classes of a class to be
0212  * described
0213  */
0214 template <typename T, int IBase,
0215           typename B = typename BaseClassTrait<T,IBase>::NthBase>
0216 struct ClassDescriptionHelper {
0217   /** Add base classes */
0218   static void addBases(vector<const ClassDescriptionBase *> & c){
0219     const ClassDescriptionBase * b = DescriptionList::find(typeid(B));
0220     if ( !b ) return;
0221     c.push_back(b);
0222     ClassDescriptionHelper<T,IBase+1>::addBases(c);
0223   }
0224 };
0225 
0226 /** @cond TRAITSPECIALIZATIONS */
0227 
0228 /**
0229  * A helper class for tracing the base classes of a class to be
0230  * described
0231  */
0232 template <typename T, int IBase>
0233 struct ClassDescriptionHelper<T, IBase, int> {
0234   /** Add base classes */
0235   static void addBases(vector<const ClassDescriptionBase *> & ) {}
0236 };
0237 
0238 /** @endcond */
0239 
0240 /**
0241  * An intermediate templated base class derived from
0242  * ClassDescriptionBase.
0243  */
0244 template <typename T>
0245 class ClassDescriptionTBase: public ClassDescriptionBase {
0246 
0247 public:
0248 
0249   /** The traits class for the template argument class. */
0250   typedef ClassTraits<T> Traits;
0251 
0252 public:
0253 
0254   /**
0255    * Default constructor. If \a abst is true then the corresponding
0256    * class is abstract.
0257    */
0258   ClassDescriptionTBase(bool abst)
0259     : ClassDescriptionBase(Traits::className(), typeid(T), Traits::version(),
0260                Traits::library(), abst) 
0261   {
0262     DescriptionList::Register(*this);
0263     T::Init();
0264   }
0265 
0266   /**
0267    * Set up the base class information for this object.
0268    */
0269   virtual void setup() {
0270     DescriptionVector bases;
0271     ClassDescriptionHelper<T,1>::addBases(bases);
0272     baseClasses(bases.begin(), bases.end());
0273   }
0274 
0275 };
0276 
0277 /**
0278  * A concreate implementation of ClassDescriptionBase describing an
0279  * abstract class with persistent data.
0280  */
0281 template <typename T>
0282 class AbstractClassDescription: public ClassDescriptionTBase<T> {
0283 
0284 public:
0285 
0286   /** The traits class for the template argument class. */
0287   typedef ClassTraits<T> Traits;
0288 
0289 public:
0290 
0291   /**
0292    * Default constructor.
0293    */
0294   AbstractClassDescription() : ClassDescriptionTBase<T>(true) {}
0295 
0296   /**
0297    * Do not create an object of the described class (which is
0298    * abstract). Just return the null pointer.
0299    */
0300   virtual BPtr create() const {
0301     throw std::logic_error("Tried to instantiate virtual class " + Named::name());
0302   }
0303 
0304   /**
0305    * Output the members of an object of the described class to a
0306    * persistent stream.
0307    * @param b the object to be written.
0308    * @param os the persistent stream.
0309    */
0310   virtual void output(tcBPtr b, PersistentOStream & os) const {
0311     Traits::output(Traits::cast(b), os);
0312   }
0313 
0314   /**
0315    * Read the members of an object of the described class from a
0316    * persistent stream.
0317    * @param b the object to be read.
0318    * @param is the persistent stream.
0319    * @param oldVersion the version number of the object when it was written.
0320    */
0321   virtual void input(tBPtr b, PersistentIStream & is,
0322              int oldVersion) const {
0323     Traits::input(Traits::cast(b), is, oldVersion);
0324   }
0325 
0326 };
0327 
0328 /**
0329  * A concreate implementation of ClassDescriptionBase describing a
0330  * concrete class with persistent data.
0331  */
0332 template <typename T>
0333 class ClassDescription: public ClassDescriptionTBase<T> {
0334 
0335 public:
0336 
0337   /** The traits class for the template argument class. */
0338   typedef ClassTraits<T> Traits;
0339 
0340 public:
0341 
0342   /**
0343    * Default constructor.
0344    */
0345   ClassDescription() : ClassDescriptionTBase<T>(false) {}
0346 
0347   /**
0348    * Create an object of the described class.
0349    */
0350   virtual BPtr create() const { return Traits::create(); }
0351 
0352   /**
0353    * Output the members of an object of the described class to a
0354    * persistent stream.
0355    * @param b the object to be written.
0356    * @param os the persistent stream.
0357    */
0358   virtual void output(tcBPtr b, PersistentOStream & os) const {
0359     Traits::output(Traits::cast(b), os);
0360   }
0361 
0362   /**
0363    * Read the members of an object of the described class from a
0364    * persistent stream.
0365    * @param b the object to be read.
0366    * @param is the persistent stream.
0367    * @param oldVersion the version number of the object when it was written.
0368    */
0369   virtual void input(tBPtr b, PersistentIStream & is,
0370              int oldVersion) const {
0371     Traits::input(Traits::cast(b), is, oldVersion);
0372   }
0373 
0374 };
0375 
0376 /**
0377  * A concreate implementation of ClassDescriptionBase describing a
0378  * concrete class without persistent data.
0379  */
0380 template <typename T>
0381 class NoPIOClassDescription: public ClassDescriptionTBase<T> {
0382 
0383 public:
0384 
0385   /** The traits class for the template argument class. */
0386   typedef ClassTraits<T> Traits;
0387 
0388 public:
0389 
0390   /**
0391    * Default constructor.
0392    */
0393   NoPIOClassDescription() : ClassDescriptionTBase<T>(false) {}
0394 
0395   /**
0396    * Create an object of the described class.
0397    */
0398   virtual BPtr create() const { return Traits::create(); }
0399 
0400   /**
0401    * Do nothing since the described class has no persistent data.
0402    */
0403   virtual void output(tcBPtr, PersistentOStream &) const {}
0404 
0405   /**
0406    * Do nothing since the described class has no persistent data.
0407    */
0408   virtual void input(tBPtr, PersistentIStream &, int) const {}
0409 
0410 };
0411 
0412 /**
0413  * A concreate implementation of ClassDescriptionBase describing an
0414  * abstract class without persistent data.
0415  */
0416 template <typename T>
0417 class AbstractNoPIOClassDescription: public ClassDescriptionTBase<T> {
0418 
0419 public:
0420 
0421   /** The traits class for the template argument class. */
0422   typedef ClassTraits<T> Traits;
0423 
0424 public:
0425 
0426   /**
0427    * Default constructor.
0428    */
0429   AbstractNoPIOClassDescription() : ClassDescriptionTBase<T>(true) {}
0430 
0431   /**
0432    * Do not create an object of the described class (which is
0433    * abstract). Just return the null pointer.
0434    */
0435   virtual BPtr create() const {
0436     throw std::logic_error("Tried to instantiate virtual class " + Named::name());
0437   }
0438 
0439   /**
0440    * Do nothing since the described class has no persistent data.
0441    */
0442   virtual void output(tcBPtr, PersistentOStream & ) const {}
0443 
0444   /**
0445    * Do nothing since the described class has no persistent data.
0446    */
0447   virtual void input(tBPtr, PersistentIStream &, int) const {}
0448 
0449 };
0450 
0451 }
0452 
0453 #define ThePEG_DECLARE_CLASS_DESCRIPTION(Class)                    \
0454 /** Describe a concrete class with persistent data. */             \
0455 static ClassDescription<Class> init ## Class                       \
0456 
0457 #define ThePEG_DECLARE_ABSTRACT_CLASS_DESCRIPTION(Class)           \
0458 /** Describe an abstract class with persistent data. */            \
0459 static AbstractClassDescription<Class> init ## Class               \
0460 
0461 #define ThePEG_DECLARE_NOPIO_CLASS_DESCRIPTION(Class)              \
0462 /** Describe a concrete class without persistent data. */          \
0463 static NoPIOClassDescription<Class> init ## Class                  \
0464 
0465 #define ThePEG_DECLARE_ABSTRACT_NOPIO_CLASS_DESCRIPTION(Class)     \
0466 /** Describe an abstract class without persistent data. */         \
0467 static AbstractNoPIOClassDescription<Class> init ## Class          \
0468 
0469 #define ThePEG_IMPLEMENT_CLASS_DESCRIPTION(Class)                  \
0470 ClassDescription<Class> Class::init ## Class                       \
0471 
0472 #define ThePEG_IMPLEMENT_ABSTRACT_CLASS_DESCRIPTION(Class)         \
0473 AbstractClassDescription<Class> Class::init ## Class               \
0474 
0475 #define ThePEG_IMPLEMENT_NOPIO_CLASS_DESCRIPTION(Class)            \
0476 NoPIOClassDescription<Class> Class::init ## Class                  \
0477 
0478 #define ThePEG_IMPLEMENT_ABSTRACT_NOPIO_CLASS_DESCRIPTION(Class)   \
0479 AbstractNoPIOClassDescription<Class> Class::init ## Class          \
0480 
0481 #endif /* ThePEG_ClassDescription_H */