Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // InterfacedBase.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_InterfacedBase_H
0010 #define ThePEG_InterfacedBase_H
0011 // This is the declaration of the InterfacedBase class.
0012 
0013 #include "ThePEG/Config/ThePEG.h"
0014 #include "ThePEG/Utilities/Named.h"
0015 #include "ThePEG/Utilities/ClassDescription.h"
0016 #include "ThePEG/Utilities/HoldFlag.h"
0017 #include "InterfacedBase.xh"
0018 
0019 namespace ThePEG {
0020 
0021 /**
0022  * InterfacedBase is the base class of all Interfaced objects to be
0023  * handled by the BaseRepository class. InterfacedBase
0024  * objects can be manipulated through objects of the InterfaceBase
0025  * class dealing with setting parameters, switches and pointers to
0026  * other InterfacedBase objects.
0027  *
0028  * The InterfacedBase has a number of virtual methods to be
0029  * implemented by sub classes for checking the state of the object,
0030  * initializing the object etc.
0031  *
0032  * The InterfacedBase is derived from the PersistentBase class to
0033  * allow for persistent I/O, and from the Named for handling the name
0034  * of the object. The full name of the object is of the form
0035  * <code>/dir/subdir/name</code> analogous to the file name in a Unix
0036  * file system.
0037  *
0038  * It is possible to lock an InterfacedBase object in which case the
0039  * BaseRepository will not do anything that will change the state of
0040  * this object.
0041  *
0042  * @see BaseRepository
0043  * @see InterfaceBase
0044  */
0045 class InterfacedBase: public PersistentBase, public Named {
0046 
0047   /** The BaseRepository is a close friend. */
0048   friend class BaseRepository;
0049 
0050   /** The InterfaceBase is a close friend. */
0051   friend class InterfaceBase;
0052 
0053   /** The EventGenerator is a friend. */
0054   friend class EventGenerator;
0055 
0056 public:
0057 
0058   /**
0059    * Enumeration reflecting the state of an InterfacedBase object.
0060    */
0061   enum InitState {
0062     initializing = -1, /**< The object is currently being
0063                 initialized. I.e. either of update(),
0064                 init(), initrun() or finish() are being
0065                 run. */
0066     uninitialized = 0, /**< The object has not been initialized. */
0067     initialized = 1,   /**< The object has been initialized. */
0068     runready = 2       /**< The object is initialized and the
0069                 initrun() method has been called. */
0070   };
0071 
0072 public:
0073 
0074   /**
0075    * The virtual (empty) destructor;
0076    */
0077   virtual ~InterfacedBase();
0078 
0079   /**
0080    * Returns the full name of this object including its path, e.g.
0081    * <code>/directory/subdirectory/name</code>.
0082    */
0083   string fullName() const { return Named::name(); }
0084 
0085   /**
0086    * Returns the name of this object, without the path.
0087    */
0088   string name() const {
0089     return Named::name().substr(Named::name().rfind('/')+1);
0090   }
0091 
0092   /**
0093    * Returns the path to this object including the trailing
0094    * '/'. <code>fullName() = path() + name()</code>.
0095    */
0096   string path() const {
0097     string::size_type slash = Named::name().rfind('/');
0098     string ret;
0099     if ( slash != string::npos ) ret = Named::name().substr(0,slash);
0100     return ret;
0101   }
0102 
0103   /**
0104    * Returns a comment assigned to this object.
0105    */
0106   string comment() const { return theComment; }
0107 
0108   /**
0109    * Read setup info from a standard istream \a is. May be called by
0110    * the Repository to initialize an object. This function first calls
0111    * the virtual readSetup() function to allow the sub classes the
0112    * part \a is to initialize themselves. What ever is left in \a is
0113    * after that will be assigned to the comment() of the object.
0114    */
0115   void setup(istream & is) {
0116     readSetup(is);
0117     getline(is, theComment);
0118   }
0119 
0120 protected:
0121 
0122   /** @name Standard InterfacedBase virtual functions. */
0123   //@{
0124   /**
0125    * Read setup info from a standard istream \a is. May be called by
0126    * the Repository to initialize an object. This function is called
0127    * by the non virtual setup() function. A sub-class implementing it
0128    * should first call the base class version before parsing the \a
0129    * is. If the \a is is not empty after readSetup is called the
0130    * remaining string will be assigned to the comment() of the object.
0131    */
0132   virtual void readSetup(istream & is);
0133 
0134   /**
0135    * Check sanity of the object during the setup phase.  This function
0136    * is called everytime the object is changed through an interface
0137    * during the setup phase. Also if the setup is changed for an
0138    * object on which this is dependent. Note that the generator() is
0139    * not available when this method is called.
0140    *
0141    * This method may be called by the user interface during the setup phase
0142    * through the update() method after manipulating objects to check
0143    * the sanity of the object. When implemented by a sub class it is
0144    * important that the doupdate() method of the base class is called,
0145    * then if the sanity of this object depend on other objects, the
0146    * update() method of these should be called. Then if touched() is
0147    * true for this object or for the ones on which this depends, it is
0148    * an indication that some things have changed since last time
0149    * doupdate() was called, and the actual checking of the state of
0150    * this object is called for. To avoid circular loops, it is
0151    * important that the doupdate() method is called for the base
0152    * class, while the update() method is called for other objects.
0153    * @throws UpdateException if the setup is such that the object
0154    * would not work properly.
0155    */
0156   virtual void doupdate() {}
0157 
0158   /**
0159    * Initialize this object after the setup phase before saving an
0160    * EventGenerator to disk. Nothing should have changed since the
0161    * last update() call.
0162    * 
0163    * This method is called after the setup
0164    * phase through the init() method to indicate that the setup of a
0165    * run is finished. This is typpically done in a setup program
0166    * before this object has been saved to a run file. It must
0167    * therefore be made sure that the state of this object after this
0168    * method has been executed will not be changed if it is written to
0169    * a file and read in again. When implemented by a sub class it is
0170    * important that the doinit() method of the base class is called
0171    * first and then, if the initialization of this object depends on
0172    * other objects, that the init() method of these objects are
0173    * called. Only then should the class-local initialization
0174    * proceed. To avoid circular loops, it is important that the
0175    * doinit() method is called for the base class, while the init()
0176    * method is called for other objects.
0177    * @throws InitException if object could not be initialized properly.
0178    */
0179   virtual void doinit() {}
0180 
0181   /**
0182    * Initialize this object. Called in the run phase just before
0183    * a run begins.
0184    *
0185    * This method is called just before
0186    * running starts through the initrun() method to indicate that the
0187    * actual running is to start. When implemented by a sub class it is
0188    * important that the doinitrun() method of the base class is called
0189    * first and then, if the initialization of this object depends on
0190    * other objects, that the initrun() method of these objects are
0191    * called. Only then should the class-local initialization
0192    * proceed. To avoid circular loops, it is important that the
0193    * doinitrun() method is called for the base class, while the
0194    * initrun() method is called for other objects.
0195    */
0196   virtual void doinitrun() {}
0197 
0198   /**
0199    * Finalize this object. Called in the run phase just after a
0200    * run has ended. Used eg. to write out statistics.
0201    *
0202    * This method is called after the running
0203    * phase through the finish() and can eg. be used to write out
0204    * statistics. When implemented by a sub class it is important that
0205    * the dofinish() method of the base class is called while the
0206    * finish() methd is called for other objects.
0207    */
0208   virtual void dofinish() {}
0209 
0210   /**
0211    * Return a vector of all pointers to Interfaced objects used in this
0212    * object.
0213    * @return a vector of pointers.
0214    */
0215   virtual IVector getReferences() { return IVector(); }
0216 
0217   /**
0218    * Rebind pointer to other Interfaced objects. Called in the setup phase
0219    * after all objects used in an EventGenerator has been cloned so that
0220    * the pointers will refer to the cloned objects afterwards.
0221    * @throws RebindException if no cloned object was found for a given
0222    * pointer.
0223    */
0224   virtual void rebind(const TranslationMap &) {}
0225   //@}
0226 
0227 public:
0228 
0229   /** @name Inlined access function. */
0230   //@{
0231   /**
0232    * Calls the doupdate() function with recursion prevention.
0233    */
0234   void update() {
0235     if ( initState ) return;
0236     HoldFlag<InitState> hold(initState, initializing, initialized);
0237     doupdate();
0238   }
0239 
0240   /**
0241    * Calls the doinit() function with recursion prevention.
0242    */
0243   void init() {
0244     if ( initState ) return;
0245     HoldFlag<InitState> hold(initState, initializing, initialized);
0246     doinit();
0247   }
0248 
0249   /**
0250    * Return true if this object needs to be initialized before all
0251    * other objects (except those for which this function also returns
0252    * true).  This default version always returns false, but subclasses
0253    * may override it to return true.
0254    */
0255   virtual bool preInitialize() const;
0256 
0257   /**
0258    * Calls the doinitrun() function with recursion prevention.
0259    */
0260   void initrun() {
0261     if ( initState == runready || initState == initializing ) return;
0262     HoldFlag<InitState> hold(initState, initializing, runready);
0263     doinitrun();
0264   }
0265 
0266   /**
0267    * Calls the dofinish() function with recursion prevention.
0268    */
0269   void finish() {
0270     if ( initState == uninitialized || initState == initializing ) return;
0271     HoldFlag<InitState> hold(initState, initializing, uninitialized);
0272     dofinish();
0273   }
0274 
0275   /**
0276    * This function should be called every time something in this
0277    * object has changed in a way that a sanity check with update() is
0278    * needed
0279    */
0280   void touch() { isTouched = true; }
0281 
0282   /**
0283    * Set the state of this object to uninitialized.
0284    */
0285   void reset() { initState = uninitialized; }
0286 
0287   /**
0288    * Calls reset() and unTouch().
0289    */
0290   void clear() {
0291     reset();
0292     untouch();
0293   }
0294 
0295   /**
0296    * Return the state of initialization of this object.
0297    */
0298   InitState state() const { return initState; }
0299 
0300   /**
0301    * Return true if the BaseRepository is not allowed to change the
0302    * state of this object.
0303    */
0304   bool locked() const { return isLocked; }
0305 
0306   /**
0307    * Return true if the state of this object has been changed since
0308    * the last call to update().
0309    */
0310   bool touched() const { return isTouched; }
0311   //@}
0312 
0313   /**
0314    * Return a full clone of this object possibly doing things to the
0315    * clone to make it sane.
0316    */
0317   virtual IBPtr fullclone() const { return clone(); }
0318 
0319   /** @name Functions used by the persistent I/O system. */
0320   //@{
0321   /**
0322    * Function used to write out object persistently.
0323    * @param os the persistent output stream written to.
0324    */
0325   void persistentOutput(PersistentOStream & os) const;
0326 
0327   /**
0328    * Function used to read in object persistently.
0329    * @param is the persistent input stream read from.
0330    * @param version the version number of the object when written.
0331    */
0332   void persistentInput(PersistentIStream & is, int version);
0333   //@}
0334 
0335   /**
0336    * Standard Init function.
0337    */
0338   static void Init();
0339 
0340 protected:
0341 
0342   /**
0343    * Return a simple clone of this object. Should be implemented as
0344    * <code>return new_ptr(*this);</code> by a derived class.
0345    */
0346   virtual IBPtr clone() const = 0;
0347 
0348   /**
0349    * Protected default constructor.
0350    */
0351   InterfacedBase()
0352     : Named(""), isLocked(false), isTouched(true), 
0353       initState(uninitialized) {}
0354 
0355   /**
0356    * Protected constructor with the name given as argument.
0357    */
0358   InterfacedBase(string newName)
0359     : Named(newName), isLocked(false), isTouched(true),
0360       initState(uninitialized) {}
0361 
0362   /**
0363    * Protected copy-constructor.
0364    */
0365   InterfacedBase(const InterfacedBase & i)
0366     : Base(i), Named(i), isLocked(false), isTouched(true), 
0367       initState(uninitialized), theComment(i.theComment),
0368       objectDefaults(i.objectDefaults) {}
0369 
0370 private:
0371 
0372   /**
0373    * Set a new name (full name including path).
0374    */
0375   void name(string newName) { Named::name(newName); }
0376 
0377   /**
0378    * Lock this object.
0379    */
0380   void lock() { isLocked = true; }
0381 
0382   /**
0383    * Unlock this object.
0384    */
0385   void unlock() { isLocked = false; }
0386 
0387   /**
0388    * Clear the isTouched flag.
0389    */
0390   void untouch() { isTouched = false; }
0391 
0392 private:
0393 
0394   /**
0395    * Used by the interface to add comments.
0396    */
0397   string addComment(string);
0398 
0399 private:
0400 
0401   /**
0402    * True if this object is not to be changed by the user interface.
0403    */
0404   bool isLocked;
0405 
0406   /**
0407    * True if this object has been chaged since the last call to
0408    * update().
0409    */
0410   bool isTouched;
0411 
0412   /**
0413    * Indicate if this object has been initialized or not, or if it is
0414    * being initialized.
0415    */
0416   InitState initState;
0417 
0418   /**
0419    * A comment assigned to this object.
0420    */
0421   string theComment;
0422 
0423   /**
0424    * A map listing object-specific defaults set for the given interfaces.
0425    */
0426   map<string,string> objectDefaults;
0427 
0428 public:
0429 
0430   /**
0431    * Print out debugging information for this object on std::cerr. To
0432    * be called from within a debugger via the debug() function.
0433    */
0434   virtual void debugme() const;
0435 
0436 private:
0437 
0438   /**
0439    * Standard Initialization object.
0440    */
0441   static AbstractClassDescription<InterfacedBase> initInterfacedBase;
0442 
0443   /**
0444    *  Private and non-existent assignment operator.
0445    */
0446   InterfacedBase & operator=(const InterfacedBase &) = delete;
0447 
0448 protected:
0449 
0450   /**
0451    * Functor class to be used to update a range of dependent object.
0452    */
0453   struct UpdateChecker {
0454     /** Constructor. */
0455     UpdateChecker(bool & touched) : isTouched(touched) {}
0456     /** Constructor. */
0457     UpdateChecker(const UpdateChecker & uc) : isTouched(uc.isTouched) {}
0458     /** Call the check function for an object. */
0459     static void check(tIBPtr, bool &);
0460     /** Function call operator. */
0461     template <typename ptr> void operator()(const ptr & i) {
0462       check(i, isTouched);
0463     }
0464     /** set to false if any check() call fails. */
0465     bool & isTouched;
0466   };
0467 
0468   /**
0469    * Functor class to be used to update a range of dependent object in a map.
0470    */
0471   struct UpdateMapChecker {
0472     /** Constructor. */
0473     UpdateMapChecker(bool & touched) : isTouched(touched) {}
0474     /** Constructor. */
0475     UpdateMapChecker(const UpdateMapChecker & uc) : isTouched(uc.isTouched) {}
0476     /** Function call operator. */
0477     template <typename ref> void operator()(const ref & i) {
0478       UpdateChecker::check(i.second, isTouched);
0479     }
0480     /** Reference to the bool variable to be set. */
0481     bool & isTouched;
0482   };
0483 
0484 };
0485 
0486 /** @cond TRAITSPECIALIZATIONS */
0487 
0488 /**
0489  * This template specialization informs ThePEG about the
0490  * base class of InterfacedBase.
0491  */
0492 template <>
0493 struct BaseClassTrait<InterfacedBase,1>: public ClassTraitsType {
0494   /** Typedef of the base class of InterfacedBase. */
0495   typedef PersistentBase NthBase;
0496 };
0497 
0498 /**
0499  * This template specialization informs ThePEG about the name of the
0500  * InterfacedBase class.
0501  */
0502 template <>
0503 struct ClassTraits<InterfacedBase>: public ClassTraitsBase<InterfacedBase> {
0504   /** Return the class name. */
0505   static string className() { return "ThePEG::InterfacedBase"; }
0506 };
0507 
0508 /** @endcond */
0509 
0510 }
0511 
0512 #endif /* ThePEG_InterfacedBase_H */