| The Gaudi Framework v32r1 (f65d50dc)

StatusCode.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_STATUSCODE_H
2 #define GAUDIKERNEL_STATUSCODE_H
3
4 #include "boost/preprocessor/facilities/overload.hpp"
5 #include <ostream>
6 #include <type_traits>
7 #include <utility>
8
9 #include "GaudiKernel/Kernel.h"
10
11 template <typename T>
12 struct is_StatusCode_enum : std::false_type {};
13
50 class StatusCode final {
51 public:
52 typedef unsigned long code_t;
53
54 enum class ErrorCode : code_t { FAILURE = 0, SUCCESS = 1, RECOVERABLE = 2 };
55
63 struct Category {
64 constexpr Category() noexcept = default;
65 virtual ~Category() {}
66
68 virtual const char* name() const = 0;
69
71 virtual std::string message( code_t code ) const { return "UNKNOWN(" + std::to_string( code ) + ")"; }
72
75 virtual bool isSuccess( code_t code ) const { return code == static_cast<code_t>( ErrorCode::SUCCESS ); }
76
78 virtual bool isRecoverable( code_t code ) const { return code == static_cast<code_t>( ErrorCode::RECOVERABLE ); }
79 };
80
82 static const Category& default_category() noexcept;
83
84 // Provide shorthands for default code values
85 constexpr const static auto SUCCESS = ErrorCode::SUCCESS;
86 constexpr const static auto FAILURE = ErrorCode::FAILURE;
87 constexpr const static auto RECOVERABLE = ErrorCode::RECOVERABLE;
88
90 StatusCode() = default;
91
93 template <typename T, typename = std::enable_if_t<is_StatusCode_enum<T>::value>>
94 StatusCode( T sc, bool checked = false ) noexcept {
95 *this = StatusCode( static_cast<StatusCode::code_t>( sc ), is_StatusCode_enum<T>::instance );
96 m_checked = checked;
97 }
98
100 explicit StatusCode( code_t code, const StatusCode::Category& cat = default_category(),
101 bool checked = false ) noexcept
102 : m_cat( &cat ), m_code( code ), m_checked( checked ) {}
103
105 explicit StatusCode( code_t code, bool checked ) noexcept : StatusCode( code, default_category(), checked ) {}
106
108 StatusCode( const StatusCode& rhs ) noexcept : m_cat( rhs.m_cat ), m_code( rhs.m_code ), m_checked( rhs.m_checked ) {
109 rhs.m_checked = true;
110 }
111
113 StatusCode( StatusCode&& rhs ) noexcept : m_cat( rhs.m_cat ), m_code( rhs.m_code ), m_checked( rhs.m_checked ) {
114 rhs.m_checked = true;
115 }
116
118 ~StatusCode() {
119 if ( UNLIKELY( s_checking ) ) check();
120 }
121
122 StatusCode& operator=( const StatusCode& rhs ) noexcept {
123 m_cat = rhs.m_cat;
124 m_code = rhs.m_code;
125 m_checked = std::exchange( rhs.m_checked, true );
126 return *this;
127 }
128
129 bool isSuccess() const;
130 bool isFailure() const { return !isSuccess(); }
131 bool isRecoverable() const;
132
134 explicit operator bool() const { return isSuccess(); }
135
137 code_t getCode() const {
138 m_checked = true;
139 return m_code;
140 }
141
143 const StatusCode& setChecked( bool checked = true ) const {
144 m_checked = checked;
145 return *this;
146 }
147 StatusCode& setChecked( bool checked = true ) {
148 m_checked = checked;
149 return *this;
150 }
151
153 const StatusCode& ignore() const {
154 setChecked( true );
155 return *this;
156 }
157 StatusCode& ignore() {
158 setChecked( true );
159 return *this;
160 }
161
163 bool checked() const { return m_checked; }
164
166 const StatusCode::Category& getCategory() const { return *m_cat; }
167
169 std::string message() const { return getCategory().message( m_code ); }
170
171 friend std::ostream& operator<<( std::ostream& s, const StatusCode& sc ) {
172 s << sc.message();
173 return s;
174 }
175
179 friend bool operator==( const StatusCode& lhs, const StatusCode& rhs );
180 friend bool operator!=( const StatusCode& lhs, const StatusCode& rhs ) { return !( lhs == rhs ); }
181
183 friend bool operator<( const StatusCode& lhs, const StatusCode& rhs ) {
184 lhs.m_checked = true;
185 rhs.m_checked = true;
186 return ( lhs.m_cat < rhs.m_cat || ( lhs.m_cat == rhs.m_cat && lhs.m_code < rhs.m_code ) );
187 }
188
190 StatusCode& operator&=( const StatusCode& rhs );
191 StatusCode& operator|=( const StatusCode& rhs );
192
193 static GAUDI_API void enableChecking();
194 static GAUDI_API void disableChecking();
195 static GAUDI_API bool checkingEnabled();
196
211 class ScopedDisableChecking {
212 bool m_enabled;
213
214 public:
215 ScopedDisableChecking() : m_enabled( StatusCode::checkingEnabled() ) {
216 if ( m_enabled ) StatusCode::disableChecking();
217 }
218 ~ScopedDisableChecking() {
219 if ( m_enabled ) StatusCode::enableChecking();
220 }
221 };
222
223 private:
224 const Category* m_cat{&default_category()};
225 code_t m_code{static_cast<code_t>( ErrorCode::SUCCESS )};
226 mutable bool m_checked{false};
227 static bool s_checking;
228
229 ErrorCode default_value() const;
230 void check();
231 };
232
233 /*
234 * Macros to declare/implement StatusCode enums/categories
235 */
236
239 #define STATUSCODE_ENUM_DECL( ENUM ) \
240 template <> \
241 struct is_StatusCode_enum<ENUM> : std::true_type { \
242 static const StatusCode::Category& instance; \
243 };
244
248 #define STATUSCODE_ENUM_IMPL( ... ) BOOST_PP_OVERLOAD( STATUSCODE_ENUM_IMPL_, __VA_ARGS__ )( __VA_ARGS__ )
249
250 #define STATUSCODE_ENUM_IMPL_1( ENUM ) \
251 const StatusCode::Category& is_StatusCode_enum<ENUM>::instance = StatusCode::default_category();
252
253 #define STATUSCODE_ENUM_IMPL_2( ENUM, CATEGORY ) \
254 const StatusCode::Category& is_StatusCode_enum<ENUM>::instance = CATEGORY{};
255
256 // Declare the default StatusCode enum
257 STATUSCODE_ENUM_DECL( StatusCode::ErrorCode )
258
259 /*
260 * Inline methods
261 */
262
263 inline const StatusCode::Category& StatusCode::default_category() noexcept {
264 return is_StatusCode_enum<StatusCode::ErrorCode>::instance;
265 }
266
267 inline bool StatusCode::isSuccess() const {
268 m_checked = true;
269 return ( m_code == static_cast<code_t>( ErrorCode::SUCCESS ) || m_cat->isSuccess( m_code ) );
270 }
271
272 inline bool StatusCode::isRecoverable() const {
273 m_checked = true;
274 return m_cat->isRecoverable( m_code );
275 }
276
277 inline StatusCode::ErrorCode StatusCode::default_value() const {
278 bool save_checked = m_checked; // Preserve checked status
279 auto r = isSuccess() ? ErrorCode::SUCCESS : ( isRecoverable() ? ErrorCode::RECOVERABLE : ErrorCode::FAILURE );
280 m_checked = save_checked;
281 return r;
282 }
283
284 inline bool operator==( const StatusCode& lhs, const StatusCode& rhs ) {
285 lhs.m_checked = true;
286 rhs.m_checked = true;
287 return ( lhs.m_code == rhs.m_code ) &&
288 ( lhs.m_code == static_cast<StatusCode::code_t>( StatusCode::ErrorCode::SUCCESS ) ||
289 lhs.m_code == static_cast<StatusCode::code_t>( StatusCode::ErrorCode::FAILURE ) ||
290 ( lhs.m_cat == rhs.m_cat ) );
291 }
292
293 inline StatusCode& StatusCode::operator&=( const StatusCode& rhs ) {
294 // Ternary AND lookup matrix
295 static constexpr StatusCode::code_t AND[3][3] = {{0, 0, 0}, {0, 1, 2}, {0, 2, 2}};
296
297 StatusCode::code_t l = static_cast<StatusCode::code_t>( default_value() );
298 StatusCode::code_t r = static_cast<StatusCode::code_t>( rhs.default_value() );
299 m_code = AND[l][r];
300 rhs.m_checked = true;
301 return *this;
302 }
303
304 inline StatusCode& StatusCode::operator|=( const StatusCode& rhs ) {
305 // Ternary OR lookup matrix
306 static constexpr StatusCode::code_t OR[3][3] = {{0, 1, 2}, {1, 1, 1}, {2, 1, 2}};
307
308 StatusCode::code_t l = static_cast<StatusCode::code_t>( default_value() );
309 StatusCode::code_t r = static_cast<StatusCode::code_t>( rhs.default_value() );
310 m_code = OR[l][r];
311 rhs.m_checked = true;
312 return *this;
313 }
314
316 inline StatusCode operator&( StatusCode lhs, const StatusCode& rhs ) { return lhs &= rhs; }
317
319 inline StatusCode operator|( StatusCode lhs, const StatusCode& rhs ) { return lhs |= rhs; }
320
322 inline bool& operator&=( bool& lhs, const StatusCode& sc ) { return lhs &= sc.isSuccess(); }
323
325 inline bool& operator|=( bool& lhs, const StatusCode& sc ) { return lhs |= sc.isSuccess(); }
326
327 #endif // GAUDIKERNEL_STATUSCODE_H
StatusCode::getCode
code_t getCode() const
Retrieve value ("checks" the StatusCode)
Definition: StatusCode.h:137
UNLIKELY
#define UNLIKELY(x)
Definition: Kernel.h:96
Kernel.h
StatusCode::checked
bool checked() const
Has the StatusCode been checked?
Definition: StatusCode.h:163
operator|
StatusCode operator|(StatusCode lhs, const StatusCode &rhs)
Ternary OR operator.
Definition: StatusCode.h:319
gaudirun.default
default
Definition: gaudirun.py:169
StatusCode::ErrorCode
ErrorCode
Definition: StatusCode.h:54
StatusCode::check
void check()
Do StatusCode check.
Definition: StatusCode.cpp:48
StatusCode::m_code
code_t m_code
The status code value.
Definition: StatusCode.h:225
StatusCode::operator<
friend bool operator<(const StatusCode &lhs, const StatusCode &rhs)
Comparison (values are grouped by category first)
Definition: StatusCode.h:183
StatusCode::m_checked
bool m_checked
If the StatusCode has been checked.
Definition: StatusCode.h:226
StatusCode::Category
The category assigned to a StatusCode.
Definition: StatusCode.h:63
StatusCode::RECOVERABLE
constexpr static const auto RECOVERABLE
Definition: StatusCode.h:87
StatusCode::operator=
StatusCode & operator=(const StatusCode &rhs) noexcept
Definition: StatusCode.h:122
std::to_string
T to_string(T... args)
StatusCode::StatusCode
StatusCode(code_t code, const StatusCode::Category &cat=default_category(), bool checked=false) noexcept
Constructor from code_t in the default category (explicit conversion only)
Definition: StatusCode.h:100
StatusCode::ScopedDisableChecking::~ScopedDisableChecking
~ScopedDisableChecking()
Definition: StatusCode.h:218
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
StatusCode::Category::name
virtual const char * name() const =0
Name of the category.
std
STL namespace.
StatusCode::~StatusCode
~StatusCode()
Destructor.
Definition: StatusCode.h:118
StatusCode::StatusCode
StatusCode(code_t code, bool checked) noexcept
Constructor from code_t and category (explicit conversion only)
Definition: StatusCode.h:105
StatusCode::enableChecking
static GAUDI_API void enableChecking()
Definition: StatusCode.cpp:42
StatusCode::StatusCode
StatusCode(const StatusCode &rhs) noexcept
Copy constructor.
Definition: StatusCode.h:108
StatusCode::ErrorCode::SUCCESS
StatusCode::checkingEnabled
static GAUDI_API bool checkingEnabled()
Definition: StatusCode.cpp:46
StatusCode::setChecked
StatusCode & setChecked(bool checked=true)
Definition: StatusCode.h:147
StatusCode::getCategory
const StatusCode::Category & getCategory() const
Retrieve category (does not "check" the StatusCode)
Definition: StatusCode.h:166
StatusCode::Category::isSuccess
virtual bool isSuccess(code_t code) const
Is code considered success ?
Definition: StatusCode.h:75
std::string
STL class.
StatusCode::operator<<
friend std::ostream & operator<<(std::ostream &s, const StatusCode &sc)
Definition: StatusCode.h:171
StatusCode::ignore
StatusCode & ignore()
Definition: StatusCode.h:157
STATUSCODE_ENUM_DECL
#define STATUSCODE_ENUM_DECL(ENUM)
Declare an enum to be used as StatusCode value.
Definition: StatusCode.h:239
StatusCode::Category::~Category
virtual ~Category()
Definition: StatusCode.h:65
StatusCode::Category::message
virtual std::string message(code_t code) const
Description for code within this category.
Definition: StatusCode.h:71
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
StatusCode::Category::isRecoverable
virtual bool isRecoverable(code_t code) const
Is code considered recoverable ?
Definition: StatusCode.h:78
StatusCode::operator!=
friend bool operator!=(const StatusCode &lhs, const StatusCode &rhs)
Definition: StatusCode.h:180
StatusCode::default_category
static const Category & default_category() noexcept
Default Gaudi StatusCode category.
Definition: StatusCode.h:263
StatusCode::ScopedDisableChecking
Simple RAII class to ignore unchecked StatusCode instances in a scope.
Definition: StatusCode.h:211
StatusCode::s_checking
static bool s_checking
Global flag to control if StatusCode need to be checked.
Definition: StatusCode.h:227
is_StatusCode_enum
Definition: StatusCode.h:12
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:267
StatusCode::ErrorCode::FAILURE
StatusCode::message
std::string message() const
Description (or name) of StatusCode value.
Definition: StatusCode.h:169
gaudirun.l
dictionary l
Definition: gaudirun.py:521
operator &
StatusCode operator &(StatusCode lhs, const StatusCode &rhs)
Ternary AND operator.
Definition: StatusCode.h:316
operator==
bool operator==(const StatusCode &lhs, const StatusCode &rhs)
Definition: StatusCode.h:284
StatusCode::ErrorCode::RECOVERABLE
StatusCode::ignore
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:153
StatusCode::operator==
friend bool operator==(const StatusCode &lhs, const StatusCode &rhs)
Check if StatusCode value and category are the same.
Definition: StatusCode.h:284
std::false_type
StatusCode::Category::Category
constexpr Category() noexcept=default
operator|=
bool & operator|=(bool &lhs, const StatusCode &sc)
Boolean OR assignment operator.
Definition: StatusCode.h:325
gaudirun.s
string s
Definition: gaudirun.py:316
StatusCode::isRecoverable
bool isRecoverable() const
Definition: StatusCode.h:272
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
StatusCode::disableChecking
static GAUDI_API void disableChecking()
Definition: StatusCode.cpp:44
StatusCode::StatusCode
StatusCode()=default
Default constructor.
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:130
operator&=
bool & operator&=(bool &lhs, const StatusCode &sc)
Boolean AND assignment operator.
Definition: StatusCode.h:322
StatusCode::StatusCode
StatusCode(StatusCode &&rhs) noexcept
Move constructor.
Definition: StatusCode.h:113
GAUDI_API
#define GAUDI_API
Definition: Kernel.h:71
std::ostream
STL class.
StatusCode::setChecked
const StatusCode & setChecked(bool checked=true) const
Check/uncheck StatusCode.
Definition: StatusCode.h:143
StatusCode::default_value
ErrorCode default_value() const
Project onto the default StatusCode values.
Definition: StatusCode.h:277
StatusCode::m_cat
const Category * m_cat
The status code category.
Definition: StatusCode.h:224
StatusCode::operator|=
StatusCode & operator|=(const StatusCode &rhs)
Ternary logic operator with RECOVERABLE being the "third" state.
Definition: StatusCode.h:304
StatusCode::ScopedDisableChecking::ScopedDisableChecking
ScopedDisableChecking()
Definition: StatusCode.h:215
StatusCode::operator&=
StatusCode & operator&=(const StatusCode &rhs)
Ternary logic operator with RECOVERABLE being the "third" state.
Definition: StatusCode.h:293
StatusCode::ScopedDisableChecking::m_enabled
bool m_enabled
Definition: StatusCode.h:212
StatusCode::code_t
unsigned long code_t
type of StatusCode value
Definition: StatusCode.h:52