ROSE  0.9.9.109
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 
93 namespace Assert {
94 
97 SAWYER_EXPORT_NORETURN void fail(const char *mesg, const char *expr, const std::string &note,
98  const char *filename, unsigned linenum, const char *funcname) SAWYER_ATTR_NORETURN;
99 
101 typedef void (*AssertFailureHandler)(const char *mesg, const char *expr, const std::string &note,
102  const char *filename, unsigned linenum, const char *funcname);
103 
107 SAWYER_EXPORT extern AssertFailureHandler assertFailureHandler;
108 
109 } // namespace
110 } // namespace
111 
113 // These "always" macros are enabled regardless of whether SAWYER_NDEBUG is defined. Don't use them for
114 // expensive assertions.
116 
117 #define ASSERT_always_require(expr) ASSERT_always_require2(expr, "")
118 #define ASSERT_always_require2(expr, note) \
119  ((expr) ? \
120  static_cast<void>(0) : \
121  Sawyer::Assert::fail("assertion failed", "required: " #expr, (note), \
122  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
123 
124 #define ASSERT_always_forbid(expr) ASSERT_always_forbid2(expr, "")
125 #define ASSERT_always_forbid2(expr, note) \
126  (!(expr) ? \
127  static_cast<void>(0) : \
128  Sawyer::Assert::fail("assertion failed", \
129  "forbidden: " #expr, (note), __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
130 
131 #define ASSERT_always_not_null(expr) ASSERT_always_not_null2(expr, "")
132 #define ASSERT_always_not_null2(expr, note) \
133  ((expr)!=NULL ? \
134  static_cast<void>(0) : \
135  Sawyer::Assert::fail("null pointer", \
136  #expr, (note), __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
137 
138 #define ASSERT_always_not_reachable(note) \
139  Sawyer::Assert::fail("reached impossible state", NULL, (note), \
140  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION);
141 
142 #define ASSERT_always_not_implemented(note) \
143  Sawyer::Assert::fail("not implemented yet", NULL, (note), \
144  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION)
145 
146 #define ASSERT_always_this() \
147  (this ? \
148  static_cast<void>(0) : \
149  Sawyer::Assert::fail("assertion failed", \
150  "required: this!=NULL", "'this' cannot be null in an object method", \
151  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION))
152 
154 // The non-"always" macros might change behavior based on whether SAWYER_NDEBUG is defined.
156 
157 #ifdef SAWYER_NDEBUG
158 
159 #define ASSERT_require(expr) /*void*/
160 #define ASSERT_require2(expr, note) /*void*/
161 #define ASSERT_forbid(expr) /*void*/
162 #define ASSERT_forbid2(expr, note) /*void*/
163 #define ASSERT_not_null(expr) /*void*/
164 #define ASSERT_not_null2(expr, note) /*void*/
165 #define ASSERT_not_reachable(note) ASSERT_always_not_reachable(note)
166 #define ASSERT_not_implemented(note) ASSERT_always_not_implemented(note)
167 #define ASSERT_this() /*void*/
168 
169 #else
170 
171 #define ASSERT_require(expr) ASSERT_always_require(expr)
172 #define ASSERT_require2(expr, note) ASSERT_always_require2(expr, note)
173 #define ASSERT_forbid(expr) ASSERT_always_forbid(expr)
174 #define ASSERT_forbid2(expr, note) ASSERT_always_forbid2(expr, note)
175 #define ASSERT_not_null(expr) ASSERT_always_not_null(expr)
176 #define ASSERT_not_null2(expr, note) ASSERT_always_not_null2(expr, note)
177 #define ASSERT_not_reachable(note) ASSERT_always_not_reachable(note)
178 #define ASSERT_not_implemented(note) ASSERT_always_not_implemented(note)
179 #define ASSERT_this() ASSERT_always_this()
180 
181 #endif
182 
184 // Macros recognized by some IDEs
186 
187 #define TODO(note) \
188  Sawyer::Assert::fail("not implemented yet", NULL, (note), \
189  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION)
190 
191 #define FIXME(note) \
192  Sawyer::Assert::fail("needs to be fixed", NULL, (note), \
193  __FILE__, __LINE__, SAWYER_PRETTY_FUNCTION)
194 
195 #endif
void fail(const char *mesg, const char *expr, const std::string &note, const char *filename, unsigned linenum, const char *funcname) __attribute__((noreturn))
Cause immediate failure.
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:101
Name space for the entire library.
Definition: Access.h:11
AssertFailureHandler assertFailureHandler
Optional user callback to handle assertion failures.