iutest  1.17.1.0
iutest_defs.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_
16 #define INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_
17 
18 //======================================================================
19 // include
21 #include "internal/iutest_pp.hpp"
23 #include "iutest_config.hpp"
24 #include <stdio.h>
25 #include <vector>
26 #include <algorithm>
28 
29 #if IUTEST_HAS_TYPED_TEST_P
30 # if IUTEST_TYPED_TEST_P_STRICT
31 # include <set>
32 # endif
33 #endif
34 
35 namespace iutest
36 {
37 
38 //======================================================================
39 // struct
40 namespace internal
41 {
42 
43 typedef void* TypeId;
44 
45 namespace helper
46 {
47 
48 //======================================================================
49 // struct
53 template<typename T>
54 struct TestTypeIdHelper { public: static bool _dummy; };
55 
56 template<typename T>bool TestTypeIdHelper<T>::_dummy = false;
57 
58 } // end of namespace helper
59 
60 //======================================================================
61 // function
66 template<typename T>
67 inline TypeId GetTypeId()
68 {
69  return &(helper::TestTypeIdHelper<T>::_dummy);
70 }
71 
76 inline IUTEST_CXX_CONSTEXPR TypeId GetTestTypeId()
77 {
78  return 0;
79 }
80 
81 template<size_t SIZE>
82 struct TypeWithSize : public detail::type_fit_t<SIZE> {};
83 
84 } // end of namespace internal
85 
86 //======================================================================
87 // class
88 namespace detail
89 {
90 
95 template<typename T>
96 struct ieee754_bits {};
97 
98 template<>
99 struct ieee754_bits<float>
100 {
101  enum {
102  EXP = 8
103  , FRAC = 23
104  };
105 };
106 
107 template<>
108 struct ieee754_bits<double>
109 {
110  enum {
111  EXP = 11
112  , FRAC = 52
113  };
114 };
115 
116 #if IUTEST_HAS_LONG_DOUBLE
117 
118 template<size_t N>
119 struct ieee754_bits_longdouble {};
120 
121 template<>
122 struct ieee754_bits_longdouble<8u>
123 {
124  enum {
125  EXP = 11
126  , FRAC = 52
127  };
128 };
129 
130 // 80bit 精度
131 template<>
132 struct ieee754_bits_longdouble<16u>
133 {
134  enum {
135  EXP = 15
136  , FRAC = 64
137  };
138 };
139 
140 template<>
141 struct ieee754_bits<long double> : ieee754_bits_longdouble<sizeof(long double)>
142 {
143 };
144 
145 #endif
146 
147 } // end of namespace detail
148 
152 template<typename RawType>
153 class floating_point
154 {
155 private:
157 
158 private:
159  typedef typename detail::type_fit_t<sizeof(RawType)> type;
160  typedef typename type::Int Int;
161  typedef typename type::UInt UInt;
162  union FInt
163  {
164  Int iv;
165  UInt uv;
166  RawType fv;
167  };
168 
169 public:
174  {
175  m_v.uv = 0;
176  }
177 
182  floating_point(RawType f) // NOLINT
183  {
184  m_v.uv = 0;
185  m_v.fv = f;
186  }
187 
191  floating_point(const floating_point& rhs)
192  : m_v(rhs.m_v)
193  {
194  }
195 
196 public:
200  bool AlmostEquals(const _Myt& rhs) const
201  {
202  if( is_nan() || rhs.is_nan() )
203  {
204  return false;
205  }
206  return NanSensitiveAlmostEquals(rhs);
207  }
208 
213  bool NanSensitiveAlmostEquals(const _Myt& rhs) const
214  {
215  const UInt v1 = norm(bits());
216  const UInt v2 = norm(rhs.bits());
217  const UInt diff = (v1 > v2) ? v1 - v2 : v2 - v1;
218  if( diff <= kMaxUlps )
219  {
220  return true;
221  }
222  return false;
223  }
224 
225 public:
229  bool AlmostNear(const _Myt& rhs, RawType max_abs_error) const
230  {
231  if( is_nan() || rhs.is_nan() )
232  {
233  return false;
234  }
235 IUTEST_PRAGMA_WARN_PUSH()
236 IUTEST_PRAGMA_WARN_FLOAT_EQUAL()
237  if( m_v.fv == rhs.m_v.fv )
238  {
239  return true;
240  }
241 IUTEST_PRAGMA_WARN_POP()
242  _Myt abs = Abs(rhs);
243  if( abs.m_v.fv <= max_abs_error )
244  {
245  return true;
246  }
247  _Myt abs_error = _Myt(max_abs_error);
248  if( abs.AlmostEquals(abs_error) ) {
249  return true;
250  }
251  return false;
252  }
253 
257  bool NanSensitiveAlmostNear(const _Myt& rhs, RawType max_abs_error) const
258  {
259  if( is_nan() && rhs.is_nan() )
260  {
261  return true;
262  }
263  return AlmostNear(rhs, max_abs_error);
264  }
265 
266 public:
267  _Myt Abs(const _Myt& rhs) const
268  {
269  if( m_v.fv > rhs.m_v.fv )
270  {
271  return _Myt(m_v.fv - rhs.m_v.fv);
272  }
273  else
274  {
275  return _Myt(rhs.m_v.fv - m_v.fv);
276  }
277  }
278 public:
282  UInt bits() const { return m_v.uv & kEnableBitMask; }
283 
287  RawType raw() const { return m_v.fv; }
288 
292  UInt exponent_bits() const { return m_v.uv & kExpMask; }
293 
297  UInt fraction_bits() const { return m_v.uv & kFracMask; }
298 
302  UInt sign_bit() const { return m_v.uv & kSignMask; }
303 
307  bool is_nan() const { return exponent_bits() == kExpMask && fraction_bits() != 0; }
308 
312  bool is_inf() const { return exponent_bits() == kExpMask && fraction_bits() == 0; }
313 
314 public:
316  static _Myt PINF()
317  {
318  _Myt f;
319  f.m_v.uv = kExpMask;
320  return f;
321  }
323  static _Myt NINF()
324  {
325  _Myt f = PINF();
326  f.m_v.uv |= kSignMask;
327  return f;
328  }
330  static _Myt PNAN()
331  {
332  _Myt f;
333  f.m_v.uv = kExpMask | 1;
334  return f;
335  }
337  static _Myt NNAN()
338  {
339  _Myt f = PNAN();
340  f.m_v.uv |= kSignMask;
341  return f;
342  }
344  static _Myt PQNAN()
345  {
346  _Myt f;
347  f.m_v.uv = ((1 << (kEXP + 1)) - 1);
348  f.m_v.uv <<= kFRAC - 1;
349  return f;
350  }
352  static _Myt NQNAN()
353  {
354  _Myt f = PQNAN();
355  f.m_v.uv |= kSignMask;
356  return f;
357  }
358 
359 public:
360 #if !defined(_MSC_VER) || _MSC_VER >= 1310
361  operator RawType () const { return m_v.fv; }
362 #else
363  operator float() const { return m_v.fv; }
364  operator double() const { return m_v.fv; }
365 #endif
366  _Myt& operator = (RawType f) { m_v.fv = f; return *this; }
367  _Myt& operator = (const _Myt& rhs) { m_v.fv = rhs.m_v; return *this; }
368 
369  bool operator == (const _Myt& rhs) const { return m_v.uv == rhs.m_v.uv; }
370 
371 private:
372  enum
373  {
374  kEXP = detail::ieee754_bits<RawType>::EXP
375  , kFRAC = detail::ieee754_bits<RawType>::FRAC
376  , kMaxUlps = 4
377  };
378 
379 private:
380  static UInt norm(UInt v) { return (v & kSignMask) ? (~v + 1) : (v | kSignMask); }
381 
382 #if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
383  static const UInt kSignMask = static_cast<UInt>(1u) << (kEXP + kFRAC);
384  static const UInt kExpMask = ((static_cast<UInt>(1u) << kEXP) - 1) << kFRAC;
385  static const UInt kFracMask = (static_cast<UInt>(1u) << kFRAC) - 1;
386  static const UInt kEnableBitMask = kSignMask | kExpMask | kFracMask;
387 #else
388  static const UInt kSignMask;
389  static const UInt kExpMask;
390  static const UInt kFracMask;
391  static const UInt kEnableBitMask;
392 #endif
393 
394 private:
395  FInt m_v;
396 };
397 
398 #if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
399 
400 template<typename T>
401 const typename floating_point<T>::UInt floating_point<T>::kSignMask
402  = static_cast<typename floating_point<T>::UInt>(1u) << (kEXP + kFRAC);
403 template<typename T>
404 const typename floating_point<T>::UInt floating_point<T>::kExpMask
405  = ((static_cast<typename floating_point<T>::UInt>(1u)
406  << floating_point<T>::kEXP) - 1) << floating_point<T>::kFRAC;
407 template<typename T>
408 const typename floating_point<T>::UInt floating_point<T>::kFracMask
409  = ((static_cast<typename floating_point<T>::UInt>(1u) << floating_point<T>::kFRAC) - 1);
410 template<typename T>
411 const typename floating_point<T>::UInt floating_point<T>::kEnableBitMask
412  = floating_point<T>::kSignMask | floating_point<T>::kExpMask | floating_point<T>::kFracMask;
413 
414 #endif
415 
416 //======================================================================
417 // typedef
418 typedef detail::type_fit_t<1>::Int Int8;
419 typedef detail::type_fit_t<1>::UInt UInt8;
420 typedef detail::type_fit_t<2>::Int Int16;
421 typedef detail::type_fit_t<2>::UInt UInt16;
422 typedef detail::type_fit_t<4>::Int Int32;
423 typedef detail::type_fit_t<4>::UInt UInt32;
424 typedef detail::type_fit_t<8>::Int Int64;
425 typedef detail::type_fit_t<8>::UInt UInt64;
426 
427 #if IUTEST_HAS_CXX11 && IUTEST_HAS_CXX_HDR_CSTDINT
428 typedef ::std::uintmax_t iu_off_t;
429 #else
430 typedef UInt64 iu_off_t;
431 #endif
432 
433 #if IUTEST_HAS_CXX11 && IUTEST_HAS_CXX_HDR_CSTDINT
434 typedef ::std::uintptr_t iu_uintptr_t;
435 #else
436 typedef detail::type_fit_t<sizeof(ptrdiff_t)>::UInt iu_uintptr_t;
437 #endif
438 
439 typedef internal::TypeId TestTypeId;
440 
441 typedef void (*SetUpMethod)();
442 typedef void (*TearDownMethod)();
443 
444 typedef detail::type_least_t<8>::UInt TimeInMillisec;
445 typedef detail::type_least_t<8>::Int BiggestInt;
446 
447 } // end of namespace iutest
448 
449 /*
450 #if IUTEST_HAS_ATTRIBUTE_DEPRECATED
451 namespace iutest {
452 namespace detail
453 {
454 
455 template<typename T>
456 struct type_check_t { static const int IUTEST_ATTRIBUTE_DEPRECATED_ value = 0; };
457 
458 #if IUTEST_HAS_RVALUE_REFS
459 template<typename T>
460 int type_check(T&& x) { return 0; }
461 #else
462 template<typename T>
463 int type_check(const T& x) { return 0; }
464 #endif
465 
466 } // end of namespace detail
467 } // end of namespace iutest
468 
469 #if defined(_MSC_VER)
470 # if IUTEST_HAS_DECLTYPE
471 # define IUTEST_CHECK_TYPE(x) (void)::iutest::detail::type_check_t< decltype(x) >::value
472 # endif
473 #else
474 # define IUTEST_CHECK_TYPE(x) ::iutest::detail::type_check(x)
475 #endif
476 
477 #if !defined(IUTEST_CHECK_TYPE)
478 # define IUTEST_CHECK_TYPE(x) (void)0
479 #endif
480 
481 #endif
482 */
483 
484 #endif // INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_
iutest::Int16
detail::type_fit_t< 2 >::Int Int16
16 bit 符号付き整数型
Definition: iutest_defs.hpp:421
iutest_pp.hpp
preprocessor definition
iutest::floating_point::fraction_bits
UInt fraction_bits() const
fraction
Definition: iutest_defs.hpp:298
iutest::floating_point::is_inf
bool is_inf() const
is inf
Definition: iutest_defs.hpp:313
iutest::floating_point::NanSensitiveAlmostNear
bool NanSensitiveAlmostNear(const _Myt &rhs, RawType max_abs_error) const
浮動小数点数の差分が max_abs_error 以内に収まるかどうか
Definition: iutest_defs.hpp:258
iutest::floating_point::AlmostNear
bool AlmostNear(const _Myt &rhs, RawType max_abs_error) const
浮動小数点数の差分が max_abs_error 以内に収まるかどうか
Definition: iutest_defs.hpp:230
iutest::floating_point::is_nan
bool is_nan() const
is nan
Definition: iutest_defs.hpp:308
iutest::floating_point::AlmostEquals
bool AlmostEquals(const _Myt &rhs) const
浮動小数点数がほぼ一致するかどうか
Definition: iutest_defs.hpp:201
iutest::floating_point::floating_point
floating_point(RawType f)
コンストラクタ
Definition: iutest_defs.hpp:183
iutest_config.hpp
iris unit test config
iutest::floating_point::NanSensitiveAlmostEquals
bool NanSensitiveAlmostEquals(const _Myt &rhs) const
浮動小数点数がほぼ一致するかどうか
Definition: iutest_defs.hpp:214
iutest::floating_point::sign_bit
UInt sign_bit() const
sign
Definition: iutest_defs.hpp:303
iutest::UInt16
detail::type_fit_t< 2 >::UInt UInt16
16 bit 符号なし整数型
Definition: iutest_defs.hpp:422
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
iutest_debug.hpp
iris unit test debug 用定義 ファイル
iutest::Int64
detail::type_fit_t< 8 >::Int Int64
64 bit 符号付き整数型
Definition: iutest_defs.hpp:425
iutest::UInt8
detail::type_fit_t< 1 >::UInt UInt8
8 bit 符号なし整数型
Definition: iutest_defs.hpp:420
iutest::floating_point::PNAN
static _Myt PNAN()
plus nan
Definition: iutest_defs.hpp:331
iutest::UInt64
detail::type_fit_t< 8 >::UInt UInt64
64 bit 符号なし整数型
Definition: iutest_defs.hpp:426
iutest::floating_point::PINF
static _Myt PINF()
plus inf
Definition: iutest_defs.hpp:317
iutest::floating_point::NINF
static _Myt NINF()
minus inf
Definition: iutest_defs.hpp:324
IUTEST_CXX_CONSTEXPR
#define IUTEST_CXX_CONSTEXPR
constexpr
Definition: iutest_compiler.hpp:298
iutest::floating_point::floating_point
floating_point()
コンストラクタ
Definition: iutest_defs.hpp:174
iutest::TestTypeId
internal::TypeId TestTypeId
テスト識別型
Definition: iutest_defs.hpp:440
iutest::floating_point::NNAN
static _Myt NNAN()
minus nan
Definition: iutest_defs.hpp:338
iutest::Int32
detail::type_fit_t< 4 >::Int Int32
32 bit 符号付き整数型
Definition: iutest_defs.hpp:423
iutest::floating_point::raw
RawType raw() const
raw データの取得
Definition: iutest_defs.hpp:288
iutest::TimeInMillisec
detail::type_least_t< 8 >::UInt TimeInMillisec
ミリ秒単位を扱う型
Definition: iutest_defs.hpp:445
iutest::TearDownMethod
void(* TearDownMethod)()
TearDown 関数型
Definition: iutest_defs.hpp:443
iutest_compiler.hpp
iris unit test compiler 依存の吸収 ファイル
iutest::UInt32
detail::type_fit_t< 4 >::UInt UInt32
32 bit 符号なし整数型
Definition: iutest_defs.hpp:424
iutest::floating_point
浮動小数点数
Definition: iutest_defs.hpp:154
iutest::SetUpMethod
void(* SetUpMethod)()
SetUp 関数型
Definition: iutest_defs.hpp:442
iutest::floating_point::PQNAN
static _Myt PQNAN()
plus qnan
Definition: iutest_defs.hpp:345
iutest::BiggestInt
detail::type_least_t< 8 >::Int BiggestInt
Biggest Int
Definition: iutest_defs.hpp:446
iutest::floating_point::exponent_bits
UInt exponent_bits() const
exponent
Definition: iutest_defs.hpp:293
iutest::floating_point::NQNAN
static _Myt NQNAN()
minus qnan
Definition: iutest_defs.hpp:353
iutest::floating_point::floating_point
floating_point(const floating_point &rhs)
コンストラクタ
Definition: iutest_defs.hpp:192
iutest_stdlib.hpp
stdlib
iutest::Int8
detail::type_fit_t< 1 >::Int Int8
8 bit 符号付き整数型
Definition: iutest_defs.hpp:419
iutest::floating_point::bits
UInt bits() const
ビット列の取得
Definition: iutest_defs.hpp:283