CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 #ifndef ZMEXCEPTION_H 00002 #define ZMEXCEPTION_H 00003 00004 00005 // ---------------------------------------------------------------------- 00006 // 00007 // ZMexception.h - class declaration for the ZOOM Exception base classes, 00008 // and macros to help set up specific exceptions definitions. 00009 // 00010 // class ZMexception: This is the public base type of all exceptions. 00011 // In particular this is the interface seen by 00012 // handler and logger. Methods are defined in 00013 // a macro ZMexClassStaticMethods, in ZMexception.icc, 00014 // or in .../Exceptions/src/ZMexception.cc: 00015 // 00016 // in the macro ZMexception.icc src/ZMexception.cc 00017 // ------------ --------------- ------------------ 00018 // setHandler() ZMexception 00019 // getHandler() message() 00020 // setLogger() 00021 // getLogger() count() 00022 // isTypeOf() wasThrown() logMessage(optText) 00023 // isBaseOf() severity() 00024 // isDerivedFrom location(line, file) 00025 // logNMore() fileName() 00026 // handleMe() line() 00027 // logMe() name() 00028 // facility() 00029 // OKtoLog() 00030 // 00031 // ZMexClassStaticMethods is defined here. It is used not only by the base 00032 // class definition (ZMexception) but also by a couple of macros established 00033 // for the convenience of creators of ZMex exceptions: 00034 // 00035 // ZMexStandardContents contains definitions of all the functions in the 00036 // interface for exception creators which are implemented 00037 // via methods in classInfo. See technical notes 2 - 5. 00038 // 00039 // ZMexStandardDefinition defines an exception in the inheritance hierarchy, 00040 // with no specific data or member functions beyond 00041 // the standard contents. If more members are needed, 00042 // use this macro as an example and add them after the 00043 // ZMexStandardContents. 00044 // 00045 // See technical note 1 for instructions on how to use these macros to define 00046 // ZOOM exceptions. (Technical notes are in file technical-notes in the 00047 // doc area of the Exceptions product). 00048 // 00049 // One further key macro should be known: 00050 // 00051 // ZMthrow(x) in ZMthrow.h calls ZMthrow_ but adds on the line and file 00052 // arguments. ZMthrow_(x,line,file) does the dispatching of the exception 00053 // handling. 00054 // 00055 // Related structures include: 00056 // 00057 // ZMexClassInfo contains the definitions of the classInfo structure. 00058 // ZMexClassInfo.h 00059 // 00060 // Revision History: 00061 // 970912 MF Initial version after separating out classInfo etc. 00062 // 970914 MF Corrected isBaseOf method, which needs isDerivedFrom. 00063 // 970916 WEB Updated per code review 00064 // 970917 WEB Updated per code review 2 00065 // 970918 WEB Updated per code review 3 00066 // 970918 PGC Updated per code review 4 00067 // 971112 WEB Updated for conformance to standard and the zoom 00068 // compatability headers 00069 // 971211 WEB Updated per code walkthrough 00070 // 971215 WEB Gave names to the default handler & logger 00071 // 980219 WEB Corrected return types of get/set Handler/Logger 00072 // to match those of those classes' methods 00073 // 980304 WEB Cleaned up logMessage() & related stuff 00074 // 980421 WEB Moved name() and facility() from .icc to .cc 00075 // 980615 WEB Added namespace support 00076 // 990318 MF Added virtual destructor 00077 // 990801 JVR Added logObject() for augmented exception purposes 00078 // 000217 WEB Improve C++ standards compliance 00079 // 000503 WEB Avoid global using 00080 // 010413 MF Vetted for proper namespace behavior: 00081 // all macros need to use the equivalent of ZM_QUAL_NAME 00082 // to append zmex if (and only if) namespaces are enabled. 00083 // 010626 MF ctor from ostringstream for syntactic convenience 00084 // 010626 MF Have ctor use string& rather than string 00085 // 011012 MF Include ZMutility/sstream so ostringstream& is OK 00086 // (KCC somehow survived the omission; gcc does not) 00087 // 011217 MF logMe() for base class does 00088 // ZMexception::classInfo().getLogger().emit(*this); 00089 // instead of emit(msg). This significantly improves 00090 // the look of the output when this path is taken, and 00091 // when logging to an ErrorLog allows statistics to work. 00092 // 031105 LG Get rid of all ZMutility references 00093 // 051117 LG Always use <sstream> 00094 // 00095 // ---------------------------------------------------------------------- 00096 00097 #include "CLHEP/Exceptions/defs.h" 00098 00099 #include <iosfwd> 00100 00101 #ifndef STRING_INCLUDED 00102 #define STRING_INCLUDED 00103 #include <string> 00104 #endif 00105 00106 #ifndef ZMEXSEVERITY_H 00107 #include "CLHEP/Exceptions/ZMexSeverity.h" 00108 #endif 00109 00110 #ifndef ZMEXLOGRESULT_H 00111 #include "CLHEP/Exceptions/ZMexLogResult.h" 00112 #endif 00113 00114 #ifndef ZMEXACTION_H 00115 #include "CLHEP/Exceptions/ZMexAction.h" 00116 #endif 00117 00118 #ifndef ZMEXCLASSINFO_H 00119 #include "CLHEP/Exceptions/ZMexClassInfo.h" 00120 #endif 00121 00122 #include <sstream> 00123 00124 00125 #ifdef ZM_USE_NAMESPACES 00126 #define ZMEX zmex 00127 #else 00128 #define ZMEX 00129 #endif 00130 00131 namespace zmex { 00132 00133 00134 class ZMexHandler; 00135 class ZMexLogger; 00136 class ZMexNoParent; 00137 00138 // ************************************** 00139 // 00140 // ZMexUserActivity, ZMexUserNumericalTag 00141 // 00142 // ************************************** 00143 00144 extern std::string ZMexUserActivity; 00145 extern int ZMexUserNumericalTag; 00146 00147 00148 // ******************* 00149 // 00150 // ZMhandler, ZMlogger 00151 // 00152 // ******************* 00153 00154 ZMexHandler & ZMhandler(); 00155 ZMexLogger & ZMlogger(); 00156 00157 // *********** 00158 // 00159 // ZMexception 00160 // 00161 // *********** 00162 00163 class ZMexception { 00164 00165 protected: 00166 static ZMexClassInfo _classInfo; 00167 // The base class has these static members for its class information. 00168 00169 const std::string message_; 00170 // Indicates reason for the exception. Should be unique to the line of 00171 // code doing ZMthrow. Multiple lines can throw the same ZMexception, 00172 // but normally supply different messages. 00173 00174 #ifndef DEFECT_NO_MUTABLE 00175 mutable 00176 #endif 00177 int line_; 00178 #ifndef DEFECT_NO_MUTABLE 00179 mutable 00180 #endif 00181 std::string sourceFileName_; 00182 // Indicate location of the source of the exception 00183 00184 // Copy for each instance of the class-wide data to snapshot them. 00185 const ZMexSeverity mySeverity_; 00186 const int myCount_; 00187 #ifndef DEFECT_NO_MUTABLE 00188 mutable 00189 #endif 00190 std::string handlerUsed_; 00191 #ifndef DEFECT_NO_MUTABLE 00192 mutable 00193 #endif 00194 bool wasThrown_; 00195 00196 00197 00198 public: 00199 // ********************** // 00200 // Constructor/Destructor // 00201 // ********************** // 00202 00203 ZMexception( 00204 const std::string & mesg 00205 , const ZMexSeverity howBad = ZMexSEVERITYenumLAST 00206 , int count = ZMexception::_classInfo.nextCount() 00207 ); 00208 00209 explicit 00210 ZMexception( 00211 const std::ostringstream & msg 00212 , const ZMexSeverity howBad = ZMexSEVERITYenumLAST 00213 , int count = ZMexception::_classInfo.nextCount() 00214 ); 00215 00216 virtual ~ZMexception() {} 00217 00218 // ********************** // 00219 // Instance Methods // 00220 // ********************** // 00221 00222 void location( int line, const std::string file ) const; 00223 // Set the location of the creator of the exception 00224 00225 ZMexSeverity severity() const; 00226 // Determine the severity of this exception. 00227 00228 int line() const; 00229 std::string fileName() const; 00230 // Determine the file/line number of the ZMthrow of this exception. 00231 00232 std::string message() const; 00233 int count() const; 00234 00235 std::string handlerUsed() const; 00236 bool wasThrown() const; 00237 00238 // The following are for internal use of the exception mechanism routines: 00239 void handlerUsed( const std::string handlerName ) const; 00240 void wasThrown( bool b ) const; 00241 00242 virtual std::string logMessage( const std::string optText = "" ) const; 00243 00244 virtual std::string facility() const; 00245 // Return the class facility preamble string. 00246 00247 virtual std::string name() const; 00248 // Return the exception name string, e.g., "ZMexWhatever". 00249 00250 bool OKtoLog() const; 00251 00252 00253 // **************************** 00254 // 00255 // Methods dealt with in the 00256 // ZMexClassStaticMethods macro 00257 // 00258 // **************************** 00259 00260 public: 00261 // ********************** // 00262 // Class static Methods // 00263 // ********************** // 00264 00265 // This declares the standard static methods and the virtual 00266 // functions that depend on the static member of exception class -- 00267 // classInfo. Technical note 5 explains why we will 00268 // need to use a macro defining these methods, rather than using simple 00269 // virtual methods or using templates. 00270 00271 // Note - These declarations become moot for every class derived from 00272 // ZMexception, because the methods of the same names are explicitly 00273 // declared and defined in the ZMexClassStaticMethods macro. However, 00274 // it is useful to have these declarations here in the base class, to 00275 // set forth a clean and commented specification of the interface to 00276 // these routines. The interface applies to ALL ZOOM exceptions. 00277 00278 /* 00279 static ZMexHandler setHandler( const ZMexHandler & newHandler ); 00280 // Replace previous handler; return old handler. 00281 00282 static const ZMexHandler getHandler(); 00283 // Return the current handler. 00284 00285 static ZMexLogger setLogger( const ZMexLogger & newLogger ); 00286 // Replace previous logger; return old logger. 00287 00288 static const ZMexLogger getLogger(); 00289 // Return the current logger. 00290 00291 static ZMexSeverity setSeverity ( const ZMexSeverity & newSeverity ); 00292 // Replace previous severity; return old severity. 00293 00294 static const std::string setName ( const std::string & newName ); 00295 // Replace previous name; return old name. 00296 00297 static const std::string setFacility ( const std::string & newFacility ); 00298 // Replace previous Facility; return old Facility. 00299 00300 static bool isTypeOf( const ZMexception & x ); 00301 // Test if x is this type of exception 00302 00303 static bool isBaseOf( const ZMexception & x ); 00304 // Test if x is exactly or derived from this type of exception 00305 */ 00306 00307 // ************************************************************** // 00308 // Virtual instance methods that utilize class static information // 00309 // ************************************************************** // 00310 00311 // Note - These are just like the class static methods in that they 00312 // have to be declared explicitly for each exception class, lest they 00313 // incorrectly use the method of that name in the base class ZMexception. 00314 // See technical note 6. 00315 // The difference is that (letting x be an instance of an exception type X) 00316 // these "instance methods" are invoked as x.f(), while the "class static 00317 // methods" are invoked by X::f(). 00318 00319 // These instance methods have to be virtual because the exception x is passed 00320 // to a method expecting a ZMexception, which then invokes x.method(). If 00321 // method() is not virtual you get ZMexception.method() - which we don't 00322 // want - even though X has a method of that same name defined. 00323 00324 /* 00325 virtual ZMexClassInfo & classInfo(); 00326 // return the appropriate classInfo 00327 00328 virtual ZMexAction handleMe() const; 00329 // handle the current instance 00330 00331 virtual ZMexLogResult logMe() const; 00332 // log the current instance 00333 00334 virtual bool isDerivedFrom( const std::string name, 00335 const std::string facility ); 00336 // check if this intance is of class derived form the one qualified 00337 // by name and facility. 00338 // Test if this exception is derived from an exception with given name 00339 */ 00340 00341 // **************************** 00342 // ZMexClassStaticMethods macro 00343 // **************************** 00344 00345 // This macro contains definitions implementing the standard static methods 00346 // (class-wide logically virtual functions) that depend on the static member 00347 // of the exception class -- classInfo. Technical note 5 00348 // addresses the need to use a macro defining these methods, 00349 00350 // CODING NOTE -- THE ROUTINES DEFINED HERE SHOULD MATCH EXACTLY THE 00351 // INTERFACE DECLARED ABOVE (except that static methods 00352 // may not be declared const). 00353 00354 #define ZMexClassStaticMethods \ 00355 \ 00356 static zmex::ZMexHandler setHandler( \ 00357 const zmex::ZMexHandler & newHandler ) { \ 00358 return _classInfo.setHandler( newHandler); } \ 00359 static zmex::ZMexHandler getHandler() { \ 00360 return _classInfo.getHandler(); } \ 00361 \ 00362 static zmex::ZMexLogger setLogger( \ 00363 const zmex::ZMexLogger & newLogger ) { \ 00364 return _classInfo.setLogger( newLogger ); } \ 00365 static zmex::ZMexLogger getLogger() { \ 00366 return _classInfo.getLogger(); } \ 00367 \ 00368 static zmex::ZMexSeverity setSeverity ( \ 00369 const zmex::ZMexSeverity & newSeverity ) { \ 00370 return _classInfo.setSeverity (newSeverity); } \ 00371 static const std::string setName ( const std::string & newName ) { \ 00372 return _classInfo.setName (newName); } \ 00373 static const std::string setFacility(const std::string& newFacility){ \ 00374 return _classInfo.setFacility (newFacility); } \ 00375 static bool isTypeOf( const zmex::ZMexception & x ) { \ 00376 return ( (_classInfo.name() == x.name()) && \ 00377 (_classInfo.facility() == x.facility() ) ); } \ 00378 \ 00379 static bool isBaseOf( const zmex::ZMexception & x ) { \ 00380 return ( x.isDerivedFrom (_classInfo.name(), \ 00381 _classInfo.facility()) ); } \ 00382 \ 00383 static void logNMore( const int N ) { \ 00384 _classInfo.logNMore( N ); } \ 00385 00386 // 00387 // end of ZMexClassStaticMethods macro 00388 00389 // **************************** 00390 // ZMexVirtualMethods macro 00391 // **************************** 00392 00393 // This macro contains definitions implementing the standard virtual methods 00394 // that depend on the static members of the exception class -- classInfo. 00395 // Technical note 5 addresses the need to use a macro defining 00396 // these methods, 00397 00398 // CODING NOTE -- THE ROUTINES DEFINED HERE SHOULD MATCH EXACTLY THE 00399 // INTERFACE DECLARED ABOVE (except that static methods 00400 // may not be declared const). 00401 00402 #define ZMexVirtualMethods(Parent,Class) \ 00403 \ 00404 virtual Class * clone() const { \ 00405 return new Class( *this ); } \ 00406 \ 00407 virtual zmex::ZMexClassInfo & classInfo() const { \ 00408 return Class::_classInfo; } \ 00409 \ 00410 virtual zmex::ZMexAction handleMe() const { \ 00411 /* DEBUG std::cerr << #Class "::handleMe()" << std::endl; */ \ 00412 zmex::ZMexAction result = \ 00413 Class::classInfo().getHandler().takeCareOf( *this ); \ 00414 return (result == zmex::ZMexHANDLEVIAPARENT) ? \ 00415 Parent::handleMe() : result; } \ 00416 \ 00417 virtual zmex::ZMexLogResult logMe() const { \ 00418 /* DEBUG std::cerr << #Class "::logMe()" << std::endl; */ \ 00419 zmex::ZMexLogResult result = \ 00420 Class::classInfo().getLogger().emit( *this ); \ 00421 return (result == zmex::ZMexLOGVIAPARENT) ? \ 00422 Parent::logMe() : result; } \ 00423 \ 00424 virtual bool isDerivedFrom( const std::string aName, \ 00425 const std::string aFacility ) const { \ 00426 return aName == name() && aFacility == facility() \ 00427 ? true \ 00428 : Parent::isDerivedFrom( aName, aFacility ); \ 00429 } \ 00430 00431 // 00432 // end of ZMexVirtualMethods macro 00433 00434 public: 00435 ZMexClassStaticMethods; 00436 // Define all the static methods for the ZMexception base class. 00437 00438 // Special cases for the virtual functions for the top exception class. 00439 virtual ZMexception * clone() const { 00440 return new ZMexception ( *this ); 00441 } 00442 00443 virtual zmex::ZMexClassInfo & classInfo() const { 00444 return ZMexception::_classInfo; 00445 } 00446 00447 virtual ZMexAction handleMe() const { 00448 // DEBUG std::cerr << "ZMexception::handleMe()" << std::endl; 00449 return ZMexception::classInfo().getHandler().takeCareOf( *this ); 00450 } 00451 00452 virtual ZMexLogResult logMe() const { 00453 // DEBUG std::cerr << "ZMexception::logMe()" << std::endl; 00454 return ZMexception::classInfo().getLogger().emit(*this); 00455 } 00456 00457 virtual bool isDerivedFrom( 00458 const std::string name 00459 , const std::string facility 00460 ) const { 00461 return false; 00462 } 00463 00464 virtual void logObject() const {} //added 00465 00466 }; // ZMexception 00467 00468 00469 // ************************************* 00470 // 00471 // Macros for deriving ZOOM exceptions 00472 // 00473 // ************************************* 00474 00475 00476 // ******************************* 00477 // ZMexStandardContents macro 00478 // ******************************* 00479 00480 #define ZMexStandardContents(Parent,Class) \ 00481 public: \ 00482 static zmex::ZMexClassInfo _classInfo; \ 00483 public: \ 00484 Class( \ 00485 const std::string & mesg \ 00486 , const zmex::ZMexSeverity howBad = \ 00487 zmex::ZMexSEVERITYenumLAST \ 00488 , int count = _classInfo.nextCount() \ 00489 ) : \ 00490 Parent( \ 00491 mesg \ 00492 , (howBad == zmex::ZMexSEVERITYenumLAST ? \ 00493 _classInfo.severity() : howBad) \ 00494 , count \ 00495 ) \ 00496 { } \ 00497 \ 00498 Class( \ 00499 const std::ostringstream& msg \ 00500 , const zmex::ZMexSeverity howBad = \ 00501 zmex::ZMexSEVERITYenumLAST \ 00502 , int count = _classInfo.nextCount() \ 00503 ) : \ 00504 Parent( \ 00505 msg \ 00506 , (howBad == zmex::ZMexSEVERITYenumLAST ? \ 00507 _classInfo.severity() : howBad) \ 00508 , count \ 00509 ) \ 00510 { } \ 00511 \ 00512 ZMexClassStaticMethods; \ 00513 ZMexVirtualMethods(Parent,Class); \ 00514 00515 // 00516 // end of ZMexStandardContents macro 00517 00518 00519 // ******************************* 00520 // ZMexStandardDefinition macro 00521 // ******************************* 00522 00523 #define ZMexStandardDefinition(Parent,Class) \ 00524 class Class : public Parent { \ 00525 ZMexStandardContents(Parent,Class) \ 00526 } \ 00527 00528 // 00529 // end of ZMexStandardDefinition macro 00530 00531 00532 } // namespace zmex 00533 00534 00535 #define ZMEXCEPTION_ICC 00536 #include "CLHEP/Exceptions/ZMexception.icc" 00537 #undef ZMEXCEPTION_ICC 00538 00539 00540 #endif // ZMEXCEPTION_H