1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/numeric/conversion/converter_policies.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,186 @@
1.4 +// © Copyright Fernando Luis Cacciola Carballal 2000-2004
1.5 +// Use, modification, and distribution is subject to the Boost Software
1.6 +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.7 +// http://www.boost.org/LICENSE_1_0.txt)
1.8 +
1.9 +// See library home page at http://www.boost.org/libs/numeric/conversion
1.10 +//
1.11 +// Contact the author at: fernando_cacciola@hotmail.com
1.12 +//
1.13 +#ifndef BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
1.14 +#define BOOST_NUMERIC_CONVERSION_CONVERTER_POLICIES_FLC_12NOV2002_HPP
1.15 +
1.16 +#include <typeinfo> // for std::bad_cast
1.17 +
1.18 +#include <cmath> // for std::floor and std::ceil
1.19 +
1.20 +#include <functional>
1.21 +
1.22 +#include "boost/type_traits/is_arithmetic.hpp"
1.23 +
1.24 +#include "boost/mpl/if.hpp"
1.25 +#include "boost/mpl/integral_c.hpp"
1.26 +
1.27 +namespace boost { namespace numeric
1.28 +{
1.29 +
1.30 +template<class S>
1.31 +struct Trunc
1.32 +{
1.33 + typedef S source_type ;
1.34 +
1.35 + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
1.36 +
1.37 + static source_type nearbyint ( argument_type s )
1.38 + {
1.39 +#if !defined(BOOST_NO_STDC_NAMESPACE)
1.40 + using std::floor ;
1.41 + using std::ceil ;
1.42 +#endif
1.43 +
1.44 + return s < static_cast<S>(0) ? ceil(s) : floor(s) ;
1.45 + }
1.46 +
1.47 + typedef mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style ;
1.48 +} ;
1.49 +
1.50 +
1.51 +
1.52 +template<class S>
1.53 +struct Floor
1.54 +{
1.55 + typedef S source_type ;
1.56 +
1.57 + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
1.58 +
1.59 + static source_type nearbyint ( argument_type s )
1.60 + {
1.61 +#if !defined(BOOST_NO_STDC_NAMESPACE)
1.62 + using std::floor ;
1.63 +#endif
1.64 +
1.65 + return floor(s) ;
1.66 + }
1.67 +
1.68 + typedef mpl::integral_c< std::float_round_style, std::round_toward_neg_infinity> round_style ;
1.69 +} ;
1.70 +
1.71 +template<class S>
1.72 +struct Ceil
1.73 +{
1.74 + typedef S source_type ;
1.75 +
1.76 + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
1.77 +
1.78 + static source_type nearbyint ( argument_type s )
1.79 + {
1.80 +#if !defined(BOOST_NO_STDC_NAMESPACE)
1.81 + using std::ceil ;
1.82 +#endif
1.83 +
1.84 + return ceil(s) ;
1.85 + }
1.86 +
1.87 + typedef mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style ;
1.88 +} ;
1.89 +
1.90 +template<class S>
1.91 +struct RoundEven
1.92 +{
1.93 + typedef S source_type ;
1.94 +
1.95 + typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
1.96 +
1.97 + static source_type nearbyint ( argument_type s )
1.98 + {
1.99 + // Algorithm contributed by Guillaume Melquiond
1.100 +
1.101 +#if !defined(BOOST_NO_STDC_NAMESPACE)
1.102 + using std::floor ;
1.103 + using std::ceil ;
1.104 +#endif
1.105 +
1.106 + // only works inside the range not at the boundaries
1.107 + S prev = floor(s);
1.108 + S next = ceil(s);
1.109 +
1.110 + S rt = (s - prev) - (next - s); // remainder type
1.111 +
1.112 + S const zero(0.0);
1.113 + S const two(2.0);
1.114 +
1.115 + if ( rt < zero )
1.116 + return prev;
1.117 + else if ( rt > zero )
1.118 + return next;
1.119 + else
1.120 + {
1.121 + bool is_prev_even = two * floor(prev / two) == prev ;
1.122 + return ( is_prev_even ? prev : next ) ;
1.123 + }
1.124 + }
1.125 +
1.126 + typedef mpl::integral_c< std::float_round_style, std::round_to_nearest> round_style ;
1.127 +} ;
1.128 +
1.129 +
1.130 +enum range_check_result
1.131 +{
1.132 + cInRange = 0 ,
1.133 + cNegOverflow = 1 ,
1.134 + cPosOverflow = 2
1.135 +} ;
1.136 +
1.137 +class bad_numeric_cast : public std::bad_cast
1.138 +{
1.139 + public:
1.140 +
1.141 + virtual const char * what() const throw()
1.142 + { return "bad numeric conversion: overflow"; }
1.143 +};
1.144 +
1.145 +class negative_overflow : public bad_numeric_cast
1.146 +{
1.147 + public:
1.148 +
1.149 + virtual const char * what() const throw()
1.150 + { return "bad numeric conversion: negative overflow"; }
1.151 +};
1.152 +class positive_overflow : public bad_numeric_cast
1.153 +{
1.154 + public:
1.155 +
1.156 + virtual const char * what() const throw()
1.157 + { return "bad numeric conversion: positive overflow"; }
1.158 +};
1.159 +
1.160 +struct def_overflow_handler
1.161 +{
1.162 + void operator() ( range_check_result r ) // throw(negative_overflow,positive_overflow)
1.163 + {
1.164 + if ( r == cNegOverflow )
1.165 + throw negative_overflow() ;
1.166 + else if ( r == cPosOverflow )
1.167 + throw positive_overflow() ;
1.168 + }
1.169 +} ;
1.170 +
1.171 +struct silent_overflow_handler
1.172 +{
1.173 + void operator() ( range_check_result ) {} // throw()
1.174 +} ;
1.175 +
1.176 +template<class Traits>
1.177 +struct raw_converter
1.178 +{
1.179 + typedef typename Traits::result_type result_type ;
1.180 + typedef typename Traits::argument_type argument_type ;
1.181 +
1.182 + static result_type low_level_convert ( argument_type s ) { return static_cast<result_type>(s) ; }
1.183 +} ;
1.184 +
1.185 +struct UseInternalRangeChecker {} ;
1.186 +
1.187 +} } // namespace boost::numeric
1.188 +
1.189 +#endif