| /* Boost interval/checking.hpp template implementation file |
| * |
| * Copyright 2002 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion |
| * |
| * Distributed under the Boost Software License, Version 1.0. |
| * (See accompanying file LICENSE_1_0.txt or |
| * copy at http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| |
| #ifndef BOOST_NUMERIC_INTERVAL_CHECKING_HPP |
| #define BOOST_NUMERIC_INTERVAL_CHECKING_HPP |
| |
| #include <stdexcept> |
| #include <string> |
| #include <cassert> |
| #include <boost/limits.hpp> |
| |
| namespace boost { |
| namespace numeric { |
| namespace interval_lib { |
| |
| struct exception_create_empty |
| { |
| void operator()() |
| { |
| throw std::runtime_error("boost::interval: empty interval created"); |
| } |
| }; |
| |
| struct exception_invalid_number |
| { |
| void operator()() |
| { |
| throw std::invalid_argument("boost::interval: invalid number"); |
| } |
| }; |
| |
| template<class T> |
| struct checking_base |
| { |
| static T pos_inf() |
| { |
| assert(std::numeric_limits<T>::has_infinity); |
| return std::numeric_limits<T>::infinity(); |
| } |
| static T neg_inf() |
| { |
| assert(std::numeric_limits<T>::has_infinity); |
| return -std::numeric_limits<T>::infinity(); |
| } |
| static T nan() |
| { |
| assert(std::numeric_limits<T>::has_quiet_NaN); |
| return std::numeric_limits<T>::quiet_NaN(); |
| } |
| static bool is_nan(const T& x) |
| { |
| return std::numeric_limits<T>::has_quiet_NaN && (x != x); |
| } |
| static T empty_lower() |
| { |
| return (std::numeric_limits<T>::has_quiet_NaN ? |
| std::numeric_limits<T>::quiet_NaN() : static_cast<T>(1)); |
| } |
| static T empty_upper() |
| { |
| return (std::numeric_limits<T>::has_quiet_NaN ? |
| std::numeric_limits<T>::quiet_NaN() : static_cast<T>(0)); |
| } |
| static bool is_empty(const T& l, const T& u) |
| { |
| return !(l <= u); // safety for partial orders |
| } |
| }; |
| |
| template<class T, class Checking = checking_base<T>, |
| class Exception = exception_create_empty> |
| struct checking_no_empty: Checking |
| { |
| static T nan() |
| { |
| assert(false); |
| return Checking::nan(); |
| } |
| static T empty_lower() |
| { |
| Exception()(); |
| return Checking::empty_lower(); |
| } |
| static T empty_upper() |
| { |
| Exception()(); |
| return Checking::empty_upper(); |
| } |
| static bool is_empty(const T&, const T&) |
| { |
| return false; |
| } |
| }; |
| |
| template<class T, class Checking = checking_base<T> > |
| struct checking_no_nan: Checking |
| { |
| static bool is_nan(const T&) |
| { |
| return false; |
| } |
| }; |
| |
| template<class T, class Checking = checking_base<T>, |
| class Exception = exception_invalid_number> |
| struct checking_catch_nan: Checking |
| { |
| static bool is_nan(const T& x) |
| { |
| if (Checking::is_nan(x)) Exception()(); |
| return false; |
| } |
| }; |
| |
| template<class T> |
| struct checking_strict: |
| checking_no_nan<T, checking_no_empty<T> > |
| {}; |
| |
| } // namespace interval_lib |
| } // namespace numeric |
| } // namespace boost |
| |
| #endif // BOOST_NUMERIC_INTERVAL_CHECKING_HPP |