mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05: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]
							 | 
						||
| 
								 | 
							
								
							 |