mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-22 00:01:09 -06:00
Initial work for G-code sender and more intensive usage of Boost
This commit is contained in:
parent
43cbad8867
commit
11dd67ab34
1649 changed files with 1860 additions and 1642 deletions
530
xs/include/boost/math/common_factor_rt.hpp
Normal file
530
xs/include/boost/math/common_factor_rt.hpp
Normal file
|
@ -0,0 +1,530 @@
|
|||
// Boost common_factor_rt.hpp header file ----------------------------------//
|
||||
|
||||
// (C) Copyright Daryle Walker and Paul Moore 2001-2002. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
// without express or implied warranty, and with no claim as to its suitability
|
||||
// for any purpose.
|
||||
|
||||
// boostinspect:nolicense (don't complain about the lack of a Boost license)
|
||||
// (Paul Moore hasn't been in contact for years, so there's no way to change the
|
||||
// license.)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
|
||||
#define BOOST_MATH_COMMON_FACTOR_RT_HPP
|
||||
|
||||
#include <boost/math_fwd.hpp> // self include
|
||||
|
||||
#include <boost/config.hpp> // for BOOST_NESTED_TEMPLATE, etc.
|
||||
#include <boost/limits.hpp> // for std::numeric_limits
|
||||
#include <climits> // for CHAR_MIN
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127 4244) // Conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
|
||||
// Forward declarations for function templates -----------------------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
IntegerType gcd( IntegerType const &a, IntegerType const &b );
|
||||
|
||||
template < typename IntegerType >
|
||||
IntegerType lcm( IntegerType const &a, IntegerType const &b );
|
||||
|
||||
|
||||
// Greatest common divisor evaluator class declaration ---------------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
class gcd_evaluator
|
||||
{
|
||||
public:
|
||||
// Types
|
||||
typedef IntegerType result_type, first_argument_type, second_argument_type;
|
||||
|
||||
// Function object interface
|
||||
result_type operator ()( first_argument_type const &a,
|
||||
second_argument_type const &b ) const;
|
||||
|
||||
}; // boost::math::gcd_evaluator
|
||||
|
||||
|
||||
// Least common multiple evaluator class declaration -----------------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
class lcm_evaluator
|
||||
{
|
||||
public:
|
||||
// Types
|
||||
typedef IntegerType result_type, first_argument_type, second_argument_type;
|
||||
|
||||
// Function object interface
|
||||
result_type operator ()( first_argument_type const &a,
|
||||
second_argument_type const &b ) const;
|
||||
|
||||
}; // boost::math::lcm_evaluator
|
||||
|
||||
|
||||
// Implementation details --------------------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Greatest common divisor for rings (including unsigned integers)
|
||||
template < typename RingType >
|
||||
RingType
|
||||
gcd_euclidean
|
||||
(
|
||||
RingType a,
|
||||
RingType b
|
||||
)
|
||||
{
|
||||
// Avoid repeated construction
|
||||
#ifndef __BORLANDC__
|
||||
RingType const zero = static_cast<RingType>( 0 );
|
||||
#else
|
||||
RingType zero = static_cast<RingType>( 0 );
|
||||
#endif
|
||||
|
||||
// Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)]
|
||||
while ( true )
|
||||
{
|
||||
if ( a == zero )
|
||||
return b;
|
||||
b %= a;
|
||||
|
||||
if ( b == zero )
|
||||
return a;
|
||||
a %= b;
|
||||
}
|
||||
}
|
||||
|
||||
// Greatest common divisor for (signed) integers
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
IntegerType
|
||||
gcd_integer
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
)
|
||||
{
|
||||
// Avoid repeated construction
|
||||
IntegerType const zero = static_cast<IntegerType>( 0 );
|
||||
IntegerType const result = gcd_euclidean( a, b );
|
||||
|
||||
return ( result < zero ) ? static_cast<IntegerType>(-result) : result;
|
||||
}
|
||||
|
||||
// Greatest common divisor for unsigned binary integers
|
||||
template < typename BuiltInUnsigned >
|
||||
BuiltInUnsigned
|
||||
gcd_binary
|
||||
(
|
||||
BuiltInUnsigned u,
|
||||
BuiltInUnsigned v
|
||||
)
|
||||
{
|
||||
if ( u && v )
|
||||
{
|
||||
// Shift out common factors of 2
|
||||
unsigned shifts = 0;
|
||||
|
||||
while ( !(u & 1u) && !(v & 1u) )
|
||||
{
|
||||
++shifts;
|
||||
u >>= 1;
|
||||
v >>= 1;
|
||||
}
|
||||
|
||||
// Start with the still-even one, if any
|
||||
BuiltInUnsigned r[] = { u, v };
|
||||
unsigned which = static_cast<bool>( u & 1u );
|
||||
|
||||
// Whittle down the values via their differences
|
||||
do
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
while ( !(r[ which ] & 1u) )
|
||||
{
|
||||
r[ which ] = (r[which] >> 1);
|
||||
}
|
||||
#else
|
||||
// Remove factors of two from the even one
|
||||
while ( !(r[ which ] & 1u) )
|
||||
{
|
||||
r[ which ] >>= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Replace the larger of the two with their difference
|
||||
if ( r[!which] > r[which] )
|
||||
{
|
||||
which ^= 1u;
|
||||
}
|
||||
|
||||
r[ which ] -= r[ !which ];
|
||||
}
|
||||
while ( r[which] );
|
||||
|
||||
// Shift-in the common factor of 2 to the residues' GCD
|
||||
return r[ !which ] << shifts;
|
||||
}
|
||||
else
|
||||
{
|
||||
// At least one input is zero, return the other
|
||||
// (adding since zero is the additive identity)
|
||||
// or zero if both are zero.
|
||||
return u + v;
|
||||
}
|
||||
}
|
||||
|
||||
// Least common multiple for rings (including unsigned integers)
|
||||
template < typename RingType >
|
||||
inline
|
||||
RingType
|
||||
lcm_euclidean
|
||||
(
|
||||
RingType const & a,
|
||||
RingType const & b
|
||||
)
|
||||
{
|
||||
RingType const zero = static_cast<RingType>( 0 );
|
||||
RingType const temp = gcd_euclidean( a, b );
|
||||
|
||||
return ( temp != zero ) ? ( a / temp * b ) : zero;
|
||||
}
|
||||
|
||||
// Least common multiple for (signed) integers
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
IntegerType
|
||||
lcm_integer
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
)
|
||||
{
|
||||
// Avoid repeated construction
|
||||
IntegerType const zero = static_cast<IntegerType>( 0 );
|
||||
IntegerType const result = lcm_euclidean( a, b );
|
||||
|
||||
return ( result < zero ) ? static_cast<IntegerType>(-result) : result;
|
||||
}
|
||||
|
||||
// Function objects to find the best way of computing GCD or LCM
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template < typename T, bool IsSpecialized, bool IsSigned >
|
||||
struct gcd_optimal_evaluator_helper_t
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return gcd_euclidean( a, b );
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct gcd_optimal_evaluator_helper_t< T, true, true >
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return gcd_integer( a, b );
|
||||
}
|
||||
};
|
||||
#else
|
||||
template < bool IsSpecialized, bool IsSigned >
|
||||
struct gcd_optimal_evaluator_helper2_t
|
||||
{
|
||||
template < typename T >
|
||||
struct helper
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return gcd_euclidean( a, b );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template < >
|
||||
struct gcd_optimal_evaluator_helper2_t< true, true >
|
||||
{
|
||||
template < typename T >
|
||||
struct helper
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return gcd_integer( a, b );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template < typename T, bool IsSpecialized, bool IsSigned >
|
||||
struct gcd_optimal_evaluator_helper_t
|
||||
: gcd_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
|
||||
::BOOST_NESTED_TEMPLATE helper<T>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
template < typename T >
|
||||
struct gcd_optimal_evaluator
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
typedef ::std::numeric_limits<T> limits_type;
|
||||
|
||||
typedef gcd_optimal_evaluator_helper_t<T,
|
||||
limits_type::is_specialized, limits_type::is_signed> helper_type;
|
||||
|
||||
helper_type solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
};
|
||||
#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
template < typename T >
|
||||
struct gcd_optimal_evaluator
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return gcd_integer( a, b );
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Specialize for the built-in integers
|
||||
#define BOOST_PRIVATE_GCD_UF( Ut ) \
|
||||
template < > struct gcd_optimal_evaluator<Ut> \
|
||||
{ Ut operator ()( Ut a, Ut b ) const { return gcd_binary( a, b ); } }
|
||||
|
||||
BOOST_PRIVATE_GCD_UF( unsigned char );
|
||||
BOOST_PRIVATE_GCD_UF( unsigned short );
|
||||
BOOST_PRIVATE_GCD_UF( unsigned );
|
||||
BOOST_PRIVATE_GCD_UF( unsigned long );
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_PRIVATE_GCD_UF( boost::ulong_long_type );
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
BOOST_PRIVATE_GCD_UF( unsigned __int64 );
|
||||
#endif
|
||||
|
||||
#if CHAR_MIN == 0
|
||||
BOOST_PRIVATE_GCD_UF( char ); // char is unsigned
|
||||
#endif
|
||||
|
||||
#undef BOOST_PRIVATE_GCD_UF
|
||||
|
||||
#define BOOST_PRIVATE_GCD_SF( St, Ut ) \
|
||||
template < > struct gcd_optimal_evaluator<St> \
|
||||
{ St operator ()( St a, St b ) const { Ut const a_abs = \
|
||||
static_cast<Ut>( a < 0 ? -a : +a ), b_abs = static_cast<Ut>( \
|
||||
b < 0 ? -b : +b ); return static_cast<St>( \
|
||||
gcd_optimal_evaluator<Ut>()(a_abs, b_abs) ); } }
|
||||
|
||||
BOOST_PRIVATE_GCD_SF( signed char, unsigned char );
|
||||
BOOST_PRIVATE_GCD_SF( short, unsigned short );
|
||||
BOOST_PRIVATE_GCD_SF( int, unsigned );
|
||||
BOOST_PRIVATE_GCD_SF( long, unsigned long );
|
||||
|
||||
#if CHAR_MIN < 0
|
||||
BOOST_PRIVATE_GCD_SF( char, unsigned char ); // char is signed
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_PRIVATE_GCD_SF( boost::long_long_type, boost::ulong_long_type );
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 );
|
||||
#endif
|
||||
|
||||
#undef BOOST_PRIVATE_GCD_SF
|
||||
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template < typename T, bool IsSpecialized, bool IsSigned >
|
||||
struct lcm_optimal_evaluator_helper_t
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return lcm_euclidean( a, b );
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct lcm_optimal_evaluator_helper_t< T, true, true >
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return lcm_integer( a, b );
|
||||
}
|
||||
};
|
||||
#else
|
||||
template < bool IsSpecialized, bool IsSigned >
|
||||
struct lcm_optimal_evaluator_helper2_t
|
||||
{
|
||||
template < typename T >
|
||||
struct helper
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return lcm_euclidean( a, b );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template < >
|
||||
struct lcm_optimal_evaluator_helper2_t< true, true >
|
||||
{
|
||||
template < typename T >
|
||||
struct helper
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return lcm_integer( a, b );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template < typename T, bool IsSpecialized, bool IsSigned >
|
||||
struct lcm_optimal_evaluator_helper_t
|
||||
: lcm_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
|
||||
::BOOST_NESTED_TEMPLATE helper<T>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
template < typename T >
|
||||
struct lcm_optimal_evaluator
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
typedef ::std::numeric_limits<T> limits_type;
|
||||
|
||||
typedef lcm_optimal_evaluator_helper_t<T,
|
||||
limits_type::is_specialized, limits_type::is_signed> helper_type;
|
||||
|
||||
helper_type solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
};
|
||||
#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
template < typename T >
|
||||
struct lcm_optimal_evaluator
|
||||
{
|
||||
T operator ()( T const &a, T const &b )
|
||||
{
|
||||
return lcm_integer( a, b );
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Functions to find the GCD or LCM in the best way
|
||||
template < typename T >
|
||||
inline
|
||||
T
|
||||
gcd_optimal
|
||||
(
|
||||
T const & a,
|
||||
T const & b
|
||||
)
|
||||
{
|
||||
gcd_optimal_evaluator<T> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
inline
|
||||
T
|
||||
lcm_optimal
|
||||
(
|
||||
T const & a,
|
||||
T const & b
|
||||
)
|
||||
{
|
||||
lcm_optimal_evaluator<T> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Greatest common divisor evaluator member function definition ------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
typename gcd_evaluator<IntegerType>::result_type
|
||||
gcd_evaluator<IntegerType>::operator ()
|
||||
(
|
||||
first_argument_type const & a,
|
||||
second_argument_type const & b
|
||||
) const
|
||||
{
|
||||
return detail::gcd_optimal( a, b );
|
||||
}
|
||||
|
||||
|
||||
// Least common multiple evaluator member function definition --------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
typename lcm_evaluator<IntegerType>::result_type
|
||||
lcm_evaluator<IntegerType>::operator ()
|
||||
(
|
||||
first_argument_type const & a,
|
||||
second_argument_type const & b
|
||||
) const
|
||||
{
|
||||
return detail::lcm_optimal( a, b );
|
||||
}
|
||||
|
||||
|
||||
// Greatest common divisor and least common multiple function definitions --//
|
||||
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
IntegerType
|
||||
gcd
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
)
|
||||
{
|
||||
gcd_evaluator<IntegerType> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
IntegerType
|
||||
lcm
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
)
|
||||
{
|
||||
lcm_evaluator<IntegerType> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_COMMON_FACTOR_RT_HPP
|
992
xs/include/boost/math/policies/policy.hpp
Normal file
992
xs/include/boost/math/policies/policy.hpp
Normal file
|
@ -0,0 +1,992 @@
|
|||
// Copyright John Maddock 2007.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_POLICY_HPP
|
||||
#define BOOST_MATH_POLICY_HPP
|
||||
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/find_if.hpp>
|
||||
#include <boost/mpl/remove_if.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/comparison.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <limits>
|
||||
// Sadly we do need the .h versions of these to be sure of getting
|
||||
// FLT_MANT_DIG etc.
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace tools{
|
||||
|
||||
template <class T>
|
||||
int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T));
|
||||
template <class T>
|
||||
T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T));
|
||||
|
||||
}
|
||||
|
||||
namespace policies{
|
||||
|
||||
//
|
||||
// Define macros for our default policies, if they're not defined already:
|
||||
//
|
||||
#ifndef BOOST_MATH_DOMAIN_ERROR_POLICY
|
||||
#define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_POLE_ERROR_POLICY
|
||||
#define BOOST_MATH_POLE_ERROR_POLICY throw_on_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY
|
||||
#define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_EVALUATION_ERROR_POLICY
|
||||
#define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_ROUNDING_ERROR_POLICY
|
||||
#define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY
|
||||
#define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_DENORM_ERROR_POLICY
|
||||
#define BOOST_MATH_DENORM_ERROR_POLICY ignore_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY
|
||||
#define BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY ignore_error
|
||||
#endif
|
||||
#ifndef BOOST_MATH_DIGITS10_POLICY
|
||||
#define BOOST_MATH_DIGITS10_POLICY 0
|
||||
#endif
|
||||
#ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY
|
||||
#define BOOST_MATH_PROMOTE_FLOAT_POLICY true
|
||||
#endif
|
||||
#ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
#define BOOST_MATH_PROMOTE_DOUBLE_POLICY false
|
||||
#else
|
||||
#define BOOST_MATH_PROMOTE_DOUBLE_POLICY true
|
||||
#endif
|
||||
#endif
|
||||
#ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY
|
||||
#define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards
|
||||
#endif
|
||||
#ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY
|
||||
#define BOOST_MATH_ASSERT_UNDEFINED_POLICY true
|
||||
#endif
|
||||
#ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY
|
||||
#define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000
|
||||
#endif
|
||||
#ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY
|
||||
#define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200
|
||||
#endif
|
||||
|
||||
#if !defined(__BORLANDC__) \
|
||||
&& !(defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ <= 2))
|
||||
#define BOOST_MATH_META_INT(type, name, Default)\
|
||||
template <type N = Default> struct name : public boost::mpl::int_<N>{};\
|
||||
namespace detail{\
|
||||
template <type N>\
|
||||
char test_is_valid_arg(const name<N>*);\
|
||||
char test_is_default_arg(const name<Default>*);\
|
||||
template <class T> struct is_##name##_imp\
|
||||
{\
|
||||
template <type N> static char test(const name<N>*);\
|
||||
static double test(...);\
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast<T*>(0))) == 1);\
|
||||
};\
|
||||
}\
|
||||
template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>{};
|
||||
|
||||
#define BOOST_MATH_META_BOOL(name, Default)\
|
||||
template <bool N = Default> struct name : public boost::mpl::bool_<N>{};\
|
||||
namespace detail{\
|
||||
template <bool N>\
|
||||
char test_is_valid_arg(const name<N>*);\
|
||||
char test_is_default_arg(const name<Default>*);\
|
||||
template <class T> struct is_##name##_imp\
|
||||
{\
|
||||
template <bool N> static char test(const name<N>*);\
|
||||
static double test(...);\
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast<T*>(0))) == 1);\
|
||||
};\
|
||||
}\
|
||||
template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>{};
|
||||
#else
|
||||
#define BOOST_MATH_META_INT(Type, name, Default)\
|
||||
template <Type N = Default> struct name : public boost::mpl::int_<N>{};\
|
||||
namespace detail{\
|
||||
template <Type N>\
|
||||
char test_is_valid_arg(const name<N>*);\
|
||||
char test_is_default_arg(const name<Default>*);\
|
||||
template <class T> struct is_##name##_tester\
|
||||
{\
|
||||
template <Type N> static char test(const name<N>&);\
|
||||
static double test(...);\
|
||||
};\
|
||||
template <class T> struct is_##name##_imp\
|
||||
{\
|
||||
static T inst;\
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof( ::boost::math::policies::detail::is_##name##_tester<T>::test(inst)) == 1);\
|
||||
};\
|
||||
}\
|
||||
template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>\
|
||||
{\
|
||||
template <class U> struct apply{ typedef is_##name<U> type; };\
|
||||
};
|
||||
|
||||
#define BOOST_MATH_META_BOOL(name, Default)\
|
||||
template <bool N = Default> struct name : public boost::mpl::bool_<N>{};\
|
||||
namespace detail{\
|
||||
template <bool N>\
|
||||
char test_is_valid_arg(const name<N>*);\
|
||||
char test_is_default_arg(const name<Default>*);\
|
||||
template <class T> struct is_##name##_tester\
|
||||
{\
|
||||
template <bool N> static char test(const name<N>&);\
|
||||
static double test(...);\
|
||||
};\
|
||||
template <class T> struct is_##name##_imp\
|
||||
{\
|
||||
static T inst;\
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof( ::boost::math::policies::detail::is_##name##_tester<T>::test(inst)) == 1);\
|
||||
};\
|
||||
}\
|
||||
template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>\
|
||||
{\
|
||||
template <class U> struct apply{ typedef is_##name<U> type; };\
|
||||
};
|
||||
#endif
|
||||
//
|
||||
// Begin by defining policy types for error handling:
|
||||
//
|
||||
enum error_policy_type
|
||||
{
|
||||
throw_on_error = 0,
|
||||
errno_on_error = 1,
|
||||
ignore_error = 2,
|
||||
user_error = 3
|
||||
};
|
||||
|
||||
BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY)
|
||||
BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY)
|
||||
|
||||
//
|
||||
// Policy types for internal promotion:
|
||||
//
|
||||
BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY)
|
||||
BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY)
|
||||
BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY)
|
||||
//
|
||||
// Policy types for discrete quantiles:
|
||||
//
|
||||
enum discrete_quantile_policy_type
|
||||
{
|
||||
real,
|
||||
integer_round_outwards,
|
||||
integer_round_inwards,
|
||||
integer_round_down,
|
||||
integer_round_up,
|
||||
integer_round_nearest
|
||||
};
|
||||
|
||||
BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY)
|
||||
//
|
||||
// Precision:
|
||||
//
|
||||
BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY)
|
||||
BOOST_MATH_META_INT(int, digits2, 0)
|
||||
//
|
||||
// Iterations:
|
||||
//
|
||||
BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY)
|
||||
BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY)
|
||||
//
|
||||
// Define the names for each possible policy:
|
||||
//
|
||||
#define BOOST_MATH_PARAMETER(name)\
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\
|
||||
BOOST_PARAMETER_NAME(name##_name)
|
||||
|
||||
struct default_policy{};
|
||||
|
||||
namespace detail{
|
||||
//
|
||||
// Trait to work out bits precision from digits10 and digits2:
|
||||
//
|
||||
template <class Digits10, class Digits2>
|
||||
struct precision
|
||||
{
|
||||
//
|
||||
// Now work out the precision:
|
||||
//
|
||||
typedef typename mpl::if_c<
|
||||
(Digits10::value == 0),
|
||||
digits2<0>,
|
||||
digits2<((Digits10::value + 1) * 1000L) / 301L>
|
||||
>::type digits2_type;
|
||||
public:
|
||||
#ifdef __BORLANDC__
|
||||
typedef typename mpl::if_c<
|
||||
(Digits2::value > ::boost::math::policies::detail::precision<Digits10,Digits2>::digits2_type::value),
|
||||
Digits2, digits2_type>::type type;
|
||||
#else
|
||||
typedef typename mpl::if_c<
|
||||
(Digits2::value > digits2_type::value),
|
||||
Digits2, digits2_type>::type type;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class A, class B, bool b>
|
||||
struct select_result
|
||||
{
|
||||
typedef A type;
|
||||
};
|
||||
template <class A, class B>
|
||||
struct select_result<A, B, false>
|
||||
{
|
||||
typedef typename mpl::deref<B>::type type;
|
||||
};
|
||||
|
||||
template <class Seq, class Pred, class DefaultType>
|
||||
struct find_arg
|
||||
{
|
||||
private:
|
||||
typedef typename mpl::find_if<Seq, Pred>::type iter;
|
||||
typedef typename mpl::end<Seq>::type end_type;
|
||||
public:
|
||||
typedef typename select_result<
|
||||
DefaultType, iter,
|
||||
::boost::is_same<iter, end_type>::value>::type type;
|
||||
};
|
||||
|
||||
double test_is_valid_arg(...);
|
||||
double test_is_default_arg(...);
|
||||
char test_is_valid_arg(const default_policy*);
|
||||
char test_is_default_arg(const default_policy*);
|
||||
|
||||
template <class T>
|
||||
struct is_valid_policy_imp
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_valid_arg(static_cast<T*>(0))) == 1);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_default_policy_imp
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_default_arg(static_cast<T*>(0))) == 1);
|
||||
};
|
||||
|
||||
template <class T> struct is_valid_policy
|
||||
: public mpl::bool_<
|
||||
::boost::math::policies::detail::is_valid_policy_imp<T>::value>
|
||||
{};
|
||||
|
||||
template <class T> struct is_default_policy
|
||||
: public mpl::bool_<
|
||||
::boost::math::policies::detail::is_default_policy_imp<T>::value>
|
||||
{
|
||||
template <class U>
|
||||
struct apply
|
||||
{
|
||||
typedef is_default_policy<U> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Seq, class T, int N>
|
||||
struct append_N
|
||||
{
|
||||
typedef typename mpl::push_back<Seq, T>::type new_seq;
|
||||
typedef typename append_N<new_seq, T, N-1>::type type;
|
||||
};
|
||||
|
||||
template <class Seq, class T>
|
||||
struct append_N<Seq, T, 0>
|
||||
{
|
||||
typedef Seq type;
|
||||
};
|
||||
|
||||
//
|
||||
// Traits class to work out what template parameters our default
|
||||
// policy<> class will have when modified for forwarding:
|
||||
//
|
||||
template <bool f, bool d>
|
||||
struct default_args
|
||||
{
|
||||
typedef promote_float<false> arg1;
|
||||
typedef promote_double<false> arg2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_args<false, false>
|
||||
{
|
||||
typedef default_policy arg1;
|
||||
typedef default_policy arg2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_args<true, false>
|
||||
{
|
||||
typedef promote_float<false> arg1;
|
||||
typedef default_policy arg2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct default_args<false, true>
|
||||
{
|
||||
typedef promote_double<false> arg1;
|
||||
typedef default_policy arg2;
|
||||
};
|
||||
|
||||
typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg1 forwarding_arg1;
|
||||
typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg2 forwarding_arg2;
|
||||
|
||||
} // detail
|
||||
//
|
||||
// Now define the policy type with enough arguments to handle all
|
||||
// the policies:
|
||||
//
|
||||
template <class A1 = default_policy,
|
||||
class A2 = default_policy,
|
||||
class A3 = default_policy,
|
||||
class A4 = default_policy,
|
||||
class A5 = default_policy,
|
||||
class A6 = default_policy,
|
||||
class A7 = default_policy,
|
||||
class A8 = default_policy,
|
||||
class A9 = default_policy,
|
||||
class A10 = default_policy,
|
||||
class A11 = default_policy,
|
||||
class A12 = default_policy,
|
||||
class A13 = default_policy>
|
||||
struct policy
|
||||
{
|
||||
private:
|
||||
//
|
||||
// Validate all our arguments:
|
||||
//
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A1>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A2>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A3>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A4>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A5>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A6>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A7>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A8>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A9>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A10>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A11>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A12>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A13>::value);
|
||||
//
|
||||
// Typelist of the arguments:
|
||||
//
|
||||
typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13> arg_list;
|
||||
|
||||
public:
|
||||
typedef typename detail::find_arg<arg_list, is_domain_error<mpl::_1>, domain_error<> >::type domain_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_pole_error<mpl::_1>, pole_error<> >::type pole_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_overflow_error<mpl::_1>, overflow_error<> >::type overflow_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, underflow_error<> >::type underflow_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, denorm_error<> >::type denorm_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, evaluation_error<> >::type evaluation_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, rounding_error<> >::type rounding_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_indeterminate_result_error<mpl::_1>, indeterminate_result_error<> >::type indeterminate_result_error_type;
|
||||
private:
|
||||
//
|
||||
// Now work out the precision:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_digits10<mpl::_1>, digits10<> >::type digits10_type;
|
||||
typedef typename detail::find_arg<arg_list, is_digits2<mpl::_1>, digits2<> >::type bits_precision_type;
|
||||
public:
|
||||
typedef typename detail::precision<digits10_type, bits_precision_type>::type precision_type;
|
||||
//
|
||||
// Internal promotion:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_promote_float<mpl::_1>, promote_float<> >::type promote_float_type;
|
||||
typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, promote_double<> >::type promote_double_type;
|
||||
//
|
||||
// Discrete quantiles:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, discrete_quantile<> >::type discrete_quantile_type;
|
||||
//
|
||||
// Mathematically undefined properties:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_assert_undefined<mpl::_1>, assert_undefined<> >::type assert_undefined_type;
|
||||
//
|
||||
// Max iterations:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_max_series_iterations<mpl::_1>, max_series_iterations<> >::type max_series_iterations_type;
|
||||
typedef typename detail::find_arg<arg_list, is_max_root_iterations<mpl::_1>, max_root_iterations<> >::type max_root_iterations_type;
|
||||
};
|
||||
//
|
||||
// These full specializations are defined to reduce the amount of
|
||||
// template instantiations that have to take place when using the default
|
||||
// policies, they have quite a large impact on compile times:
|
||||
//
|
||||
template <>
|
||||
struct policy<default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
|
||||
{
|
||||
public:
|
||||
typedef domain_error<> domain_error_type;
|
||||
typedef pole_error<> pole_error_type;
|
||||
typedef overflow_error<> overflow_error_type;
|
||||
typedef underflow_error<> underflow_error_type;
|
||||
typedef denorm_error<> denorm_error_type;
|
||||
typedef evaluation_error<> evaluation_error_type;
|
||||
typedef rounding_error<> rounding_error_type;
|
||||
typedef indeterminate_result_error<> indeterminate_result_error_type;
|
||||
#if BOOST_MATH_DIGITS10_POLICY == 0
|
||||
typedef digits2<> precision_type;
|
||||
#else
|
||||
typedef detail::precision<digits10<>, digits2<> >::type precision_type;
|
||||
#endif
|
||||
typedef promote_float<> promote_float_type;
|
||||
typedef promote_double<> promote_double_type;
|
||||
typedef discrete_quantile<> discrete_quantile_type;
|
||||
typedef assert_undefined<> assert_undefined_type;
|
||||
typedef max_series_iterations<> max_series_iterations_type;
|
||||
typedef max_root_iterations<> max_root_iterations_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct policy<detail::forwarding_arg1, detail::forwarding_arg2, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
|
||||
{
|
||||
public:
|
||||
typedef domain_error<> domain_error_type;
|
||||
typedef pole_error<> pole_error_type;
|
||||
typedef overflow_error<> overflow_error_type;
|
||||
typedef underflow_error<> underflow_error_type;
|
||||
typedef denorm_error<> denorm_error_type;
|
||||
typedef evaluation_error<> evaluation_error_type;
|
||||
typedef rounding_error<> rounding_error_type;
|
||||
typedef indeterminate_result_error<> indeterminate_result_error_type;
|
||||
#if BOOST_MATH_DIGITS10_POLICY == 0
|
||||
typedef digits2<> precision_type;
|
||||
#else
|
||||
typedef detail::precision<digits10<>, digits2<> >::type precision_type;
|
||||
#endif
|
||||
typedef promote_float<false> promote_float_type;
|
||||
typedef promote_double<false> promote_double_type;
|
||||
typedef discrete_quantile<> discrete_quantile_type;
|
||||
typedef assert_undefined<> assert_undefined_type;
|
||||
typedef max_series_iterations<> max_series_iterations_type;
|
||||
typedef max_root_iterations<> max_root_iterations_type;
|
||||
};
|
||||
|
||||
template <class Policy,
|
||||
class A1 = default_policy,
|
||||
class A2 = default_policy,
|
||||
class A3 = default_policy,
|
||||
class A4 = default_policy,
|
||||
class A5 = default_policy,
|
||||
class A6 = default_policy,
|
||||
class A7 = default_policy,
|
||||
class A8 = default_policy,
|
||||
class A9 = default_policy,
|
||||
class A10 = default_policy,
|
||||
class A11 = default_policy,
|
||||
class A12 = default_policy,
|
||||
class A13 = default_policy>
|
||||
struct normalise
|
||||
{
|
||||
private:
|
||||
typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13> arg_list;
|
||||
typedef typename detail::find_arg<arg_list, is_domain_error<mpl::_1>, typename Policy::domain_error_type >::type domain_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_pole_error<mpl::_1>, typename Policy::pole_error_type >::type pole_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_overflow_error<mpl::_1>, typename Policy::overflow_error_type >::type overflow_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, typename Policy::underflow_error_type >::type underflow_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, typename Policy::denorm_error_type >::type denorm_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, typename Policy::evaluation_error_type >::type evaluation_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, typename Policy::rounding_error_type >::type rounding_error_type;
|
||||
typedef typename detail::find_arg<arg_list, is_indeterminate_result_error<mpl::_1>, typename Policy::indeterminate_result_error_type >::type indeterminate_result_error_type;
|
||||
//
|
||||
// Now work out the precision:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_digits10<mpl::_1>, digits10<> >::type digits10_type;
|
||||
typedef typename detail::find_arg<arg_list, is_digits2<mpl::_1>, typename Policy::precision_type >::type bits_precision_type;
|
||||
typedef typename detail::precision<digits10_type, bits_precision_type>::type precision_type;
|
||||
//
|
||||
// Internal promotion:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_promote_float<mpl::_1>, typename Policy::promote_float_type >::type promote_float_type;
|
||||
typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, typename Policy::promote_double_type >::type promote_double_type;
|
||||
//
|
||||
// Discrete quantiles:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, typename Policy::discrete_quantile_type >::type discrete_quantile_type;
|
||||
//
|
||||
// Mathematically undefined properties:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_assert_undefined<mpl::_1>, typename Policy::assert_undefined_type >::type assert_undefined_type;
|
||||
//
|
||||
// Max iterations:
|
||||
//
|
||||
typedef typename detail::find_arg<arg_list, is_max_series_iterations<mpl::_1>, typename Policy::max_series_iterations_type>::type max_series_iterations_type;
|
||||
typedef typename detail::find_arg<arg_list, is_max_root_iterations<mpl::_1>, typename Policy::max_root_iterations_type>::type max_root_iterations_type;
|
||||
//
|
||||
// Define a typelist of the policies:
|
||||
//
|
||||
typedef mpl::vector<
|
||||
domain_error_type,
|
||||
pole_error_type,
|
||||
overflow_error_type,
|
||||
underflow_error_type,
|
||||
denorm_error_type,
|
||||
evaluation_error_type,
|
||||
rounding_error_type,
|
||||
indeterminate_result_error_type,
|
||||
precision_type,
|
||||
promote_float_type,
|
||||
promote_double_type,
|
||||
discrete_quantile_type,
|
||||
assert_undefined_type,
|
||||
max_series_iterations_type,
|
||||
max_root_iterations_type> result_list;
|
||||
//
|
||||
// Remove all the policies that are the same as the default:
|
||||
//
|
||||
typedef typename mpl::remove_if<result_list, detail::is_default_policy<mpl::_> >::type reduced_list;
|
||||
//
|
||||
// Pad out the list with defaults:
|
||||
//
|
||||
typedef typename detail::append_N<reduced_list, default_policy, (14 - ::boost::mpl::size<reduced_list>::value)>::type result_type;
|
||||
public:
|
||||
typedef policy<
|
||||
typename mpl::at<result_type, mpl::int_<0> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<1> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<2> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<3> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<4> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<5> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<6> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<7> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<8> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<9> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<10> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<11> >::type,
|
||||
typename mpl::at<result_type, mpl::int_<12> >::type > type;
|
||||
};
|
||||
//
|
||||
// Full specialisation to speed up compilation of the common case:
|
||||
//
|
||||
template <>
|
||||
struct normalise<policy<>,
|
||||
promote_float<false>,
|
||||
promote_double<false>,
|
||||
discrete_quantile<>,
|
||||
assert_undefined<>,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy>
|
||||
{
|
||||
typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct normalise<policy<detail::forwarding_arg1, detail::forwarding_arg2>,
|
||||
promote_float<false>,
|
||||
promote_double<false>,
|
||||
discrete_quantile<>,
|
||||
assert_undefined<>,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy,
|
||||
default_policy>
|
||||
{
|
||||
typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;
|
||||
};
|
||||
|
||||
inline policy<> make_policy()
|
||||
{ return policy<>(); }
|
||||
|
||||
template <class A1>
|
||||
inline typename normalise<policy<>, A1>::type make_policy(const A1&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
inline typename normalise<policy<>, A1, A2>::type make_policy(const A1&, const A2&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
inline typename normalise<policy<>, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11>
|
||||
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&, const A11&)
|
||||
{
|
||||
typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type result_type;
|
||||
return result_type();
|
||||
}
|
||||
|
||||
//
|
||||
// Traits class to handle internal promotion:
|
||||
//
|
||||
template <class Real, class Policy>
|
||||
struct evaluation
|
||||
{
|
||||
typedef Real type;
|
||||
};
|
||||
|
||||
template <class Policy>
|
||||
struct evaluation<float, Policy>
|
||||
{
|
||||
typedef typename mpl::if_<typename Policy::promote_float_type, double, float>::type type;
|
||||
};
|
||||
|
||||
template <class Policy>
|
||||
struct evaluation<double, Policy>
|
||||
{
|
||||
typedef typename mpl::if_<typename Policy::promote_double_type, long double, double>::type type;
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
|
||||
template <class Real>
|
||||
struct basic_digits : public mpl::int_<0>{ };
|
||||
template <>
|
||||
struct basic_digits<float> : public mpl::int_<FLT_MANT_DIG>{ };
|
||||
template <>
|
||||
struct basic_digits<double> : public mpl::int_<DBL_MANT_DIG>{ };
|
||||
template <>
|
||||
struct basic_digits<long double> : public mpl::int_<LDBL_MANT_DIG>{ };
|
||||
|
||||
template <class Real, class Policy>
|
||||
struct precision
|
||||
{
|
||||
BOOST_STATIC_ASSERT( ::std::numeric_limits<Real>::radix == 2);
|
||||
typedef typename Policy::precision_type precision_type;
|
||||
typedef basic_digits<Real> digits_t;
|
||||
typedef typename mpl::if_<
|
||||
mpl::equal_to<digits_t, mpl::int_<0> >,
|
||||
// Possibly unknown precision:
|
||||
precision_type,
|
||||
typename mpl::if_<
|
||||
mpl::or_<mpl::less_equal<digits_t, precision_type>, mpl::less_equal<precision_type, mpl::int_<0> > >,
|
||||
// Default case, full precision for RealType:
|
||||
digits2< ::std::numeric_limits<Real>::digits>,
|
||||
// User customised precision:
|
||||
precision_type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Policy>
|
||||
struct precision<float, Policy>
|
||||
{
|
||||
typedef digits2<FLT_MANT_DIG> type;
|
||||
};
|
||||
template <class Policy>
|
||||
struct precision<double, Policy>
|
||||
{
|
||||
typedef digits2<DBL_MANT_DIG> type;
|
||||
};
|
||||
template <class Policy>
|
||||
struct precision<long double, Policy>
|
||||
{
|
||||
typedef digits2<LDBL_MANT_DIG> type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <class Real, class Policy>
|
||||
struct precision
|
||||
{
|
||||
BOOST_STATIC_ASSERT((::std::numeric_limits<Real>::radix == 2) || ((::std::numeric_limits<Real>::is_specialized == 0) || (::std::numeric_limits<Real>::digits == 0)));
|
||||
#ifndef __BORLANDC__
|
||||
typedef typename Policy::precision_type precision_type;
|
||||
typedef typename mpl::if_c<
|
||||
((::std::numeric_limits<Real>::is_specialized == 0) || (::std::numeric_limits<Real>::digits == 0)),
|
||||
// Possibly unknown precision:
|
||||
precision_type,
|
||||
typename mpl::if_c<
|
||||
((::std::numeric_limits<Real>::digits <= precision_type::value)
|
||||
|| (Policy::precision_type::value <= 0)),
|
||||
// Default case, full precision for RealType:
|
||||
digits2< ::std::numeric_limits<Real>::digits>,
|
||||
// User customised precision:
|
||||
precision_type
|
||||
>::type
|
||||
>::type type;
|
||||
#else
|
||||
typedef typename Policy::precision_type precision_type;
|
||||
typedef mpl::int_< ::std::numeric_limits<Real>::digits> digits_t;
|
||||
typedef mpl::bool_< ::std::numeric_limits<Real>::is_specialized> spec_t;
|
||||
typedef typename mpl::if_<
|
||||
mpl::or_<mpl::equal_to<spec_t, mpl::false_>, mpl::equal_to<digits_t, mpl::int_<0> > >,
|
||||
// Possibly unknown precision:
|
||||
precision_type,
|
||||
typename mpl::if_<
|
||||
mpl::or_<mpl::less_equal<digits_t, precision_type>, mpl::less_equal<precision_type, mpl::int_<0> > >,
|
||||
// Default case, full precision for RealType:
|
||||
digits2< ::std::numeric_limits<Real>::digits>,
|
||||
// User customised precision:
|
||||
precision_type
|
||||
>::type
|
||||
>::type type;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
|
||||
template <class Policy>
|
||||
struct precision<__float128, Policy>
|
||||
{
|
||||
typedef mpl::int_<113> type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class T, class Policy>
|
||||
inline int digits_imp(mpl::true_ const&)
|
||||
{
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
|
||||
#else
|
||||
BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
|
||||
#endif
|
||||
typedef typename boost::math::policies::precision<T, Policy>::type p_t;
|
||||
return p_t::value;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline int digits_imp(mpl::false_ const&)
|
||||
{
|
||||
return tools::digits<T>();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T, class Policy>
|
||||
inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
|
||||
{
|
||||
typedef mpl::bool_< std::numeric_limits<T>::is_specialized > tag_type;
|
||||
return detail::digits_imp<T, Policy>(tag_type());
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline unsigned long get_max_series_iterations()
|
||||
{
|
||||
typedef typename Policy::max_series_iterations_type iter_type;
|
||||
return iter_type::value;
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline unsigned long get_max_root_iterations()
|
||||
{
|
||||
typedef typename Policy::max_root_iterations_type iter_type;
|
||||
return iter_type::value;
|
||||
}
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class T, class Digits, class Small, class Default>
|
||||
struct series_factor_calc
|
||||
{
|
||||
static T get()
|
||||
{
|
||||
return ldexp(T(1.0), 1 - Digits::value);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Digits>
|
||||
struct series_factor_calc<T, Digits, mpl::true_, mpl::true_>
|
||||
{
|
||||
static T get()
|
||||
{
|
||||
return boost::math::tools::epsilon<T>();
|
||||
}
|
||||
};
|
||||
template <class T, class Digits>
|
||||
struct series_factor_calc<T, Digits, mpl::true_, mpl::false_>
|
||||
{
|
||||
static T get()
|
||||
{
|
||||
static const boost::uintmax_t v = static_cast<boost::uintmax_t>(1u) << (Digits::value - 1);
|
||||
return 1 / static_cast<T>(v);
|
||||
}
|
||||
};
|
||||
template <class T, class Digits>
|
||||
struct series_factor_calc<T, Digits, mpl::false_, mpl::true_>
|
||||
{
|
||||
static T get()
|
||||
{
|
||||
return boost::math::tools::epsilon<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T get_epsilon_imp(mpl::true_ const&)
|
||||
{
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
|
||||
BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::radix == 2);
|
||||
#else
|
||||
BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
|
||||
BOOST_ASSERT(::std::numeric_limits<T>::radix == 2);
|
||||
#endif
|
||||
typedef typename boost::math::policies::precision<T, Policy>::type p_t;
|
||||
typedef mpl::bool_<p_t::value <= std::numeric_limits<boost::uintmax_t>::digits> is_small_int;
|
||||
typedef mpl::bool_<p_t::value >= std::numeric_limits<T>::digits> is_default_value;
|
||||
return series_factor_calc<T, p_t, is_small_int, is_default_value>::get();
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T get_epsilon_imp(mpl::false_ const&)
|
||||
{
|
||||
return tools::epsilon<T>();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
|
||||
{
|
||||
typedef mpl::bool_< (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2)) > tag_type;
|
||||
return detail::get_epsilon_imp<T, Policy>(tag_type());
|
||||
}
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class A1,
|
||||
class A2,
|
||||
class A3,
|
||||
class A4,
|
||||
class A5,
|
||||
class A6,
|
||||
class A7,
|
||||
class A8,
|
||||
class A9,
|
||||
class A10,
|
||||
class A11>
|
||||
char test_is_policy(const policy<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11>*);
|
||||
double test_is_policy(...);
|
||||
|
||||
template <class P>
|
||||
struct is_policy_imp
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast<P*>(0))) == 1));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class P>
|
||||
struct is_policy : public mpl::bool_< ::boost::math::policies::detail::is_policy_imp<P>::value> {};
|
||||
|
||||
//
|
||||
// Helper traits class for distribution error handling:
|
||||
//
|
||||
template <class Policy>
|
||||
struct constructor_error_check
|
||||
{
|
||||
typedef typename Policy::domain_error_type domain_error_type;
|
||||
typedef typename mpl::if_c<
|
||||
(domain_error_type::value == throw_on_error) || (domain_error_type::value == user_error),
|
||||
mpl::true_,
|
||||
mpl::false_>::type type;
|
||||
};
|
||||
|
||||
template <class Policy>
|
||||
struct method_error_check
|
||||
{
|
||||
typedef typename Policy::domain_error_type domain_error_type;
|
||||
typedef typename mpl::if_c<
|
||||
(domain_error_type::value == throw_on_error) && (domain_error_type::value != user_error),
|
||||
mpl::false_,
|
||||
mpl::true_>::type type;
|
||||
};
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_MATH_POLICY_HPP
|
||||
|
||||
|
||||
|
570
xs/include/boost/math/special_functions/detail/fp_traits.hpp
Normal file
570
xs/include/boost/math/special_functions/detail/fp_traits.hpp
Normal file
|
@ -0,0 +1,570 @@
|
|||
// fp_traits.hpp
|
||||
|
||||
#ifndef BOOST_MATH_FP_TRAITS_HPP
|
||||
#define BOOST_MATH_FP_TRAITS_HPP
|
||||
|
||||
// Copyright (c) 2006 Johan Rade
|
||||
|
||||
// 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)
|
||||
|
||||
/*
|
||||
To support old compilers, care has been taken to avoid partial template
|
||||
specialization and meta function forwarding.
|
||||
With these techniques, the code could be simplified.
|
||||
*/
|
||||
|
||||
#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
|
||||
// The VAX floating point formats are used (for float and double)
|
||||
# define BOOST_FPCLASSIFY_VAX_FORMAT
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std{ using ::memcpy; }
|
||||
#endif
|
||||
|
||||
#ifndef FP_NORMAL
|
||||
|
||||
#define FP_ZERO 0
|
||||
#define FP_NORMAL 1
|
||||
#define FP_INFINITE 2
|
||||
#define FP_NAN 3
|
||||
#define FP_SUBNORMAL 4
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_HAS_FPCLASSIFY
|
||||
|
||||
#ifndef fpclassify
|
||||
# if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \
|
||||
&& defined(_GLIBCXX_USE_C99_MATH) \
|
||||
&& !(defined(_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) \
|
||||
&& (_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC != 0))
|
||||
# ifdef _STLP_VENDOR_CSTD
|
||||
# if _STLPORT_VERSION >= 0x520
|
||||
# define BOOST_FPCLASSIFY_PREFIX ::__std_alias::
|
||||
# else
|
||||
# define BOOST_FPCLASSIFY_PREFIX ::_STLP_VENDOR_CSTD::
|
||||
# endif
|
||||
# else
|
||||
# define BOOST_FPCLASSIFY_PREFIX ::std::
|
||||
# endif
|
||||
# else
|
||||
# undef BOOST_HAS_FPCLASSIFY
|
||||
# define BOOST_FPCLASSIFY_PREFIX
|
||||
# endif
|
||||
#elif (defined(__HP_aCC) && !defined(__hppa))
|
||||
// aCC 6 appears to do "#define fpclassify fpclassify" which messes us up a bit!
|
||||
# define BOOST_FPCLASSIFY_PREFIX ::
|
||||
#else
|
||||
# define BOOST_FPCLASSIFY_PREFIX
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# undef BOOST_HAS_FPCLASSIFY
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace boost {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
The following classes are used to tag the different methods that are used
|
||||
for floating point classification
|
||||
*/
|
||||
|
||||
struct native_tag {};
|
||||
template <bool has_limits>
|
||||
struct generic_tag {};
|
||||
struct ieee_tag {};
|
||||
struct ieee_copy_all_bits_tag : public ieee_tag {};
|
||||
struct ieee_copy_leading_bits_tag : public ieee_tag {};
|
||||
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
//
|
||||
// These helper functions are used only when numeric_limits<>
|
||||
// members are not compile time constants:
|
||||
//
|
||||
inline bool is_generic_tag_false(const generic_tag<false>*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
inline bool is_generic_tag_false(const void*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Most processors support three different floating point precisions:
|
||||
single precision (32 bits), double precision (64 bits)
|
||||
and extended double precision (80 - 128 bits, depending on the processor)
|
||||
|
||||
Note that the C++ type long double can be implemented
|
||||
both as double precision and extended double precision.
|
||||
*/
|
||||
|
||||
struct unknown_precision{};
|
||||
struct single_precision {};
|
||||
struct double_precision {};
|
||||
struct extended_double_precision {};
|
||||
|
||||
// native_tag version --------------------------------------------------------------
|
||||
|
||||
template<class T> struct fp_traits_native
|
||||
{
|
||||
typedef native_tag method;
|
||||
};
|
||||
|
||||
// generic_tag version -------------------------------------------------------------
|
||||
|
||||
template<class T, class U> struct fp_traits_non_native
|
||||
{
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
typedef generic_tag<std::numeric_limits<T>::is_specialized> method;
|
||||
#else
|
||||
typedef generic_tag<false> method;
|
||||
#endif
|
||||
};
|
||||
|
||||
// ieee_tag versions ---------------------------------------------------------------
|
||||
|
||||
/*
|
||||
These specializations of fp_traits_non_native contain information needed
|
||||
to "parse" the binary representation of a floating point number.
|
||||
|
||||
Typedef members:
|
||||
|
||||
bits -- the target type when copying the leading bytes of a floating
|
||||
point number. It is a typedef for uint32_t or uint64_t.
|
||||
|
||||
method -- tells us whether all bytes are copied or not.
|
||||
It is a typedef for ieee_copy_all_bits_tag or ieee_copy_leading_bits_tag.
|
||||
|
||||
Static data members:
|
||||
|
||||
sign, exponent, flag, significand -- bit masks that give the meaning of the
|
||||
bits in the leading bytes.
|
||||
|
||||
Static function members:
|
||||
|
||||
get_bits(), set_bits() -- provide access to the leading bytes.
|
||||
|
||||
*/
|
||||
|
||||
// ieee_tag version, float (32 bits) -----------------------------------------------
|
||||
|
||||
#ifndef BOOST_FPCLASSIFY_VAX_FORMAT
|
||||
|
||||
template<> struct fp_traits_non_native<float, single_precision>
|
||||
{
|
||||
typedef ieee_copy_all_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x007fffff);
|
||||
|
||||
typedef uint32_t bits;
|
||||
static void get_bits(float x, uint32_t& a) { std::memcpy(&a, &x, 4); }
|
||||
static void set_bits(float& x, uint32_t a) { std::memcpy(&x, &a, 4); }
|
||||
};
|
||||
|
||||
// ieee_tag version, double (64 bits) ----------------------------------------------
|
||||
|
||||
#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) \
|
||||
|| defined(__BORLANDC__) || defined(__CODEGEAR__)
|
||||
|
||||
template<> struct fp_traits_non_native<double, double_precision>
|
||||
{
|
||||
typedef ieee_copy_leading_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);
|
||||
|
||||
typedef uint32_t bits;
|
||||
|
||||
static void get_bits(double x, uint32_t& a)
|
||||
{
|
||||
std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(double& x, uint32_t a)
|
||||
{
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 4);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
//..............................................................................
|
||||
|
||||
#else
|
||||
|
||||
template<> struct fp_traits_non_native<double, double_precision>
|
||||
{
|
||||
typedef ieee_copy_all_bits_tag method;
|
||||
|
||||
static const uint64_t sign = ((uint64_t)0x80000000u) << 32;
|
||||
static const uint64_t exponent = ((uint64_t)0x7ff00000) << 32;
|
||||
static const uint64_t flag = 0;
|
||||
static const uint64_t significand
|
||||
= (((uint64_t)0x000fffff) << 32) + ((uint64_t)0xffffffffu);
|
||||
|
||||
typedef uint64_t bits;
|
||||
static void get_bits(double x, uint64_t& a) { std::memcpy(&a, &x, 8); }
|
||||
static void set_bits(double& x, uint64_t a) { std::memcpy(&x, &a, 8); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_FPCLASSIFY_VAX_FORMAT
|
||||
|
||||
// long double (64 bits) -------------------------------------------------------
|
||||
|
||||
#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\
|
||||
|| defined(__BORLANDC__) || defined(__CODEGEAR__)
|
||||
|
||||
template<> struct fp_traits_non_native<long double, double_precision>
|
||||
{
|
||||
typedef ieee_copy_leading_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);
|
||||
|
||||
typedef uint32_t bits;
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 4);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
//..............................................................................
|
||||
|
||||
#else
|
||||
|
||||
template<> struct fp_traits_non_native<long double, double_precision>
|
||||
{
|
||||
typedef ieee_copy_all_bits_tag method;
|
||||
|
||||
static const uint64_t sign = (uint64_t)0x80000000u << 32;
|
||||
static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
|
||||
static const uint64_t flag = 0;
|
||||
static const uint64_t significand
|
||||
= ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffffu;
|
||||
|
||||
typedef uint64_t bits;
|
||||
static void get_bits(long double x, uint64_t& a) { std::memcpy(&a, &x, 8); }
|
||||
static void set_bits(long double& x, uint64_t a) { std::memcpy(&x, &a, 8); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// long double (>64 bits), x86 and x64 -----------------------------------------
|
||||
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|
||||
|| defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
|
||||
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
|
||||
|
||||
// Intel extended double precision format (80 bits)
|
||||
|
||||
template<>
|
||||
struct fp_traits_non_native<long double, extended_double_precision>
|
||||
{
|
||||
typedef ieee_copy_leading_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x00007fff);
|
||||
|
||||
typedef uint32_t bits;
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// long double (>64 bits), Itanium ---------------------------------------------
|
||||
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
|
||||
// The floating point format is unknown at compile time
|
||||
// No template specialization is provided.
|
||||
// The generic_tag definition is used.
|
||||
|
||||
// The Itanium supports both
|
||||
// the Intel extended double precision format (80 bits) and
|
||||
// the IEEE extended double precision format with 15 exponent bits (128 bits).
|
||||
|
||||
|
||||
// long double (>64 bits), PowerPC ---------------------------------------------
|
||||
|
||||
#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
|
||||
|| defined(__ppc) || defined(__ppc__) || defined(__PPC__)
|
||||
|
||||
// PowerPC extended double precision format (128 bits)
|
||||
|
||||
template<>
|
||||
struct fp_traits_non_native<long double, extended_double_precision>
|
||||
{
|
||||
typedef ieee_copy_leading_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);
|
||||
|
||||
typedef uint32_t bits;
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 12);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// long double (>64 bits), Motorola 68K ----------------------------------------
|
||||
|
||||
#elif defined(__m68k) || defined(__m68k__) \
|
||||
|| defined(__mc68000) || defined(__mc68000__) \
|
||||
|
||||
// Motorola extended double precision format (96 bits)
|
||||
|
||||
// It is the same format as the Intel extended double precision format,
|
||||
// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
|
||||
// 3) the flag bit is not set for infinity
|
||||
|
||||
template<>
|
||||
struct fp_traits_non_native<long double, extended_double_precision>
|
||||
{
|
||||
typedef ieee_copy_leading_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x00007fff);
|
||||
|
||||
// copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
|
||||
|
||||
typedef uint32_t bits;
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
std::memcpy(&a, &x, 2);
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
|
||||
reinterpret_cast<const unsigned char*>(&x) + 4, 2);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
std::memcpy(&x, &a, 2);
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
|
||||
reinterpret_cast<const unsigned char*>(&a) + 2, 2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// long double (>64 bits), All other processors --------------------------------
|
||||
|
||||
#else
|
||||
|
||||
// IEEE extended double precision format with 15 exponent bits (128 bits)
|
||||
|
||||
template<>
|
||||
struct fp_traits_non_native<long double, extended_double_precision>
|
||||
{
|
||||
typedef ieee_copy_leading_bits_tag method;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, significand = 0x0000ffff);
|
||||
|
||||
typedef uint32_t bits;
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 12);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// size_to_precision is a type switch for converting a C++ floating point type
|
||||
// to the corresponding precision type.
|
||||
|
||||
template<int n, bool fp> struct size_to_precision
|
||||
{
|
||||
typedef unknown_precision type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<4, true>
|
||||
{
|
||||
typedef single_precision type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<8, true>
|
||||
{
|
||||
typedef double_precision type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<10, true>
|
||||
{
|
||||
typedef extended_double_precision type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<12, true>
|
||||
{
|
||||
typedef extended_double_precision type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<16, true>
|
||||
{
|
||||
typedef extended_double_precision type;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Figure out whether to use native classification functions based on
|
||||
// whether T is a built in floating point type or not:
|
||||
//
|
||||
template <class T>
|
||||
struct select_native
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
|
||||
typedef fp_traits_non_native<T, precision> type;
|
||||
};
|
||||
template<>
|
||||
struct select_native<float>
|
||||
{
|
||||
typedef fp_traits_native<float> type;
|
||||
};
|
||||
template<>
|
||||
struct select_native<double>
|
||||
{
|
||||
typedef fp_traits_native<double> type;
|
||||
};
|
||||
template<>
|
||||
struct select_native<long double>
|
||||
{
|
||||
typedef fp_traits_native<long double> type;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// fp_traits is a type switch that selects the right fp_traits_non_native
|
||||
|
||||
#if (defined(BOOST_MATH_USE_C99) && !(defined(__GNUC__) && (__GNUC__ < 4))) \
|
||||
&& !defined(__hpux) \
|
||||
&& !defined(__DECCXX)\
|
||||
&& !defined(__osf__) \
|
||||
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)\
|
||||
&& !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
|
||||
# define BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
#endif
|
||||
|
||||
template<class T> struct fp_traits
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
|
||||
typedef typename select_native<T>::type type;
|
||||
#else
|
||||
typedef fp_traits_non_native<T, precision> type;
|
||||
#endif
|
||||
typedef fp_traits_non_native<T, precision> sign_change_type;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace detail
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
93
xs/include/boost/math/special_functions/detail/round_fwd.hpp
Normal file
93
xs/include/boost/math/special_functions/detail/round_fwd.hpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Copyright John Maddock 2008.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_SPECIAL_ROUND_FWD_HPP
|
||||
#define BOOST_MATH_SPECIAL_ROUND_FWD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
template <class T, class Policy>
|
||||
typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
typename tools::promote_args<T>::type trunc(const T& v);
|
||||
template <class T, class Policy>
|
||||
int itrunc(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
int itrunc(const T& v);
|
||||
template <class T, class Policy>
|
||||
long ltrunc(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
long ltrunc(const T& v);
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <class T, class Policy>
|
||||
boost::long_long_type lltrunc(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
boost::long_long_type lltrunc(const T& v);
|
||||
#endif
|
||||
template <class T, class Policy>
|
||||
typename tools::promote_args<T>::type round(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
typename tools::promote_args<T>::type round(const T& v);
|
||||
template <class T, class Policy>
|
||||
int iround(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
int iround(const T& v);
|
||||
template <class T, class Policy>
|
||||
long lround(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
long lround(const T& v);
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <class T, class Policy>
|
||||
boost::long_long_type llround(const T& v, const Policy& pol);
|
||||
template <class T>
|
||||
boost::long_long_type llround(const T& v);
|
||||
#endif
|
||||
template <class T, class Policy>
|
||||
T modf(const T& v, T* ipart, const Policy& pol);
|
||||
template <class T>
|
||||
T modf(const T& v, T* ipart);
|
||||
template <class T, class Policy>
|
||||
T modf(const T& v, int* ipart, const Policy& pol);
|
||||
template <class T>
|
||||
T modf(const T& v, int* ipart);
|
||||
template <class T, class Policy>
|
||||
T modf(const T& v, long* ipart, const Policy& pol);
|
||||
template <class T>
|
||||
T modf(const T& v, long* ipart);
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <class T, class Policy>
|
||||
T modf(const T& v, boost::long_long_type* ipart, const Policy& pol);
|
||||
template <class T>
|
||||
T modf(const T& v, boost::long_long_type* ipart);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef BOOST_MATH_STD_USING
|
||||
#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE\
|
||||
using boost::math::round;\
|
||||
using boost::math::iround;\
|
||||
using boost::math::lround;\
|
||||
using boost::math::trunc;\
|
||||
using boost::math::itrunc;\
|
||||
using boost::math::ltrunc;\
|
||||
using boost::math::modf;
|
||||
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_ROUND_FWD_HPP
|
||||
|
606
xs/include/boost/math/special_functions/fpclassify.hpp
Normal file
606
xs/include/boost/math/special_functions/fpclassify.hpp
Normal file
|
@ -0,0 +1,606 @@
|
|||
// Copyright John Maddock 2005-2008.
|
||||
// Copyright (c) 2006-2008 Johan Rade
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_FPCLASSIFY_HPP
|
||||
#define BOOST_MATH_FPCLASSIFY_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/math/tools/real_cast.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <boost/math/special_functions/math_fwd.hpp>
|
||||
#include <boost/math/special_functions/detail/fp_traits.hpp>
|
||||
/*!
|
||||
\file fpclassify.hpp
|
||||
\brief Classify floating-point value as normal, subnormal, zero, infinite, or NaN.
|
||||
\version 1.0
|
||||
\author John Maddock
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
1. If the platform is C99 compliant, then the native floating point
|
||||
classification functions are used. However, note that we must only
|
||||
define the functions which call std::fpclassify etc if that function
|
||||
really does exist: otherwise a compiler may reject the code even though
|
||||
the template is never instantiated.
|
||||
|
||||
2. If the platform is not C99 compliant, and the binary format for
|
||||
a floating point type (float, double or long double) can be determined
|
||||
at compile time, then the following algorithm is used:
|
||||
|
||||
If all exponent bits, the flag bit (if there is one),
|
||||
and all significand bits are 0, then the number is zero.
|
||||
|
||||
If all exponent bits and the flag bit (if there is one) are 0,
|
||||
and at least one significand bit is 1, then the number is subnormal.
|
||||
|
||||
If all exponent bits are 1 and all significand bits are 0,
|
||||
then the number is infinity.
|
||||
|
||||
If all exponent bits are 1 and at least one significand bit is 1,
|
||||
then the number is a not-a-number.
|
||||
|
||||
Otherwise the number is normal.
|
||||
|
||||
This algorithm works for the IEEE 754 representation,
|
||||
and also for several non IEEE 754 formats.
|
||||
|
||||
Most formats have the structure
|
||||
sign bit + exponent bits + significand bits.
|
||||
|
||||
A few have the structure
|
||||
sign bit + exponent bits + flag bit + significand bits.
|
||||
The flag bit is 0 for zero and subnormal numbers,
|
||||
and 1 for normal numbers and NaN.
|
||||
It is 0 (Motorola 68K) or 1 (Intel) for infinity.
|
||||
|
||||
To get the bits, the four or eight most significant bytes are copied
|
||||
into an uint32_t or uint64_t and bit masks are applied.
|
||||
This covers all the exponent bits and the flag bit (if there is one),
|
||||
but not always all the significand bits.
|
||||
Some of the functions below have two implementations,
|
||||
depending on whether all the significand bits are copied or not.
|
||||
|
||||
3. If the platform is not C99 compliant, and the binary format for
|
||||
a floating point type (float, double or long double) can not be determined
|
||||
at compile time, then comparison with std::numeric_limits values
|
||||
is used.
|
||||
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std{ using ::abs; using ::fabs; }
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
//
|
||||
// This must not be located in any namespace under boost::math
|
||||
// otherwise we can get into an infinite loop if isnan is
|
||||
// a #define for "isnan" !
|
||||
//
|
||||
namespace math_detail{
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4800)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline bool is_nan_helper(T t, const boost::true_type&)
|
||||
{
|
||||
#ifdef isnan
|
||||
return isnan(t);
|
||||
#elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY)
|
||||
(void)t;
|
||||
return false;
|
||||
#else // BOOST_HAS_FPCLASSIFY
|
||||
return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline bool is_nan_helper(T, const boost::false_type&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace math{
|
||||
|
||||
namespace detail{
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template <class T>
|
||||
inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&)
|
||||
{
|
||||
return (std::fpclassify)(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<true>&)
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(t);
|
||||
|
||||
// whenever possible check for Nan's first:
|
||||
#if defined(BOOST_HAS_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
|
||||
if(::boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
|
||||
return FP_NAN;
|
||||
#elif defined(isnan)
|
||||
if(boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
|
||||
return FP_NAN;
|
||||
#elif defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
if(::_isnan(boost::math::tools::real_cast<double>(t)))
|
||||
return FP_NAN;
|
||||
#endif
|
||||
// std::fabs broken on a few systems especially for long long!!!!
|
||||
T at = (t < T(0)) ? -t : t;
|
||||
|
||||
// Use a process of exclusion to figure out
|
||||
// what kind of type we have, this relies on
|
||||
// IEEE conforming reals that will treat
|
||||
// Nan's as unordered. Some compilers
|
||||
// don't do this once optimisations are
|
||||
// turned on, hence the check for nan's above.
|
||||
if(at <= (std::numeric_limits<T>::max)())
|
||||
{
|
||||
if(at >= (std::numeric_limits<T>::min)())
|
||||
return FP_NORMAL;
|
||||
return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
|
||||
}
|
||||
else if(at > (std::numeric_limits<T>::max)())
|
||||
return FP_INFINITE;
|
||||
return FP_NAN;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
|
||||
{
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<T>::is_specialized)
|
||||
return fpclassify_imp(t, generic_tag<true>());
|
||||
#endif
|
||||
//
|
||||
// An unknown type with no numeric_limits support,
|
||||
// so what are we supposed to do we do here?
|
||||
//
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(t);
|
||||
|
||||
return t == 0 ? FP_ZERO : FP_NORMAL;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(a);
|
||||
a &= traits::exponent | traits::flag | traits::significand;
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand));
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(a);
|
||||
|
||||
if(a <= traits::significand) {
|
||||
if(a == 0)
|
||||
return FP_ZERO;
|
||||
else
|
||||
return FP_SUBNORMAL;
|
||||
}
|
||||
|
||||
if(a < traits::exponent) return FP_NORMAL;
|
||||
|
||||
a &= traits::significand;
|
||||
if(a == 0) return FP_INFINITE;
|
||||
|
||||
return FP_NAN;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x);
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::flag | traits::significand;
|
||||
|
||||
if(a <= traits::significand) {
|
||||
if(x == 0)
|
||||
return FP_ZERO;
|
||||
else
|
||||
return FP_SUBNORMAL;
|
||||
}
|
||||
|
||||
if(a < traits::exponent) return FP_NORMAL;
|
||||
|
||||
a &= traits::significand;
|
||||
traits::set_bits(x,a);
|
||||
if(x == 0) return FP_INFINITE;
|
||||
|
||||
return FP_NAN;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS))
|
||||
inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
|
||||
{
|
||||
return boost::math::detail::fpclassify_imp(t, generic_tag<true>());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T>
|
||||
inline int fpclassify BOOST_NO_MACRO_EXPAND(T t)
|
||||
{
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
typedef typename tools::promote_args_permissive<T>::type value_type;
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
|
||||
return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
|
||||
return detail::fpclassify_imp(static_cast<value_type>(t), method());
|
||||
#else
|
||||
return detail::fpclassify_imp(static_cast<value_type>(t), method());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
template <>
|
||||
inline int fpclassify<long double> BOOST_NO_MACRO_EXPAND(long double t)
|
||||
{
|
||||
typedef detail::fp_traits<long double>::type traits;
|
||||
typedef traits::method method;
|
||||
typedef long double value_type;
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<long double>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
|
||||
return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
|
||||
return detail::fpclassify_imp(static_cast<value_type>(t), method());
|
||||
#else
|
||||
return detail::fpclassify_imp(static_cast<value_type>(t), method());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template<class T>
|
||||
inline bool isfinite_impl(T x, native_tag const&)
|
||||
{
|
||||
return (std::isfinite)(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline bool isfinite_impl(T x, generic_tag<true> const&)
|
||||
{
|
||||
return x >= -(std::numeric_limits<T>::max)()
|
||||
&& x <= (std::numeric_limits<T>::max)();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isfinite_impl(T x, generic_tag<false> const&)
|
||||
{
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<T>::is_specialized)
|
||||
return isfinite_impl(x, generic_tag<true>());
|
||||
#endif
|
||||
(void)x; // warning supression.
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isfinite_impl(T x, ieee_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent;
|
||||
return a != traits::exponent;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
|
||||
inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
|
||||
{
|
||||
return boost::math::detail::isfinite_impl(t, generic_tag<true>());
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool (isfinite)(T x)
|
||||
{ //!< \brief return true if floating-point type t is finite.
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
// typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
typedef typename tools::promote_args_permissive<T>::type value_type;
|
||||
return detail::isfinite_impl(static_cast<value_type>(x), method());
|
||||
}
|
||||
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
template<>
|
||||
inline bool (isfinite)(long double x)
|
||||
{ //!< \brief return true if floating-point type t is finite.
|
||||
typedef detail::fp_traits<long double>::type traits;
|
||||
typedef traits::method method;
|
||||
typedef boost::is_floating_point<long double>::type fp_tag;
|
||||
typedef long double value_type;
|
||||
return detail::isfinite_impl(static_cast<value_type>(x), method());
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template<class T>
|
||||
inline bool isnormal_impl(T x, native_tag const&)
|
||||
{
|
||||
return (std::isnormal)(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline bool isnormal_impl(T x, generic_tag<true> const&)
|
||||
{
|
||||
if(x < 0) x = -x;
|
||||
return x >= (std::numeric_limits<T>::min)()
|
||||
&& x <= (std::numeric_limits<T>::max)();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isnormal_impl(T x, generic_tag<false> const&)
|
||||
{
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<T>::is_specialized)
|
||||
return isnormal_impl(x, generic_tag<true>());
|
||||
#endif
|
||||
return !(x == 0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isnormal_impl(T x, ieee_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::flag;
|
||||
return (a != 0) && (a < traits::exponent);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
|
||||
inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
|
||||
{
|
||||
return boost::math::detail::isnormal_impl(t, generic_tag<true>());
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool (isnormal)(T x)
|
||||
{
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
//typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
typedef typename tools::promote_args_permissive<T>::type value_type;
|
||||
return detail::isnormal_impl(static_cast<value_type>(x), method());
|
||||
}
|
||||
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
template<>
|
||||
inline bool (isnormal)(long double x)
|
||||
{
|
||||
typedef detail::fp_traits<long double>::type traits;
|
||||
typedef traits::method method;
|
||||
typedef boost::is_floating_point<long double>::type fp_tag;
|
||||
typedef long double value_type;
|
||||
return detail::isnormal_impl(static_cast<value_type>(x), method());
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template<class T>
|
||||
inline bool isinf_impl(T x, native_tag const&)
|
||||
{
|
||||
return (std::isinf)(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline bool isinf_impl(T x, generic_tag<true> const&)
|
||||
{
|
||||
(void)x; // in case the compiler thinks that x is unused because std::numeric_limits<T>::has_infinity is false
|
||||
return std::numeric_limits<T>::has_infinity
|
||||
&& ( x == std::numeric_limits<T>::infinity()
|
||||
|| x == -std::numeric_limits<T>::infinity());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isinf_impl(T x, generic_tag<false> const&)
|
||||
{
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<T>::is_specialized)
|
||||
return isinf_impl(x, generic_tag<true>());
|
||||
#endif
|
||||
(void)x; // warning supression.
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::significand;
|
||||
return a == traits::exponent;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::significand;
|
||||
if(a != traits::exponent)
|
||||
return false;
|
||||
|
||||
traits::set_bits(x,0);
|
||||
return x == 0;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
|
||||
inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
|
||||
{
|
||||
return boost::math::detail::isinf_impl(t, generic_tag<true>());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
inline bool (isinf)(T x)
|
||||
{
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
// typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
typedef typename tools::promote_args_permissive<T>::type value_type;
|
||||
return detail::isinf_impl(static_cast<value_type>(x), method());
|
||||
}
|
||||
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
template<>
|
||||
inline bool (isinf)(long double x)
|
||||
{
|
||||
typedef detail::fp_traits<long double>::type traits;
|
||||
typedef traits::method method;
|
||||
typedef boost::is_floating_point<long double>::type fp_tag;
|
||||
typedef long double value_type;
|
||||
return detail::isinf_impl(static_cast<value_type>(x), method());
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template<class T>
|
||||
inline bool isnan_impl(T x, native_tag const&)
|
||||
{
|
||||
return (std::isnan)(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline bool isnan_impl(T x, generic_tag<true> const&)
|
||||
{
|
||||
return std::numeric_limits<T>::has_infinity
|
||||
? !(x <= std::numeric_limits<T>::infinity())
|
||||
: x != x;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isnan_impl(T x, generic_tag<false> const&)
|
||||
{
|
||||
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
if(std::numeric_limits<T>::is_specialized)
|
||||
return isnan_impl(x, generic_tag<true>());
|
||||
#endif
|
||||
(void)x; // warning supression
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::significand;
|
||||
return a > traits::exponent;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
|
||||
a &= traits::exponent | traits::significand;
|
||||
if(a < traits::exponent)
|
||||
return false;
|
||||
|
||||
a &= traits::significand;
|
||||
traits::set_bits(x,a);
|
||||
return x != 0;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
inline bool (isnan)(T x)
|
||||
{ //!< \brief return true if floating-point type t is NaN (Not A Number).
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
// typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
return detail::isnan_impl(x, method());
|
||||
}
|
||||
|
||||
#ifdef isnan
|
||||
template <> inline bool isnan BOOST_NO_MACRO_EXPAND<float>(float t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
|
||||
template <> inline bool isnan BOOST_NO_MACRO_EXPAND<double>(double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
|
||||
template <> inline bool isnan BOOST_NO_MACRO_EXPAND<long double>(long double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
|
||||
#elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
|
||||
template<>
|
||||
inline bool (isnan)(long double x)
|
||||
{ //!< \brief return true if floating-point type t is NaN (Not A Number).
|
||||
typedef detail::fp_traits<long double>::type traits;
|
||||
typedef traits::method method;
|
||||
typedef boost::is_floating_point<long double>::type fp_tag;
|
||||
return detail::isnan_impl(x, method());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_MATH_FPCLASSIFY_HPP
|
||||
|
1408
xs/include/boost/math/special_functions/math_fwd.hpp
Normal file
1408
xs/include/boost/math/special_functions/math_fwd.hpp
Normal file
File diff suppressed because it is too large
Load diff
150
xs/include/boost/math/special_functions/sign.hpp
Normal file
150
xs/include/boost/math/special_functions/sign.hpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
// (C) Copyright John Maddock 2006.
|
||||
// (C) Copyright Johan Rade 2006.
|
||||
// (C) Copyright Paul A. Bristow 2011 (added changesign).
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_TOOLS_SIGN_HPP
|
||||
#define BOOST_MATH_TOOLS_SIGN_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/special_functions/math_fwd.hpp>
|
||||
#include <boost/math/special_functions/detail/fp_traits.hpp>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace detail {
|
||||
|
||||
// signbit
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template<class T>
|
||||
inline int signbit_impl(T x, native_tag const&)
|
||||
{
|
||||
return (std::signbit)(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline int signbit_impl(T x, generic_tag<true> const&)
|
||||
{
|
||||
return x < 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline int signbit_impl(T x, generic_tag<false> const&)
|
||||
{
|
||||
return x < 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline int signbit_impl(T x, ieee_copy_all_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
return a & traits::sign ? 1 : 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline int signbit_impl(T x, ieee_copy_leading_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
|
||||
return a & traits::sign ? 1 : 0;
|
||||
}
|
||||
|
||||
// Changesign
|
||||
|
||||
template<class T>
|
||||
inline T (changesign_impl)(T x, generic_tag<true> const&)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T (changesign_impl)(T x, generic_tag<false> const&)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T changesign_impl(T x, ieee_copy_all_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a ^= traits::sign;
|
||||
traits::set_bits(x,a);
|
||||
return x;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a ^= traits::sign;
|
||||
traits::set_bits(x,a);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> int (signbit)(T x)
|
||||
{
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
// typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
typedef typename tools::promote_args_permissive<T>::type result_type;
|
||||
return detail::signbit_impl(static_cast<result_type>(x), method());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int sign BOOST_NO_MACRO_EXPAND(const T& z)
|
||||
{
|
||||
return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1;
|
||||
}
|
||||
|
||||
template <class T> typename tools::promote_args_permissive<T>::type (changesign)(const T& x)
|
||||
{ //!< \brief return unchanged binary pattern of x, except for change of sign bit.
|
||||
typedef typename detail::fp_traits<T>::sign_change_type traits;
|
||||
typedef typename traits::method method;
|
||||
// typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
typedef typename tools::promote_args_permissive<T>::type result_type;
|
||||
|
||||
return detail::changesign_impl(static_cast<result_type>(x), method());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline typename tools::promote_args_permissive<T, U>::type
|
||||
copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
typedef typename tools::promote_args_permissive<T, U>::type result_type;
|
||||
return (boost::math::signbit)(static_cast<result_type>(x)) != (boost::math::signbit)(static_cast<result_type>(y))
|
||||
? (boost::math::changesign)(static_cast<result_type>(x)) : static_cast<result_type>(x);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_MATH_TOOLS_SIGN_HPP
|
||||
|
||||
|
352
xs/include/boost/math/tools/config.hpp
Normal file
352
xs/include/boost/math/tools/config.hpp
Normal file
|
@ -0,0 +1,352 @@
|
|||
// Copyright (c) 2006-7 John Maddock
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_TOOLS_CONFIG_HPP
|
||||
#define BOOST_MATH_TOOLS_CONFIG_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp> // for boost::uintmax_t
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <algorithm> // for min and max
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <climits>
|
||||
#include <cfloat>
|
||||
#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/user.hpp>
|
||||
|
||||
#if (defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__NetBSD__) \
|
||||
|| (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \
|
||||
&& !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
|
||||
# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
#endif
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
//
|
||||
// Borland post 5.8.2 uses Dinkumware's std C lib which
|
||||
// doesn't have true long double precision. Earlier
|
||||
// versions are problematic too:
|
||||
//
|
||||
# define BOOST_MATH_NO_REAL_CONCEPT_TESTS
|
||||
# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
# define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM)
|
||||
# include <float.h>
|
||||
#endif
|
||||
#ifdef __IBMCPP__
|
||||
//
|
||||
// For reasons I don't unserstand, the tests with IMB's compiler all
|
||||
// pass at long double precision, but fail with real_concept, those tests
|
||||
// are disabled for now. (JM 2012).
|
||||
# define BOOST_MATH_NO_REAL_CONCEPT_TESTS
|
||||
#endif
|
||||
#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
|
||||
//
|
||||
// Darwin's rather strange "double double" is rather hard to
|
||||
// support, it should be possible given enough effort though...
|
||||
//
|
||||
# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
#endif
|
||||
#if defined(unix) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER <= 1000) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
|
||||
//
|
||||
// Intel compiler prior to version 10 has sporadic problems
|
||||
// calling the long double overloads of the std lib math functions:
|
||||
// calling ::powl is OK, but std::pow(long double, long double)
|
||||
// may segfault depending upon the value of the arguments passed
|
||||
// and the specific Linux distribution.
|
||||
//
|
||||
// We'll be conservative and disable long double support for this compiler.
|
||||
//
|
||||
// Comment out this #define and try building the tests to determine whether
|
||||
// your Intel compiler version has this issue or not.
|
||||
//
|
||||
# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
#endif
|
||||
#if defined(unix) && defined(__INTEL_COMPILER)
|
||||
//
|
||||
// Intel compiler has sporadic issues compiling std::fpclassify depending on
|
||||
// the exact OS version used. Use our own code for this as we know it works
|
||||
// well on Intel processors:
|
||||
//
|
||||
#define BOOST_MATH_DISABLE_STD_FPCLASSIFY
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC) && !defined(_WIN32_WCE)
|
||||
// Better safe than sorry, our tests don't support hardware exceptions:
|
||||
# define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM)
|
||||
#endif
|
||||
|
||||
#ifdef __IBMCPP__
|
||||
# define BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS
|
||||
#endif
|
||||
|
||||
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901))
|
||||
# define BOOST_MATH_USE_C99
|
||||
#endif
|
||||
|
||||
#if (defined(__hpux) && !defined(__hppa))
|
||||
# define BOOST_MATH_USE_C99
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(_GLIBCXX_USE_C99)
|
||||
# define BOOST_MATH_USE_C99
|
||||
#endif
|
||||
|
||||
#if defined(_LIBCPP_VERSION) && !defined(_MSC_VER)
|
||||
# define BOOST_MATH_USE_C99
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__HP_aCC) || defined(BOOST_INTEL) \
|
||||
|| defined(BOOST_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) \
|
||||
|| (defined(__GNUC__) && !defined(BOOST_MATH_USE_C99))\
|
||||
|| defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
|
||||
# define BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
|
||||
|
||||
# include "boost/type.hpp"
|
||||
# include "boost/non_type.hpp"
|
||||
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) boost::type<t>* = 0
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type<t>*
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type<t, v>* = 0
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type<t, v>*
|
||||
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \
|
||||
, BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \
|
||||
, BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \
|
||||
, BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
|
||||
|
||||
#else
|
||||
|
||||
// no workaround needed: expand to nothing
|
||||
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
|
||||
# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
|
||||
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
|
||||
# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
|
||||
|
||||
|
||||
#endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
|
||||
|
||||
#if (defined(__SUNPRO_CC) || defined(__hppa) || defined(__GNUC__)) && !defined(BOOST_MATH_SMALL_CONSTANT)
|
||||
// Sun's compiler emits a hard error if a constant underflows,
|
||||
// as does aCC on PA-RISC, while gcc issues a large number of warnings:
|
||||
# define BOOST_MATH_SMALL_CONSTANT(x) 0
|
||||
#else
|
||||
# define BOOST_MATH_SMALL_CONSTANT(x) x
|
||||
#endif
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
//
|
||||
// Define if constants too large for a float cause "bad"
|
||||
// values to be stored in the data, rather than infinity
|
||||
// or a suitably large value.
|
||||
//
|
||||
# define BOOST_MATH_BUGGY_LARGE_FLOAT_CONSTANTS
|
||||
#endif
|
||||
//
|
||||
// Tune performance options for specific compilers:
|
||||
//
|
||||
#ifdef BOOST_MSVC
|
||||
# define BOOST_MATH_POLY_METHOD 2
|
||||
#elif defined(BOOST_INTEL)
|
||||
# define BOOST_MATH_POLY_METHOD 2
|
||||
# define BOOST_MATH_RATIONAL_METHOD 2
|
||||
#elif defined(__GNUC__)
|
||||
# define BOOST_MATH_POLY_METHOD 3
|
||||
# define BOOST_MATH_RATIONAL_METHOD 3
|
||||
# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT
|
||||
# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_LONG_LONG) && !defined(BOOST_MATH_INT_TABLE_TYPE)
|
||||
# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT
|
||||
# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L
|
||||
#endif
|
||||
|
||||
//
|
||||
// The maximum order of polynomial that will be evaluated
|
||||
// via an unrolled specialisation:
|
||||
//
|
||||
#ifndef BOOST_MATH_MAX_POLY_ORDER
|
||||
# define BOOST_MATH_MAX_POLY_ORDER 17
|
||||
#endif
|
||||
//
|
||||
// Set the method used to evaluate polynomials and rationals:
|
||||
//
|
||||
#ifndef BOOST_MATH_POLY_METHOD
|
||||
# define BOOST_MATH_POLY_METHOD 1
|
||||
#endif
|
||||
#ifndef BOOST_MATH_RATIONAL_METHOD
|
||||
# define BOOST_MATH_RATIONAL_METHOD 0
|
||||
#endif
|
||||
//
|
||||
// decide whether to store constants as integers or reals:
|
||||
//
|
||||
#ifndef BOOST_MATH_INT_TABLE_TYPE
|
||||
# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT
|
||||
#endif
|
||||
#ifndef BOOST_MATH_INT_VALUE_SUFFIX
|
||||
# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF
|
||||
#endif
|
||||
//
|
||||
// Test whether to support __float128:
|
||||
//
|
||||
#if defined(_GLIBCXX_USE_FLOAT128) && defined(BOOST_GCC) && !defined(__STRICT_ANSI__)
|
||||
//
|
||||
// Only enable this when the compiler really is GCC as clang and probably
|
||||
// intel too don't support __float128 yet :-(
|
||||
//
|
||||
# define BOOST_MATH_USE_FLOAT128
|
||||
#endif
|
||||
//
|
||||
// Check for WinCE with no iostream support:
|
||||
//
|
||||
#if defined(_WIN32_WCE) && !defined(__SGI_STL_PORT)
|
||||
# define BOOST_MATH_NO_LEXICAL_CAST
|
||||
#endif
|
||||
|
||||
//
|
||||
// Helper macro for controlling the FP behaviour:
|
||||
//
|
||||
#ifndef BOOST_MATH_CONTROL_FP
|
||||
# define BOOST_MATH_CONTROL_FP
|
||||
#endif
|
||||
//
|
||||
// Helper macro for using statements:
|
||||
//
|
||||
#define BOOST_MATH_STD_USING_CORE \
|
||||
using std::abs;\
|
||||
using std::acos;\
|
||||
using std::cos;\
|
||||
using std::fmod;\
|
||||
using std::modf;\
|
||||
using std::tan;\
|
||||
using std::asin;\
|
||||
using std::cosh;\
|
||||
using std::frexp;\
|
||||
using std::pow;\
|
||||
using std::tanh;\
|
||||
using std::atan;\
|
||||
using std::exp;\
|
||||
using std::ldexp;\
|
||||
using std::sin;\
|
||||
using std::atan2;\
|
||||
using std::fabs;\
|
||||
using std::log;\
|
||||
using std::sinh;\
|
||||
using std::ceil;\
|
||||
using std::floor;\
|
||||
using std::log10;\
|
||||
using std::sqrt;
|
||||
|
||||
#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE
|
||||
|
||||
namespace boost{ namespace math{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template <class T>
|
||||
inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c)
|
||||
{
|
||||
return (std::max)((std::max)(a, b), c);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c, T d)
|
||||
{
|
||||
return (std::max)((std::max)(a, b), (std::max)(c, d));
|
||||
}
|
||||
|
||||
} // namespace tools
|
||||
|
||||
template <class T>
|
||||
void suppress_unused_variable_warning(const T&)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost namespace math
|
||||
|
||||
#if ((defined(__linux__) && !defined(__UCLIBC__)) || defined(__QNX__) || defined(__IBMCPP__)) && !defined(BOOST_NO_FENV_H)
|
||||
|
||||
#include <boost/detail/fenv.hpp>
|
||||
|
||||
# ifdef FE_ALL_EXCEPT
|
||||
|
||||
namespace boost{ namespace math{
|
||||
namespace detail
|
||||
{
|
||||
struct fpu_guard
|
||||
{
|
||||
fpu_guard()
|
||||
{
|
||||
fegetexceptflag(&m_flags, FE_ALL_EXCEPT);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
}
|
||||
~fpu_guard()
|
||||
{
|
||||
fesetexceptflag(&m_flags, FE_ALL_EXCEPT);
|
||||
}
|
||||
private:
|
||||
fexcept_t m_flags;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
}} // namespaces
|
||||
|
||||
# define BOOST_FPU_EXCEPTION_GUARD boost::math::detail::fpu_guard local_guard_object;
|
||||
# define BOOST_MATH_INSTRUMENT_FPU do{ fexcept_t cpu_flags; fegetexceptflag(&cpu_flags, FE_ALL_EXCEPT); BOOST_MATH_INSTRUMENT_VARIABLE(cpu_flags); } while(0);
|
||||
|
||||
# else
|
||||
|
||||
# define BOOST_FPU_EXCEPTION_GUARD
|
||||
# define BOOST_MATH_INSTRUMENT_FPU
|
||||
|
||||
# endif
|
||||
|
||||
#else // All other platforms.
|
||||
# define BOOST_FPU_EXCEPTION_GUARD
|
||||
# define BOOST_MATH_INSTRUMENT_FPU
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
|
||||
# include <iostream>
|
||||
# include <iomanip>
|
||||
# include <typeinfo>
|
||||
|
||||
# define BOOST_MATH_INSTRUMENT_CODE(x) \
|
||||
std::cout << std::setprecision(35) << __FILE__ << ":" << __LINE__ << " " << x << std::endl;
|
||||
# define BOOST_MATH_INSTRUMENT_VARIABLE(name) BOOST_MATH_INSTRUMENT_CODE(BOOST_STRINGIZE(name) << " = " << name)
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_MATH_INSTRUMENT_CODE(x)
|
||||
# define BOOST_MATH_INSTRUMENT_VARIABLE(name)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_TOOLS_CONFIG_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
|
175
xs/include/boost/math/tools/promotion.hpp
Normal file
175
xs/include/boost/math/tools/promotion.hpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
// boost\math\tools\promotion.hpp
|
||||
|
||||
// Copyright John Maddock 2006.
|
||||
// Copyright Paul A. Bristow 2006.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
// Promote arguments functions to allow math functions to have arguments
|
||||
// provided as integer OR real (floating-point, built-in or UDT)
|
||||
// (called ArithmeticType in functions that use promotion)
|
||||
// that help to reduce the risk of creating multiple instantiations.
|
||||
// Allows creation of an inline wrapper that forwards to a foo(RT, RT) function,
|
||||
// so you never get to instantiate any mixed foo(RT, IT) functions.
|
||||
|
||||
#ifndef BOOST_MATH_PROMOTION_HPP
|
||||
#define BOOST_MATH_PROMOTION_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Boost type traits:
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp> // for boost::is_floating_point;
|
||||
#include <boost/type_traits/is_integral.hpp> // for boost::is_integral
|
||||
#include <boost/type_traits/is_convertible.hpp> // for boost::is_convertible
|
||||
#include <boost/type_traits/is_same.hpp>// for boost::is_same
|
||||
#include <boost/type_traits/remove_cv.hpp>// for boost::remove_cv
|
||||
// Boost Template meta programming:
|
||||
#include <boost/mpl/if.hpp> // for boost::mpl::if_c.
|
||||
#include <boost/mpl/and.hpp> // for boost::mpl::if_c.
|
||||
#include <boost/mpl/or.hpp> // for boost::mpl::if_c.
|
||||
#include <boost/mpl/not.hpp> // for boost::mpl::if_c.
|
||||
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
#include <boost/static_assert.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
// If either T1 or T2 is an integer type,
|
||||
// pretend it was a double (for the purposes of further analysis).
|
||||
// Then pick the wider of the two floating-point types
|
||||
// as the actual signature to forward to.
|
||||
// For example:
|
||||
// foo(int, short) -> double foo(double, double);
|
||||
// foo(int, float) -> double foo(double, double);
|
||||
// Note: NOT float foo(float, float)
|
||||
// foo(int, double) -> foo(double, double);
|
||||
// foo(double, float) -> double foo(double, double);
|
||||
// foo(double, float) -> double foo(double, double);
|
||||
// foo(any-int-or-float-type, long double) -> foo(long double, long double);
|
||||
// but ONLY float foo(float, float) is unchanged.
|
||||
// So the only way to get an entirely float version is to call foo(1.F, 2.F),
|
||||
// But since most (all?) the math functions convert to double internally,
|
||||
// probably there would not be the hoped-for gain by using float here.
|
||||
|
||||
// This follows the C-compatible conversion rules of pow, etc
|
||||
// where pow(int, float) is converted to pow(double, double).
|
||||
|
||||
template <class T>
|
||||
struct promote_arg
|
||||
{ // If T is integral type, then promote to double.
|
||||
typedef typename mpl::if_<is_integral<T>, double, T>::type type;
|
||||
};
|
||||
// These full specialisations reduce mpl::if_ usage and speed up
|
||||
// compilation:
|
||||
template <> struct promote_arg<float> { typedef float type; };
|
||||
template <> struct promote_arg<double>{ typedef double type; };
|
||||
template <> struct promote_arg<long double> { typedef long double type; };
|
||||
template <> struct promote_arg<int> { typedef double type; };
|
||||
|
||||
template <class T1, class T2>
|
||||
struct promote_args_2
|
||||
{ // Promote, if necessary, & pick the wider of the two floating-point types.
|
||||
// for both parameter types, if integral promote to double.
|
||||
typedef typename promote_arg<T1>::type T1P; // T1 perhaps promoted.
|
||||
typedef typename promote_arg<T2>::type T2P; // T2 perhaps promoted.
|
||||
|
||||
typedef typename mpl::if_<
|
||||
typename mpl::and_<is_floating_point<T1P>, is_floating_point<T2P> >::type, // both T1P and T2P are floating-point?
|
||||
typename mpl::if_< typename mpl::or_<is_same<long double, T1P>, is_same<long double, T2P> >::type, // either long double?
|
||||
long double, // then result type is long double.
|
||||
typename mpl::if_< typename mpl::or_<is_same<double, T1P>, is_same<double, T2P> >::type, // either double?
|
||||
double, // result type is double.
|
||||
float // else result type is float.
|
||||
>::type
|
||||
>::type,
|
||||
// else one or the other is a user-defined type:
|
||||
typename mpl::if_< typename mpl::and_<mpl::not_<is_floating_point<T2P> >, ::boost::is_convertible<T1P, T2P> >, T2P, T1P>::type>::type type;
|
||||
}; // promote_arg2
|
||||
// These full specialisations reduce mpl::if_ usage and speed up
|
||||
// compilation:
|
||||
template <> struct promote_args_2<float, float> { typedef float type; };
|
||||
template <> struct promote_args_2<double, double>{ typedef double type; };
|
||||
template <> struct promote_args_2<long double, long double> { typedef long double type; };
|
||||
template <> struct promote_args_2<int, int> { typedef double type; };
|
||||
template <> struct promote_args_2<int, float> { typedef double type; };
|
||||
template <> struct promote_args_2<float, int> { typedef double type; };
|
||||
template <> struct promote_args_2<int, double> { typedef double type; };
|
||||
template <> struct promote_args_2<double, int> { typedef double type; };
|
||||
template <> struct promote_args_2<int, long double> { typedef long double type; };
|
||||
template <> struct promote_args_2<long double, int> { typedef long double type; };
|
||||
template <> struct promote_args_2<float, double> { typedef double type; };
|
||||
template <> struct promote_args_2<double, float> { typedef double type; };
|
||||
template <> struct promote_args_2<float, long double> { typedef long double type; };
|
||||
template <> struct promote_args_2<long double, float> { typedef long double type; };
|
||||
template <> struct promote_args_2<double, long double> { typedef long double type; };
|
||||
template <> struct promote_args_2<long double, double> { typedef long double type; };
|
||||
|
||||
template <class T1, class T2=float, class T3=float, class T4=float, class T5=float, class T6=float>
|
||||
struct promote_args
|
||||
{
|
||||
typedef typename promote_args_2<
|
||||
typename remove_cv<T1>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T2>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T3>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T4>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T5>::type, typename remove_cv<T6>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
//
|
||||
// Guard against use of long double if it's not supported:
|
||||
//
|
||||
BOOST_STATIC_ASSERT_MSG((0 == ::boost::is_same<type, long double>::value), "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented.");
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// This struct is the same as above, but has no static assert on long double usage,
|
||||
// it should be used only on functions that can be implemented for long double
|
||||
// even when std lib support is missing or broken for that type.
|
||||
//
|
||||
template <class T1, class T2=float, class T3=float, class T4=float, class T5=float, class T6=float>
|
||||
struct promote_args_permissive
|
||||
{
|
||||
typedef typename promote_args_2<
|
||||
typename remove_cv<T1>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T2>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T3>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T4>::type,
|
||||
typename promote_args_2<
|
||||
typename remove_cv<T5>::type, typename remove_cv<T6>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace tools
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_MATH_PROMOTION_HPP
|
||||
|
29
xs/include/boost/math/tools/real_cast.hpp
Normal file
29
xs/include/boost/math/tools/real_cast.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright John Maddock 2006.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_TOOLS_REAL_CAST_HPP
|
||||
#define BOOST_MATH_TOOLS_REAL_CAST_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
template <class To, class T>
|
||||
inline To real_cast(T t)
|
||||
{
|
||||
return static_cast<To>(t);
|
||||
}
|
||||
} // namespace tools
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_MATH_TOOLS_REAL_CAST_HPP
|
||||
|
||||
|
||||
|
97
xs/include/boost/math/tools/user.hpp
Normal file
97
xs/include/boost/math/tools/user.hpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Copyright John Maddock 2007.
|
||||
// Copyright Paul A. Bristow 2007.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_MATH_TOOLS_USER_HPP
|
||||
#define BOOST_MATH_TOOLS_USER_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// This file can be modified by the user to change the default policies.
|
||||
// See "Changing the Policy Defaults" in documentation.
|
||||
|
||||
// define this if the platform has no long double functions,
|
||||
// or if the long double versions have only double precision:
|
||||
//
|
||||
// #define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
//
|
||||
// Performance tuning options:
|
||||
//
|
||||
// #define BOOST_MATH_POLY_METHOD 3
|
||||
// #define BOOST_MATH_RATIONAL_METHOD 3
|
||||
//
|
||||
// The maximum order of polynomial that will be evaluated
|
||||
// via an unrolled specialisation:
|
||||
//
|
||||
// #define BOOST_MATH_MAX_POLY_ORDER 17
|
||||
//
|
||||
// decide whether to store constants as integers or reals:
|
||||
//
|
||||
// #define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT
|
||||
|
||||
//
|
||||
// Default policies follow:
|
||||
//
|
||||
// Domain errors:
|
||||
//
|
||||
// #define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error
|
||||
//
|
||||
// Pole errors:
|
||||
//
|
||||
// #define BOOST_MATH_POLE_ERROR_POLICY throw_on_error
|
||||
//
|
||||
// Overflow Errors:
|
||||
//
|
||||
// #define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error
|
||||
//
|
||||
// Internal Evaluation Errors:
|
||||
//
|
||||
// #define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error
|
||||
//
|
||||
// Underfow:
|
||||
//
|
||||
// #define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error
|
||||
//
|
||||
// Denorms:
|
||||
//
|
||||
// #define BOOST_MATH_DENORM_ERROR_POLICY ignore_error
|
||||
//
|
||||
// Max digits to use for internal calculations:
|
||||
//
|
||||
// #define BOOST_MATH_DIGITS10_POLICY 0
|
||||
//
|
||||
// Promote floats to doubles internally?
|
||||
//
|
||||
// #define BOOST_MATH_PROMOTE_FLOAT_POLICY true
|
||||
//
|
||||
// Promote doubles to long double internally:
|
||||
//
|
||||
// #define BOOST_MATH_PROMOTE_DOUBLE_POLICY true
|
||||
//
|
||||
// What do discrete quantiles return?
|
||||
//
|
||||
// #define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards
|
||||
//
|
||||
// If a function is mathematically undefined
|
||||
// (for example the Cauchy distribution has no mean),
|
||||
// then do we stop the code from compiling?
|
||||
//
|
||||
// #define BOOST_MATH_ASSERT_UNDEFINED_POLICY true
|
||||
//
|
||||
// Maximum series iterstions permitted:
|
||||
//
|
||||
// #define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000
|
||||
//
|
||||
// Maximum root finding steps permitted:
|
||||
//
|
||||
// define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200
|
||||
|
||||
#endif // BOOST_MATH_TOOLS_USER_HPP
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue