ROSE  0.11.96.11
Assert.h
1 // WARNING: Changes to this file must be contributed back to Sawyer or else they will
2 // be clobbered by the next update from Sawyer. The Sawyer repository is at
3 // https://github.com/matzke1/sawyer.
4 
5 
6 
7 
8 #ifndef Sawyer_Assert_H
9 #define Sawyer_Assert_H
10 
11 #include <Sawyer/Sawyer.h>
12 #include <string>
13 
14 // If SAWYER_NDEBUG is defined then some of the macros defined in this header become no-ops. For interoperability with the
15 // more standard NDEBUG symbol, we define SAWYER_NDEBUG if NDEBUG is defined.
16 #ifdef NDEBUG
17 #undef SAWYER_NDEBUG
18 #define SAWYER_NDEBUG
19 #endif
20 
21 namespace Sawyer { // documented elsewhere
22 
90 namespace Assert {
91 
94 SAWYER_EXPORT
95 #if __cplusplus >= 201103L
96 [[noreturn]]
97 #endif
98 void fail(const char *mesg, const char *expr, const std::string &note,
99  const char *filename, unsigned linenum, const char *funcname);
100 
102 typedef void (*AssertFailureHandler)(const char *mesg, const char *expr, const std::string &note,
103  const char *filename, unsigned linenum, const char *funcname);
104 
108 SAWYER_EXPORT extern AssertFailureHandler assertFailureHandler;
109 
110 } // namespace
111 } // namespace
112 
114 // These "always" macros are enabled regardless of whether SAWYER_NDEBUG is defined. Don't use them for
115 // expensive assertions.
117 
118 #define ASSERT_always_require(expr) ASSERT_always_require2(expr, "")
119 #define ASSERT_always_require2(expr, note) \
120  ((expr) ? \
121  static_cast<void>(0) : \
122  Sawyer::Assert::fail("assertion failed", "required: " #expr, (note), \
123  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
124 
125 #define ASSERT_always_forbid(expr) ASSERT_always_forbid2(expr, "")
126 #define ASSERT_always_forbid2(expr, note) \
127  (!(expr) ? \
128  static_cast<void>(0) : \
129  Sawyer::Assert::fail("assertion failed", \
130  "forbidden: " #expr, (note), __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
131 
132 #define ASSERT_always_not_null(expr) ASSERT_always_not_null2(expr, "")
133 #define ASSERT_always_not_null2(expr, note) \
134  ((expr)!=NULL ? \
135  static_cast<void>(0) : \
136  Sawyer::Assert::fail("null pointer", \
137  #expr, (note), __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
138 
139 #define ASSERT_always_not_reachable(note) \
140  Sawyer::Assert::fail("reached impossible state", NULL, (note), \
141  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION);
142 
143 #define ASSERT_always_not_implemented(note) \
144  Sawyer::Assert::fail("not implemented yet", NULL, (note), \
145  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION)
146 
147 #define ASSERT_always_this() /*void*/
148 
150 // The non-"always" macros might change behavior based on whether SAWYER_NDEBUG is defined.
152 
153 #ifdef SAWYER_NDEBUG
154 
155 #define ASSERT_require(expr) /*void*/
156 #define ASSERT_require2(expr, note) /*void*/
157 #define ASSERT_forbid(expr) /*void*/
158 #define ASSERT_forbid2(expr, note) /*void*/
159 #define ASSERT_not_null(expr) /*void*/
160 #define ASSERT_not_null2(expr, note) /*void*/
161 #define ASSERT_not_reachable(note) ASSERT_always_not_reachable(note)
162 #define ASSERT_not_implemented(note) ASSERT_always_not_implemented(note)
163 #define ASSERT_this() /*void*/
164 
165 #else
166 
167 #define ASSERT_require(expr) ASSERT_always_require(expr)
168 #define ASSERT_require2(expr, note) ASSERT_always_require2(expr, note)
169 #define ASSERT_forbid(expr) ASSERT_always_forbid(expr)
170 #define ASSERT_forbid2(expr, note) ASSERT_always_forbid2(expr, note)
171 #define ASSERT_not_null(expr) ASSERT_always_not_null(expr)
172 #define ASSERT_not_null2(expr, note) ASSERT_always_not_null2(expr, note)
173 #define ASSERT_not_reachable(note) ASSERT_always_not_reachable(note)
174 #define ASSERT_not_implemented(note) ASSERT_always_not_implemented(note)
175 #define ASSERT_this() /*void*/
176 
177 #endif
178 
180 // Macros recognized by some IDEs
182 
183 #define TODO(note) \
184  Sawyer::Assert::fail("not implemented yet", NULL, (note), \
185  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION)
186 
187 #define FIXME(note) \
188  Sawyer::Assert::fail("needs to be fixed", NULL, (note), \
189  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION)
190 
191 #endif
Sawyer::Assert::fail
void fail(const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname)
Cause immediate failure.
Sawyer::Assert::AssertFailureHandler
void(* AssertFailureHandler)(const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname)
Type for user-defined assertion failure handler.
Definition: Assert.h:102
Sawyer
Name space for the entire library.
Definition: Access.h:13
Sawyer::Assert::assertFailureHandler
AssertFailureHandler assertFailureHandler
Optional user callback to handle assertion failures.