RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
Invariant.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2013 Greg Landrum, Randal M. Henne and Rational Discovery
3// LLC
4//
5// @@ All Rights Reserved @@
6// This file is part of the RDKit.
7// The contents are covered by the terms of the BSD license
8// which is included in the file license.txt, found at the root
9// of the RDKit source tree.
10//
11
12#include <RDGeneral/export.h>
13#ifndef __RD_INVARIANT_H__
14#define __RD_INVARIANT_H__
15
16#include <cassert>
17#include <string>
18#include <stdexcept>
19
20#include "BoostStartInclude.h"
21#include <RDGeneral/RDLog.h>
22#include "BoostEndInclude.h"
23
24#ifdef RDDEBUG
25// Enable RDDEBUG for testing whether rdcast
26// conversions are within numerical limits
28#include <boost/numeric/conversion/cast.hpp>
30#endif
31//
32// What if no invariant method is defined?
33//
34#if !defined INVARIANT_EXCEPTION_METHOD && !defined INVARIANT_ASSERT_METHOD && \
35 !defined INVARIANT_SILENT_METHOD
36#define INVARIANT_EXCEPTION_METHOD 1
37#endif
38
39//
40// What if an invariant method is defined, but none are true?
41//
42#if !INVARIANT_EXCEPTION_METHOD && !INVARIANT_ASSERT_METHOD && \
43 !INVARIANT_SILENT_METHOD
44#undef INVARIANT_EXCEPTION_METHOD
45#define INVARIANT_EXCEPTION_METHOD 1
46#endif
47
48namespace Invar {
49
50class RDKIT_RDGENERAL_EXPORT Invariant : public std::runtime_error {
51 public:
52 Invariant(const char *prefix, const char *mess, const char *expr,
53 const char *const file, int line)
54 : std::runtime_error(prefix),
55 mess_d(mess),
56 expr_d(expr),
57 prefix_d(prefix),
58 file_dp(file),
59 line_d(line) {}
60 Invariant(const char *prefix, const std::string &mess, const char *expr,
61 const char *const file, int line)
62 : std::runtime_error(prefix),
63 mess_d(mess.c_str()),
64 expr_d(expr),
65 prefix_d(prefix),
66 file_dp(file),
67 line_d(line) {}
68 ~Invariant() noexcept override = default;
69
70 const char *what() const noexcept override { return mess_d.c_str(); }
71
72 const char *getFile() const { return file_dp; }
73
74 std::string getExpression() const { return expr_d; }
75
76 int getLine() const { return line_d; }
77
78 std::string toString() const;
79 std::string toUserString() const; // strips build info, adds version
80
81 private:
82 std::string mess_d, expr_d, prefix_d;
83
84 const char *const file_dp;
85
86 int line_d;
87};
88RDKIT_RDGENERAL_EXPORT std::ostream &operator<<(std::ostream &s,
89 const Invariant &inv);
90} // end of namespace Invar
91
92#define ASSERT_INVARIANT(expr, mess) assert(expr)
93
94//
95// Set desired reporting method
96//
97
98#if INVARIANT_EXCEPTION_METHOD
99
100#define CHECK_INVARIANT(expr, mess) \
101 if (!(expr)) { \
102 Invar::Invariant inv("Invariant Violation", mess, #expr, __FILE__, \
103 __LINE__); \
104 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
105 throw inv; \
106 }
107
108#define PRECONDITION(expr, mess) \
109 if (!(expr)) { \
110 Invar::Invariant inv("Pre-condition Violation", mess, #expr, __FILE__, \
111 __LINE__); \
112 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
113 throw inv; \
114 }
115
116#define POSTCONDITION(expr, mess) \
117 if (!(expr)) { \
118 Invar::Invariant inv("Post-condition Violation", mess, #expr, __FILE__, \
119 __LINE__); \
120 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
121 throw inv; \
122 }
123
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; \
129 throw inv;
130
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__, \
136 __LINE__); \
137 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
138 throw inv; \
139 }
140
141#define URANGE_CHECK(x, hi) \
142 if (x >= (hi)) { \
143 std::stringstream errstr; \
144 errstr << x << " < " << hi; \
145 Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
146 __LINE__); \
147 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
148 throw inv; \
149 }
150
151#define TEST_ASSERT(expr) \
152 if (!(expr)) { \
153 Invar::Invariant inv("Test Assert", "Expression Failed: ", #expr, \
154 __FILE__, __LINE__); \
155 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n" << std::endl; \
156 ; \
157 throw inv; \
158 }
159
160#elif INVARIANT_ASSERT_METHOD
161
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);
170
171#elif INVARIANT_SILENT_METHOD
172
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)
180
181#endif
182
183#ifdef RDDEBUG
184// use rdcast to convert between types
185// when RDDEBUG is defined, this checks for
186// validity (overflow, etc)
187// when RDDEBUG is off, the cast is a no-cost
188// static_cast
189#define rdcast boost::numeric_cast
190#else
191#define rdcast static_cast
192#endif
193
194// Silence warnings for unused params while
195// still indicating that they are unused
196#define RDUNUSED_PARAM(x) (void)x;
197
198#endif
std::string getExpression() const
Definition Invariant.h:74
~Invariant() noexcept override=default
Invariant(const char *prefix, const std::string &mess, const char *expr, const char *const file, int line)
Definition Invariant.h:60
int getLine() const
Definition Invariant.h:76
const char * what() const noexcept override
Definition Invariant.h:70
std::string toString() const
std::string toUserString() const
Invariant(const char *prefix, const char *mess, const char *expr, const char *const file, int line)
Definition Invariant.h:52
const char * getFile() const
Definition Invariant.h:72
#define RDKIT_RDGENERAL_EXPORT
Definition export.h:441
RDKIT_RDGENERAL_EXPORT std::ostream & operator<<(std::ostream &s, const Invariant &inv)