13#ifndef __RD_INVARIANT_H__
14#define __RD_INVARIANT_H__
28#include <boost/numeric/conversion/cast.hpp>
34#if !defined INVARIANT_EXCEPTION_METHOD && !defined INVARIANT_ASSERT_METHOD && \
35 !defined INVARIANT_SILENT_METHOD
36#define INVARIANT_EXCEPTION_METHOD 1
42#if !INVARIANT_EXCEPTION_METHOD && !INVARIANT_ASSERT_METHOD && \
43 !INVARIANT_SILENT_METHOD
44#undef INVARIANT_EXCEPTION_METHOD
45#define INVARIANT_EXCEPTION_METHOD 1
52 Invariant(
const char *prefix,
const char *mess,
const char *expr,
53 const char *
const file,
int line)
54 : std::runtime_error(prefix),
60 Invariant(
const char *prefix,
const std::string &mess,
const char *expr,
61 const char *
const file,
int line)
62 : std::runtime_error(prefix),
70 const
char *
what() const noexcept
override {
return mess_d.c_str(); }
72 const char *
getFile()
const {
return file_dp; }
82 std::string mess_d, expr_d, prefix_d;
84 const char *
const file_dp;
92#define ASSERT_INVARIANT(expr, mess) assert(expr)
98#if INVARIANT_EXCEPTION_METHOD
100#define CHECK_INVARIANT(expr, mess) \
102 Invar::Invariant inv("Invariant Violation", mess, #expr, __FILE__, \
104 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
108#define PRECONDITION(expr, mess) \
110 Invar::Invariant inv("Pre-condition Violation", mess, #expr, __FILE__, \
112 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
116#define POSTCONDITION(expr, mess) \
118 Invar::Invariant inv("Post-condition Violation", mess, #expr, __FILE__, \
120 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
124#define UNDER_CONSTRUCTION(fn) \
125 Invar::Invariant inv("Incomplete Code", \
126 "This routine is still under development", fn, \
127 __FILE__, __LINE__); \
128 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
131#define RANGE_CHECK(lo, x, hi) \
132 if ((lo) > (hi) || (x) < (lo) || (x) > (hi)) { \
133 std::stringstream errstr; \
134 errstr << lo << " <= " << x << " <= " << hi; \
135 Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
137 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
141#define URANGE_CHECK(x, hi) \
143 std::stringstream errstr; \
144 errstr << x << " < " << hi; \
145 Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
147 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
151#define TEST_ASSERT(expr) \
153 Invar::Invariant inv("Test Assert", "Expression Failed: ", #expr, \
154 __FILE__, __LINE__); \
155 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
160#elif INVARIANT_ASSERT_METHOD
162#define CHECK_INVARIANT(expr, mess) assert(expr);
163#define PRECONDITION(expr, mess) assert(expr);
164#define POSTCONDITION(expr, mess) assert(expr);
165#define UNDER_CONSTRUCTION(fn) assert(0);
166#define RANGE_CHECK(lo, x, hi) \
167 assert((lo) <= (hi) && (x) >= (lo) && (x) <= (hi));
168#define URANGE_CHECK(lo, x, hi) assert((hi > 0) && (x < hi));
169#define TEST_ASSERT(expr) assert(expr);
171#elif INVARIANT_SILENT_METHOD
173#define CHECK_INVARIANT(expr, mess)
174#define PRECONDITION(expr, mess)
175#define POSTCONDITION(expr, mess)
176#define UNDER_CONSTRUCTION(fn)
177#define RANGE_CHECK(lo, x, hi)
178#define URANGE_CHECK(x, hi)
179#define TEST_ASSERT(expr)
189#define rdcast boost::numeric_cast
191#define rdcast static_cast
196#define RDUNUSED_PARAM(x) (void)x;
std::string getExpression() const
~Invariant() noexcept override=default
Invariant(const char *prefix, const std::string &mess, const char *expr, const char *const file, int line)
const char * what() const noexcept override
std::string toString() const
std::string toUserString() const
Invariant(const char *prefix, const char *mess, const char *expr, const char *const file, int line)
const char * getFile() const
#define RDKIT_RDGENERAL_EXPORT
RDKIT_RDGENERAL_EXPORT std::ostream & operator<<(std::ostream &s, const Invariant &inv)