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 10 #ifndef BOOST_NUMERIC_INTERVAL_CHECKING_HPP 11 #define BOOST_NUMERIC_INTERVAL_CHECKING_HPP 12 13 #include <stdexcept> 14 #include <string> 15 #include <cassert> 16 #include <boost/limits.hpp> 17 18 namespace boost { 19 namespace numeric { 20 namespace interval_lib { 21 22 struct exception_create_empty 23 { operator ()boost::numeric::interval_lib::exception_create_empty24 void operator()() 25 { 26 throw std::runtime_error("boost::interval: empty interval created"); 27 } 28 }; 29 30 struct exception_invalid_number 31 { operator ()boost::numeric::interval_lib::exception_invalid_number32 void operator()() 33 { 34 throw std::invalid_argument("boost::interval: invalid number"); 35 } 36 }; 37 38 template<class T> 39 struct checking_base 40 { pos_infboost::numeric::interval_lib::checking_base41 static T pos_inf() 42 { 43 assert(std::numeric_limits<T>::has_infinity); 44 return std::numeric_limits<T>::infinity(); 45 } neg_infboost::numeric::interval_lib::checking_base46 static T neg_inf() 47 { 48 assert(std::numeric_limits<T>::has_infinity); 49 return -std::numeric_limits<T>::infinity(); 50 } nanboost::numeric::interval_lib::checking_base51 static T nan() 52 { 53 assert(std::numeric_limits<T>::has_quiet_NaN); 54 return std::numeric_limits<T>::quiet_NaN(); 55 } is_nanboost::numeric::interval_lib::checking_base56 static bool is_nan(const T& x) 57 { 58 return std::numeric_limits<T>::has_quiet_NaN && (x != x); 59 } empty_lowerboost::numeric::interval_lib::checking_base60 static T empty_lower() 61 { 62 return (std::numeric_limits<T>::has_quiet_NaN ? 63 std::numeric_limits<T>::quiet_NaN() : static_cast<T>(1)); 64 } empty_upperboost::numeric::interval_lib::checking_base65 static T empty_upper() 66 { 67 return (std::numeric_limits<T>::has_quiet_NaN ? 68 std::numeric_limits<T>::quiet_NaN() : static_cast<T>(0)); 69 } is_emptyboost::numeric::interval_lib::checking_base70 static bool is_empty(const T& l, const T& u) 71 { 72 return !(l <= u); // safety for partial orders 73 } 74 }; 75 76 template<class T, class Checking = checking_base<T>, 77 class Exception = exception_create_empty> 78 struct checking_no_empty: Checking 79 { nanboost::numeric::interval_lib::checking_no_empty80 static T nan() 81 { 82 assert(false); 83 return Checking::nan(); 84 } empty_lowerboost::numeric::interval_lib::checking_no_empty85 static T empty_lower() 86 { 87 Exception()(); 88 return Checking::empty_lower(); 89 } empty_upperboost::numeric::interval_lib::checking_no_empty90 static T empty_upper() 91 { 92 Exception()(); 93 return Checking::empty_upper(); 94 } is_emptyboost::numeric::interval_lib::checking_no_empty95 static bool is_empty(const T&, const T&) 96 { 97 return false; 98 } 99 }; 100 101 template<class T, class Checking = checking_base<T> > 102 struct checking_no_nan: Checking 103 { is_nanboost::numeric::interval_lib::checking_no_nan104 static bool is_nan(const T&) 105 { 106 return false; 107 } 108 }; 109 110 template<class T, class Checking = checking_base<T>, 111 class Exception = exception_invalid_number> 112 struct checking_catch_nan: Checking 113 { is_nanboost::numeric::interval_lib::checking_catch_nan114 static bool is_nan(const T& x) 115 { 116 if (Checking::is_nan(x)) Exception()(); 117 return false; 118 } 119 }; 120 121 template<class T> 122 struct checking_strict: 123 checking_no_nan<T, checking_no_empty<T> > 124 {}; 125 126 } // namespace interval_lib 127 } // namespace numeric 128 } // namespace boost 129 130 #endif // BOOST_NUMERIC_INTERVAL_CHECKING_HPP 131