File indexing completed on 2025-01-18 09:42:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
0011 #define BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
0012
0013 #include <functional>
0014 #include <typeinfo> // for std::bad_cast
0015
0016 #include <boost/config.hpp>
0017 #include <boost/config/no_tr1/cmath.hpp> // for std::floor and std::ceil
0018 #include <boost/throw_exception.hpp>
0019
0020 #include "boost/type_traits/is_arithmetic.hpp"
0021
0022 #include "boost/mpl/if.hpp"
0023 #include "boost/mpl/integral_c.hpp"
0024
0025 namespace boost { namespace numeric
0026 {
0027
0028 template<class S>
0029 struct Trunc
0030 {
0031 typedef S source_type ;
0032
0033 typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
0034
0035 static source_type nearbyint ( argument_type s )
0036 {
0037 #if !defined(BOOST_NO_STDC_NAMESPACE)
0038 using std::floor ;
0039 using std::ceil ;
0040 #endif
0041
0042 return s < static_cast<S>(0) ? ceil(s) : floor(s) ;
0043 }
0044
0045 typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ;
0046 } ;
0047
0048
0049
0050 template<class S>
0051 struct Floor
0052 {
0053 typedef S source_type ;
0054
0055 typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
0056
0057 static source_type nearbyint ( argument_type s )
0058 {
0059 #if !defined(BOOST_NO_STDC_NAMESPACE)
0060 using std::floor ;
0061 #endif
0062
0063 return floor(s) ;
0064 }
0065
0066 typedef mpl::integral_c< std::float_round_style, std::round_toward_neg_infinity> round_style ;
0067 } ;
0068
0069 template<class S>
0070 struct Ceil
0071 {
0072 typedef S source_type ;
0073
0074 typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
0075
0076 static source_type nearbyint ( argument_type s )
0077 {
0078 #if !defined(BOOST_NO_STDC_NAMESPACE)
0079 using std::ceil ;
0080 #endif
0081
0082 return ceil(s) ;
0083 }
0084
0085 typedef mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style ;
0086 } ;
0087
0088 template<class S>
0089 struct RoundEven
0090 {
0091 typedef S source_type ;
0092
0093 typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
0094
0095 static source_type nearbyint ( argument_type s )
0096 {
0097
0098
0099 #if !defined(BOOST_NO_STDC_NAMESPACE)
0100 using std::floor ;
0101 using std::ceil ;
0102 #endif
0103
0104
0105 S prev = floor(s);
0106 S next = ceil(s);
0107
0108 S rt = (s - prev) - (next - s);
0109
0110 S const zero(0.0);
0111 S const two(2.0);
0112
0113 if ( rt < zero )
0114 return prev;
0115 else if ( rt > zero )
0116 return next;
0117 else
0118 {
0119 bool is_prev_even = two * floor(prev / two) == prev ;
0120 return ( is_prev_even ? prev : next ) ;
0121 }
0122 }
0123
0124 typedef mpl::integral_c< std::float_round_style, std::round_to_nearest> round_style ;
0125 } ;
0126
0127
0128 enum range_check_result
0129 {
0130 cInRange = 0 ,
0131 cNegOverflow = 1 ,
0132 cPosOverflow = 2
0133 } ;
0134
0135 class bad_numeric_cast : public std::bad_cast
0136 {
0137 public:
0138
0139 const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
0140 { return "bad numeric conversion: overflow"; }
0141 };
0142
0143 class negative_overflow : public bad_numeric_cast
0144 {
0145 public:
0146
0147 const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
0148 { return "bad numeric conversion: negative overflow"; }
0149 };
0150 class positive_overflow : public bad_numeric_cast
0151 {
0152 public:
0153
0154 const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
0155 { return "bad numeric conversion: positive overflow"; }
0156 };
0157
0158 struct def_overflow_handler
0159 {
0160 void operator() ( range_check_result r )
0161 {
0162 #ifndef BOOST_NO_EXCEPTIONS
0163 if ( r == cNegOverflow )
0164 throw negative_overflow() ;
0165 else if ( r == cPosOverflow )
0166 throw positive_overflow() ;
0167 #else
0168 if ( r == cNegOverflow )
0169 ::boost::throw_exception(negative_overflow()) ;
0170 else if ( r == cPosOverflow )
0171 ::boost::throw_exception(positive_overflow()) ;
0172 #endif
0173 }
0174 } ;
0175
0176 struct silent_overflow_handler
0177 {
0178 void operator() ( range_check_result ) {}
0179 } ;
0180
0181 template<class Traits>
0182 struct raw_converter
0183 {
0184 typedef typename Traits::result_type result_type ;
0185 typedef typename Traits::argument_type argument_type ;
0186
0187 static result_type low_level_convert ( argument_type s ) { return static_cast<result_type>(s) ; }
0188 } ;
0189
0190 struct UseInternalRangeChecker {} ;
0191
0192 } }
0193
0194 #endif