• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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