Assertion.h
1 /*
2  * Copyright (C) 2005-2008 by Dr. Marc Boris Duerner
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 #ifndef PT_UNIT_ASSERTION_H
29 #define PT_UNIT_ASSERTION_H
30 
31 #include <Pt/Unit/Api.h>
32 #include "Pt/SourceInfo.h"
33 #include <stdexcept>
34 #include <iostream>
35 #include <cmath>
36 #include <limits>
37 
38 namespace Pt {
39 
40 namespace Unit {
41 
78  class PT_UNIT_API Assertion
79  {
80  public:
91  Assertion(const std::string& what, const SourceInfo& si);
92 
95  const Pt::SourceInfo& sourceInfo() const;
96 
97  const char* what() const { return _what.c_str(); }
98 
99  private:
100  Pt::SourceInfo _sourceInfo;
101  std::string _what;
102  };
103 
104  namespace { bool testCond = false; }
105 
106  inline bool getFalse()
107  { return testCond; }
108 
118  #define PT_UNIT_ASSERT(cond) \
119  do { \
120  if( !(cond) ) \
121  throw Pt::Unit::Assertion(#cond, PT_SOURCEINFO); \
122  } while (::Pt::Unit::testCond)
123 
134  #define PT_UNIT_ASSERT_MSG(cond, what) \
135  do { \
136  if( !(cond) ) \
137  { \
138  std::ostringstream _pt_msg; \
139  _pt_msg << what; \
140  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
141  } \
142  } while (::Pt::Unit::testCond)
143 
148  // TODO: deprecated
149  #define PT_UNIT_ASSERT_EQUALS(value1, value2) \
150  do { \
151  if( ! ((value1) == (value2)) ) \
152  { \
153  std::ostringstream _pt_msg; \
154  _pt_msg << "not equal: value1 (" #value1 ")=<" << value1 << "> value2 (" #value2 ")=<" << value2 << '>'; \
155  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
156  } \
157  } while (::Pt::Unit::testCond)
158 
169  #define PT_UNIT_ASSERT_EQUAL(value1, value2) \
170  do { \
171  if( ! ((value1) == (value2)) ) \
172  { \
173  std::ostringstream _pt_msg; \
174  _pt_msg << "not equal: (" #value1 ")=<" << value1 << ">, (" #value2 ")=<" << value2 << '>'; \
175  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
176  } \
177  } while (::Pt::Unit::testCond)
178 
190  #define PT_UNIT_ASSERT_NEAR(value1, value2) \
191  do { \
192  const double _pt_v1 = static_cast<double>(value1); \
193  const double _pt_v2 = static_cast<double>(value2); \
194  const double _pt_rel_eps = std::sqrt(std::numeric_limits<double>::epsilon()); \
195  const double _pt_abs_eps = std::numeric_limits<double>::min(); \
196  const double _pt_scale = std::fmax(std::fabs(_pt_v1), std::fabs(_pt_v2)); \
197  const double _pt_eps = std::fmax(_pt_rel_eps * _pt_scale, _pt_abs_eps); \
198  if( std::fabs(_pt_v1 - _pt_v2) > _pt_eps ) \
199  { \
200  std::ostringstream _pt_msg; \
201  _pt_msg << "not near: (" #value1 ")=<" << _pt_v1 \
202  << ">, (" #value2 ")=<" << _pt_v2 \
203  << ">, eps=<" << _pt_eps \
204  << ">, diff=<" << std::fabs(_pt_v1 - _pt_v2) << '>'; \
205  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
206  } \
207  } while (::Pt::Unit::testCond)
208 
219  #define PT_UNIT_ASSERT_THROW(cond, EX) \
220  do { \
221  struct _pt_ex { }; \
222  try \
223  { \
224  cond; \
225  throw _pt_ex(); \
226  } \
227  catch(const _pt_ex &) \
228  { \
229  std::ostringstream _pt_msg; \
230  _pt_msg << "exception of type " #EX " expected in " #cond; \
231  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
232  } \
233  catch(const EX &) \
234  {} \
235  } while (::Pt::Unit::testCond)
236 
245  #define PT_UNIT_ASSERT_NOTHROW(cond) \
246  do { \
247  try { \
248  \
249  cond; \
250  } \
251  catch(const std::exception& e) \
252  { \
253  throw Pt::Unit::Assertion( \
254  std::string("unexpected exception of type ") + typeid(e).name() + ": " + e.what(), \
255  PT_SOURCEINFO); \
256  } \
257  catch(...) \
258  { \
259  throw Pt::Unit::Assertion("unexpected exception." , PT_SOURCEINFO); \
260  } \
261  } while (::Pt::Unit::testCond)
262 
271  #define PT_UNIT_FAIL(what) \
272  do { \
273  std::ostringstream _pt_msg; \
274  _pt_msg << what; \
275  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
276  } while (::Pt::Unit::testCond)
277 
278 } // namespace
279 
280 } // namespace
281 
282 #endif // include guard
Core module.
Definition: Allocator.h:33
const Pt::SourceInfo & sourceInfo() const
Information where assertion failed.
Assertion(const std::string &what, const SourceInfo &si)
Construct from a message and source info.
Test Assertion exception
Definition: Assertion.h:79
Source code info class.
Definition: SourceInfo.h:101