iutest  1.17.99.14
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
20 // IWYU pragma: begin_exports
22 #include "internal/iutest_pp.hpp"
24 #include "iutest_config.hpp"
25 #include <stdio.h>
26 #include <utility>
27 #include <vector>
28 #include <algorithm>
30 // IWYU pragma: end_exports
31 
32 #if IUTEST_HAS_TYPED_TEST_P
33 # if IUTEST_TYPED_TEST_P_STRICT
34 # include <set>
35 # endif
36 #endif
37 
38 namespace iutest
39 {
40 
41 //======================================================================
42 // struct
43 namespace internal
44 {
45 
46 typedef void* TypeId;
47 
48 namespace helper
49 {
50 
51 //======================================================================
52 // struct
56 template<typename T>
57 struct TestTypeIdHelper { public: static bool _dummy; };
58 
59 template<typename T>bool TestTypeIdHelper<T>::_dummy = false;
60 
61 } // end of namespace helper
62 
63 //======================================================================
64 // function
69 template<typename T>
70 inline TypeId GetTypeId()
71 {
72  return &(helper::TestTypeIdHelper<T>::_dummy);
73 }
74 
79 inline IUTEST_CXX_CONSTEXPR TypeId GetTestTypeId()
80 {
81  return 0;
82 }
83 
84 template<size_t SIZE>
85 struct TypeWithSize : public detail::type_fit_t<SIZE> {};
86 
87 } // end of namespace internal
88 
89 //======================================================================
90 // class
91 namespace detail
92 {
93 
94 template<size_t MANT>
95 struct ieee754_bits_from_mant {};
96 
97 // half float
98 template<>
99 struct ieee754_bits_from_mant<11>
100 {
101  enum
102  {
103  EXP = 5
104  , MANT = 10
105  , MANT_HIDDEN = 1
106  };
107 };
108 
109 // float
110 template<>
111 struct ieee754_bits_from_mant<24>
112 {
113  enum
114  {
115  EXP = 8
116  , MANT = 23
117  , MANT_HIDDEN = 1
118  };
119 };
120 
121 // double
122 template<>
123 struct ieee754_bits_from_mant<53>
124 {
125  enum
126  {
127  EXP = 11
128  , MANT = 52
129  , MANT_HIDDEN = 1
130  };
131 };
132 
133 // 80bit
134 template<>
135 struct ieee754_bits_from_mant<64>
136 {
137  enum
138  {
139  EXP = 15
140  , MANT = 64
141  , MANT_HIDDEN = 0
142  };
143 };
144 
145 // double double
146 template<>
147 struct ieee754_bits_from_mant<106>
148 {
149  enum
150  {
151  EXP = 22
152  , MANT = 104
153  , MANT_HIDDEN = 2
154  };
155 };
156 
157 // 128bit
158 template<>
159 struct ieee754_bits_from_mant<113>
160 {
161  enum
162  {
163  EXP = 15
164  , MANT = 112
165  , MANT_HIDDEN = 1
166  };
167 };
168 
173 template<typename T>
174 struct ieee754_bits : ieee754_bits_from_mant< ::std::numeric_limits<T>::digits > {};
175 
176 #if IUTEST_HAS_FLOAT128
177 template<>
178 struct ieee754_bits<__float128> : ieee754_bits_from_mant<IUTEST_FLT128_MANT_DIG> {};
179 #endif
180 
181 } // end of namespace detail
182 
186 template<typename RawType>
187 class floating_point
188 {
189 private:
191  typedef typename detail::type_fit_t<sizeof(RawType)> IntType;
192 
193 public:
194  typedef typename IntType::Int Int;
195  typedef typename IntType::UInt UInt;
196  typedef RawType Float;
197  union FInt
198  {
199  Int iv;
200  UInt uv;
201  Float fv;
202  };
203 
204 public:
209  {
210  m_v.uv = 0;
211  }
212 
217  floating_point(RawType f) // NOLINT
218  {
219  m_v.uv = 0;
220  m_v.fv = f;
221  }
222 
226  floating_point(const floating_point& rhs)
227  : m_v(rhs.m_v)
228  {
229  }
230 
231 public:
235  bool AlmostEquals(const _Myt& rhs) const
236  {
237  if( is_nan() || rhs.is_nan() )
238  {
239  return false;
240  }
241  return NanSensitiveAlmostEquals(rhs);
242  }
243 
248  bool NanSensitiveAlmostEquals(const _Myt& rhs) const
249  {
250  const UInt v1 = norm(enable_bits());
251  const UInt v2 = norm(rhs.enable_bits());
252  const UInt diff = (v1 > v2) ? v1 - v2 : v2 - v1;
253  const UInt kMaxUlps = 4u;
254  if( diff <= kMaxUlps )
255  {
256  return true;
257  }
258  return false;
259  }
260 
261 public:
265  bool AlmostNear(const _Myt& rhs, RawType max_abs_error) const
266  {
267  if( is_nan() || rhs.is_nan() )
268  {
269  return false;
270  }
271 IUTEST_PRAGMA_WARN_PUSH()
272 IUTEST_PRAGMA_WARN_DISABLE_FLOAT_EQUAL()
273  if( m_v.fv == rhs.m_v.fv )
274  {
275  return true;
276  }
277 IUTEST_PRAGMA_WARN_POP()
278  _Myt abs = Abs(rhs);
279  if( abs.m_v.fv <= max_abs_error )
280  {
281  return true;
282  }
283  _Myt abs_error = _Myt(max_abs_error);
284  if( abs.AlmostEquals(abs_error) ) {
285  return true;
286  }
287  return false;
288  }
289 
293  bool NanSensitiveAlmostNear(const _Myt& rhs, RawType max_abs_error) const
294  {
295  if( is_nan() && rhs.is_nan() )
296  {
297  return true;
298  }
299  return AlmostNear(rhs, max_abs_error);
300  }
301 
302 public:
303  _Myt Abs(const _Myt& rhs) const
304  {
305  if( m_v.fv > rhs.m_v.fv )
306  {
307  return _Myt(m_v.fv - rhs.m_v.fv);
308  }
309  else
310  {
311  return _Myt(rhs.m_v.fv - m_v.fv);
312  }
313  }
314 public:
318  UInt bits() const { return m_v.uv; }
319 
323  UInt enable_bits() const { return m_v.uv & kEnableBitMask; }
324 
328  RawType raw() const { return m_v.fv; }
329 
333  UInt exponent_bits() const { return m_v.uv & kExpMask; }
334 
338  UInt fraction_bits() const { return mantissa_bits(); }
339 
343  UInt mantissa_bits() const { return m_v.uv & kMantMask; }
344 
348  UInt economized_mantissa_bits() const { return m_v.uv & kEconomizedMantMask; }
349 
353  UInt sign_bit() const { return m_v.uv & kSignMask; }
354 
358  bool is_nan() const { return exponent_bits() == kExpMask && economized_mantissa_bits() != 0; }
359 
363  bool is_inf() const { return exponent_bits() == kExpMask && economized_mantissa_bits() == 0; }
364 
365 public:
367  static _Myt PINF()
368  {
369  _Myt f;
370  f.m_v.uv = kExpMask | kDefaultMantBitMask;
371  return f;
372  }
374  static _Myt NINF()
375  {
376  _Myt f = PINF();
377  f.m_v.uv |= kSignMask;
378  return f;
379  }
381  static _Myt PNAN()
382  {
383  _Myt f;
384  f.m_v.uv = kExpMask | kDefaultMantBitMask | 1;
385  return f;
386  }
388  static _Myt NNAN()
389  {
390  _Myt f = PNAN();
391  f.m_v.uv |= kSignMask;
392  return f;
393  }
395  static _Myt PQNAN()
396  {
397  _Myt f;
398  f.m_v.uv = ((1 << (kEXP + 1)) - 1);
399  f.m_v.uv <<= kMANT - 1;
400  f.m_v.uv |= kDefaultMantBitMask;
401  return f;
402  }
404  static _Myt NQNAN()
405  {
406  _Myt f = PQNAN();
407  f.m_v.uv |= kSignMask;
408  return f;
409  }
410 
411 public:
412 #if !defined(_MSC_VER) || _MSC_VER >= 1310
413  operator RawType () const { return m_v.fv; }
414 #else
415  operator float() const { return m_v.fv; }
416  operator double() const { return m_v.fv; }
417 #endif
418  _Myt& operator = (RawType f) { m_v.fv = f; return *this; }
419  _Myt& operator = (const _Myt& rhs) { m_v.fv = rhs.m_v.fv; return *this; }
420 
421  bool operator == (RawType rhs) const { return enable_bits() == _Myt(rhs).enable_bits(); }
422  bool operator == (const _Myt& rhs) const { return enable_bits() == rhs.enable_bits(); }
423  // bool operator == (const _Myt& rhs) const { return m_v.uv == rhs.m_v.uv; } //!< 比較
424 
425 public:
426  static const int kEXP;
427  static const int kMANT;
428  static const int kDIGITS;
429 
430 private:
431  static UInt norm(UInt v) { return (v & kSignMask) ? (~v + 1) : (v | kSignMask); }
432 
433  static const UInt kSignMask;
434  static const UInt kExpMask;
435  static const UInt kMantMask;
436  static const UInt kEconomizedMantMask;
437  static const UInt kDefaultMantBitMask;
438  static const UInt kEnableBitMask;
439 
440 private:
441  FInt m_v;
442 };
443 
444 template<typename T>
445 const int floating_point<T>::kEXP = detail::ieee754_bits<T>::EXP;
446 template<typename T>
447 const int floating_point<T>::kMANT = detail::ieee754_bits<T>::MANT;
448 template<typename T>
449 const int floating_point<T>::kDIGITS = detail::ieee754_bits<T>::MANT + detail::ieee754_bits<T>::MANT_HIDDEN;
450 
451 template<typename T>
452 const typename floating_point<T>::UInt floating_point<T>::kSignMask
453  = static_cast<typename floating_point<T>::UInt>(1u) << (kEXP + kMANT);
454 template<typename T>
455 const typename floating_point<T>::UInt floating_point<T>::kExpMask
456  = ((static_cast<typename floating_point<T>::UInt>(1u)
457  << floating_point<T>::kEXP) - 1) << floating_point<T>::kMANT;
458 template<typename T>
459 const typename floating_point<T>::UInt floating_point<T>::kMantMask
460  = ((static_cast<typename floating_point<T>::UInt>(1u) << floating_point<T>::kMANT) - 1);
461 template<typename T>
462 const typename floating_point<T>::UInt floating_point<T>::kEconomizedMantMask
463  = ((static_cast<typename floating_point<T>::UInt>(1u) << (floating_point<T>::kDIGITS - 1)) - 1);
464 template<typename T>
465 const typename floating_point<T>::UInt floating_point<T>::kDefaultMantBitMask
466  = (static_cast<typename floating_point<T>::UInt>(1u) << (floating_point<T>::kDIGITS - 1));
467 template<typename T>
468 const typename floating_point<T>::UInt floating_point<T>::kEnableBitMask
469  = floating_point<T>::kSignMask | floating_point<T>::kExpMask | floating_point<T>::kMantMask;
470 
471 // googletest compat
472 
473 namespace internal
474 {
475 
476 template<typename T>
477 class FloatingPoint : public floating_point<T>
478 {
479 public:
480  explicit FloatingPoint(const T& rhs) : floating_point<T>(rhs) {}
481 };
482 
483 typedef FloatingPoint<float> Float;
484 typedef FloatingPoint<double> Double;
485 
486 #if IUTEST_HAS_LONG_DOUBLE
487 typedef FloatingPoint<long double> LongDouble;
488 #endif
489 #if IUTEST_HAS_FLOAT128
490 typedef FloatingPoint<__float128> Float128;
491 #endif
492 
493 } // end of namespace internal
494 
495 //======================================================================
496 // typedef
497 typedef detail::type_fit_t<1>::Int Int8;
498 typedef detail::type_fit_t<1>::UInt UInt8;
499 typedef detail::type_fit_t<2>::Int Int16;
500 typedef detail::type_fit_t<2>::UInt UInt16;
501 typedef detail::type_fit_t<4>::Int Int32;
502 typedef detail::type_fit_t<4>::UInt UInt32;
503 typedef detail::type_fit_t<8>::Int Int64;
504 typedef detail::type_fit_t<8>::UInt UInt64;
505 
506 #if IUTEST_HAS_CXX11 && IUTEST_HAS_CXX_HDR_CSTDINT
507 typedef ::std::intmax_t iu_off_t;
508 typedef ::std::uintmax_t iu_uint_max_t;
509 #else
510 typedef Int64 iu_off_t;
511 typedef UInt64 iu_uint_max_t;
512 #endif
513 
514 #if IUTEST_HAS_CXX11 && IUTEST_HAS_CXX_HDR_CSTDINT
515 typedef ::std::uintptr_t iu_uintptr_t;
516 #else
517 typedef detail::type_fit_t<sizeof(ptrdiff_t)>::UInt iu_uintptr_t;
518 #endif
519 
520 typedef internal::TypeId TestTypeId;
521 
522 typedef void (*SetUpMethod)();
523 typedef void (*TearDownMethod)();
524 
525 typedef detail::type_least_t<8>::UInt TimeInMillisec;
526 typedef detail::type_least_t<8>::Int BiggestInt;
527 
528 } // end of namespace iutest
529 
530 /*
531 #if IUTEST_HAS_ATTRIBUTE_DEPRECATED
532 namespace iutest {
533 namespace detail
534 {
535 
536 template<typename T>
537 struct type_check_t { static const int IUTEST_ATTRIBUTE_DEPRECATED_ value = 0; };
538 
539 #if IUTEST_HAS_RVALUE_REFS
540 template<typename T>
541 int type_check(T&& x) { return 0; }
542 #else
543 template<typename T>
544 int type_check(const T& x) { return 0; }
545 #endif
546 
547 } // end of namespace detail
548 } // end of namespace iutest
549 
550 #if defined(_MSC_VER)
551 # if IUTEST_HAS_DECLTYPE
552 # define IUTEST_CHECK_TYPE(x) (void)::iutest::detail::type_check_t< decltype(x) >::value
553 # endif
554 #else
555 # define IUTEST_CHECK_TYPE(x) ::iutest::detail::type_check(x)
556 #endif
557 
558 #if !defined(IUTEST_CHECK_TYPE)
559 # define IUTEST_CHECK_TYPE(x) (void)0
560 #endif
561 
562 #endif
563 */
564 
565 #endif // INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_
浮動小数点数
Definition: iutest_defs.hpp:189
UInt economized_mantissa_bits() const
economized mantissa
Definition: iutest_defs.hpp:349
static _Myt PNAN()
plus nan
Definition: iutest_defs.hpp:382
UInt sign_bit() const
sign
Definition: iutest_defs.hpp:354
static _Myt NNAN()
minus nan
Definition: iutest_defs.hpp:389
bool AlmostEquals(const _Myt &rhs) const
浮動小数点数がほぼ一致するかどうか
Definition: iutest_defs.hpp:236
bool NanSensitiveAlmostEquals(const _Myt &rhs) const
浮動小数点数がほぼ一致するかどうか
Definition: iutest_defs.hpp:249
UInt bits() const
ビット列の取得
Definition: iutest_defs.hpp:319
bool operator==(RawType rhs) const
比較
Definition: iutest_defs.hpp:422
UInt exponent_bits() const
exponent
Definition: iutest_defs.hpp:334
UInt enable_bits() const
ビット列の取得
Definition: iutest_defs.hpp:324
floating_point()
コンストラクタ
Definition: iutest_defs.hpp:209
bool AlmostNear(const _Myt &rhs, RawType max_abs_error) const
浮動小数点数の差分が max_abs_error 以内に収まるかどうか
Definition: iutest_defs.hpp:266
RawType raw() const
raw データの取得
Definition: iutest_defs.hpp:329
bool NanSensitiveAlmostNear(const _Myt &rhs, RawType max_abs_error) const
浮動小数点数の差分が max_abs_error 以内に収まるかどうか
Definition: iutest_defs.hpp:294
static _Myt PINF()
plus inf
Definition: iutest_defs.hpp:368
bool is_nan() const
is nan
Definition: iutest_defs.hpp:359
UInt fraction_bits() const
fraction (mantissa)
Definition: iutest_defs.hpp:339
static _Myt NQNAN()
minus qnan
Definition: iutest_defs.hpp:405
static _Myt PQNAN()
plus qnan
Definition: iutest_defs.hpp:396
bool is_inf() const
is inf
Definition: iutest_defs.hpp:364
static _Myt NINF()
minus inf
Definition: iutest_defs.hpp:375
UInt mantissa_bits() const
mantissa
Definition: iutest_defs.hpp:344
_Myt & operator=(RawType f)
代入
Definition: iutest_defs.hpp:419
iris unit test compiler 依存の吸収 ファイル
#define IUTEST_CXX_CONSTEXPR
constexpr
Definition: iutest_compiler.hpp:372
iris unit test config
iris unit test debug 用定義 ファイル
preprocessor definition
iutest root namespace
Definition: iutest_charcode.hpp:33
detail::type_fit_t< 1 >::UInt UInt8
8 bit 符号なし整数型
Definition: iutest_defs.hpp:499
detail::type_least_t< 8 >::UInt TimeInMillisec
ミリ秒単位を扱う型
Definition: iutest_defs.hpp:526
detail::type_fit_t< 1 >::Int Int8
8 bit 符号付き整数型
Definition: iutest_defs.hpp:498
void(* SetUpMethod)()
SetUp 関数型
Definition: iutest_defs.hpp:523
void(* TearDownMethod)()
TearDown 関数型
Definition: iutest_defs.hpp:524
detail::type_fit_t< 4 >::UInt UInt32
32 bit 符号なし整数型
Definition: iutest_defs.hpp:503
detail::type_fit_t< 4 >::Int Int32
32 bit 符号付き整数型
Definition: iutest_defs.hpp:502
detail::type_fit_t< 8 >::UInt UInt64
64 bit 符号なし整数型
Definition: iutest_defs.hpp:505
detail::type_fit_t< 2 >::Int Int16
16 bit 符号付き整数型
Definition: iutest_defs.hpp:500
detail::type_fit_t< 8 >::Int Int64
64 bit 符号付き整数型
Definition: iutest_defs.hpp:504
internal::TypeId TestTypeId
テスト識別型
Definition: iutest_defs.hpp:521
detail::type_least_t< 8 >::Int BiggestInt
Biggest Int
Definition: iutest_defs.hpp:527
detail::type_fit_t< 2 >::UInt UInt16
16 bit 符号なし整数型
Definition: iutest_defs.hpp:501
Definition: iutest_defs.hpp:199