checking.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* Boost interval/checking.hpp template implementation file
  2. *
  3. * Copyright 2002 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
  4. *
  5. * Distributed under the Boost Software License, Version 1.0.
  6. * (See accompanying file LICENSE_1_0.txt or
  7. * copy at http://www.boost.org/LICENSE_1_0.txt)
  8. */
  9. #ifndef BOOST_NUMERIC_INTERVAL_CHECKING_HPP
  10. #define BOOST_NUMERIC_INTERVAL_CHECKING_HPP
  11. #include <stdexcept>
  12. #include <string>
  13. #include <cassert>
  14. #include <boost/limits.hpp>
  15. namespace boost {
  16. namespace numeric {
  17. namespace interval_lib {
  18. struct exception_create_empty
  19. {
  20. void operator()()
  21. {
  22. throw std::runtime_error("boost::interval: empty interval created");
  23. }
  24. };
  25. struct exception_invalid_number
  26. {
  27. void operator()()
  28. {
  29. throw std::invalid_argument("boost::interval: invalid number");
  30. }
  31. };
  32. template<class T>
  33. struct checking_base
  34. {
  35. static T pos_inf()
  36. {
  37. assert(std::numeric_limits<T>::has_infinity);
  38. return std::numeric_limits<T>::infinity();
  39. }
  40. static T neg_inf()
  41. {
  42. assert(std::numeric_limits<T>::has_infinity);
  43. return -std::numeric_limits<T>::infinity();
  44. }
  45. static T nan()
  46. {
  47. assert(std::numeric_limits<T>::has_quiet_NaN);
  48. return std::numeric_limits<T>::quiet_NaN();
  49. }
  50. static bool is_nan(const T& x)
  51. {
  52. return std::numeric_limits<T>::has_quiet_NaN && (x != x);
  53. }
  54. static T empty_lower()
  55. {
  56. return (std::numeric_limits<T>::has_quiet_NaN ?
  57. std::numeric_limits<T>::quiet_NaN() : static_cast<T>(1));
  58. }
  59. static T empty_upper()
  60. {
  61. return (std::numeric_limits<T>::has_quiet_NaN ?
  62. std::numeric_limits<T>::quiet_NaN() : static_cast<T>(0));
  63. }
  64. static bool is_empty(const T& l, const T& u)
  65. {
  66. return !(l <= u); // safety for partial orders
  67. }
  68. };
  69. template<class T, class Checking = checking_base<T>,
  70. class Exception = exception_create_empty>
  71. struct checking_no_empty: Checking
  72. {
  73. static T nan()
  74. {
  75. assert(false);
  76. return Checking::nan();
  77. }
  78. static T empty_lower()
  79. {
  80. Exception()();
  81. return Checking::empty_lower();
  82. }
  83. static T empty_upper()
  84. {
  85. Exception()();
  86. return Checking::empty_upper();
  87. }
  88. static bool is_empty(const T&, const T&)
  89. {
  90. return false;
  91. }
  92. };
  93. template<class T, class Checking = checking_base<T> >
  94. struct checking_no_nan: Checking
  95. {
  96. static bool is_nan(const T&)
  97. {
  98. return false;
  99. }
  100. };
  101. template<class T, class Checking = checking_base<T>,
  102. class Exception = exception_invalid_number>
  103. struct checking_catch_nan: Checking
  104. {
  105. static bool is_nan(const T& x)
  106. {
  107. if (Checking::is_nan(x)) Exception()();
  108. return false;
  109. }
  110. };
  111. template<class T>
  112. struct checking_strict:
  113. checking_no_nan<T, checking_no_empty<T> >
  114. {};
  115. } // namespace interval_lib
  116. } // namespace numeric
  117. } // namespace boost
  118. #endif // BOOST_NUMERIC_INTERVAL_CHECKING_HPP