mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
	
	
		
			294 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			294 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | [/ | ||
|  |     Boost.Optional | ||
|  | 
 | ||
|  |     Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal | ||
|  | 
 | ||
|  |     Distributed under 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) | ||
|  | ] | ||
|  | 
 | ||
|  | [section converter<> function object] | ||
|  | 
 | ||
|  | [section Synopsis] | ||
|  | 
 | ||
|  |     namespace boost { namespace numeric { | ||
|  | 
 | ||
|  | 
 | ||
|  |         template<class T, | ||
|  |                  class S, | ||
|  |                  class Traits,          = conversion_traits<T,S> | ||
|  |                  class OverflowHandler  = def_overflow_handler, | ||
|  |                  class Float2IntRounder = Trunc< typename Traits::source_type >, | ||
|  |                  class RawConverter     = raw_converter<Traits>, | ||
|  |                  class UserRangeChecker = UseInternalRangeChecker | ||
|  |                 > | ||
|  |         struct converter | ||
|  |         { | ||
|  |             typedef Traits traits ; | ||
|  | 
 | ||
|  |             typedef typename Traits::source_type   source_type   ; | ||
|  |             typedef typename Traits::argument_type argument_type ; | ||
|  |             typedef typename Traits::result_type   result_type   ; | ||
|  | 
 | ||
|  |             static result_type convert ( argument_type s ) ; | ||
|  | 
 | ||
|  |             result_type operator() ( argument_type s ) const ; | ||
|  | 
 | ||
|  |             // Internal member functions: | ||
|  | 
 | ||
|  |             static range_check_result out_of_range      ( argument_type s ) ; | ||
|  |             static void               validate_range    ( argument_type s ) ; | ||
|  |             static result_type        low_level_convert ( argument_type s ) ; | ||
|  |             static source_type        nearbyint         ( argument_type s ) ; | ||
|  | 
 | ||
|  |         } ; | ||
|  | 
 | ||
|  |     } } // namespace numeric, boost | ||
|  | 
 | ||
|  | 
 | ||
|  | `boost::numeric::converter<>` is a __SGI_UNARY_FUNCTION__ encapsulating | ||
|  | the code to perform a numeric conversion with the direction and | ||
|  | properties specified by the Traits template parameter. It can optionally | ||
|  | take some [link boost_numericconversion.numeric_converter_policy_classes policies] which can be used to customize its behavior. The | ||
|  | `Traits` parameter is not a policy but the parameter that defines | ||
|  | the conversion. | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section Template parameters] | ||
|  | 
 | ||
|  | [table | ||
|  | [[            ][           ]] | ||
|  | [[`T`][ | ||
|  | The [link boost_numericconversion.definitions.numeric_types Numeric Type]  | ||
|  | which is the ['Target] of the conversion. | ||
|  | ]] | ||
|  | [[`S`][ | ||
|  | The [link boost_numericconversion.definitions.numeric_types Numeric Type]  | ||
|  | which is the ['Source] of the conversion. | ||
|  | ]] | ||
|  | [[`Traits`][ | ||
|  | This must be a conversion traits class with the interface of | ||
|  | [link boost_numericconversion.conversion_traits___traits_class `boost::numeric::conversion_traits`] | ||
|  | ]] | ||
|  | [[`OverflowHandler`][ | ||
|  | [*Stateless Policy] called to administrate the result of the range checking. | ||
|  | 
 | ||
|  | It is a [*Function Object] which receives the result of `out_of_range()` | ||
|  | and is called inside the `validate_range()` static member function exposed | ||
|  | by the converter. | ||
|  | ]] | ||
|  | [[`Float2IntRounder`][ | ||
|  | [*Stateless Policy] which specifies the rounding mode used for float to | ||
|  | integral conversions. | ||
|  | 
 | ||
|  | It supplies the `nearbyint()` static member function exposed by the converter. | ||
|  | ]] | ||
|  | [[`RawConverter`][ | ||
|  | [*Stateless Policy] which is used to perform the actual conversion. | ||
|  | 
 | ||
|  | It supplies the `low_level_convert()` static member function exposed | ||
|  | by the converter. | ||
|  | ]] | ||
|  | [[`UserRangeChecker`][ | ||
|  | ['Special and Optional] [*Stateless Policy] which can be used to override | ||
|  | the internal range checking logic. | ||
|  | 
 | ||
|  | If given, supplies alternative code for the `out_of_range()` and | ||
|  | `validate_range()` static member functions exposed by the converter. | ||
|  | ]] | ||
|  | ] | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section Member functions] | ||
|  | 
 | ||
|  | [: `static result_type converter<>::convert ( argument_type s ) ; // throw | ||
|  | `] | ||
|  | 
 | ||
|  | This static member function converts an rvalue of type `source_type` to | ||
|  | an rvalue of type `target_type`. | ||
|  | 
 | ||
|  | If the conversion requires it, it performs a range checking before the conversion | ||
|  | and passes the result of the check to the overflow handler policy (the default | ||
|  | policy throws an exception if out-of-range is detected) | ||
|  | 
 | ||
|  | The implementation of this function is actually built from the policies and is | ||
|  | basically as follows: | ||
|  | 
 | ||
|  |     result_type converter<>::convert ( argument_type s ) | ||
|  |     { | ||
|  |         validate_range(s); // Implemented by the internal range checking logic | ||
|  |                            // (which also calls the OverflowHandler policy) | ||
|  |                            // or externally supplied by the UserRangeChecker policy. | ||
|  | 
 | ||
|  |         s = nearbyint(s); // Externally supplied by the Float2IntRounder policy. | ||
|  |                           // NOTE: This is actually called only for float to int conversions. | ||
|  | 
 | ||
|  |         return low_level_convert(s); // Externally supplied by the RawConverter policy. | ||
|  |     } | ||
|  | 
 | ||
|  | `converter<>::operator() const` just calls `convert()` | ||
|  | 
 | ||
|  | __SPACE__ | ||
|  | 
 | ||
|  | [: `static range_check_result numeric_converter<>::out_of_range ( argument_type s ) ;`] | ||
|  | 
 | ||
|  | This [link numeric_conversion_converter_internal internal] static member function  | ||
|  | determines if the value `s` can be | ||
|  | represented by the target type without overflow. | ||
|  | 
 | ||
|  | It does not determine if the conversion is ['exact]; that is, it does not detect | ||
|  | ['inexact] conversions, only ['out-of-range] conversions (see the | ||
|  | [link boost_numericconversion.definitions.exact__correctly_rounded_and_out_of_range_representations Definitions] for further details). | ||
|  | 
 | ||
|  | The return value is of enum type  | ||
|  | [link boost_numericconversion.numeric_converter_policy_classes.enum_range_check_result `boost::numeric::range_check_result`] | ||
|  | 
 | ||
|  | The actual code for the range checking logic is optimized for the combined | ||
|  | properties of the source and target types. For example, a non-subranged | ||
|  | conversion (i.e: `int`->`float`), requires no range checking, so `out_of_range()` | ||
|  | returns `cInRange` directly. See the following  | ||
|  | [link boost_numericconversion.converter___function_object.range_checking_logic table] for more details. | ||
|  | 
 | ||
|  | If the user supplied a | ||
|  | [link boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy,  | ||
|  | is this policy which implements this function, so the implementation is user  | ||
|  | defined, although it is expected to perform the same conceptual check and  | ||
|  | return the appropriate result. | ||
|  | 
 | ||
|  | __SPACE__ | ||
|  | 
 | ||
|  | [: `static void numeric_converter<>::validate_range ( argument_type s ) ; // no throw | ||
|  | `] | ||
|  | 
 | ||
|  | This [link numeric_conversion_converter_internal internal] static member function  | ||
|  | calls out_of_range(s), and passes the | ||
|  | result to the [link boost_numericconversion.numeric_converter_policy_classes.policy_overflowhandler OverflowHandler]  | ||
|  | policy class. | ||
|  | 
 | ||
|  | For those Target/Source combinations which don't require range checking, this | ||
|  | is an empty inline function. | ||
|  | 
 | ||
|  | If the user supplied a  | ||
|  | [link boost_numericconversion.numeric_converter_policy_classes.policy_userrangechecker UserRangeChecker] policy,  | ||
|  | is this policy which implements this function, so the implementation is user  | ||
|  | defined, although it is expected to perform the same action as the default.  | ||
|  | In particular, it is expected to pass the result of the check to the overflow handler. | ||
|  | 
 | ||
|  | __SPACE__ | ||
|  | 
 | ||
|  | [: `static result_type numeric_converter<>::low_level_convert ( argument_type s ) ;` ] | ||
|  | 
 | ||
|  | This [link numeric_conversion_converter_internal internal] static member function  | ||
|  | performs the actual conversion. | ||
|  | 
 | ||
|  | This function is externally supplied by the  | ||
|  | [link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy class. | ||
|  | 
 | ||
|  | __SPACE__ | ||
|  | 
 | ||
|  | [: `static source_type converter<>::nearbyint ( argument_type s ) ;`] | ||
|  | 
 | ||
|  | This [link numeric_conversion_converter_internal internal] static member function,  | ||
|  | which is [_only used] for | ||
|  | `float` to `int` conversions, returns an ['integer] value of ['[_floating-point | ||
|  | type]] according to some rounding direction. | ||
|  | 
 | ||
|  | This function is externally supplied by the  | ||
|  | [link boost_numericconversion.numeric_converter_policy_classes.policy_float2introunder Float2IntRounder] policy class | ||
|  | which encapsulates the specific rounding mode. | ||
|  | 
 | ||
|  | __SPACE__ | ||
|  | 
 | ||
|  | [#numeric_conversion_converter_internal] | ||
|  | 
 | ||
|  | [heading Internal Member Functions] | ||
|  | 
 | ||
|  | These static member functions build the actual conversion code used by `convert()`. | ||
|  | The user does not have to call these if calling `convert()`, since `convert()` calls | ||
|  | them infernally, but they can be called separately for specific needs. | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section Range Checking Logic] | ||
|  | 
 | ||
|  | The following table summarizes the internal range checking logic performed for | ||
|  | each combination of the properties of Source and Target. | ||
|  | 
 | ||
|  | LowestT/HighestT denotes the highest and lowest values of the Target type, respectively. | ||
|  | 
 | ||
|  | `S(n)` is short for `static_cast<S>(n)` (`S` denotes the Source type). | ||
|  | 
 | ||
|  | `NONE` indicates that for this case there is no range checking. | ||
|  | 
 | ||
|  | [pre | ||
|  | [^ | ||
|  | int_to_int    |--> sig_to_sig     |--> subranged     |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) ) | ||
|  |               |                   |--> not subranged |--> NONE | ||
|  |               | | ||
|  |               |--> unsig_to_unsig |--> subranged     |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) ) | ||
|  |               |                   |--> not subranged |--> NONE | ||
|  |               | | ||
|  |               |--> sig_to_unsig   |--> pos subranged     |--> ( s >= S(0) ) && ( s <= S(HighestT) ) | ||
|  |               |                   |--> not pos subranged |--> ( s >= S(0) ) | ||
|  |               | | ||
|  |               |--> unsig_to_sig   |--> subranged     |--> ( s <= S(HighestT) ) | ||
|  |               |                   |--> not subranged |--> NONE | ||
|  | ] | ||
|  | [^ | ||
|  | int_to_float   |--> NONE | ||
|  | ] | ||
|  | [^ | ||
|  | float_to_int   |--> round_to_zero         |--> ( s >  S(LowestT)-S(1)   ) && ( s <  S(HighestT)+S(1)   ) | ||
|  |                |--> round_to_even_nearest |--> ( s >= S(LowestT)-S(0.5) ) && ( s <  S(HighestT)+S(0.5) ) | ||
|  |                |--> round_to_infinity     |--> ( s >  S(LowestT)-S(1)   ) && ( s <= S(HighestT)        ) | ||
|  |                |--> round_to_neg_infinity |--> ( s >= S(LowestT)        ) && ( s <  S(HighestT)+S(1)   ) | ||
|  | ] | ||
|  | [^ | ||
|  | float_to_float |--> subranged     |--> ( s >= S(LowestT) ) && ( s <= S(HighestT) ) | ||
|  |                |--> not subranged |--> NONE | ||
|  | ] | ||
|  | ] | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section Examples] | ||
|  | 
 | ||
|  |     #include <cassert> | ||
|  |     #include <boost/numeric/conversion/converter.hpp> | ||
|  | 
 | ||
|  |     int main() { | ||
|  | 
 | ||
|  |         typedef boost::numeric::converter<int,double> Double2Int ; | ||
|  | 
 | ||
|  |         int x = Double2Int::convert(2.0); | ||
|  |         assert ( x == 2 ); | ||
|  | 
 | ||
|  |         int y = Double2Int()(3.14); // As a function object. | ||
|  |         assert ( y == 3 ) ; // The default rounding is trunc. | ||
|  | 
 | ||
|  |         try | ||
|  |         { | ||
|  |             double m = boost::numeric::bounds<double>::highest(); | ||
|  |             int z = Double2Int::convert(m); // By default throws positive_overflow() | ||
|  |         } | ||
|  |         catch ( boost::numeric::positive_overflow const& ) | ||
|  |         { | ||
|  |         } | ||
|  | 
 | ||
|  |         return 0; | ||
|  |     } | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 |