Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // PersistentIStream.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_PersistentIStream_H
0010 #define ThePEG_PersistentIStream_H
0011 // This is the declaration of the PersistentIStream class.
0012 
0013 #include "ThePEG/Config/ThePEG.h"
0014 #include "InputDescription.h"
0015 #include "PersistentIStream.fh"
0016 #include "ThePEG/Utilities/Exception.h"
0017 #include <climits>
0018 #include <valarray>
0019 
0020 namespace ThePEG {
0021 
0022 /** @ingroup Persistency
0023  * PersistentIStream is used to read persistent objects from a stream
0024  * where they were previously written using PersistentOStream. Basic
0025  * types and pointers to objects derived from
0026  * <code>PersistentBase</code> should be read in the same order they
0027  * were written out. If <code>pedantic()</code> is true the same
0028  * classes that were written out must be present in the current
0029  * program. If <code>pedantic()</code> is false and if an object is
0030  * read for which only a base class is present in the current program,
0031  * only the parts corresponding to the base class will be read, and
0032  * the rest will be gracefully skipped.
0033  *
0034  * Each base class of a given object will be asked to read its
0035  * members from the stream starting from the least derived class going to
0036  * the most derived one. Members may be pointers to other persistent
0037  * objects or basic types or containers of these. The output for each
0038  * object part should be implemented by specializing the
0039  * ClassTraits<T>::input method, which otherwise
0040  * will call the non-virtual <code>persistentInput</code> function of
0041  * the class. Note that for diamond-shaped multiple inheritance
0042  * structures, the virtual base classes will be written out several
0043  * times for the same object.
0044  *
0045  * @see PersistentOStream
0046  * @see ClassTraits
0047  */
0048 class PersistentIStream {
0049 
0050 public:
0051 
0052   ThePEG_DECLARE_POINTERS(PersistentBase,BPtr);
0053 
0054   /** A vector of pointers to persistent objects */
0055   typedef vector<BPtr> ObjectVector;
0056 
0057   /** A vector of bare pointers to InputDescription objects. */
0058   typedef InputDescription::DescriptionVector DescriptionVector;
0059 
0060 public:
0061 
0062   /**
0063    * Constuctor giving an input stream to be used as an underlying
0064    * istream.
0065    */
0066   PersistentIStream(istream & is) 
0067     : theIStream(&is), isPedantic(true), 
0068       allocStream(false), badState(false)
0069   {
0070     init();
0071   }
0072 
0073 
0074 
0075   /**
0076    * Constuctor giving a file name to read from. If the first
0077    * character in the string is a '|', the corresponding program is
0078    * run and its standard output is used instead. If the filename ends
0079    * in ".gz" the file is uncompressed with gzip.
0080    */
0081   PersistentIStream(string);
0082 
0083   /**
0084    * The destructor.
0085    */
0086   ~PersistentIStream();
0087 
0088   /**
0089    * Operator for extracting persistent objects from the stream.
0090    * @param ptr this pointer will refer to the extracted object.
0091    * @return a reference to the stream.
0092    */
0093   template <typename T>
0094   PersistentIStream & operator>>(RCPtr<T> & ptr) {
0095     BPtr b = getObject();
0096     ptr = dynamic_ptr_cast< RCPtr<T> >(b);
0097     if ( b && !ptr ) setBadState();
0098     return *this;
0099   }
0100 
0101   /**
0102    * Operator for extracting persistent objects from the stream.
0103    * @param ptr this pointer will refer to the extracted object.
0104    * @return a reference to the stream.
0105    */
0106   template <typename T>
0107   PersistentIStream & operator>>(ConstRCPtr<T> & ptr) {
0108     BPtr b = getObject();
0109     ptr = dynamic_ptr_cast< ConstRCPtr<T> >(b);
0110     if ( b && !ptr ) setBadState();
0111     return *this;
0112   }
0113 
0114   /**
0115    * Operator for extracting persistent objects from the stream.
0116    * @param ptr this pointer will refer to the extracted object.
0117    * @return a reference to the stream.
0118    */
0119   template <typename T>
0120   PersistentIStream & operator>>(TransientRCPtr<T> & ptr) {
0121     BPtr b = getObject();
0122     ptr = dynamic_ptr_cast< TransientRCPtr<T> >(b);
0123     if ( b && !ptr ) setBadState();
0124     return *this;
0125   }
0126 
0127   /**
0128    * Operator for extracting persistent objects from the stream.
0129    * @param ptr this pointer will refer to the extracted object.
0130    * @return a reference to the stream.
0131    */
0132   template <typename T>
0133   PersistentIStream & operator>>(TransientConstRCPtr<T> & ptr) {
0134     BPtr b = getObject();
0135     ptr = dynamic_ptr_cast< TransientConstRCPtr<T> >(b);
0136     if ( b && !ptr ) setBadState();
0137     return *this;
0138   }
0139 
0140 
0141   /** @name Operators for extracting built-in types from the stream. */
0142   //@{
0143   /**
0144    * Read a character string.
0145    */
0146   PersistentIStream & operator>>(string &);
0147 
0148   /**
0149    * Read a character.
0150    */
0151   PersistentIStream & operator>>(char &);
0152 
0153   /**
0154    * Read a signed character.
0155    */
0156   PersistentIStream & operator>>(signed char &);
0157 
0158   /**
0159    * Read an unsigned character.
0160    */
0161   PersistentIStream & operator>>(unsigned char &);
0162 
0163   /**
0164    * Read an integer.
0165    */
0166   PersistentIStream & operator>>(int & i) {
0167     is() >> i;
0168     getSep();
0169     return *this;
0170   }
0171 
0172   /**
0173    * Read an unsigned integer.
0174    */
0175   PersistentIStream & operator>>(unsigned int & i) {
0176     is() >> i;
0177     getSep();
0178     return *this;
0179   }
0180 
0181   /**
0182    * Read a long integer.
0183    */
0184   PersistentIStream & operator>>(long & i) {
0185     is() >> i;
0186     getSep();
0187     return *this;
0188   }
0189 
0190   /**
0191    * Read an unsigned long integer.
0192    */
0193   PersistentIStream & operator>>(unsigned long & i) {
0194     is() >> i;
0195     getSep();
0196     return *this;
0197   }
0198 
0199   /**
0200    * Read a short integer.
0201    */
0202   PersistentIStream & operator>>(short & i) {
0203     is() >> i;
0204     getSep();
0205     return *this;
0206   }
0207 
0208   /**
0209    * Read an unsigned short integer.
0210    */
0211   PersistentIStream & operator>>(unsigned short & i) {
0212     is() >> i;
0213     getSep();
0214     return *this;
0215   }
0216 
0217   /**
0218    * Read a double.
0219    */
0220   PersistentIStream & operator>>(double & d) {
0221     is() >> d;
0222     getSep();
0223     return *this;
0224   }
0225 
0226   /**
0227    * Read a float.
0228    */
0229   PersistentIStream & operator>>(float & f) {
0230     is() >> f;
0231     getSep();
0232     return *this;
0233   }
0234 
0235   /**
0236    * Read a bool.
0237    */
0238   PersistentIStream & operator>>(bool &);
0239 
0240   /**
0241    * Read a Complex.
0242    */
0243   PersistentIStream & operator>>(Complex &);
0244   //@}
0245 
0246   /**
0247    * Intput of containers streamable objects.
0248    * @param c the container into which objects are added.
0249    */
0250   template <typename Container> void getContainer(Container & c) {
0251     long size;
0252     typename Container::value_type val;
0253     c.clear();
0254     *this >> size;
0255     while ( size-- && good() ) {
0256       *this >> val;
0257       c.insert(c.end(), val);
0258     }
0259   }
0260 
0261   /**
0262    * Read in an object. Create an object and read its data from the
0263    * stream.
0264    * @return a pointer to the read object.
0265    */
0266   BPtr getObject();
0267 
0268   /**
0269    * For a given object, read the member variables corresponding to a
0270    * given InputDescription object.
0271    * @param obj the object to be read into.
0272    * @param pid a pointer to an InputDescription describing the
0273    * (sub)class to be read.
0274    */
0275   void getObjectPart(tBPtr obj, const InputDescription * pid);
0276 
0277   /**
0278    * Read a class description from the underlying stream and return a
0279    * corresponding InputDescription object
0280    */
0281   const InputDescription * getClass();
0282   
0283   /**
0284    * Set pedantic mode.  If the stream is set to be tolerant it is
0285    * allowed to read an object from the stream even if the
0286    * corresponding class is not known to the running executable, under
0287    * the condition that a public base class of the unknown class is
0288    * known. If the stream is set to be pedantic this is not allowed.
0289    * By default, the stream is pedantic.
0290    */
0291   PersistentIStream & setPedantic() {
0292     isPedantic = true;
0293     return *this;
0294   }
0295 
0296   /**
0297    * Set tolerant mode.  If the stream is set to be tolerant it is
0298    * allowed to read an object from the stream even if the
0299    * corresponding class is not known to the running executable, under
0300    * the condition that a public base class of the unknown class is
0301    * known. If the stream is set to be pedantic this is not allowed.
0302    * By default, the stream is pedantic.
0303    */
0304   PersistentIStream & setTolerant() {
0305     isPedantic = false;
0306     return *this;
0307   }
0308 
0309   /**
0310    * Check the state of the stream.
0311    */
0312   bool good() const { return !badState && is(); }
0313   
0314   /**
0315    * Check the state of the stream.
0316    */
0317   bool operator!() const { return !good(); }
0318 
0319   /**
0320    * Check the state of the stream.
0321    */
0322   operator bool() const { return good(); }
0323 
0324   /**
0325    * Check the tolerance. Returns true if setPedantic() has been
0326    * called or if not setTolerant() has been called.
0327    */
0328   bool pedantic() const { return isPedantic; }
0329 
0330   /**
0331    * The global libraries loaded on initialization.
0332    */
0333   const vector<string> & globalLibraries() const {
0334     return theGlobalLibraries;
0335   }
0336 
0337 private:
0338 
0339   /** @cond EXCEPTIONCLASSES */
0340   /** @ingroup Persistency
0341       Thrown if a class is missing */
0342   struct MissingClass: public Exception {};
0343 
0344   /** @ingroup Persistency Thrown if an object which should have been
0345       read in is missing. */
0346   struct MissingObject: public Exception {};
0347 
0348   /** @ingroup Persistency Thrown if reading from the stream failed
0349       for some reason. */
0350   struct ReadFailure: public Exception {};
0351   /** @endcond */
0352 
0353   /**
0354    * Internal initialization.
0355    */
0356   void init();
0357 
0358   /**
0359    * Get the next character from the associated istream.
0360    */
0361   char get() { return is().get(); }
0362 
0363   /**
0364    * Get the next character from the associated istream and decode it
0365    * if it is escaped.
0366    */
0367   char escaped() {
0368     char c = get();
0369     return c == tNoSep? tSep: c;
0370   }
0371 
0372   /**
0373    * Set the stream in a bad state
0374    */
0375   void setBadState() {
0376     breakThePEG();
0377     badState = true;
0378   }
0379 
0380   /**
0381    * Read a field separator from the stream.
0382    */
0383   void getSep() {
0384     if ( !pedantic() ) skipField();
0385     else if ( get() != tSep ) setBadState();
0386   }
0387 
0388   /**
0389    * Scan the stream for the next field separator.
0390    */
0391   void skipField() {
0392     is().ignore(INT_MAX, tSep);
0393     if ( !is() ) setBadState();
0394   }
0395 
0396 
0397   /**
0398    * Check if the next char to be read is a tBegin marker.
0399    */
0400   bool beginObject() { return is().peek() == tBegin; }
0401 
0402   /**
0403    * Scan the stream to the end of the current object. If any new object are
0404    * found these are read prom the stream to ensure that the pointer structure
0405    * is preserved.
0406    */
0407   void endObject();
0408 
0409   /**
0410    * Scan stream for "end base class" marker. The \a classname is the
0411    * name of the class currently being read and is only used for
0412    * documenting exceptions.
0413    */
0414   void endBase(string classname);
0415 
0416   /**
0417    * Return a reference to the associated stream.
0418    */
0419   istream & is() { return *theIStream; }
0420 
0421   /**
0422    * Return a const reference to the associated stream.
0423    */
0424   const istream & is() const { return *theIStream; }
0425 
0426   /**
0427    * Lists of objects that have been read.
0428    */
0429   ObjectVector readObjects;
0430 
0431   /**
0432    * Lists of classes and corresponding version strings that have been read.
0433    */
0434   DescriptionVector readClasses;
0435 
0436   /**
0437    * A pointer to the associated istream.
0438    */
0439   istream * theIStream;
0440 
0441   /**
0442    * Pedantic or tolerant. See description of the setPedantic() and
0443    * setTolerant() methods.
0444    */
0445   bool isPedantic;
0446 
0447   /**
0448    * True if the associated istream should be deleted when the PersistentIStream
0449    * is destroyed.
0450    */
0451   bool allocStream;
0452 
0453   /**
0454    * False if no errors has occurred.
0455    */
0456   bool badState;
0457 
0458   /** Version number of the PersistentOStream which has written the
0459    *  file being read. */
0460   int version;
0461 
0462   /** Subversion number of the PersistentOStream which has written the
0463    *  file being read. */
0464   int subVersion;
0465 
0466   /**
0467    * Global libraries loaded in the initialization.
0468    */
0469   vector<string> theGlobalLibraries;
0470 
0471   /** @name Special marker characters */
0472   //@{
0473   /**
0474    * The special marker character indicating the beginning of an object.
0475    */
0476   static const char tBegin = '{';
0477 
0478   /**
0479    * The special marker character indicating the end of an object.
0480    */
0481   static const char tEnd = '}';
0482 
0483   /**
0484    * The marker character indicating the beginning of the next base
0485    * class in case of multiple inheritance.
0486    */
0487   static const char tNext = '|';
0488 
0489   /**
0490    * The special marker character indicating an escaped marker character.
0491    */
0492   static const char tNull = '\\';
0493 
0494   /**
0495    * The special marker character indicating the end of a value.
0496    */
0497   static const char tSep = '\n';
0498 
0499   /**
0500    * The special marker character used to avoid confusion with escaped
0501    * tSep markers.
0502    */
0503   static const char tNoSep = 'n';
0504 
0505   /**
0506    * The special marker character indicating a true boolean value.
0507    */
0508   static const char tYes = 'y';
0509 
0510   /**
0511    * The special marker character indicating a false boolean value.
0512    */
0513   static const char tNo = 'n';
0514   //@}
0515 
0516 private:
0517 
0518   /**
0519    * Standard ctors and assignment are private and not implemented.
0520    */
0521   PersistentIStream();
0522 
0523   /**
0524    * Standard ctors and assignment are private and not implemented.
0525    */
0526   PersistentIStream(const PersistentIStream &);
0527 
0528   /**
0529    * Standard ctors and assignment are private and not implemented.
0530    */
0531   PersistentIStream & operator=(const PersistentIStream &) = delete;
0532 
0533 };
0534 
0535 
0536 /**
0537  * Operator for applying manipulators to the stream.
0538  */
0539 inline PersistentIStream & operator>>(PersistentIStream & is, 
0540                       PersistentIManip func) {
0541   return (*func)(is);
0542 }
0543   
0544 /**
0545  * The manipulator for setting pedantic mode.
0546  */
0547 inline PersistentIStream & pedantic(PersistentIStream & is) {
0548   return is.setPedantic();
0549 }
0550 
0551 
0552 /**
0553  * The manipulator for setting tolerant mode.
0554  */
0555 inline PersistentIStream & tolerant(PersistentIStream & is) {
0556   return is.setTolerant();
0557 }
0558 
0559 
0560 /**
0561  * @name Partial specializations of operator>> for input of
0562  * std::containers.
0563  */
0564 //@{
0565 /** Input a pair of objects. */
0566 template <typename T1, typename T2>
0567 inline PersistentIStream & operator>>(PersistentIStream & is, pair<T1,T2> & p) {
0568   return is >> p.first >> p.second;
0569 }
0570 
0571 /** Input a map of key/objects pairs. */
0572 template <typename Key, typename T, typename Cmp, typename A>
0573 inline PersistentIStream & operator>>(PersistentIStream & is, map<Key,T,Cmp,A> & m) {
0574   m.clear();
0575   long size;
0576   Key k;
0577   is >> size;
0578   while ( size-- && is ) {
0579     is >> k;
0580     is >> m[k];
0581   }
0582   return is;
0583 }
0584 
0585 /** Input a multimap of key/objects pairs. */
0586 template <typename Key, typename T, typename Cmp, typename A>
0587 inline PersistentIStream & operator>>(PersistentIStream & is,
0588                       multimap<Key,T,Cmp,A> & m) {
0589   m.clear();
0590   long size;
0591   Key k;
0592   T t;
0593   is >> size;
0594   while ( size-- && is ) {
0595     is >> k;
0596     is >> t;
0597     m.insert(make_pair(k, t));
0598   }
0599   return is;
0600 }
0601 
0602 
0603 /** Input a set of objects. */
0604 template <typename Key, typename Cmp, typename A>
0605 inline PersistentIStream & operator>>(PersistentIStream & is, 
0606                       set<Key,Cmp,A> & s) {
0607   is.getContainer(s);
0608   return is;
0609 }
0610 
0611 /** Input a multoset of objects. */
0612 template <typename Key, typename Cmp, typename A>
0613 inline PersistentIStream & operator>>(PersistentIStream & is,
0614                       multiset<Key,Cmp,A> & s) {
0615   is.getContainer(s);
0616   return is;
0617 }
0618 
0619 
0620 /** Input a list of objects. */
0621 template <typename T, typename A>
0622 inline PersistentIStream & operator>>(PersistentIStream & is, 
0623                       list<T,A> & l) {
0624   is.getContainer(l);
0625   return is;
0626 }
0627 
0628 
0629 /** Input a vector of objects. */
0630 template <typename T, typename A>
0631 inline PersistentIStream & operator>>(PersistentIStream & is, 
0632               vector<T,A> & v) {
0633   is.getContainer(v);
0634   return is;
0635 }
0636 
0637 /** Input an array of objects. */
0638 template <typename T, size_t N>
0639 inline PersistentIStream & operator>>(PersistentIStream & is, 
0640               array<T,N> & a) {
0641   for ( size_t i = 0; i < N && is.good(); ++i ) 
0642     is >> a[i];
0643   return is;
0644 }
0645 
0646 /** Input a deque of objects. */
0647 template <typename T, typename A>
0648 inline PersistentIStream & operator>>(PersistentIStream & is, 
0649                       deque<T,A> & d) {
0650   is.getContainer(d);
0651   return is;
0652 }
0653 
0654 /** Input a valarray. */
0655 template <typename T>
0656 inline PersistentIStream & operator>>(PersistentIStream & is, 
0657                       std::valarray<T> & v) {
0658   long size;
0659   is >> size;
0660   v = std::valarray<T>(size);
0661   for ( int i = 0; i < size && is.good(); ++i ) is >> v[i];
0662   return is;
0663 }
0664 
0665 }
0666 
0667 #endif /* ThePEG_PersistentIStream_H */