1[/ 2 Boost.Optional 3 4 Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal 5 6 Distributed under the Boost Software License, Version 1.0. 7 (See accompanying file LICENSE_1_0.txt or copy at 8 http://www.boost.org/LICENSE_1_0.txt) 9] 10 11[section Numeric Converter Policy Classes] 12 13 14[section enum range_check_result] 15 16 namespace boost { namespace numeric { 17 18 enum range_check_result 19 { 20 cInRange , 21 cNegOverflow , 22 cPosOverflow 23 } ; 24 25 } } 26 27Defines the values returned by `boost::numeric::converter<>::out_of_range()` 28 29[endsect] 30 31[section Policy OverflowHandler] 32 33This ['stateless] non-template policy class must be a ['function object] and is 34called to administrate the result of the range checking. It can throw an exception 35if overflow has been detected by the range checking as indicated by its argument. 36If it throws, is is recommended that it be `std::bad_cast` or derived. 37 38It must have the following interface (it does not has to be a template class): 39 40 struct YourOverflowHandlerPolicy 41 { 42 void operator() ( boost::range_check_result ) ; // throw bad_cast or derived 43 } ; 44 45It is called with the result of the converter's `out_of_range()` inside `validate_range()`. 46 47These are the two overflow handler classes provided by the library: 48 49 namespace boost { namespace numeric { 50 51 struct def_overflow_handler 52 { 53 void operator() ( range_check_result r ) // throw bad_numeric_conversion derived 54 { 55 if ( r == cNegOverflow ) 56 throw negative_overflow() ; 57 else if ( r == cPosOverflow ) 58 throw positive_overflow() ; 59 } 60 } ; 61 62 struct silent_overflow_handler 63 { 64 void operator() ( range_check_result ) // no-throw 65 {} 66 } ; 67 68 } } 69 70And these are the Exception Classes thrown by the default overflow handler 71[link numeric_conversion_policy_overflow_handler_important_note (see IMPORTANT note)] 72 73 namespace boost { namespace numeric { 74 75 ``[#numeric_conversion_bad_numeric_cast]`` 76 class bad_numeric_cast : public std::bad_cast 77 { 78 public: 79 virtual const char *what() const // throw() 80 { 81 return "bad numeric conversion: overflow"; 82 } 83 84 }; 85 86 ``[#numeric_conversion_negative_overflow]`` 87 class negative_overflow : public bad_numeric_cast 88 { 89 public: 90 virtual const char *what() const // throw() 91 { 92 return "bad numeric conversion: negative overflow"; 93 } 94 }; 95 96 ``[#numeric_conversion_possitive_overflow]`` 97 class positive_overflow : public bad_numeric_cast 98 { 99 public: 100 virtual const char *what() const // throw() 101 { 102 return "bad numeric conversion: positive overflow"; 103 } 104 }; 105 106 107 } } 108 109[#numeric_conversion_policy_overflow_handler_important_note] 110 111[important [*RELEASE NOTE for 1.33] 112Previous to boost version 1.33, the exception class `bad_numeric_cast` was 113named `bad_numeric_conversion`. However, in 1.33, the old function 114`numeric_cast<>` from `boost/cast.hpp` was completly replaced by the 115new `numeric_cast<>` in `boost/numeric/conversion/cast.hpp` 116(and `boost/cast.hpp` is including `boost/numeric/conversion/cast.hpp` now). 117That old function which existed in boost for quite some time used the 118`bad_numeric_cast` as its exception type so I decided to avoid backward 119compatibility problems by adopting it (guessing that the user base for 120the old code is wider than for the new code). 121] 122 123[endsect] 124 125[section Policy Float2IntRounder] 126 127This ['stateless] template policy class specifies the rounding mode used 128for [_float to integral] conversions. It supplies the `nearbyint()` 129static member function exposed by the converter, which means that it 130[_publicly inherits from this policy]. 131 132The policy must have the following interface: 133 134 template<class S> 135 struct YourFloat2IntRounderPolicy 136 { 137 typedef S source_type ; 138 typedef {S or S const&} argument_type ; 139 140 static source_type nearbyint ( argument_type s ) { ... } 141 142 typedef mpl::integral_c<std::float_round_style,std::round_...> round_style ; 143 144 } ; 145 146These are the rounder classes provided by the library (only the specific parts are shown, 147see the general policy form above) 148 149[note 150These classes are not intended to be general purpose rounding functions 151but specific policies for `converter<>`. This is why they are not function objects. 152] 153 154 namespace boost { namespace numeric { 155 156 157 template<class S> 158 struct Trunc 159 { 160 static source_type nearbyint ( argument_type s ) 161 { 162 using std::floor ; 163 using std::ceil ; 164 165 return s >= static_cast<S>(0) ? floor(s) : ceil(s) ; 166 } 167 168 typedef mpl::integral_c<std::float_round_style,std::round_toward_zero> round_style ; 169 } ; 170 171 172 template<class S> 173 struct RoundEven 174 { 175 static source_type nearbyint ( argument_type s ) 176 { 177 return impl-defined-value ; 178 } 179 180 typedef mpl::integral_c<std::float_round_style,std::round_to_nearest> round_style ; 181 } ; 182 183 184 template<class S> 185 struct Ceil 186 { 187 static source_type nearbyint ( argument_type s ) 188 { 189 using std::ceil ; 190 return ceil(s) ; 191 } 192 193 typedef mpl::integral_c<std::float_round_style,std::round_toward_infinity> round_style ; 194 } ; 195 196 197 template<class S> 198 struct Floor 199 { 200 static source_type nearbyint ( argument_type s ) 201 { 202 using std::floor ; 203 return floor(s) ; 204 } 205 typedef mpl::integral_c<std::float_round_style,std::round_toward_neg_infinity> round_style ; 206 } ; 207 208 } } // namespace numeric, namespace boost 209 210[heading Math Functions used by the rounder policies] 211 212The rounder policies supplied by this header use math functions `floor()` and `ceil()`. 213The standard versions of these functions are introduced in context by a using directive, 214so in normal conditions, the standard functions will be used. 215 216However, if there are other visible corresponding overloads an ambiguity could arise. 217In this case, the user can supply her own rounder policy which could, for instance, 218use a fully qualified call. 219 220This technique allows the default rounder policies to be used directly with 221user defined types. The user only requires that suitable overloads of `floor()` and `ceil()` 222be visible. See also [link boost_numericconversion.type_requirements_and_user_defined_types_support User Defined Numeric Types] 223support. 224 225[endsect] 226 227[section Policy RawConverter] 228 229This ['stateless] template policy class is used to perform the 230actual conversion from Source to Target. It supplies the 231`low_level_convert()` static member function exposed by the 232converter, which means that it publicly inherits from this policy. 233 234The policy must have the following interface: 235 236 template<class Traits> 237 struct YourRawConverterPolicy 238 { 239 typedef typename Traits::result_type result_type ; 240 typedef typename Traits::argument_type argument_type ; 241 242 static result_type low_level_convert ( argument_type s ) { return <impl defined> ; } 243 } ; 244 245 246This policy is mostly provided as a hook for user defined types which don't support `static_cast<>` conversions to some types 247 248This is the only raw converter policy class provided by the library: 249 250 namespace boost { namespace numeric { 251 252 template<class Traits> 253 struct raw_numeric_converter 254 { 255 typedef typename Traits::result_type result_type ; 256 typedef typename Traits::argument_type argument_type ; 257 258 static result_type low_level_convert ( argument_type s ) 259 { 260 return static_cast<result_type>(s) ; 261 } 262 } ; 263 264 } } 265 266[endsect] 267 268[section Policy UserRangeChecker] 269 270This ['stateless] template policy class is used [_only if supplied] 271to [*override] the internal range checking logic. 272 273It supplies the `validate_range()` static member function 274exposed by the converter, which means that it publicly inherits 275from this policy. 276 277The policy must have the following interface: 278 279 template<class Traits> 280 struct YourRangeCheckerPolicy 281 { 282 typedef typename Traits::argument_type argument_type ; 283 284 // Determines if the value 's' fits in the range of the Target type. 285 static range_check_result out_of_range ( argument_type s ) ; 286 287 // Checks whether the value 's' is out_of_range() 288 // and passes the result of the check to the OverflowHandler policy. 289 static void validate_range ( argument_type s ) 290 { 291 OverflowHandler()( out_of_range(s) ) ; 292 } 293 } ; 294 295 296This policy is [*only] provided as a hook for user defined types which require 297range checking (which is disabled by default when a UDT is involved). 298The library provides a class: `UseInternalRangeChecker{}`; which is a ['fake] 299`RangeChecker` policy used to signal the converter to use its internal 300range checking implementation. 301 302[endsect] 303 304[endsect] 305 306 307 308 309 310 311 312