Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
die.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/die.hpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2016-2018 Timo Bingmann <[email protected]>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #ifndef TLX_DIE_HEADER
12 #define TLX_DIE_HEADER
13 
14 #include <cstring>
15 #include <sstream>
16 #include <stdexcept>
17 #include <string>
18 
19 namespace tlx {
20 
21 /******************************************************************************/
22 // die macros
23 
24 //! die with message - either throw an exception or die via std::terminate()
25 void die_with_message(const std::string& msg);
26 
27 //! die with message - either throw an exception or die via std::terminate()
28 void die_with_message(const char* msg, const char* file, size_t line);
29 
30 //! die with message - either throw an exception or die via std::terminate()
31 void die_with_message(const std::string& msg, const char* file, size_t line);
32 
33 //! Instead of std::terminate(), throw the output the message via an exception.
34 #define die_with_sstream(msg) \
35  do { \
36  std::ostringstream oss__; \
37  oss__ << msg << " @ " << __FILE__ << ':' << __LINE__; \
38  ::tlx::die_with_message(oss__.str()); \
39  std::terminate(); /* tell compiler this never returns */ \
40  } while (false)
41 
42 //! Instead of std::terminate(), throw the output the message via an exception.
43 #define die(msg) \
44  do { \
45  die_with_sstream("DIE: " << msg); \
46  } while (false)
47 
48 //! Exception thrown by die_with_message() if
49 class DieException : public std::runtime_error
50 {
51 public:
52  explicit DieException(const std::string& message);
53 };
54 
55 //! Switch between dying via std::terminate() and throwing an exception.
56 //! Alternatively define the macro TLX_DIE_WITH_EXCEPTION=1
57 bool set_die_with_exception(bool b);
58 
59 /******************************************************************************/
60 // die_unless() and die_if()
61 
62 //! Check condition X and die miserably if false. Same as assert() except this
63 //! is also active in Release mode.
64 #define die_unless(X) \
65  do { \
66  if (!(X)) { \
67  ::tlx::die_with_message( \
68  "DIE: Assertion \"" #X "\" failed!", __FILE__, __LINE__); \
69  } \
70  } while (false)
71 
72 //! Check condition X and die miserably if true. Opposite of assert() except
73 //! this is also active in Release mode.
74 #define die_if(X) \
75  do { \
76  if (X) { \
77  ::tlx::die_with_message( \
78  "DIE: Assertion \"" #X "\" succeeded!", __FILE__, __LINE__); \
79  } \
80  } while (false)
81 
82 /******************************************************************************/
83 // die_unequal()
84 
85 //! helper method to compare two values in die_unequal()
86 template <typename TypeA, typename TypeB>
87 inline bool die_equal_compare(TypeA a, TypeB b) {
88  return a == b;
89 }
90 
91 template <>
92 inline bool die_equal_compare(const char* a, const char* b) {
93  // compare string contents
94  return std::strcmp(a, b) == 0;
95 }
96 
97 template <>
98 inline bool die_equal_compare(float a, float b) {
99  // special case for NAN
100  return a != a ? b != b : a == b;
101 }
102 
103 template <>
104 inline bool die_equal_compare(double a, double b) {
105  // special case for NAN
106  return a != a ? b != b : a == b;
107 }
108 
109 //! Check that X == Y or die miserably, but output the values of X and Y for
110 //! better debugging.
111 #define die_unequal(X, Y) \
112  do { \
113  auto x__ = (X); /* NOLINT */ \
114  auto y__ = (Y); /* NOLINT */ \
115  if (!::tlx::die_equal_compare(x__, y__)) \
116  die_with_sstream("DIE-UNEQUAL: " #X " != " #Y " : " \
117  "\"" << x__ << "\" != \"" << y__ << "\""); \
118  } while (false)
119 
120 //! Check that X == Y or die miserably, but output the values of X and Y for
121 //! better debugging. Only active if NDEBUG is not defined.
122 #ifdef NDEBUG
123 #define assert_equal(X, Y)
124 #else
125 #define assert_equal(X, Y) die_unequal(X, Y)
126 #endif
127 
128 /******************************************************************************/
129 // die_unequal_eps()
130 
131 //! simple replacement for std::abs
132 template <typename Type>
133 inline Type die_unequal_eps_abs(const Type& t) {
134  return t < 0 ? -t : t;
135 }
136 
137 //! helper method to compare two values in die_unequal_eps()
138 template <typename TypeA, typename TypeB>
139 inline bool die_equal_eps_compare(TypeA x, TypeB y, double eps) {
140  // special case for NAN
141  return x != x ? y != y : die_unequal_eps_abs(x - y) <= eps;
142 }
143 
144 //! Check that ABS(X - Y) <= eps or die miserably, but output the values of X
145 //! and Y for better debugging.
146 #define die_unequal_eps(X, Y, eps) \
147  do { \
148  auto x__ = (X); /* NOLINT */ \
149  auto y__ = (Y); /* NOLINT */ \
150  if (!::tlx::die_equal_eps_compare(x__, y__, eps)) \
151  die("DIE-UNEQUAL-EPS: " #X " != " #Y " : " \
152  << std::setprecision(18) \
153  << "\"" << x__ << "\" != \"" << y__ << "\""); \
154  } while (false)
155 
156 //! Check that ABS(X - Y) <= 0.000001 or die miserably, but output the values of
157 //! X and Y for better debugging.
158 #define die_unequal_eps6(X, Y) \
159  die_unequal_eps(X, Y, 1e-6)
160 
161 /******************************************************************************/
162 // die_unless_throws()
163 
164 //! Define to check that [code] throws and exception of given type
165 #define die_unless_throws(code, exception_type) \
166  do { \
167  try { \
168  code; \
169  } \
170  catch (const exception_type&) { \
171  break; \
172  } \
173  ::tlx::die_with_message( \
174  "DIE-UNLESS-THROWS: " #code " - NO EXCEPTION " #exception_type, \
175  __FILE__, __LINE__); \
176  } while (false)
177 
178 } // namespace tlx
179 
180 #endif // !TLX_DIE_HEADER
181 
182 /******************************************************************************/
Type die_unequal_eps_abs(const Type &t)
simple replacement for std::abs
Definition: die.hpp:133
bool set_die_with_exception(bool b)
Definition: die.cpp:52
bool die_equal_compare(TypeA a, TypeB b)
helper method to compare two values in die_unequal()
Definition: die.hpp:87
Type
VFS object type.
Definition: file_io.hpp:52
DieException(const std::string &message)
Definition: die.cpp:49
bool die_equal_eps_compare(TypeA x, TypeB y, double eps)
helper method to compare two values in die_unequal_eps()
Definition: die.hpp:139
void die_with_message(const std::string &msg)
die with message - either throw an exception or die via std::terminate()
Definition: die.cpp:29
Exception thrown by die_with_message() if.
Definition: die.hpp:49
list x
Definition: gen_data.py:39
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220