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 <sstream>
35 #include <iostream>
36 #include <cmath>
37 #include <limits>
38 
39 namespace Pt {
40 
41 namespace Unit {
42 
79  class PT_UNIT_API Assertion
80  {
81  public:
92  Assertion(const std::string& what, const SourceInfo& si);
93 
96  const Pt::SourceInfo& sourceInfo() const;
97 
98  const char* what() const { return _what.c_str(); }
99 
100  private:
101  Pt::SourceInfo _sourceInfo;
102  std::string _what;
103  };
104 
105  namespace { bool testCond = false; }
106 
107  inline bool getFalse()
108  { return testCond; }
109 
119  #define PT_UNIT_ASSERT(cond) \
120  do { \
121  if( !(cond) ) \
122  throw Pt::Unit::Assertion(#cond, PT_SOURCEINFO); \
123  } while (::Pt::Unit::testCond)
124 
135  #define PT_UNIT_ASSERT_MSG(cond, what) \
136  do { \
137  if( !(cond) ) \
138  { \
139  std::ostringstream _pt_msg; \
140  _pt_msg << what; \
141  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
142  } \
143  } while (::Pt::Unit::testCond)
144 
149  // TODO: deprecated
150  #define PT_UNIT_ASSERT_EQUALS(value1, value2) \
151  do { \
152  if( ! ((value1) == (value2)) ) \
153  { \
154  std::ostringstream _pt_msg; \
155  _pt_msg << "not equal: value1 (" #value1 ")=<" << value1 << "> value2 (" #value2 ")=<" << value2 << '>'; \
156  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
157  } \
158  } while (::Pt::Unit::testCond)
159 
170  #define PT_UNIT_ASSERT_EQUAL(value1, value2) \
171  do { \
172  if( ! ((value1) == (value2)) ) \
173  { \
174  std::ostringstream _pt_msg; \
175  _pt_msg << "not equal: (" #value1 ")=<" << value1 << ">, (" #value2 ")=<" << value2 << '>'; \
176  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
177  } \
178  } while (::Pt::Unit::testCond)
179 
191  #define PT_UNIT_ASSERT_NEAR(value1, value2) \
192  do { \
193  const double _pt_v1 = static_cast<double>(value1); \
194  const double _pt_v2 = static_cast<double>(value2); \
195  const double _pt_rel_eps = std::sqrt(std::numeric_limits<double>::epsilon()); \
196  const double _pt_abs_eps = std::numeric_limits<double>::min(); \
197  const double _pt_scale = std::fmax(std::fabs(_pt_v1), std::fabs(_pt_v2)); \
198  const double _pt_eps = std::fmax(_pt_rel_eps * _pt_scale, _pt_abs_eps); \
199  if( std::fabs(_pt_v1 - _pt_v2) > _pt_eps ) \
200  { \
201  std::ostringstream _pt_msg; \
202  _pt_msg << "not near: (" #value1 ")=<" << _pt_v1 \
203  << ">, (" #value2 ")=<" << _pt_v2 \
204  << ">, eps=<" << _pt_eps \
205  << ">, diff=<" << std::fabs(_pt_v1 - _pt_v2) << '>'; \
206  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
207  } \
208  } while (::Pt::Unit::testCond)
209 
220  #define PT_UNIT_ASSERT_THROW(cond, EX) \
221  do { \
222  struct _pt_ex { }; \
223  try \
224  { \
225  cond; \
226  throw _pt_ex(); \
227  } \
228  catch(const _pt_ex &) \
229  { \
230  std::ostringstream _pt_msg; \
231  _pt_msg << "exception of type " #EX " expected in " #cond; \
232  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
233  } \
234  catch(const EX &) \
235  {} \
236  } while (::Pt::Unit::testCond)
237 
246  #define PT_UNIT_ASSERT_NOTHROW(cond) \
247  do { \
248  try { \
249  \
250  cond; \
251  } \
252  catch(const std::exception& e) \
253  { \
254  throw Pt::Unit::Assertion( \
255  std::string("unexpected exception of type ") + typeid(e).name() + ": " + e.what(), \
256  PT_SOURCEINFO); \
257  } \
258  catch(...) \
259  { \
260  throw Pt::Unit::Assertion("unexpected exception." , PT_SOURCEINFO); \
261  } \
262  } while (::Pt::Unit::testCond)
263 
272  #define PT_UNIT_FAIL(what) \
273  do { \
274  std::ostringstream _pt_msg; \
275  _pt_msg << what; \
276  throw Pt::Unit::Assertion(_pt_msg.str(), PT_SOURCEINFO); \
277  } while (::Pt::Unit::testCond)
278 
279 } // namespace
280 
281 } // namespace
282 
283 #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:80
Source code info class.
Definition: SourceInfo.h:101