Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:03:24

0001 #ifndef ZMEXCEPTION_H
0002 #define ZMEXCEPTION_H
0003 
0004 
0005 // ----------------------------------------------------------------------
0006 //
0007 // ZMexception.h - class declaration for the ZOOM Exception base classes,
0008 //         and macros to help set up specific exceptions definitions.
0009 //
0010 //   class ZMexception:  This is the public base type of all exceptions.
0011 //                       In particular this is the interface seen by
0012 //                       handler and logger.  Methods are defined in
0013 //               a macro ZMexClassStaticMethods, in ZMexception.icc,
0014 //           or in .../Exceptions/src/ZMexception.cc:
0015 //
0016 //   in the macro   ZMexception.icc     src/ZMexception.cc
0017 //   ------------   ---------------     ------------------
0018 //   setHandler()   ZMexception
0019 //   getHandler()   message()
0020 //   setLogger()
0021 //   getLogger()    count()
0022 //   isTypeOf()     wasThrown()     logMessage(optText)
0023 //   isBaseOf()     severity()
0024 //   isDerivedFrom  location(line, file)
0025 //   logNMore()     fileName()
0026 //   handleMe()     line()
0027 //   logMe()                    name()
0028 //                      facility()
0029 //          OKtoLog()
0030 //
0031 // ZMexClassStaticMethods is defined here.  It is used not only by the base
0032 // class definition (ZMexception) but also by a couple of macros established
0033 // for the convenience of creators of ZMex exceptions:
0034 //
0035 //   ZMexStandardContents contains definitions of all the functions in the
0036 //            interface for exception creators which are implemented
0037 //            via methods in classInfo.  See technical notes 2 - 5.
0038 //
0039 //   ZMexStandardDefinition defines an exception in the inheritance hierarchy,
0040 //             with no specific data or member functions beyond
0041 //             the standard contents.  If more members are needed,
0042 //             use this macro as an example and add them after the
0043 //             ZMexStandardContents.
0044 //
0045 // See technical note 1 for instructions on how to use these macros to define
0046 // ZOOM exceptions.  (Technical notes are in file technical-notes in the
0047 // doc area of the Exceptions product).
0048 //
0049 // One further key macro should be known:
0050 //
0051 //   ZMthrow(x) in ZMthrow.h calls ZMthrow_ but adds on the line and file
0052 //   arguments.  ZMthrow_(x,line,file) does the dispatching of the exception
0053 //   handling.
0054 //
0055 // Related structures include:
0056 //
0057 //   ZMexClassInfo  contains the definitions of the classInfo structure.
0058 //          ZMexClassInfo.h
0059 //
0060 // Revision History:
0061 //  970912  MF  Initial version after separating out classInfo etc.
0062 //  970914  MF  Corrected isBaseOf method, which needs isDerivedFrom.
0063 //  970916  WEB Updated per code review
0064 //  970917  WEB Updated per code review 2
0065 //  970918  WEB Updated per code review 3
0066 //  970918  PGC Updated per code review 4
0067 //      971112  WEB Updated for conformance to standard and the zoom
0068 //          compatability headers
0069 //  971211  WEB Updated per code walkthrough
0070 //      971215  WEB     Gave names to the default handler & logger
0071 //      980219  WEB     Corrected return types of get/set Handler/Logger
0072 //          to match those of those classes' methods
0073 //      980304  WEB     Cleaned up logMessage() & related stuff
0074 //      980421  WEB     Moved name() and facility() from .icc to .cc
0075 //  980615  WEB Added namespace support
0076 //  990318  MF  Added virtual destructor
0077 //      990801  JVR     Added logObject() for augmented exception purposes
0078 //  000217  WEB Improve C++ standards compliance
0079 //  000503  WEB Avoid global using
0080 //  010413  MF  Vetted for proper namespace behavior:
0081 //          all macros need to use the equivalent of ZM_QUAL_NAME 
0082 //          to append zmex if (and only if) namespaces are enabled.
0083 //  010626  MF  ctor from ostringstream for syntactic convenience
0084 //  010626  MF  Have ctor use string& rather than string 
0085 //  011012  MF  Include ZMutility/sstream so ostringstream& is OK
0086 //          (KCC somehow survived the omission; gcc does not)
0087 //  011217  MF  logMe() for base class does 
0088 //          ZMexception::classInfo().getLogger().emit(*this);
0089 //          instead of emit(msg).  This significantly improves
0090 //          the look of the output when this path is taken, and
0091 //          when logging to an ErrorLog allows statistics to work.
0092 //  031105  LG  Get rid of all ZMutility references
0093 //      051117  LG      Always use <sstream>
0094 //
0095 // ----------------------------------------------------------------------
0096 
0097 #include "CLHEP/Exceptions/defs.h"
0098 
0099 #include <iosfwd>
0100 
0101 #ifndef STRING_INCLUDED
0102   #define STRING_INCLUDED
0103   #include <string>
0104 #endif
0105 
0106 #ifndef ZMEXSEVERITY_H
0107   #include "CLHEP/Exceptions/ZMexSeverity.h"
0108 #endif
0109 
0110 #ifndef ZMEXLOGRESULT_H
0111   #include "CLHEP/Exceptions/ZMexLogResult.h"
0112 #endif
0113 
0114 #ifndef ZMEXACTION_H
0115   #include "CLHEP/Exceptions/ZMexAction.h"
0116 #endif
0117 
0118 #ifndef ZMEXCLASSINFO_H
0119   #include "CLHEP/Exceptions/ZMexClassInfo.h"
0120 #endif
0121 
0122 #include <sstream>
0123 
0124 
0125 #ifdef ZM_USE_NAMESPACES
0126 #define ZMEX zmex
0127 #else
0128 #define ZMEX
0129 #endif
0130 
0131 namespace zmex  {
0132 
0133 
0134 class ZMexHandler;
0135 class ZMexLogger;
0136 class ZMexNoParent;
0137 
0138 // **************************************
0139 //
0140 // ZMexUserActivity, ZMexUserNumericalTag
0141 //
0142 // **************************************
0143 
0144 extern std::string ZMexUserActivity;
0145 extern int ZMexUserNumericalTag;
0146 
0147 
0148 // *******************
0149 //
0150 // ZMhandler, ZMlogger
0151 //
0152 // *******************
0153 
0154 ZMexHandler &  ZMhandler();
0155 ZMexLogger  &  ZMlogger();
0156 
0157 // ***********
0158 //
0159 // ZMexception
0160 //
0161 // ***********
0162 
0163 class ZMexception {
0164 
0165 protected:
0166   static ZMexClassInfo _classInfo;
0167     // The base class has these static members for its class information.
0168 
0169   const std::string message_;
0170     // Indicates reason for the exception.  Should be unique to the line of
0171     // code doing ZMthrow.  Multiple lines can throw the same ZMexception,
0172     // but normally supply different messages.
0173 
0174   #ifndef DEFECT_NO_MUTABLE
0175   mutable
0176   #endif
0177   int    line_;
0178   #ifndef DEFECT_NO_MUTABLE
0179   mutable
0180   #endif
0181   std::string sourceFileName_;
0182     // Indicate location of the source of the exception
0183 
0184     // Copy for each instance of the class-wide data to snapshot them.
0185   const ZMexSeverity mySeverity_;
0186   const int          myCount_;
0187   #ifndef DEFECT_NO_MUTABLE
0188   mutable
0189   #endif
0190   std::string     handlerUsed_;
0191   #ifndef DEFECT_NO_MUTABLE
0192   mutable
0193   #endif
0194   bool       wasThrown_;
0195 
0196 
0197 
0198 public:
0199   // ********************** //
0200   // Constructor/Destructor //
0201   // ********************** //
0202 
0203   ZMexception(
0204     const std::string &      mesg
0205   , const ZMexSeverity howBad = ZMexSEVERITYenumLAST
0206   , int                icount  = ZMexception::_classInfo.nextCount()
0207   );
0208 
0209   explicit
0210   ZMexception(
0211     const std::ostringstream & msg
0212   , const ZMexSeverity howBad = ZMexSEVERITYenumLAST
0213   , int                icount  = ZMexception::_classInfo.nextCount()
0214   );
0215 
0216   virtual ~ZMexception() {}
0217 
0218   // ********************** //
0219   // Instance Methods       //
0220   // ********************** //
0221 
0222   void location( int line, const std::string file ) const;
0223     // Set the location of the creator of the exception
0224 
0225   ZMexSeverity severity() const;
0226     // Determine the severity of this exception.
0227 
0228   int line() const;
0229   std::string fileName() const;
0230     // Determine the file/line number of the ZMthrow of this exception.
0231 
0232   std::string message() const;
0233   int count() const;
0234 
0235   std::string handlerUsed() const;
0236   bool   wasThrown() const;
0237 
0238   // The following are for internal use of the exception mechanism routines:
0239   void handlerUsed( const std::string handlerName ) const;
0240   void wasThrown( bool b ) const;
0241 
0242   virtual std::string logMessage( const std::string optText = "" ) const;
0243 
0244   virtual std::string facility() const;
0245     // Return the class facility preamble string.
0246 
0247   virtual std::string name() const;
0248     // Return the exception name string, e.g., "ZMexWhatever".
0249 
0250   bool OKtoLog() const;
0251 
0252 
0253   // ****************************
0254   //
0255   // Methods dealt with in the
0256   // ZMexClassStaticMethods macro
0257   //
0258   // ****************************
0259 
0260 public:
0261   // ********************** //
0262   // Class static Methods   //
0263   // ********************** //
0264 
0265   // This declares the standard static methods and the virtual
0266   // functions that depend on the static member of exception class --
0267   // classInfo.  Technical note 5 explains why we will
0268   // need to use a macro defining these methods, rather than using simple
0269   // virtual methods or using templates.
0270 
0271   // Note - These declarations become moot for every class derived from
0272   // ZMexception, because the methods of the same names are explicitly
0273   // declared and defined in the ZMexClassStaticMethods macro.  However,
0274   // it is useful to have these declarations here in the base class, to
0275   // set forth a clean and commented specification of the interface to
0276   // these routines.  The interface applies to ALL ZOOM exceptions.
0277 
0278   /*
0279   static ZMexHandler setHandler( const ZMexHandler & newHandler );
0280     // Replace previous handler; return old handler.
0281 
0282   static const ZMexHandler getHandler();
0283     // Return the current handler.
0284 
0285   static ZMexLogger setLogger( const ZMexLogger & newLogger );
0286     // Replace previous logger; return old logger.
0287 
0288   static const ZMexLogger getLogger();
0289     // Return the current logger.
0290 
0291   static ZMexSeverity setSeverity ( const ZMexSeverity & newSeverity );
0292     // Replace previous severity; return old severity.
0293 
0294   static const std::string setName ( const std::string & newName );
0295     // Replace previous name; return old name.
0296 
0297   static const std::string setFacility ( const std::string & newFacility );
0298     // Replace previous Facility; return old Facility.
0299 
0300   static bool isTypeOf( const ZMexception & x );
0301     // Test if x is this type of exception
0302 
0303   static bool isBaseOf( const ZMexception & x );
0304     // Test if x is exactly or derived from this type of exception
0305   */
0306 
0307   // ************************************************************** //
0308   // Virtual instance methods that utilize class static information //
0309   // ************************************************************** //
0310 
0311   // Note - These are just like the class static methods in that they
0312   // have to be declared explicitly for each exception class, lest they
0313   // incorrectly use the method of that name in the base class ZMexception.
0314   // See technical note 6.
0315   // The difference is that (letting x be an instance of an exception type X)
0316   // these "instance methods" are invoked as x.f(), while the "class static
0317   // methods" are invoked by X::f().
0318 
0319   // These instance methods have to be virtual because the exception x is passed
0320   // to a method expecting a ZMexception, which then invokes x.method().  If
0321   // method() is not virtual you get ZMexception.method() - which we don't
0322   // want - even though X has a method of that same name defined.
0323 
0324   /*
0325   virtual ZMexClassInfo & classInfo();
0326     // return  the appropriate classInfo
0327 
0328   virtual ZMexAction handleMe() const;
0329     // handle the current instance
0330 
0331   virtual ZMexLogResult logMe() const;
0332     // log the current instance
0333 
0334   virtual bool isDerivedFrom( const std::string name,
0335                   const std::string facility );
0336     // check if this intance is of class derived form the one qualified
0337     // by name and facility.
0338     // Test if this exception is derived from an exception with given name
0339   */
0340 
0341   // ****************************
0342   // ZMexClassStaticMethods macro
0343   // ****************************
0344 
0345   // This macro contains definitions implementing the standard static methods
0346   // (class-wide logically virtual functions) that depend on the static member
0347   // of the exception class -- classInfo.  Technical note 5
0348   // addresses the need to use a macro defining these methods,
0349 
0350   // CODING NOTE -- THE ROUTINES DEFINED HERE SHOULD MATCH EXACTLY THE
0351   //            INTERFACE DECLARED ABOVE (except that static methods
0352   //                may not be declared const).
0353 
0354 #define ZMexClassStaticMethods                      \
0355                                     \
0356   static zmex::ZMexHandler setHandler(          \
0357         const zmex::ZMexHandler & newHandler ) {    \
0358     return  _classInfo.setHandler( newHandler); }           \
0359   static zmex::ZMexHandler getHandler() {           \
0360     return  _classInfo.getHandler(); }                  \
0361                                     \
0362   static zmex::ZMexLogger setLogger(            \
0363         const zmex::ZMexLogger & newLogger ) {  \
0364     return _classInfo.setLogger( newLogger ); }             \
0365   static zmex::ZMexLogger getLogger() {         \
0366     return  _classInfo.getLogger(); }                   \
0367                                     \
0368   static zmex::ZMexSeverity setSeverity (           \
0369     const zmex::ZMexSeverity & newSeverity ) {      \
0370     return _classInfo.setSeverity (newSeverity); }          \
0371   static const std::string setName ( const std::string & newName ) {    \
0372     return _classInfo.setName (newName); }              \
0373   static const std::string setFacility(const std::string& newFacility){ \
0374     return _classInfo.setFacility (newFacility); }          \
0375   static bool isTypeOf( const zmex::ZMexception & x ) { \
0376     return  ( (_classInfo.name() == x.name()) &&            \
0377           (_classInfo.facility() == x.facility() ) ); }     \
0378                                     \
0379   static bool isBaseOf( const zmex::ZMexception & x ) { \
0380     return  ( x.isDerivedFrom (_classInfo.name(),           \
0381                    _classInfo.facility()) ); }      \
0382                                     \
0383   static void logNMore( const int N )  {                \
0384     _classInfo.logNMore( N ); }                     \
0385 
0386 //
0387 // end of ZMexClassStaticMethods macro
0388 
0389   // ****************************
0390   // ZMexVirtualMethods macro
0391   // ****************************
0392 
0393   // This macro contains definitions implementing the standard virtual methods
0394   // that depend on the static members of the exception class -- classInfo.
0395   // Technical note 5 addresses the need to use a macro defining
0396   // these methods,
0397 
0398   // CODING NOTE -- THE ROUTINES DEFINED HERE SHOULD MATCH EXACTLY THE
0399   //            INTERFACE DECLARED ABOVE (except that static methods
0400   //                may not be declared const).
0401 
0402 #define ZMexVirtualMethods(Parent,Class)                \
0403                                     \
0404   virtual Class *                             clone() const {   \
0405     return  new Class( *this ); }                   \
0406                                     \
0407   virtual zmex::ZMexClassInfo & classInfo() const { \
0408     return  Class::_classInfo; }                    \
0409                                     \
0410   virtual zmex::ZMexAction handleMe() const {       \
0411       /* DEBUG  std::cerr << #Class "::handleMe()" << std::endl; */ \
0412     zmex::ZMexAction result =               \
0413         Class::classInfo().getHandler().takeCareOf( *this );    \
0414     return  (result == zmex::ZMexHANDLEVIAPARENT) ?     \
0415             Parent::handleMe() : result; }          \
0416                                     \
0417   virtual zmex::ZMexLogResult logMe() const {       \
0418     /* DEBUG  std::cerr << #Class "::logMe()" << std::endl; */  \
0419     zmex::ZMexLogResult result =                \
0420         Class::classInfo().getLogger().emit( *this );       \
0421     return  (result == zmex::ZMexLOGVIAPARENT) ?        \
0422                 Parent::logMe() : result; }     \
0423                                     \
0424   virtual bool isDerivedFrom( const std::string aName,          \
0425                   const std::string aFacility ) const { \
0426     return  aName == name()  &&  aFacility == facility()        \
0427       ? true                                \
0428       : Parent::isDerivedFrom( aName, aFacility );          \
0429   }                                 \
0430 
0431 //
0432 // end of ZMexVirtualMethods macro
0433 
0434 public:
0435   ZMexClassStaticMethods;
0436     // Define all the static methods for the ZMexception base class.
0437 
0438   // Special cases for the virtual functions for the top exception class.
0439   virtual ZMexception * clone() const {
0440     return  new ZMexception ( *this );
0441   }
0442 
0443   virtual zmex::ZMexClassInfo & classInfo() const {
0444     return  ZMexception::_classInfo;
0445   }
0446 
0447   virtual ZMexAction handleMe() const {
0448     // DEBUG  std::cerr << "ZMexception::handleMe()" << std::endl;
0449     return  ZMexception::classInfo().getHandler().takeCareOf( *this );
0450   }
0451 
0452   virtual ZMexLogResult logMe() const {
0453     // DEBUG  std::cerr << "ZMexception::logMe()" << std::endl;
0454     return ZMexception::classInfo().getLogger().emit(*this);
0455   }
0456 
0457   virtual bool isDerivedFrom(
0458     const std::string 
0459   , const std::string 
0460   ) const {
0461     return  false;
0462   }
0463 
0464   virtual void logObject() const {}                                //added
0465 
0466 };  // ZMexception
0467 
0468 
0469 // *************************************
0470 //
0471 // Macros for deriving ZOOM exceptions
0472 //
0473 // *************************************
0474 
0475 
0476 // *******************************
0477 // ZMexStandardContents macro
0478 // *******************************
0479 
0480 #define ZMexStandardContents(Parent,Class)              \
0481 public:                                 \
0482   static zmex::ZMexClassInfo _classInfo;            \
0483 public:                                 \
0484   Class(                                \
0485     const std::string  & mesg                       \
0486   , const zmex::ZMexSeverity howBad =           \
0487             zmex::ZMexSEVERITYenumLAST      \
0488   , int                      icount = _classInfo.nextCount()        \
0489   )  :                                  \
0490     Parent(                             \
0491       mesg                              \
0492     , (howBad == zmex::ZMexSEVERITYenumLAST ?       \
0493             _classInfo.severity() : howBad)         \
0494     , icount                                \
0495     )                                   \
0496   { }                                   \
0497                                     \
0498   Class(                                \
0499     const std::ostringstream&  msg                  \
0500   , const zmex::ZMexSeverity howBad =           \
0501             zmex::ZMexSEVERITYenumLAST      \
0502   , int                      icount = _classInfo.nextCount()        \
0503   )  :                                  \
0504     Parent(                             \
0505       msg                               \
0506     , (howBad == zmex::ZMexSEVERITYenumLAST ?       \
0507             _classInfo.severity() : howBad)         \
0508     , icount                                \
0509     )                                   \
0510   { }                                   \
0511                                     \
0512   ZMexClassStaticMethods;                       \
0513   ZMexVirtualMethods(Parent,Class);                 \
0514 
0515 //
0516 // end of ZMexStandardContents macro
0517 
0518 
0519 // *******************************
0520 // ZMexStandardDefinition macro
0521 // *******************************
0522 
0523 #define ZMexStandardDefinition(Parent,Class)                \
0524   class Class : public Parent {                     \
0525     ZMexStandardContents(Parent,Class)                  \
0526   }                                 \
0527 
0528 //
0529 // end of ZMexStandardDefinition macro
0530 
0531 
0532 }  // namespace zmex
0533 
0534 
0535 #define ZMEXCEPTION_ICC
0536 #include "CLHEP/Exceptions/ZMexception.icc"
0537 #undef ZMEXCEPTION_ICC
0538 
0539 
0540 #endif  // ZMEXCEPTION_H