9 #ifndef IMPBASE_CHECK_MACROS_H
10 #define IMPBASE_CHECK_MACROS_H
12 #include <IMP/base/base_config.h>
18 #if !defined(IMP_HAS_CHECKS)
19 #error "IMP_HAS_CHECKS is not defined, compilation is broken"
22 #if !defined(IMP_NONE)
23 #error "IMP_NONE is not defined, compilation is broken"
30 #define IMP_CATCH_AND_TERMINATE(expr) \
34 catch (const IMP::base::Exception &e) { \
35 std::cerr << "Application terminated with error :" << e.what() \
50 #define IMP_THROW(message, exception_name) \
53 using namespace IMP::base; \
54 std::ostringstream imp_throw_oss; \
55 imp_throw_oss << message << std::endl; \
56 BOOST_STATIC_ASSERT( \
57 (!(boost::is_base_of<IMP::base::UsageException, \
58 exception_name>::value) && \
59 !(boost::is_base_of<IMP::base::InternalException, \
60 exception_name>::value) && \
61 (boost::is_base_of<IMP::base::Exception, exception_name>::value))); \
62 throw exception_name(imp_throw_oss.str().c_str()); \
69 #define IMP_ALWAYS_CHECK(condition, message, exception_name) \
71 IMP_THROW(message, exception_name); \
80 #define IMP_FAILURE(message) \
82 std::ostringstream imp_failure_oss; \
83 imp_failure_oss << message << std::endl; \
84 IMP::base::handle_error(imp_failure_oss.str().c_str()); \
85 throw IMP::base::InternalException(imp_failure_oss.str().c_str()); \
91 #define IMP_NOT_IMPLEMENTED \
93 IMP::base::handle_error("This method is not implemented."); \
94 throw IMP::base::InternalException("Not implemented"); \
114 #define IMP_IF_CHECK(level)
127 #define IMP_CHECK_CODE(expr)
149 #define IMP_INTERNAL_CHECK(expr, message)
159 #define IMP_INTERNAL_CHECK_FLOAT_EQUAL(expra, exprb, message)
178 #define IMP_USAGE_CHECK(expr, message)
188 #define IMP_USAGE_CHECK_FLOAT_EQUAL(expra, exprb, message)
194 #define IMP_CHECK_VARIABLE(variable)
200 #define IMP_USAGE_CHECK_VARIABLE(variable)
205 #define IMP_INTERNAL_CHECK_VARIABLE(variable)
209 #if IMP_HAS_CHECKS == IMP_INTERNAL
210 #define IMP_CHECK_VARIABLE(variable)
211 #define IMP_USAGE_CHECK_VARIABLE(variable)
212 #define IMP_INTERNAL_CHECK_VARIABLE(variable)
213 #elif IMP_HAS_CHECKS == IMP_USAGE
214 #define IMP_CHECK_VARIABLE(variable)
215 #define IMP_USAGE_CHECK_VARIABLE(variable)
216 #define IMP_INTERNAL_CHECK_VARIABLE(variable) IMP_UNUSED(variable)
218 #define IMP_CHECK_VARIABLE(variable) IMP_UNUSED(variable)
219 #define IMP_USAGE_CHECK_VARIABLE(variable) IMP_UNUSED(variable)
220 #define IMP_INTERNAL_CHECK_VARIABLE(variable) IMP_UNUSED(variable)
223 #if IMP_HAS_CHECKS > IMP_NONE
224 #define IMP_IF_CHECK(level) \
225 using IMP::base::NONE; \
226 using IMP::base::USAGE; \
227 using IMP::base::USAGE_AND_INTERNAL; \
228 if (level <= ::IMP::base::get_check_level())
230 #define IMP_CHECK_CODE(expr) expr
232 #if IMP_BASE_HAS_LOG4CXX
233 #define IMP_BASE_CONTEXT
235 #define IMP_BASE_CONTEXT << IMP::base::get_context_message()
238 #else // IMP_HAS_CHECKS == IMP_NONE
239 #define IMP_IF_CHECK(level) if (0)
240 #define IMP_CHECK_CODE(expr)
241 #endif // IMP_HAS_CHECKS
243 #if IMP_HAS_CHECKS >= IMP_INTERNAL
244 #define IMP_INTERNAL_CHECK(expr, message) \
246 if (IMP::base::get_check_level() >= IMP::base::USAGE_AND_INTERNAL && \
248 std::ostringstream imp_check_oss; \
249 imp_check_oss << "Internal check failure: " << message << std::endl \
250 << " File \"" << __FILE__ << "\", line " \
251 << __LINE__ IMP_BASE_CONTEXT << std::endl; \
252 IMP::base::handle_error(imp_check_oss.str().c_str()); \
253 throw IMP::base::InternalException(imp_check_oss.str().c_str()); \
257 #define IMP_INTERNAL_CHECK_FLOAT_EQUAL(expra, exprb, message) \
258 IMP_INTERNAL_CHECK( \
259 std::abs((expra) - (exprb)) < .1 * std::abs((expra) + (exprb)) + .1, \
260 (expra) << " != " << (exprb) << " - " << message)
262 #define IMP_INTERNAL_CHECK(expr, message)
263 #define IMP_INTERNAL_CHECK_FLOAT_EQUAL(expra, exprb, message)
266 #if IMP_HAS_CHECKS >= IMP_USAGE
267 #define IMP_USAGE_CHECK(expr, message) \
269 if (IMP::base::get_check_level() >= IMP::base::USAGE && !(expr)) { \
270 std::ostringstream imp_check_oss; \
271 imp_check_oss << "Usage check failure: " << message IMP_BASE_CONTEXT \
273 IMP::base::handle_error(imp_check_oss.str().c_str()); \
274 throw IMP::base::UsageException(imp_check_oss.str().c_str()); \
277 #define IMP_USAGE_CHECK_FLOAT_EQUAL(expra, exprb, message) \
279 std::abs((expra) - (exprb)) < .1 * std::abs((expra) + (exprb)) + .1, \
280 expra << " != " << exprb << " - " << message)
282 #define IMP_USAGE_CHECK(expr, message)
283 #define IMP_USAGE_CHECK_FLOAT_EQUAL(expra, exprb, message)
286 #endif // IMP_DOXYGEN
288 #if defined(IMP_DOXYGEN) || IMP_HAS_CHECKS == IMP_NONE
290 #define IMP_CHECK_OBJECT(obj) IMP_UNUSED(obj)
291 #define IMP_CHECK_OBJECT_IF_NOT_nullptr(obj) IMP_UNUSED(obj)
294 #define IMP_CHECK_OBJECT(obj) \
297 IMP_INTERNAL_CHECK((obj), "nullptr object"); \
298 IMP_INTERNAL_CHECK((obj)->get_is_valid(), \
299 "Check object " << static_cast<const void *>(obj) \
300 << " was previously freed"); \
303 #define IMP_CHECK_OBJECT_IF_NOT_nullptr(obj) \
306 IMP_INTERNAL_CHECK((obj)->get_is_valid(), \
307 "Check object " << static_cast<const void *>(obj) \
308 << " was previously freed"); \
Various compiler workarounds.
Exception definitions and assertions.