RDKit
Open-source cheminformatics and machine learning.
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 #ifndef __RD_INVARIANT_H__
13 #define __RD_INVARIANT_H__
14 
15 #include <assert.h>
16 #include <string>
17 #include <iostream>
18 #include <stdexcept>
19 
20 #include <RDGeneral/RDLog.h>
21 
22 #ifdef RDDEBUG
23 // Enable RDDEBUG for testing whether rdcast
24 // conversions are within numerical limits
25 #include <boost/numeric/conversion/cast.hpp>
26 #endif
27 //
28 // What if no invariant method is defined?
29 //
30 #if !defined INVARIANT_EXCEPTION_METHOD && !defined INVARIANT_ASSERT_METHOD && \
31  !defined INVARIANT_SILENT_METHOD
32 #define INVARIANT_EXCEPTION_METHOD 1
33 #endif
34 
35 //
36 // What if an invariant method is defined, but none are true?
37 //
38 #if !INVARIANT_EXCEPTION_METHOD && !INVARIANT_ASSERT_METHOD && \
39  !INVARIANT_SILENT_METHOD
40 #undef INVARIANT_EXCEPTION_METHOD
41 #define INVARIANT_EXCEPTION_METHOD 1
42 #endif
43 
44 namespace Invar {
45 
46 class Invariant : public std::runtime_error {
47  public:
48  Invariant(const char* prefix, const char* mess, const char* expr,
49  const char* const file, int line)
50  : std::runtime_error(prefix),
51  mess_d(mess),
52  expr_d(expr),
53  prefix_d(prefix),
54  file_dp(file),
55  line_d(line) {}
56  Invariant(const char* prefix, const std::string& mess, const char* expr,
57  const char* const file, int line)
58  : std::runtime_error(prefix),
59  mess_d(mess.c_str()),
60  expr_d(expr),
61  prefix_d(prefix),
62  file_dp(file),
63  line_d(line) {}
64  ~Invariant() throw(){};
65 
66  std::string getMessage() const { return mess_d; }
67 
68  const char* getFile() const { return file_dp; }
69 
70  std::string getExpression() const { return expr_d; }
71 
72  int getLine() const { return line_d; }
73 
74  std::string toString() const;
75  std::string toUserString() const; // strips build info, adds version
76 
77  private:
78  std::string mess_d, expr_d, prefix_d;
79 
80  const char* const file_dp;
81 
82  int line_d;
83 };
84 std::ostream& operator<<(std::ostream& s, const Invariant& inv);
85 } // end of namespace Invar
86 
87 #define ASSERT_INVARIANT(expr, mess) assert(expr)
88 
89 //
90 // Set desired reporting method
91 //
92 
93 #if INVARIANT_EXCEPTION_METHOD
94 
95 #define CHECK_INVARIANT(expr, mess) \
96  if (!(expr)) { \
97  Invar::Invariant inv("Invariant Violation", mess, #expr, __FILE__, \
98  __LINE__); \
99  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
100  throw inv; \
101  }
102 
103 #define PRECONDITION(expr, mess) \
104  if (!(expr)) { \
105  Invar::Invariant inv("Pre-condition Violation", mess, #expr, __FILE__, \
106  __LINE__); \
107  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
108  throw inv; \
109  }
110 
111 #define POSTCONDITION(expr, mess) \
112  if (!(expr)) { \
113  Invar::Invariant inv("Post-condition Violation", mess, #expr, __FILE__, \
114  __LINE__); \
115  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
116  throw inv; \
117  }
118 
119 #define UNDER_CONSTRUCTION(fn) \
120  Invar::Invariant inv("Incomplete Code", \
121  "This routine is still under development", fn, \
122  __FILE__, __LINE__); \
123  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
124  throw inv;
125 
126 #define RANGE_CHECK(lo, x, hi) \
127  if ((lo) > (hi) || (x) < (lo) || (x) > (hi)) { \
128  std::stringstream errstr; \
129  errstr << lo << " <= " << x << " <= " << hi; \
130  Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
131  __LINE__); \
132  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
133  throw inv; \
134  }
135 
136 #define URANGE_CHECK(x, hi) \
137  if ((x) > (hi)) { \
138  std::stringstream errstr; \
139  errstr << x << " <= " << hi; \
140  Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
141  __LINE__); \
142  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
143  throw inv; \
144  }
145 
146 #define TEST_ASSERT(expr) \
147  if (!(expr)) { \
148  Invar::Invariant inv("Test Assert", "Expression Failed: ", #expr, \
149  __FILE__, __LINE__); \
150  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
151  throw inv; \
152  }
153 
154 #elif INVARIANT_ASSERT_METHOD
155 
156 #define CHECK_INVARIANT(expr, mess) assert(expr);
157 #define PRECONDITION(expr, mess) assert(expr);
158 #define POSTCONDITION(expr, mess) assert(expr);
159 #define UNDER_CONSTRUCTION(fn) assert(0);
160 #define RANGE_CHECK(lo, x, hi) \
161  assert((lo) <= (hi) && (x) >= (lo) && (x) <= (hi));
162 #define URANGE_CHECK(lo, x, hi) assert((x) <= (hi));
163 #define TEST_ASSERT(expr) assert(expr);
164 
165 #elif INVARIANT_SILENT_METHOD
166 
167 #define CHECK_INVARIANT(expr, mess)
168 #define PRECONDITION(expr, mess)
169 #define POSTCONDITION(expr, mess)
170 #define UNDER_CONSTRUCTION(fn)
171 #define RANGE_CHECK(lo, x, hi)
172 #define URANGE_CHECK(x, hi)
173 #define TEST_ASSERT(expr)
174 
175 #endif
176 
177 #ifdef RDDEBUG
178 // use rdcast to convert between types
179 // when RDDEBUG is defined, this checks for
180 // validity (overflow, etc)
181 // when RDDEBUG is off, the cast is a no-cost
182 // static_cast
183 #define rdcast boost::numeric_cast
184 #else
185 #define rdcast static_cast
186 #endif
187 
188 // Silence warnings for unused params while
189 // still indicating that they are unused
190 #define RDUNUSED_PARAM(x) (void) x;
191 
192 #endif
Invariant(const char *prefix, const std::string &mess, const char *expr, const char *const file, int line)
Definition: Invariant.h:56
const char * getFile() const
Definition: Invariant.h:68
STL namespace.
std::string toUserString() const
std::string getMessage() const
Definition: Invariant.h:66
std::string getExpression() const
Definition: Invariant.h:70
Invariant(const char *prefix, const char *mess, const char *expr, const char *const file, int line)
Definition: Invariant.h:48
std::string toString() const
int getLine() const
Definition: Invariant.h:72
std::ostream & operator<<(std::ostream &s, const Invariant &inv)