Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/geometry/util/math.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/geometry/util/math.hpp Fri Sep 04 12:01:02 2015 +0100 +++ b/DEPENDENCIES/generic/include/boost/geometry/util/math.hpp Mon Sep 07 11:12:49 2015 +0100 @@ -1,8 +1,14 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2014, 2015. +// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -17,7 +23,15 @@ #include <cmath> #include <limits> +#include <boost/core/ignore_unused.hpp> + #include <boost/math/constants/constants.hpp> +#ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS +#include <boost/math/special_functions/fpclassify.hpp> +#endif // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS +#include <boost/math/special_functions/round.hpp> +#include <boost/numeric/conversion/cast.hpp> +#include <boost/type_traits/is_fundamental.hpp> #include <boost/geometry/util/select_most_precise.hpp> @@ -31,11 +45,104 @@ namespace detail { +template <typename T> +inline T const& greatest(T const& v1, T const& v2) +{ + return (std::max)(v1, v2); +} -template <typename Type, bool IsFloatingPoint> +template <typename T> +inline T const& greatest(T const& v1, T const& v2, T const& v3) +{ + return (std::max)(greatest(v1, v2), v3); +} + +template <typename T> +inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4) +{ + return (std::max)(greatest(v1, v2, v3), v4); +} + +template <typename T> +inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4, T const& v5) +{ + return (std::max)(greatest(v1, v2, v3, v4), v5); +} + + +template <typename T, + bool IsFloatingPoint = boost::is_floating_point<T>::value> +struct abs +{ + static inline T apply(T const& value) + { + T const zero = T(); + return value < zero ? -value : value; + } +}; + +template <typename T> +struct abs<T, true> +{ + static inline T apply(T const& value) + { + return fabs(value); + } +}; + + +struct equals_default_policy +{ + template <typename T> + static inline T apply(T const& a, T const& b) + { + // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17 + return greatest(abs<T>::apply(a), abs<T>::apply(b), T(1)); + } +}; + +template <typename T, + bool IsFloatingPoint = boost::is_floating_point<T>::value> +struct equals_factor_policy +{ + equals_factor_policy() + : factor(1) {} + explicit equals_factor_policy(T const& v) + : factor(greatest(abs<T>::apply(v), T(1))) + {} + equals_factor_policy(T const& v0, T const& v1, T const& v2, T const& v3) + : factor(greatest(abs<T>::apply(v0), abs<T>::apply(v1), + abs<T>::apply(v2), abs<T>::apply(v3), + T(1))) + {} + + T const& apply(T const&, T const&) const + { + return factor; + } + + T factor; +}; + +template <typename T> +struct equals_factor_policy<T, false> +{ + equals_factor_policy() {} + explicit equals_factor_policy(T const&) {} + equals_factor_policy(T const& , T const& , T const& , T const& ) {} + + static inline T apply(T const&, T const&) + { + return T(1); + } +}; + +template <typename Type, + bool IsFloatingPoint = boost::is_floating_point<Type>::value> struct equals { - static inline bool apply(Type const& a, Type const& b) + template <typename Policy> + static inline bool apply(Type const& a, Type const& b, Policy const&) { return a == b; } @@ -44,25 +151,31 @@ template <typename Type> struct equals<Type, true> { - static inline Type get_max(Type const& a, Type const& b, Type const& c) + template <typename Policy> + static inline bool apply(Type const& a, Type const& b, Policy const& policy) { - return (std::max)((std::max)(a, b), c); - } + boost::ignore_unused(policy); - static inline bool apply(Type const& a, Type const& b) - { if (a == b) { return true; } - // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17, - // FUTURE: replace by some boost tool or boost::test::close_at_tolerance - return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * get_max(std::abs(a), std::abs(b), 1.0); + return abs<Type>::apply(a - b) <= std::numeric_limits<Type>::epsilon() * policy.apply(a, b); } }; -template <typename Type, bool IsFloatingPoint> +template <typename T1, typename T2, typename Policy> +inline bool equals_by_policy(T1 const& a, T2 const& b, Policy const& policy) +{ + return detail::equals + < + typename select_most_precise<T1, T2>::type + >::apply(a, b, policy); +} + +template <typename Type, + bool IsFloatingPoint = boost::is_floating_point<Type>::value> struct smaller { static inline bool apply(Type const& a, Type const& b) @@ -76,7 +189,7 @@ { static inline bool apply(Type const& a, Type const& b) { - if (equals<Type, true>::apply(a, b)) + if (equals<Type, true>::apply(a, b, equals_default_policy())) { return false; } @@ -85,8 +198,101 @@ }; -template <typename Type, bool IsFloatingPoint> -struct equals_with_epsilon : public equals<Type, IsFloatingPoint> {}; +template <typename Type, + bool IsFloatingPoint = boost::is_floating_point<Type>::value> +struct equals_with_epsilon + : public equals<Type, IsFloatingPoint> +{}; + +template +< + typename T, + bool IsFundemantal = boost::is_fundamental<T>::value /* false */ +> +struct square_root +{ + typedef T return_type; + + static inline T apply(T const& value) + { + // for non-fundamental number types assume that sqrt is + // defined either: + // 1) at T's scope, or + // 2) at global scope, or + // 3) in namespace std + using ::sqrt; + using std::sqrt; + + return sqrt(value); + } +}; + +template <typename FundamentalFP> +struct square_root_for_fundamental_fp +{ + typedef FundamentalFP return_type; + + static inline FundamentalFP apply(FundamentalFP const& value) + { +#ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS + // This is a workaround for some 32-bit platforms. + // For some of those platforms it has been reported that + // std::sqrt(nan) and/or std::sqrt(-nan) returns a finite value. + // For those platforms we need to define the macro + // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS so that the argument + // to std::sqrt is checked appropriately before passed to std::sqrt + if (boost::math::isfinite(value)) + { + return std::sqrt(value); + } + else if (boost::math::isinf(value) && value < 0) + { + return -std::numeric_limits<FundamentalFP>::quiet_NaN(); + } + return value; +#else + // for fundamental floating point numbers use std::sqrt + return std::sqrt(value); +#endif // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS + } +}; + +template <> +struct square_root<float, true> + : square_root_for_fundamental_fp<float> +{ +}; + +template <> +struct square_root<double, true> + : square_root_for_fundamental_fp<double> +{ +}; + +template <> +struct square_root<long double, true> + : square_root_for_fundamental_fp<long double> +{ +}; + +template <typename T> +struct square_root<T, true> +{ + typedef double return_type; + + static inline double apply(T const& value) + { + // for all other fundamental number types use also std::sqrt + // + // Note: in C++98 the only other possibility is double; + // in C++11 there are also overloads for integral types; + // this specialization works for those as well. + return square_root_for_fundamental_fp + < + double + >::apply(boost::numeric_cast<double>(value)); + } +}; /*! @@ -111,6 +317,30 @@ } }; +// ItoF ItoI FtoF +template <typename Result, typename Source, + bool ResultIsInteger = std::numeric_limits<Result>::is_integer, + bool SourceIsInteger = std::numeric_limits<Source>::is_integer> +struct round +{ + static inline Result apply(Source const& v) + { + return boost::numeric_cast<Result>(v); + } +}; + +// FtoI +template <typename Result, typename Source> +struct round<Result, Source, true, false> +{ + static inline Result apply(Source const& v) + { + namespace bmp = boost::math::policies; + // ignore rounding errors for backward compatibility + typedef bmp::policy< bmp::rounding_error<bmp::ignore_error> > policy; + return boost::numeric_cast<Result>(boost::math::round(v, policy())); + } +}; } // namespace detail #endif @@ -144,44 +374,36 @@ template <typename T1, typename T2> inline bool equals(T1 const& a, T2 const& b) { - typedef typename select_most_precise<T1, T2>::type select_type; return detail::equals < - select_type, - boost::is_floating_point<select_type>::type::value - >::apply(a, b); + typename select_most_precise<T1, T2>::type + >::apply(a, b, detail::equals_default_policy()); } template <typename T1, typename T2> inline bool equals_with_epsilon(T1 const& a, T2 const& b) { - typedef typename select_most_precise<T1, T2>::type select_type; return detail::equals_with_epsilon < - select_type, - boost::is_floating_point<select_type>::type::value - >::apply(a, b); + typename select_most_precise<T1, T2>::type + >::apply(a, b, detail::equals_default_policy()); } template <typename T1, typename T2> inline bool smaller(T1 const& a, T2 const& b) { - typedef typename select_most_precise<T1, T2>::type select_type; return detail::smaller < - select_type, - boost::is_floating_point<select_type>::type::value + typename select_most_precise<T1, T2>::type >::apply(a, b); } template <typename T1, typename T2> inline bool larger(T1 const& a, T2 const& b) { - typedef typename select_most_precise<T1, T2>::type select_type; return detail::smaller < - select_type, - boost::is_floating_point<select_type>::type::value + typename select_most_precise<T1, T2>::type >::apply(b, a); } @@ -217,6 +439,22 @@ } /*! +\brief Short utility to return the square root +\ingroup utility +\param value Value to calculate the square root from +\return The square root value +*/ +template <typename T> +inline typename detail::square_root<T>::return_type +sqrt(T const& value) +{ + return detail::square_root + < + T, boost::is_fundamental<T>::value + >::apply(value); +} + +/*! \brief Short utility to workaround gcc/clang problem that abs is converting to integer and that older versions of MSVC does not support abs of long long... \ingroup utility @@ -224,8 +462,7 @@ template<typename T> inline T abs(T const& value) { - T const zero = T(); - return value < zero ? -value : value; + return detail::abs<T>::apply(value); } /*! @@ -233,12 +470,24 @@ \ingroup utility */ template <typename T> -static inline int sign(T const& value) +static inline int sign(T const& value) { T const zero = T(); return value > zero ? 1 : value < zero ? -1 : 0; } +/*! +\brief Short utility to calculate the rounded value of a number. +\ingroup utility +\note If the source T is NOT an integral type and Result is an integral type + the value is rounded towards the closest integral value. Otherwise it's + casted. +*/ +template <typename Result, typename T> +inline Result round(T const& v) +{ + return detail::round<Result, T>::apply(v); +} } // namespace math