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 "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 
48 namespace Invar {
49 
50 class 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() throw(){};
69 
70  std::string getMessage() const { return mess_d; }
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 };
88 std::ostream& operator<<(std::ostream& s, const Invariant& inv);
89 } // end of namespace Invar
90 
91 #define ASSERT_INVARIANT(expr, mess) assert(expr)
92 
93 //
94 // Set desired reporting method
95 //
96 
97 #if INVARIANT_EXCEPTION_METHOD
98 
99 #define CHECK_INVARIANT(expr, mess) \
100  if (!(expr)) { \
101  Invar::Invariant inv("Invariant Violation", mess, #expr, __FILE__, \
102  __LINE__); \
103  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
104  throw inv; \
105  }
106 
107 #define PRECONDITION(expr, mess) \
108  if (!(expr)) { \
109  Invar::Invariant inv("Pre-condition Violation", mess, #expr, __FILE__, \
110  __LINE__); \
111  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
112  throw inv; \
113  }
114 
115 #define POSTCONDITION(expr, mess) \
116  if (!(expr)) { \
117  Invar::Invariant inv("Post-condition Violation", mess, #expr, __FILE__, \
118  __LINE__); \
119  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
120  throw inv; \
121  }
122 
123 #define UNDER_CONSTRUCTION(fn) \
124  Invar::Invariant inv("Incomplete Code", \
125  "This routine is still under development", fn, \
126  __FILE__, __LINE__); \
127  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
128  throw inv;
129 
130 #define RANGE_CHECK(lo, x, hi) \
131  if ((lo) > (hi) || (x) < (lo) || (x) > (hi)) { \
132  std::stringstream errstr; \
133  errstr << lo << " <= " << x << " <= " << hi; \
134  Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
135  __LINE__); \
136  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
137  throw inv; \
138  }
139 
140 #define URANGE_CHECK(x, hi) \
141  if ((x) > (hi)) { \
142  std::stringstream errstr; \
143  errstr << x << " <= " << hi; \
144  Invar::Invariant inv("Range Error", #x, errstr.str().c_str(), __FILE__, \
145  __LINE__); \
146  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
147  throw inv; \
148  }
149 
150 #define TEST_ASSERT(expr) \
151  if (!(expr)) { \
152  Invar::Invariant inv("Test Assert", "Expression Failed: ", #expr, \
153  __FILE__, __LINE__); \
154  BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; \
155  throw inv; \
156  }
157 
158 #elif INVARIANT_ASSERT_METHOD
159 
160 #define CHECK_INVARIANT(expr, mess) assert(expr);
161 #define PRECONDITION(expr, mess) assert(expr);
162 #define POSTCONDITION(expr, mess) assert(expr);
163 #define UNDER_CONSTRUCTION(fn) assert(0);
164 #define RANGE_CHECK(lo, x, hi) \
165  assert((lo) <= (hi) && (x) >= (lo) && (x) <= (hi));
166 #define URANGE_CHECK(lo, x, hi) assert((x) <= (hi));
167 #define TEST_ASSERT(expr) assert(expr);
168 
169 #elif INVARIANT_SILENT_METHOD
170 
171 #define CHECK_INVARIANT(expr, mess)
172 #define PRECONDITION(expr, mess)
173 #define POSTCONDITION(expr, mess)
174 #define UNDER_CONSTRUCTION(fn)
175 #define RANGE_CHECK(lo, x, hi)
176 #define URANGE_CHECK(x, hi)
177 #define TEST_ASSERT(expr)
178 
179 #endif
180 
181 #ifdef RDDEBUG
182 // use rdcast to convert between types
183 // when RDDEBUG is defined, this checks for
184 // validity (overflow, etc)
185 // when RDDEBUG is off, the cast is a no-cost
186 // static_cast
187 #define rdcast boost::numeric_cast
188 #else
189 #define rdcast static_cast
190 #endif
191 
192 // Silence warnings for unused params while
193 // still indicating that they are unused
194 #define RDUNUSED_PARAM(x) (void) x;
195 
196 #endif
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
STL namespace.
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
std::string getMessage() const
Definition: Invariant.h:70
std::ostream & operator<<(std::ostream &s, const Invariant &inv)
std::string getExpression() const
Definition: Invariant.h:74