mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -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]
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |