mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			449 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			449 lines
		
	
	
		
			14 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 Type Requirements and User-defined-types support]
 | |
| 
 | |
| [section Type Requirements]
 | |
| 
 | |
| Both arithmetic (built-in) and user-defined numeric types require proper
 | |
| specialization of `std::numeric_limits<>` (that is, with (in-class) integral
 | |
| constants).
 | |
| 
 | |
| The library uses `std::numeric_limits<T>::is_specialized` to detect whether
 | |
| the type is builtin or user defined, and `std::numeric_limits<T>::is_integer`,
 | |
| `std::numeric_limits<T>::is_signed` to detect whether the type is integer
 | |
| or floating point; and whether it is signed/unsigned.
 | |
| 
 | |
| The default `Float2IntRounder` policies uses unqualified calls to functions
 | |
| `floor()` and `ceil()`; but the standard functions are introduced in scope
 | |
| by a using directive:
 | |
| 
 | |
|     using std::floor ; return floor(s);
 | |
| 
 | |
| Therefore, for builtin arithmetic types, the std functions will be used.
 | |
| User defined types should provide overloaded versions of these functions in
 | |
| order to use the default rounder policies. If these overloads are defined
 | |
| within a user namespace argument dependent lookup (ADL) should find them,
 | |
| but if your compiler has a weak ADL you might need to put these functions
 | |
| some place else or write your own rounder policy.
 | |
| 
 | |
| The default `Trunc<>` rounder policy needs to determine if the source value
 | |
| is positive or not, and for this it evaluates the expression
 | |
| `s < static_cast<S>(0)`. Therefore, user defined types require a visible
 | |
| `operator<` in order to use the `Trunc<>` policy (the default).
 | |
| 
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section UDT's special semantics]
 | |
| 
 | |
| [heading Conversion Traits]
 | |
| 
 | |
| If a User Defined Type is involved in a conversion, it is ['assumed] that
 | |
| the UDT has [link boost_numericconversion.definitions.range_and_precision wider range] 
 | |
| than any built-in type, and consequently the values
 | |
| of some `converter_traits<>` members are hardwired regardless of the reality.
 | |
| The following table summarizes this:
 | |
| 
 | |
| * `Target=`['UDT] and `Source=`['built-in]
 | |
|     * `subranged=false`
 | |
|     * `supertype=Target`
 | |
|     * `subtype=Source`
 | |
| * `Target=`['built-in] and `Source=`['UDT]
 | |
|     * `subranged=true`
 | |
|     * `supertype=Source`
 | |
|     * `subtype=Target`
 | |
| 
 | |
| * `Target=`['UDT] and `Source=`['UDT]
 | |
|     * `subranged=false`
 | |
|     * `supertype=Target`
 | |
|     * `subtype=Source`
 | |
| 
 | |
| 
 | |
| The `Traits` member `udt_mixture` can be used to detect whether a UDT is involved
 | |
| and to infer the validity of the other members as shown above.
 | |
| 
 | |
| [heading Range Checking]
 | |
| 
 | |
| Because User Defined Numeric Types might have peculiar ranges (such as an
 | |
| unbounded range), this library does not attempt to supply a meaningful range
 | |
| checking logic when UDTs are involved in a conversion. Therefore, if either
 | |
| Target or Source are not built-in types, the bundled range checking of the
 | |
| `converter<>` function object is automatically disabled. However, it is possible
 | |
| to supply a user-defined range-checker. See 
 | |
| [link boost_numericconversion.type_requirements_and_user_defined_types_support.special_policies Special Policies]
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section Special Policies]
 | |
| 
 | |
| There are two components of the `converter<>` class that might require special
 | |
| behavior if User Defined Numeric Types are involved: the Range Checking and the
 | |
| Raw Conversion.
 | |
| 
 | |
| When both Target and Source are built-in types, the converter class uses an internal
 | |
| range checking logic which is optimized and customized for the combined properties
 | |
| of the types.
 | |
| 
 | |
| However, this internal logic is disabled when either type is User Defined.
 | |
| In this case, the user can specify an ['external] range checking policy which will be
 | |
| used in place of the internal code. See
 | |
| [link boost_numericconversion.type_requirements_and_user_defined_types_support.udts_with_numeric_cast numeric_cast_traits]
 | |
| for details on using UDTs with `numeric_cast`.
 | |
| 
 | |
| The converter class performs the actual conversion using a Raw Converter policy.
 | |
| The default raw converter simply performs a `static_cast<Target>(source)`.
 | |
| 
 | |
| However, if the a UDT is involved, the `static_cast` might not work. In this case,
 | |
| the user can implement and pass a different raw converter policy.
 | |
| See [link boost_numericconversion.numeric_converter_policy_classes.policy_rawconverter RawConverter] policy for details.
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section UDTs with numeric_cast]
 | |
| 
 | |
| In order to employ UDTs with `numeric_cast`, the user should define
 | |
| a `numeric_cast_traits` specialization on the UDT for each conversion.
 | |
| Here is an example of specializations for converting between the UDT
 | |
| and any other type:
 | |
| 
 | |
|     namespace boost { namespace numeric {
 | |
|     template <typename Source>
 | |
|     struct numeric_cast_traits<UDT, Source>
 | |
|     {
 | |
|         typedef conversion_traits<UDT, Source>      conv_traits;
 | |
|         
 | |
|         //! The following are required:
 | |
|         typedef YourOverflowHandlerPolicy           overflow_policy;
 | |
|         typedef YourRangeCheckerPolicy<conv_traits> range_checking_policy;
 | |
|         typedef YourFloat2IntRounderPolicy<Source>  rounding_policy;
 | |
|     };
 | |
|     template <typename Target>
 | |
|     struct numeric_cast_traits<Target, UDT>
 | |
|     {
 | |
|         typedef conversion_traits<Target, UDT>      conv_traits;
 | |
|         
 | |
|         //! The following are required:
 | |
|         typedef YourOverflowHandlerPolicy           overflow_policy;
 | |
|         typedef YourRangeCheckerPolicy<conv_traits> range_checking_policy;
 | |
|         typedef YourFloat2IntRounderPolicy<UDT>     rounding_policy;
 | |
|     };
 | |
|     }}//namespace boost::numeric;
 | |
| 
 | |
| These specializations are already defined with default values for the built-in
 | |
| numeric types. It is possible to disable the generation of specializations for
 | |
| built-in types by defining `BOOST_NUMERIC_CONVERSION_RELAX_BUILT_IN_CAST_TRAITS`.
 | |
| For details on defining custom policies see [link boost_numericconversion.numeric_converter_policy_classes Converter Policies].
 | |
| 
 | |
| Here is a full example of how to define a custom UDT for use with `numeric_cast`:
 | |
| 
 | |
|     //! Define a simple custom number
 | |
|     struct Double
 | |
|         :   boost::ordered_field_operators
 | |
|             <
 | |
|                 Double
 | |
|               , boost::ordered_field_operators2< Double, long double
 | |
|               , boost::ordered_field_operators2< Double, double
 | |
|               , boost::ordered_field_operators2< Double, float
 | |
|               , boost::ordered_field_operators2< Double, int
 | |
|               , boost::ordered_field_operators2< Double, unsigned int
 | |
|               , boost::ordered_field_operators2< Double, long
 | |
|               , boost::ordered_field_operators2< Double, unsigned long
 | |
|               , boost::ordered_field_operators2< Double, long long
 | |
|               , boost::ordered_field_operators2< Double, unsigned long long
 | |
|               , boost::ordered_field_operators2< Double, char
 | |
|               , boost::ordered_field_operators2< Double, unsigned char
 | |
|               , boost::ordered_field_operators2< Double, short
 | |
|               , boost::ordered_field_operators2< Double, unsigned short
 | |
|             > > > > > > > > > > > > > >
 | |
|     {
 | |
|         Double()
 | |
|             : v(0)
 | |
|         {}
 | |
| 
 | |
|         template <typename T>
 | |
|         explicit Double( T v )
 | |
|             : v(static_cast<double>(v))
 | |
|         {}
 | |
| 
 | |
|         template <typename T>
 | |
|         Double& operator= ( T t )
 | |
|         {
 | |
|             v = static_cast<double>(t);
 | |
|             return *this;
 | |
|         }
 | |
| 
 | |
|         bool operator < ( const Double& rhs ) const
 | |
|         {
 | |
|             return v < rhs.v;
 | |
|         }
 | |
| 
 | |
|         template <typename T>
 | |
|         bool operator < ( T rhs ) const
 | |
|         {
 | |
|             return v < static_cast<double>(rhs);
 | |
|         }
 | |
| 
 | |
|         bool operator > ( const Double& rhs ) const
 | |
|         {
 | |
|             return v > rhs.v;
 | |
|         }
 | |
|     
 | |
|         template <typename T>
 | |
|         bool operator > ( T rhs ) const
 | |
|         {
 | |
|             return v > static_cast<double>(rhs);
 | |
|         }
 | |
|     
 | |
|         bool operator ==( const Double& rhs ) const
 | |
|         {
 | |
|             return v == rhs.v;
 | |
|         }
 | |
|     
 | |
|         template <typename T>
 | |
|         bool operator == ( T rhs ) const
 | |
|         {
 | |
|             return v == static_cast<double>(rhs);
 | |
|         }
 | |
|     
 | |
|         bool operator !() const
 | |
|         {
 | |
|             return v == 0; 
 | |
|         }
 | |
|     
 | |
|         Double operator -() const
 | |
|         {
 | |
|             return Double(-v);
 | |
|         }
 | |
|     
 | |
|         Double& operator +=( const Double& t )
 | |
|         {
 | |
|             v += t.v;
 | |
|             return *this;
 | |
|         }
 | |
|     
 | |
|         template <typename T>
 | |
|         Double& operator +=( T t )
 | |
|         {
 | |
|             v += static_cast<double>(t);
 | |
|             return *this;
 | |
|         }
 | |
|     
 | |
|         Double& operator -=( const Double& t )
 | |
|         {
 | |
|             v -= t.v;
 | |
|             return *this;
 | |
|         }
 | |
|     
 | |
|         template <typename T>
 | |
|         Double& operator -=( T t )
 | |
|         {
 | |
|             v -= static_cast<double>(t);
 | |
|             return *this;
 | |
|         }
 | |
|     
 | |
|         Double& operator *= ( const Double& factor )
 | |
|         {
 | |
|             v *= factor.v;
 | |
|             return *this;
 | |
|         }
 | |
|     
 | |
|         template <typename T>
 | |
|         Double& operator *=( T t )
 | |
|         {
 | |
|             v *= static_cast<double>(t);
 | |
|             return *this;
 | |
|         }
 | |
| 
 | |
|         Double& operator /= (const Double& divisor)
 | |
|         {
 | |
|             v /= divisor.v;
 | |
|             return *this;
 | |
|         }
 | |
|     
 | |
|         template <typename T>
 | |
|         Double& operator /=( T t )
 | |
|         {
 | |
|              v /= static_cast<double>(t);
 | |
|             return (*this);       
 | |
|         }
 | |
|     
 | |
|         double v;
 | |
|     };
 | |
| 
 | |
|     //! Define numeric_limits for the custom type.
 | |
|     namespace std
 | |
|     {
 | |
|         template<>
 | |
|         class numeric_limits<Double> : public numeric_limits<double>
 | |
|         {
 | |
|         public:
 | |
| 
 | |
|             //! Limit our Double to a range of +/- 100.0
 | |
|             static Double (min)()
 | |
|             {            
 | |
|                 return Double(1.e-2);
 | |
|             }
 | |
| 
 | |
|             static Double (max)()
 | |
|             {
 | |
|                 return Double(1.e2);
 | |
|             }
 | |
| 
 | |
|             static Double epsilon()
 | |
|             {
 | |
|                 return Double( std::numeric_limits<double>::epsilon() );
 | |
|             }
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     //! Define range checking and overflow policies.
 | |
|     namespace custom
 | |
|     {
 | |
|         //! Define a custom range checker
 | |
|         template<typename Traits, typename OverFlowHandler>
 | |
|         struct range_checker
 | |
|         {
 | |
|             typedef typename Traits::argument_type argument_type ;
 | |
|             typedef typename Traits::source_type S;
 | |
|             typedef typename Traits::target_type T;
 | |
|         
 | |
|             //! Check range of integral types.
 | |
|             static boost::numeric::range_check_result out_of_range( argument_type s )
 | |
|             {
 | |
|                 using namespace boost::numeric;
 | |
|                 if( s > bounds<T>::highest() )
 | |
|                     return cPosOverflow;
 | |
|                 else if( s < bounds<T>::lowest() )
 | |
|                     return cNegOverflow;
 | |
|                 else
 | |
|                     return cInRange;
 | |
|             }
 | |
| 
 | |
|             static void validate_range ( argument_type s )
 | |
|             {
 | |
|                 BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_bounded );
 | |
|                 OverFlowHandler()( out_of_range(s) );
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         //! Overflow handler
 | |
|         struct positive_overflow{};
 | |
|         struct negative_overflow{};
 | |
| 
 | |
|         struct overflow_handler
 | |
|         {
 | |
|             void operator() ( boost::numeric::range_check_result r )
 | |
|             {
 | |
|                 using namespace boost::numeric;
 | |
|                 if( r == cNegOverflow )
 | |
|                     throw negative_overflow() ;
 | |
|                 else if( r == cPosOverflow )
 | |
|                     throw positive_overflow() ;
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         //! Define a rounding policy and specialize on the custom type.
 | |
|         template<class S>
 | |
|         struct Ceil : boost::numeric::Ceil<S>{};
 | |
| 
 | |
|         template<>
 | |
|         struct Ceil<Double>
 | |
|         {
 | |
|           typedef Double source_type;
 | |
| 
 | |
|           typedef Double const& argument_type;
 | |
| 
 | |
|           static source_type nearbyint ( argument_type s )
 | |
|           {
 | |
|     #if !defined(BOOST_NO_STDC_NAMESPACE)
 | |
|               using std::ceil ;
 | |
|     #endif
 | |
|               return Double( ceil(s.v) );
 | |
|           }
 | |
| 
 | |
|           typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_infinity> round_style;
 | |
|         };
 | |
| 
 | |
|         //! Define a rounding policy and specialize on the custom type.
 | |
|         template<class S>
 | |
|         struct Trunc: boost::numeric::Trunc<S>{};
 | |
| 
 | |
|         template<>
 | |
|         struct Trunc<Double>
 | |
|         {
 | |
|           typedef Double source_type;
 | |
| 
 | |
|           typedef Double const& argument_type;
 | |
| 
 | |
|           static source_type nearbyint ( argument_type s )
 | |
|           {
 | |
|     #if !defined(BOOST_NO_STDC_NAMESPACE)
 | |
|               using std::floor;
 | |
|     #endif
 | |
|               return Double( floor(s.v) );
 | |
|           }
 | |
| 
 | |
|           typedef boost::mpl::integral_c< std::float_round_style, std::round_toward_zero> round_style;
 | |
|         };
 | |
|     }//namespace custom;
 | |
| 
 | |
|     namespace boost { namespace numeric {
 | |
| 
 | |
|         //! Define the numeric_cast_traits specializations on the custom type.
 | |
|         template <typename S>
 | |
|         struct numeric_cast_traits<Double, S>
 | |
|         {
 | |
|             typedef custom::overflow_handler                         overflow_policy;
 | |
|             typedef custom::range_checker
 | |
|                     <
 | |
|                         boost::numeric::conversion_traits<Double, S>
 | |
|                       , overflow_policy
 | |
|                     >                                                range_checking_policy;
 | |
|             typedef boost::numeric::Trunc<S>                         rounding_policy;
 | |
|         };
 | |
|     
 | |
|         template <typename T>
 | |
|         struct numeric_cast_traits<T, Double>
 | |
|         {
 | |
|             typedef custom::overflow_handler                         overflow_policy;
 | |
|             typedef custom::range_checker
 | |
|                     <
 | |
|                         boost::numeric::conversion_traits<T, Double>
 | |
|                       , overflow_policy
 | |
|                     >                                                range_checking_policy;
 | |
|             typedef custom::Trunc<Double>                            rounding_policy;
 | |
|         };
 | |
| 
 | |
|         //! Define the conversion from the custom type to built-in types and vice-versa.
 | |
|         template<typename T>
 | |
|         struct raw_converter< conversion_traits< T, Double > >
 | |
|         {
 | |
|             static T low_level_convert ( const Double& n )
 | |
|             {
 | |
|                 return static_cast<T>( n.v ); 
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         template<typename S>
 | |
|         struct raw_converter< conversion_traits< Double, S > >
 | |
|         {
 | |
|             static Double low_level_convert ( const S& n )
 | |
|             {
 | |
|                 return Double(n); 
 | |
|             }
 | |
|         };
 | |
|     }}//namespace boost::numeric;
 | |
| 	
 | |
| [endsect]
 | |
| 
 | |
| [endsect]
 | |
| 
 |