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 (msgProperty)
00178 ANA_MSG_HEADER (msgToolHandle)
00179 ANA_MSG_HEADER (msgUserCode)
00180 }
00181
00182 namespace asg
00183 {
00186 template<typename T> struct CheckHelper;
00187
00188 template<> struct CheckHelper<StatusCode>
00189 {
00191 static inline bool isSuccess (const StatusCode& sc) {
00192 return sc.isSuccess(); }
00193
00195 static inline decltype(StatusCode::SUCCESS) successCode () {
00196 return StatusCode::SUCCESS;}
00197
00199 static inline decltype(StatusCode::FAILURE) failureCode () {
00200 return StatusCode::FAILURE;}
00201 };
00202
00203 template<> struct CheckHelper<xAOD::TReturnCode>
00204 {
00206 static inline bool isSuccess (const xAOD::TReturnCode& sc) {
00207 return sc.isSuccess(); }
00208
00210 static inline decltype (xAOD::TReturnCode::kSuccess) successCode () {
00211 return xAOD::TReturnCode::kSuccess;}
00212
00214 static inline decltype (xAOD::TReturnCode::kFailure) failureCode () {
00215 return xAOD::TReturnCode::kFailure;}
00216 };
00217
00218 template<> struct CheckHelper<int>
00219 {
00221 static inline int successCode () {
00222 return 0;}
00223
00225 static inline int failureCode () {
00226 return 1;}
00227 };
00228
00229 template<> struct CheckHelper<bool>
00230 {
00232 static inline bool isSuccess (const bool& sc) {
00233 return sc; }
00234
00236 static inline bool successCode () {
00237 return true;}
00238
00240 static inline bool failureCode () {
00241 return false;}
00242 };
00243
00244 template<typename T> struct CheckHelper<T*>
00245 {
00247 static inline bool isSuccess (const T *sc) {
00248 return sc; }
00249
00251 static inline T *failureCode () {
00252 return nullptr;}
00253 };
00254
00255 namespace detail
00256 {
00257 #ifndef ROOTCORE
00260 IMessageSvc* getMessageSvcAthena();
00261 #endif
00262
00267 [[noreturn]] void throw_check_fail (const std::string& str);
00268 }
00269 }
00270
00271
00272
00273 #if defined( __GNUC__ )
00274 # define MSGSTREAM_FNAME __PRETTY_FUNCTION__
00275 #else
00276 # define MSGSTREAM_FNAME ""
00277 #endif
00278
00279
00280
00281 #if defined( __GNUC__ )
00282 # define ASG_TOOLS_MSGSTREAM_FNAME __PRETTY_FUNCTION__
00283 #else
00284 # define ASG_TOOLS_MSGSTREAM_FNAME ""
00285 #endif
00286
00294 #define ASG_TOOLS_MSGSTREAM_PREFIX \
00295 __FILE__ << ":" << __LINE__ << " (" << ASG_TOOLS_MSGSTREAM_FNAME << "): "
00296
00298 #define ANA_MSG_LVL_SERIOUS( lvl, xmsg ) \
00299 msg( lvl ) << ASG_TOOLS_MSGSTREAM_PREFIX << xmsg << endmsg
00300
00302 #define ANA_MSG_LVL_NOCHK( lvl, xmsg ) \
00303 msg( lvl ) << xmsg << endmsg
00304
00306 #define ANA_MSG_LVL( lvl, xmsg ) \
00307 do { \
00308 if( msg().level() <= lvl ) { \
00309 ANA_MSG_LVL_NOCHK( lvl, xmsg ); \
00310 } \
00311 } while( 0 )
00312
00314 #define ANA_MSG_VERBOSE( xmsg ) ANA_MSG_LVL( MSG::VERBOSE, xmsg )
00316 #define ANA_MSG_DEBUG( xmsg ) ANA_MSG_LVL( MSG::DEBUG, xmsg )
00318 #define ANA_MSG_INFO( xmsg ) ANA_MSG_LVL_NOCHK( MSG::INFO, xmsg )
00320 #define ANA_MSG_WARNING( xmsg ) ANA_MSG_LVL_NOCHK( MSG::WARNING, xmsg )
00322 #define ANA_MSG_ERROR( xmsg ) ANA_MSG_LVL_SERIOUS( MSG::ERROR, xmsg )
00324 #define ANA_MSG_FATAL( xmsg ) ANA_MSG_LVL_SERIOUS( MSG::FATAL, xmsg )
00326 #define ANA_MSG_ALWAYS( xmsg ) ANA_MSG_LVL_NOCHK( MSG::ALWAYS, xmsg )
00327
00328
00329
00334 typedef StatusCode AsgToolsCheckResultType;
00335
00336
00342 #define ANA_CHECK_SET_TYPE(TYPE) \
00343 typedef TYPE AsgToolsCheckResultType;
00344
00345
00352 #define ANA_CHECK(EXP) \
00353 { const auto sc__ = EXP; \
00354 typedef typename std::decay<decltype(sc__)>::type scType__; \
00355 if (!::asg::CheckHelper<scType__>::isSuccess (sc__)) { \
00356 ANA_MSG_ERROR ("Failed to call \"" << #EXP << "\""); \
00357 return ::asg::CheckHelper<AsgToolsCheckResultType>::failureCode(); \
00358 } }
00359
00360
00367 #define ANA_CHECK_THROW(EXP) \
00368 { const auto sc__ = EXP; \
00369 typedef typename std::decay<decltype(sc__)>::type scType__; \
00370 if (!::asg::CheckHelper<scType__>::isSuccess (sc__)) { \
00371 std::ostringstream str; \
00372 str << #EXP; \
00373 ANA_MSG_ERROR ("Failed to call \"" << str.str() << "\", throwing exception"); \
00374 ::asg::detail::throw_check_fail (str.str()); \
00375 } }
00376
00377 #endif