diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-06-01 08:48:42 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-06-01 09:24:28 (GMT) |
commit | 2812bddd81f8a1b804c7460f4e14cd0aa393d129 (patch) | |
tree | d46294f35150c4f0f43deaf2d31fceaf945ae715 /3rdParty/Boost/boost/numeric/conversion/converter_policies.hpp | |
download | swift-contrib-2812bddd81f8a1b804c7460f4e14cd0aa393d129.zip swift-contrib-2812bddd81f8a1b804c7460f4e14cd0aa393d129.tar.bz2 |
Import.
Diffstat (limited to '3rdParty/Boost/boost/numeric/conversion/converter_policies.hpp')
-rw-r--r-- | 3rdParty/Boost/boost/numeric/conversion/converter_policies.hpp | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/3rdParty/Boost/boost/numeric/conversion/converter_policies.hpp b/3rdParty/Boost/boost/numeric/conversion/converter_policies.hpp new file mode 100644 index 0000000..b0d741b --- /dev/null +++ b/3rdParty/Boost/boost/numeric/conversion/converter_policies.hpp @@ -0,0 +1,186 @@ +// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004 +// Use, modification, and distribution is subject to 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) + +// See library home page at http://www.boost.org/libs/numeric/conversion +// +// Contact the author at: fernando_cacciola@hotmail.com +// +#ifndef BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP +#define BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP + +#include <typeinfo> // for std::bad_cast + +#include <boost/config/no_tr1/cmath.hpp> // for std::floor and std::ceil + +#include <functional> + +#include "boost/type_traits/is_arithmetic.hpp" + +#include "boost/mpl/if.hpp" +#include "boost/mpl/integral_c.hpp" + +namespace boost { namespace numeric +{ + +template<class S> +struct Trunc +{ + typedef S source_type ; + + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ; + + static source_type nearbyint ( argument_type s ) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; + using std::ceil ; +#endif + + return s < static_cast<S>(0) ? ceil(s) : floor(s) ; + } + + typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ; +} ; + + + +template<class S> +struct Floor +{ + typedef S source_type ; + + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ; + + static source_type nearbyint ( argument_type s ) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; +#endif + + return floor(s) ; + } + + typedef mpl::integral_c< std::float_round_style, std::round_toward_neg_infinity> round_style ; +} ; + +template<class S> +struct Ceil +{ + typedef S source_type ; + + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ; + + static source_type nearbyint ( argument_type s ) + { +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::ceil ; +#endif + + return ceil(s) ; + } + + typedef mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style ; +} ; + +template<class S> +struct RoundEven +{ + typedef S source_type ; + + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ; + + static source_type nearbyint ( argument_type s ) + { + // Algorithm contributed by Guillaume Melquiond + +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::floor ; + using std::ceil ; +#endif + + // only works inside the range not at the boundaries + S prev = floor(s); + S next = ceil(s); + + S rt = (s - prev) - (next - s); // remainder type + + S const zero(0.0); + S const two(2.0); + + if ( rt < zero ) + return prev; + else if ( rt > zero ) + return next; + else + { + bool is_prev_even = two * floor(prev / two) == prev ; + return ( is_prev_even ? prev : next ) ; + } + } + + typedef mpl::integral_c< std::float_round_style, std::round_to_nearest> round_style ; +} ; + + +enum range_check_result +{ + cInRange = 0 , + cNegOverflow = 1 , + cPosOverflow = 2 +} ; + +class bad_numeric_cast : public std::bad_cast +{ + public: + + virtual const char * what() const throw() + { return "bad numeric conversion: overflow"; } +}; + +class negative_overflow : public bad_numeric_cast +{ + public: + + virtual const char * what() const throw() + { return "bad numeric conversion: negative overflow"; } +}; +class positive_overflow : public bad_numeric_cast +{ + public: + + virtual const char * what() const throw() + { return "bad numeric conversion: positive overflow"; } +}; + +struct def_overflow_handler +{ + void operator() ( range_check_result r ) // throw(negative_overflow,positive_overflow) + { + if ( r == cNegOverflow ) + throw negative_overflow() ; + else if ( r == cPosOverflow ) + throw positive_overflow() ; + } +} ; + +struct silent_overflow_handler +{ + void operator() ( range_check_result ) {} // throw() +} ; + +template<class Traits> +struct raw_converter +{ + typedef typename Traits::result_type result_type ; + typedef typename Traits::argument_type argument_type ; + + static result_type low_level_convert ( argument_type s ) { return static_cast<result_type>(s) ; } +} ; + +struct UseInternalRangeChecker {} ; + +} } // namespace boost::numeric + +#endif |