gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 1 0
merge default
0 files changed with 3 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 4294967296 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_ASSERT_H
20 20
#define LEMON_ASSERT_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Extended assertion handling
25 25

	
26 26
#include <lemon/error.h>
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  inline void assert_fail_log(const char *file, int line, const char *function,
31 31
                              const char *message, const char *assertion)
32 32
  {
33 33
    std::cerr << file << ":" << line << ": ";
34 34
    if (function)
35 35
      std::cerr << function << ": ";
36 36
    std::cerr << message;
37 37
    if (assertion)
38 38
      std::cerr << " (assertion '" << assertion << "' failed)";
39 39
    std::cerr << std::endl;
40 40
  }
41 41

	
42 42
  inline void assert_fail_abort(const char *file, int line,
43 43
                                const char *function, const char* message,
44 44
                                const char *assertion)
45 45
  {
46 46
    assert_fail_log(file, line, function, message, assertion);
47 47
    std::abort();
48 48
  }
49 49

	
50 50
  namespace _assert_bits {
51 51

	
52 52

	
53 53
    inline const char* cstringify(const std::string& str) {
54 54
      return str.c_str();
55 55
    }
56 56

	
57 57
    inline const char* cstringify(const char* str) {
58 58
      return str;
59 59
    }
60 60
  }
61 61
}
62 62

	
63 63
#endif // LEMON_ASSERT_H
64 64

	
65 65
#undef LEMON_ASSERT
66 66
#undef LEMON_FIXME
67 67
#undef LEMON_DEBUG
68 68

	
69 69
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +               \
70 70
  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
71 71
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
72 72
#error "LEMON assertion system is not set properly"
73 73
#endif
74 74

	
75 75
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +              \
76 76
     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
77 77
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
78 78
     defined(LEMON_ENABLE_ASSERTS)) &&                  \
79 79
  (defined(LEMON_DISABLE_ASSERTS) ||                    \
80 80
   defined(NDEBUG))
81 81
#error "LEMON assertion system is not set properly"
82 82
#endif
83 83

	
84 84

	
85 85
#if defined LEMON_ASSERT_LOG
86 86
#  undef LEMON_ASSERT_HANDLER
87 87
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
88 88
#elif defined LEMON_ASSERT_ABORT
89 89
#  undef LEMON_ASSERT_HANDLER
90 90
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91 91
#elif defined LEMON_ASSERT_CUSTOM
92 92
#  undef LEMON_ASSERT_HANDLER
93 93
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
94 94
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
95 95
#  endif
96 96
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
97 97
#elif defined LEMON_DISABLE_ASSERTS
98 98
#  undef LEMON_ASSERT_HANDLER
99 99
#elif defined NDEBUG
100 100
#  undef LEMON_ASSERT_HANDLER
101 101
#else
102 102
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
103 103
#endif
104 104

	
105 105
#ifndef LEMON_FUNCTION_NAME
106 106
#  if defined __GNUC__
107 107
#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
108 108
#  elif defined _MSC_VER
109 109
#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
110
#  elif __STDC_VERSION__ >= 199901L
111
#    define LEMON_FUNCTION_NAME (__func__)
110 112
#  else
111
#    define LEMON_FUNCTION_NAME (__func__)
113
#    define LEMON_FUNCTION_NAME ("<unknown>")
112 114
#  endif
113 115
#endif
114 116

	
115 117
#ifdef DOXYGEN
116 118

	
117 119
/// \ingroup exceptions
118 120
///
119 121
/// \brief Macro for assertion with customizable message
120 122
///
121 123
/// Macro for assertion with customizable message.  \param exp An
122 124
/// expression that must be convertible to \c bool.  If it is \c
123 125
/// false, then an assertion is raised. The concrete behaviour depends
124 126
/// on the settings of the assertion system.  \param msg A <tt>const
125 127
/// char*</tt> parameter, which can be used to provide information
126 128
/// about the circumstances of the failed assertion.
127 129
///
128 130
/// The assertions are enabled in the default behaviour.
129 131
/// You can disable them with the following code:
130 132
/// \code
131 133
/// #define LEMON_DISABLE_ASSERTS
132 134
/// \endcode
133 135
/// or with compilation parameters:
134 136
/// \code
135 137
/// g++ -DLEMON_DISABLE_ASSERTS
136 138
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
137 139
/// \endcode
138 140
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
139 141
///
140 142
/// The LEMON assertion system has a wide range of customization
141 143
/// properties. As a default behaviour the failed assertion prints a
142 144
/// short log message to the standard error and aborts the execution.
143 145
///
144 146
/// The following modes can be used in the assertion system:
145 147
///
146 148
/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
147 149
///   message to the standard error and continues the execution.
148 150
/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
149 151
///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
150 152
///   behaviour.
151 153
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
152 154
///   function.
153 155
///   \code
154 156
///     void custom_assert_handler(const char* file, int line,
155 157
///                                const char* function, const char* message,
156 158
///                                const char* assertion);
157 159
///   \endcode
158 160
///   The name of the function should be defined as the \c
159 161
///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
160 162
///   \code
161 163
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
162 164
///   \endcode
163 165
///   Whenever an assertion is occured, the custom assertion
164 166
///   handler is called with appropiate parameters.
165 167
///
166 168
/// The assertion mode can also be changed within one compilation unit.
167 169
/// If the macros are redefined with other settings and the
168 170
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
169 171
/// behaviour is changed appropiately to the new settings.
170 172
#  define LEMON_ASSERT(exp, msg)                                        \
171 173
  (static_cast<void> (!!(exp) ? 0 : (                                   \
172 174
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
173 175
                         LEMON_FUNCTION_NAME,                           \
174 176
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
175 177

	
176 178
/// \ingroup exceptions
177 179
///
178 180
/// \brief Macro for mark not yet implemented features.
179 181
///
180 182
/// Macro for mark not yet implemented features and outstanding bugs.
181 183
/// It is close to be the shortcut of the following code:
182 184
/// \code
183 185
///   LEMON_ASSERT(false, msg);
184 186
/// \endcode
185 187
///
186 188
/// \see LEMON_ASSERT
187 189
#  define LEMON_FIXME(msg)                                              \
188 190
  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,        \
189 191
                        ::lemon::_assert_bits::cstringify(msg),         \
190 192
                        static_cast<const char*>(0)))
191 193

	
192 194
/// \ingroup exceptions
193 195
///
194 196
/// \brief Macro for internal assertions
195 197
///
196 198
/// Macro for internal assertions, it is used in the library to check
197 199
/// the consistency of results of algorithms, several pre- and
198 200
/// postconditions and invariants. The checking is disabled by
199 201
/// default, but it can be turned on with the macro \c
200 202
/// LEMON_ENABLE_DEBUG.
201 203
/// \code
202 204
/// #define LEMON_ENABLE_DEBUG
203 205
/// \endcode
204 206
/// or with compilation parameters:
205 207
/// \code
206 208
/// g++ -DLEMON_ENABLE_DEBUG
207 209
/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
208 210
/// \endcode
209 211
///
210 212
/// This macro works like the \c LEMON_ASSERT macro, therefore the
211 213
/// current behaviour depends on the settings of \c LEMON_ASSERT
212 214
/// macro.
213 215
///
214 216
/// \see LEMON_ASSERT
215 217
#  define LEMON_DEBUG(exp, msg)                                         \
216 218
  (static_cast<void> (!!(exp) ? 0 : (                                   \
217 219
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
218 220
                         LEMON_FUNCTION_NAME,                           \
219 221
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
220 222

	
221 223
#else
222 224

	
223 225
#  ifndef LEMON_ASSERT_HANDLER
224 226
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
225 227
#    define LEMON_FIXME(msg) (static_cast<void>(0))
226 228
#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
227 229
#  else
228 230
#    define LEMON_ASSERT(exp, msg)                                      \
229 231
       (static_cast<void> (!!(exp) ? 0 : (                              \
230 232
        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
231 233
                             LEMON_FUNCTION_NAME,                       \
232 234
                             ::lemon::_assert_bits::cstringify(msg),    \
233 235
                             #exp), 0)))
234 236
#    define LEMON_FIXME(msg)                                            \
235 237
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,   \
236 238
                             ::lemon::_assert_bits::cstringify(msg),    \
237 239
                             static_cast<const char*>(0)))
238 240

	
239 241
#    if LEMON_ENABLE_DEBUG
240 242
#      define LEMON_DEBUG(exp, msg)                                     \
241 243
         (static_cast<void> (!!(exp) ? 0 : (                            \
242 244
           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
243 245
                                LEMON_FUNCTION_NAME,                    \
244 246
                                ::lemon::_assert_bits::cstringify(msg), \
245 247
                                #exp), 0)))
246 248
#    else
247 249
#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
248 250
#    endif
249 251
#  endif
250 252

	
251 253
#endif
0 comments (0 inline)