00001 #ifndef ASG_TOOLS__MESSAGE_CHECK_H
00002 #define ASG_TOOLS__MESSAGE_CHECK_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00076
00077
00078
00079 #include <type_traits>
00080
00081 #include <xAODRootAccess/tools/TReturnCode.h>
00082 #ifdef ROOTCORE
00083 #include <AsgTools/MsgStream.h>
00084 #else
00085 #include "AthenaBaseComps/AthMessaging.h"
00086 #endif
00087
00113 #define ANA_MSG_HEADER(NAME) \
00114 namespace NAME { \
00115 MsgStream& msg (); \
00116 MsgStream& msg (MSG::Level level); \
00117 bool msgLvl (MSG::Level lvl); \
00118 void setMsgLevel (MSG::Level level); }
00119
00120
00121 #ifdef ROOTCORE
00122 #define ASG_TOOLS_MSG_STREAM(NAME,TITLE) \
00123 static MsgStream NAME (TITLE);
00124 #else
00125 #define ASG_TOOLS_MSG_STREAM(NAME,TITLE) \
00126 static MsgStream NAME (::asg::detail::getMessageSvcAthena(), TITLE);
00127 #endif
00128
00134 #define ANA_MSG_SOURCE(NAME,TITLE) \
00135 namespace NAME \
00136 { \
00137 namespace \
00138 { \
00139 MSG::Level& msgLevel () \
00140 { \
00141 static MSG::Level level = MSG::INFO; \
00142 return level; \
00143 } \
00144 } \
00145 \
00146 \
00147 \
00148 MsgStream& msg () \
00149 { \
00150 ASG_TOOLS_MSG_STREAM (result, TITLE); \
00151 return result; \
00152 } \
00153 \
00154 \
00155 MsgStream& msg (MSG::Level level) \
00156 { \
00157 return msg() << level; \
00158 } \
00159 \
00160 \
00161 \
00162 bool msgLvl (MSG::Level lvl) \
00163 { \
00164 return msgLevel() <= lvl; \
00165 } \
00166 \
00167 \
00168 \
00169 void setMsgLevel (MSG::Level level) \
00170 { \
00171 msgLevel() = level; \
00172 } \
00173 }
00174
00175 namespace asg
00176 {
00177 ANA_MSG_HEADER (msgToolHandle)
00178 ANA_MSG_HEADER (msgUserCode)
00179 }
00180
00181 namespace asg
00182 {
00185 template<typename T> struct CheckHelper;
00186
00187 template<> struct CheckHelper<StatusCode>
00188 {
00190 static inline bool isSuccess (const StatusCode& sc) {
00191 return sc.isSuccess(); }
00192
00194 static inline decltype(StatusCode::SUCCESS) successCode () {
00195 return StatusCode::SUCCESS;}
00196
00198 static inline decltype(StatusCode::FAILURE) failureCode () {
00199 return StatusCode::FAILURE;}
00200 };
00201
00202 template<> struct CheckHelper<xAOD::TReturnCode>
00203 {
00205 static inline bool isSuccess (const xAOD::TReturnCode& sc) {
00206 return sc.isSuccess(); }
00207
00209 static inline decltype (xAOD::TReturnCode::kSuccess) successCode () {
00210 return xAOD::TReturnCode::kSuccess;}
00211
00213 static inline decltype (xAOD::TReturnCode::kFailure) failureCode () {
00214 return xAOD::TReturnCode::kFailure;}
00215 };
00216
00217 template<> struct CheckHelper<int>
00218 {
00220 static inline int successCode () {
00221 return 0;}
00222
00224 static inline int failureCode () {
00225 return 1;}
00226 };
00227
00228 template<> struct CheckHelper<bool>
00229 {
00231 static inline bool isSuccess (const bool& sc) {
00232 return sc; }
00233
00235 static inline bool successCode () {
00236 return true;}
00237
00239 static inline bool failureCode () {
00240 return false;}
00241 };
00242
00243 template<typename T> struct CheckHelper<T*>
00244 {
00246 static inline bool isSuccess (const T *sc) {
00247 return sc; }
00248
00250 static inline T *failureCode () {
00251 return nullptr;}
00252 };
00253
00254 namespace detail
00255 {
00256 #ifndef ROOTCORE
00259 IMessageSvc* getMessageSvcAthena();
00260 #endif
00261
00266 [[noreturn]] void throw_check_fail (const std::string& str);
00267 }
00268 }
00269
00270
00271
00272 #if defined( __GNUC__ )
00273 # define MSGSTREAM_FNAME __PRETTY_FUNCTION__
00274 #else
00275 # define MSGSTREAM_FNAME ""
00276 #endif
00277
00278
00279
00280 #if defined( __GNUC__ )
00281 # define ASG_TOOLS_MSGSTREAM_FNAME __PRETTY_FUNCTION__
00282 #else
00283 # define ASG_TOOLS_MSGSTREAM_FNAME ""
00284 #endif
00285
00293 #define ASG_TOOLS_MSGSTREAM_PREFIX \
00294 __FILE__ << ":" << __LINE__ << " (" << ASG_TOOLS_MSGSTREAM_FNAME << "): "
00295
00297 #define ANA_MSG_LVL_SERIOUS( lvl, xmsg ) \
00298 msg( lvl ) << ASG_TOOLS_MSGSTREAM_PREFIX << xmsg << endmsg
00299
00301 #define ANA_MSG_LVL_NOCHK( lvl, xmsg ) \
00302 msg( lvl ) << xmsg << endmsg
00303
00305 #define ANA_MSG_LVL( lvl, xmsg ) \
00306 do { \
00307 if( msg().level() <= lvl ) { \
00308 ANA_MSG_LVL_NOCHK( lvl, xmsg ); \
00309 } \
00310 } while( 0 )
00311
00313 #define ANA_MSG_VERBOSE( xmsg ) ANA_MSG_LVL( MSG::VERBOSE, xmsg )
00315 #define ANA_MSG_DEBUG( xmsg ) ANA_MSG_LVL( MSG::DEBUG, xmsg )
00317 #define ANA_MSG_INFO( xmsg ) ANA_MSG_LVL_NOCHK( MSG::INFO, xmsg )
00319 #define ANA_MSG_WARNING( xmsg ) ANA_MSG_LVL_NOCHK( MSG::WARNING, xmsg )
00321 #define ANA_MSG_ERROR( xmsg ) ANA_MSG_LVL_SERIOUS( MSG::ERROR, xmsg )
00323 #define ANA_MSG_FATAL( xmsg ) ANA_MSG_LVL_SERIOUS( MSG::FATAL, xmsg )
00325 #define ANA_MSG_ALWAYS( xmsg ) ANA_MSG_LVL_NOCHK( MSG::ALWAYS, xmsg )
00326
00327
00328
00333 typedef StatusCode AsgToolsCheckResultType;
00334
00335
00341 #define ANA_CHECK_SET_TYPE(TYPE) \
00342 typedef TYPE AsgToolsCheckResultType;
00343
00344
00351 #define ANA_CHECK(EXP) \
00352 { const auto sc__ = EXP; \
00353 typedef typename std::decay<decltype(sc__)>::type scType__; \
00354 if (!::asg::CheckHelper<scType__>::isSuccess (sc__)) { \
00355 ANA_MSG_ERROR ("Failed to call \"" << #EXP << "\""); \
00356 return ::asg::CheckHelper<AsgToolsCheckResultType>::failureCode(); \
00357 } }
00358
00359
00366 #define ANA_CHECK_THROW(EXP) \
00367 { const auto sc__ = EXP; \
00368 typedef typename std::decay<decltype(sc__)>::type scType__; \
00369 if (!::asg::CheckHelper<scType__>::isSuccess (sc__)) { \
00370 std::ostringstream str; \
00371 str << #EXP; \
00372 ANA_MSG_ERROR ("Failed to call \"" << str.str() << "\", throwing exception"); \
00373 ::asg::detail::throw_check_fail (str.str()); \
00374 } }
00375
00376 #endif