siplasplas
A library for C++ reflection and introspection
assert.hpp
1 #ifndef SIPLASPLAS_UTILITY_ASSERT_HPP
2 #define SIPLASPLAS_UTILITY_ASSERT_HPP
3 
4 #include <stdexcept>
5 #include <functional>
6 #include "preprocessor.hpp"
7 #include "exception.hpp"
8 #include <siplasplas/utility/export.hpp>
9 
10 namespace cpp
11 {
12 
26 class SIPLASPLAS_UTILITY_EXPORT AssertException : public std::logic_error
27 {
28 public:
29  using std::logic_error::logic_error;
30 };
31 
43 class SIPLASPLAS_UTILITY_EXPORT AssertExpression
44 {
45 public:
55  AssertExpression(bool expressionResult,
56  const std::string& message,
57  const std::string& file,
58  std::size_t line);
59 
69  ~AssertExpression() noexcept(false);
70 
102  AssertExpression& onFailure(const std::function<void()>& callback);
103 
114  template<typename String, typename... Args>
115  AssertExpression& detail(String&& messageBody, Args&&... messageArgs)
116  {
117  _detail = ::fmt::format(std::forward<String>(messageBody), std::forward<Args>(messageArgs)...);
118  return *this;
119  }
120 
124  template<typename String, typename... Args>
125  AssertExpression& operator()(String&& messageBody, Args&&... args)
126  {
127  return detail(std::forward<String>(messageBody), std::forward<Args>(args)...);
128  }
129 
130 private:
131  std::string _message;
132  std::string _detail;
133  std::string _file;
134  std::size_t _line;
135  std::function<void()> _onFailureCallback;
136  bool _assertionFailed;
137 };
138 
146 class SIPLASPLAS_UTILITY_EXPORT DummyAssertExpression
147 {
148 public:
158  template<typename Function>
160  {
161  return *this;
162  }
163 
173  template<typename String, typename... Args>
174  DummyAssertExpression& detail(String&&, Args&&...)
175  {
176  return *this;
177  }
178 
182  template<typename String, typename... Args>
183  DummyAssertExpression& operator()(String&&, Args&&...)
184  {
185  return *this;
186  }
187 };
188 
189 }
190 
191 #if !defined(NDEBUG) || defined(SIPLASPLAS_ENABLE_ASSERTS)
192 #define SIPLASPLAS_ASSERTS_ENABLED
193 #define SIPLASPLAS_ASSERT_IMPL(MESSAGE, ...) ::cpp::AssertExpression((__VA_ARGS__), MESSAGE, __FILE__, __LINE__)
194 #else
195 #define SIPLASPLAS_ASSERT_IMPL(MESSAGE, ...) ::cpp::DummyAssertExpression()
196 #endif
197 
212 #define SIPLASPLAS_ASSERT(...) SIPLASPLAS_ASSERT_IMPL(SIPLASPLAS_PP_STR((__VA_ARGS__)), __VA_ARGS__)
213 
252 #define SIPLASPLAS_ASSERT_COMP_IMPL(a, b, op, wording) SIPLASPLAS_ASSERT_IMPL(::fmt::format( \
253  "Expected '{}' ({}) {} '{}' ({})", \
254  SIPLASPLAS_PP_STR(a), \
255  a, \
256  wording, \
257  SIPLASPLAS_PP_STR(b), \
258  b \
259  ), ((a) op (b)))
260 
279 #define SIPLASPLAS_ASSERT_EQ(a, b) SIPLASPLAS_ASSERT_COMP_IMPL(a, b, ==, "equal to")
280 
281 
300 #define SIPLASPLAS_ASSERT_NE(a, b) SIPLASPLAS_ASSERT_COMP_IMPL(a, b, !=, "not equal to")
301 
302 
321 #define SIPLASPLAS_ASSERT_BT(a, b) SIPLASPLAS_ASSERT_COMP_IMPL(a, b, > , "bigger than")
322 
323 
342 #define SIPLASPLAS_ASSERT_LT(a, b) SIPLASPLAS_ASSERT_COMP_IMPL(a, b, < , "less than")
343 
344 
363 #define SIPLASPLAS_ASSERT_BE(a, b) SIPLASPLAS_ASSERT_COMP_IMPL(a, b, >=, "bigger or equal to")
364 
365 
384 #define SIPLASPLAS_ASSERT_LE(a, b) SIPLASPLAS_ASSERT_COMP_IMPL(a, b, <=, "less or equal to")
385 
398 #define SIPLASPLAS_ASSERT_TRUE(...) SIPLASPLAS_ASSERT_IMPL(::fmt::format( \
399  "Expected '{}' to be true. Got false instead", \
400  SIPLASPLAS_PP_STR((__VA_ARGS__)) \
401  ), __VA_ARGS__)
402 
415 #define SIPLASPLAS_ASSERT_FALSE(...) SIPLASPLAS_ASSERT_IMPL(::fmt::format( \
416  "Expected '{}' to be false. Got true instead", \
417  SIPLASPLAS_PP_STR((__VA_ARGS__)) \
418  ), !(__VA_ARGS__))
419 
420 
421 #endif // SIPLASPLAS_UTILITY_ASSERT_HPP
DummyAssertExpression & onFailure(Function)
Does nothing.
Definition: assert.hpp:159
Definition: canary_allocator.hpp:7
Represents an assertion error.
Definition: assert.hpp:26
Represents an assert expression when SIPLASPLAS_ASSERT() macros are disabled.
Definition: assert.hpp:146
DummyAssertExpression & operator()(String &&, Args &&...)
Does nothing. Equivalent to detail().
Definition: assert.hpp:183
Implements a siplasplas assertion.
Definition: assert.hpp:43
AssertExpression & detail(String &&messageBody, Args &&...messageArgs)
Adds detailed information to the assertion report.
Definition: assert.hpp:115
DummyAssertExpression & detail(String &&, Args &&...)
Does nothing.
Definition: assert.hpp:174
AssertExpression & operator()(String &&messageBody, Args &&...args)
Adds detailed information to the assertion report. Equivalent to detail().
Definition: assert.hpp:125