diff options
author | thegeorg <thegeorg@yandex-team.com> | 2022-12-14 13:11:45 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2022-12-14 13:11:45 +0300 |
commit | 7b2317ba8baa3414534e276c89e74f3033be9f69 (patch) | |
tree | 34bcc887b61bd073162b9ea5f017f3f792d78a2c /contrib | |
parent | 47490f2785d458995a29c75f5dd92f68f492a065 (diff) | |
download | ydb-7b2317ba8baa3414534e276c89e74f3033be9f69.tar.gz |
Drop MSVC-specific workaround for using int128 implementation from boost
Diffstat (limited to 'contrib')
83 files changed, 1 insertions, 35315 deletions
diff --git a/contrib/libs/apache/arrow/CMakeLists.txt b/contrib/libs/apache/arrow/CMakeLists.txt index 556be8910c..0bf52780a4 100644 --- a/contrib/libs/apache/arrow/CMakeLists.txt +++ b/contrib/libs/apache/arrow/CMakeLists.txt @@ -57,7 +57,6 @@ target_link_libraries(libs-apache-arrow PUBLIC contrib-libs-xxhash ZLIB::ZLIB contrib-libs-zstd - restricted-boost-multiprecision contrib-restricted-fast_float contrib-restricted-thrift contrib-restricted-uriparser diff --git a/contrib/libs/apache/arrow/cpp/src/arrow/util/int128_internal.h b/contrib/libs/apache/arrow/cpp/src/arrow/util/int128_internal.h index 1d494671a9..d7eb834904 100644 --- a/contrib/libs/apache/arrow/cpp/src/arrow/util/int128_internal.h +++ b/contrib/libs/apache/arrow/cpp/src/arrow/util/int128_internal.h @@ -20,7 +20,7 @@ #include "arrow/util/macros.h" #ifndef ARROW_USE_NATIVE_INT128 -#include <boost/multiprecision/cpp_int.hpp> +#error #include <boost/multiprecision/cpp_int.hpp> #endif namespace arrow { diff --git a/contrib/libs/apache/arrow/src/arrow/util/config.h b/contrib/libs/apache/arrow/src/arrow/util/config.h index 4e002e3d29..b3cff642c5 100644 --- a/contrib/libs/apache/arrow/src/arrow/util/config.h +++ b/contrib/libs/apache/arrow/src/arrow/util/config.h @@ -43,8 +43,6 @@ #define ARROW_JSON /* #undef ARROW_S3 */ -#ifdef __GNUC__ #define ARROW_USE_NATIVE_INT128 -#endif /* #undef GRPCPP_PP_INCLUDE */ diff --git a/contrib/restricted/boost/CMakeLists.darwin.txt b/contrib/restricted/boost/CMakeLists.darwin.txt index 1b4eb0485e..f33c165857 100644 --- a/contrib/restricted/boost/CMakeLists.darwin.txt +++ b/contrib/restricted/boost/CMakeLists.darwin.txt @@ -56,7 +56,6 @@ add_subdirectory(mp11) add_subdirectory(mpl) add_subdirectory(multi_array) add_subdirectory(multi_index) -add_subdirectory(multiprecision) add_subdirectory(numeric_conversion) add_subdirectory(optional) add_subdirectory(parameter) diff --git a/contrib/restricted/boost/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/CMakeLists.linux-aarch64.txt index b767ae0013..ce99fbdd33 100644 --- a/contrib/restricted/boost/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/boost/CMakeLists.linux-aarch64.txt @@ -53,7 +53,6 @@ add_subdirectory(mp11) add_subdirectory(mpl) add_subdirectory(multi_array) add_subdirectory(multi_index) -add_subdirectory(multiprecision) add_subdirectory(numeric_conversion) add_subdirectory(optional) add_subdirectory(parameter) diff --git a/contrib/restricted/boost/CMakeLists.linux.txt b/contrib/restricted/boost/CMakeLists.linux.txt index 1b4eb0485e..f33c165857 100644 --- a/contrib/restricted/boost/CMakeLists.linux.txt +++ b/contrib/restricted/boost/CMakeLists.linux.txt @@ -56,7 +56,6 @@ add_subdirectory(mp11) add_subdirectory(mpl) add_subdirectory(multi_array) add_subdirectory(multi_index) -add_subdirectory(multiprecision) add_subdirectory(numeric_conversion) add_subdirectory(optional) add_subdirectory(parameter) diff --git a/contrib/restricted/boost/math/include/boost/cstdfloat.hpp b/contrib/restricted/boost/math/include/boost/cstdfloat.hpp deleted file mode 100644 index 2814bb08bb..0000000000 --- a/contrib/restricted/boost/math/include/boost/cstdfloat.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// <boost/cstdfloat.hpp> implements floating-point typedefs having -// specified widths, as described in N3626 (proposed for C++14). -// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3626.pdf - -#ifndef BOOST_MATH_CSTDFLOAT_2014_01_09_HPP_ - #define BOOST_MATH_CSTDFLOAT_2014_01_09_HPP_ - - // Include the floating-point type definitions. - #include <boost/math/cstdfloat/cstdfloat_types.hpp> - - // Support a specialization of std::numeric_limits<> for the wrapped quadmath library (if available). - #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) - #include <boost/math/cstdfloat/cstdfloat_limits.hpp> - #endif - - // Support <cmath> functions for the wrapped quadmath library (if available). - #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) - #include <boost/math/cstdfloat/cstdfloat_cmath.hpp> - #endif - - // Support I/O stream operations for the wrapped quadmath library (if available). - #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) - #error You can not use <boost/math/cstdfloat/cstdfloat_iostream.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. - #endif - #include <boost/math/cstdfloat/cstdfloat_iostream.hpp> - #endif - - // Support a specialization of std::complex<> for the wrapped quadmath library (if available). - #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_COMPLEX) - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) - #error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined. - #endif - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) - #error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. - #endif - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) - #error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined. - #endif - #include <boost/math/cstdfloat/cstdfloat_complex.hpp> - #endif - - - // Undefine BOOST_NO_FLOAT128_T because this constant is not meant for public use. - #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) - #undef BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T - #endif - -#endif // BOOST_MATH_CSTDFLOAT_2014_01_09_HPP_ diff --git a/contrib/restricted/boost/math/include/boost/math/constants/calculate_constants.hpp b/contrib/restricted/boost/math/include/boost/math/constants/calculate_constants.hpp deleted file mode 100644 index 0f383bf684..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/constants/calculate_constants.hpp +++ /dev/null @@ -1,1110 +0,0 @@ -// Copyright John Maddock 2010, 2012. -// Copyright Paul A. Bristow 2011, 2012. - -// 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_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED -#define BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED -#include <type_traits> - -namespace boost{ namespace math{ namespace constants{ namespace detail{ - -template <class T> -template<int N> -inline T constant_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - - return ldexp(acos(T(0)), 1); - - /* - // Although this code works well, it's usually more accurate to just call acos - // and access the number types own representation of PI which is usually calculated - // at slightly higher precision... - - T result; - T a = 1; - T b; - T A(a); - T B = 0.5f; - T D = 0.25f; - - T lim; - lim = boost::math::tools::epsilon<T>(); - - unsigned k = 1; - - do - { - result = A + B; - result = ldexp(result, -2); - b = sqrt(B); - a += b; - a = ldexp(a, -1); - A = a * a; - B = A - result; - B = ldexp(B, 1); - result = A - B; - bool neg = boost::math::sign(result) < 0; - if(neg) - result = -result; - if(result <= lim) - break; - if(neg) - result = -result; - result = ldexp(result, k - 1); - D -= result; - ++k; - lim = ldexp(lim, 1); - } - while(true); - - result = B / D; - return result; - */ -} - -template <class T> -template<int N> -inline T constant_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return 2 * pi<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> // 2 / pi -template<int N> -inline T constant_two_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return 2 / pi<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> // sqrt(2/pi) -template <int N> -inline T constant_root_two_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt((2 / pi<T, policies::policy<policies::digits2<N> > >())); -} - -template <class T> -template<int N> -inline T constant_one_div_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return 1 / two_pi<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> -template<int N> -inline T constant_root_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(pi<T, policies::policy<policies::digits2<N> > >()); -} - -template <class T> -template<int N> -inline T constant_root_half_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(pi<T, policies::policy<policies::digits2<N> > >() / 2); -} - -template <class T> -template<int N> -inline T constant_root_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(two_pi<T, policies::policy<policies::digits2<N> > >()); -} - -template <class T> -template<int N> -inline T constant_log_root_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return log(root_two_pi<T, policies::policy<policies::digits2<N> > >()); -} - -template <class T> -template<int N> -inline T constant_root_ln_four<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(log(static_cast<T>(4))); -} - -template <class T> -template<int N> -inline T constant_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // - // Although we can clearly calculate this from first principles, this hooks into - // T's own notion of e, which hopefully will more accurate than one calculated to - // a few epsilon: - // - BOOST_MATH_STD_USING - return exp(static_cast<T>(1)); -} - -template <class T> -template<int N> -inline T constant_half<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return static_cast<T>(1) / static_cast<T>(2); -} - -template <class T> -template<int M> -inline T constant_euler<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, M>))) -{ - BOOST_MATH_STD_USING - // - // This is the method described in: - // "Some New Algorithms for High-Precision Computation of Euler's Constant" - // Richard P Brent and Edwin M McMillan. - // Mathematics of Computation, Volume 34, Number 149, Jan 1980, pages 305-312. - // See equation 17 with p = 2. - // - T n = 3 + (M ? (std::min)(M, tools::digits<T>()) : tools::digits<T>()) / 4; - T lim = M ? ldexp(T(1), 1 - (std::min)(M, tools::digits<T>())) : tools::epsilon<T>(); - T lnn = log(n); - T term = 1; - T N = -lnn; - T D = 1; - T Hk = 0; - T one = 1; - - for(unsigned k = 1;; ++k) - { - term *= n * n; - term /= k * k; - Hk += one / k; - N += term * (Hk - lnn); - D += term; - - if(term < D * lim) - break; - } - return N / D; -} - -template <class T> -template<int N> -inline T constant_euler_sqr<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return euler<T, policies::policy<policies::digits2<N> > >() - * euler<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> -template<int N> -inline T constant_one_div_euler<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(1) - / euler<T, policies::policy<policies::digits2<N> > >(); -} - - -template <class T> -template<int N> -inline T constant_root_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(static_cast<T>(2)); -} - - -template <class T> -template<int N> -inline T constant_root_three<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(static_cast<T>(3)); -} - -template <class T> -template<int N> -inline T constant_half_root_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(static_cast<T>(2)) / 2; -} - -template <class T> -template<int N> -inline T constant_ln_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // - // Although there are good ways to calculate this from scratch, this hooks into - // T's own notion of log(2) which will hopefully be accurate to the full precision - // of T: - // - BOOST_MATH_STD_USING - return log(static_cast<T>(2)); -} - -template <class T> -template<int N> -inline T constant_ln_ten<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return log(static_cast<T>(10)); -} - -template <class T> -template<int N> -inline T constant_ln_ln_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return log(log(static_cast<T>(2))); -} - -template <class T> -template<int N> -inline T constant_third<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(1) / static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_twothirds<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(2) / static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_two_thirds<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(2) / static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_three_quarters<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(3) / static_cast<T>(4); -} - -template <class T> -template<int N> -inline T constant_sixth<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(1) / static_cast<T>(6); -} - -// Pi and related constants. -template <class T> -template<int N> -inline T constant_pi_minus_three<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_four_minus_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return static_cast<T>(4) - pi<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> -template<int N> -inline T constant_exp_minus_half<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return exp(static_cast<T>(-0.5)); -} - -template <class T> -template<int N> -inline T constant_exp_minus_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return exp(static_cast<T>(-1.)); -} - -template <class T> -template<int N> -inline T constant_one_div_root_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return static_cast<T>(1) / root_two<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> -template<int N> -inline T constant_one_div_root_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return static_cast<T>(1) / root_pi<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> -template<int N> -inline T constant_one_div_root_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return static_cast<T>(1) / root_two_pi<T, policies::policy<policies::digits2<N> > >(); -} - -template <class T> -template<int N> -inline T constant_root_one_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(static_cast<T>(1) / pi<T, policies::policy<policies::digits2<N> > >()); -} - -template <class T> -template<int N> -inline T constant_four_thirds_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() * static_cast<T>(4) / static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_half_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() / static_cast<T>(2); -} - -template <class T> -template<int N> -inline T constant_third_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() / static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_sixth_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() / static_cast<T>(6); -} - -template <class T> -template<int N> -inline T constant_two_thirds_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() * static_cast<T>(2) / static_cast<T>(3); -} - -template <class T> -template<int N> -inline T constant_three_quarters_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() * static_cast<T>(3) / static_cast<T>(4); -} - -template <class T> -template<int N> -inline T constant_pi_pow_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pow(pi<T, policies::policy<policies::digits2<N> > >(), e<T, policies::policy<policies::digits2<N> > >()); // -} - -template <class T> -template<int N> -inline T constant_pi_sqr<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >() ; // -} - -template <class T> -template<int N> -inline T constant_pi_sqr_div_six<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >() - / static_cast<T>(6); // -} - -template <class T> -template<int N> -inline T constant_pi_cubed<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >() - ; // -} - -template <class T> -template<int N> -inline T constant_cbrt_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pow(pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(1)/ static_cast<T>(3)); -} - -template <class T> -template<int N> -inline T constant_one_div_cbrt_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(1) - / pow(pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(1)/ static_cast<T>(3)); -} - -// Euler's e - -template <class T> -template<int N> -inline T constant_e_pow_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pow(e<T, policies::policy<policies::digits2<N> > >(), pi<T, policies::policy<policies::digits2<N> > >()); // -} - -template <class T> -template<int N> -inline T constant_root_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sqrt(e<T, policies::policy<policies::digits2<N> > >()); -} - -template <class T> -template<int N> -inline T constant_log10_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return log10(e<T, policies::policy<policies::digits2<N> > >()); -} - -template <class T> -template<int N> -inline T constant_one_div_log10_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(1) / - log10(e<T, policies::policy<policies::digits2<N> > >()); -} - -// Trigonometric - -template <class T> -template<int N> -inline T constant_degree<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return pi<T, policies::policy<policies::digits2<N> > >() - / static_cast<T>(180) - ; // -} - -template <class T> -template<int N> -inline T constant_radian<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(180) - / pi<T, policies::policy<policies::digits2<N> > >() - ; // -} - -template <class T> -template<int N> -inline T constant_sin_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sin(static_cast<T>(1)) ; // -} - -template <class T> -template<int N> -inline T constant_cos_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return cos(static_cast<T>(1)) ; // -} - -template <class T> -template<int N> -inline T constant_sinh_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return sinh(static_cast<T>(1)) ; // -} - -template <class T> -template<int N> -inline T constant_cosh_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return cosh(static_cast<T>(1)) ; // -} - -template <class T> -template<int N> -inline T constant_phi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return (static_cast<T>(1) + sqrt(static_cast<T>(5)) )/static_cast<T>(2) ; // -} - -template <class T> -template<int N> -inline T constant_ln_phi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return log((static_cast<T>(1) + sqrt(static_cast<T>(5)) )/static_cast<T>(2) ); -} - -template <class T> -template<int N> -inline T constant_one_div_ln_phi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - return static_cast<T>(1) / - log((static_cast<T>(1) + sqrt(static_cast<T>(5)) )/static_cast<T>(2) ); -} - -// Zeta - -template <class T> -template<int N> -inline T constant_zeta_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - BOOST_MATH_STD_USING - - return pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >() - /static_cast<T>(6); -} - -template <class T> -template<int N> -inline T constant_zeta_three<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // http://mathworld.wolfram.com/AperysConstant.html - // http://en.wikipedia.org/wiki/Mathematical_constant - - // http://oeis.org/A002117/constant - //T zeta3("1.20205690315959428539973816151144999076" - // "4986292340498881792271555341838205786313" - // "09018645587360933525814619915"); - - //"1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915" A002117 - // 1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915780, +00); - //"1.2020569031595942 double - // http://www.spaennare.se/SSPROG/ssnum.pdf // section 11, Algorithm for Apery's constant zeta(3). - // Programs to Calculate some Mathematical Constants to Large Precision, Document Version 1.50 - - // by Stefan Spannare September 19, 2007 - // zeta(3) = 1/64 * sum - BOOST_MATH_STD_USING - T n_fact=static_cast<T>(1); // build n! for n = 0. - T sum = static_cast<double>(77); // Start with n = 0 case. - // for n = 0, (77/1) /64 = 1.203125 - //double lim = std::numeric_limits<double>::epsilon(); - T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits<T>())) : tools::epsilon<T>(); - for(unsigned int n = 1; n < 40; ++n) - { // three to five decimal digits per term, so 40 should be plenty for 100 decimal digits. - //cout << "n = " << n << endl; - n_fact *= n; // n! - T n_fact_p10 = n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact; // (n!)^10 - T num = ((205 * n * n) + (250 * n) + 77) * n_fact_p10; // 205n^2 + 250n + 77 - // int nn = (2 * n + 1); - // T d = factorial(nn); // inline factorial. - T d = 1; - for(unsigned int i = 1; i <= (n+n + 1); ++i) // (2n + 1) - { - d *= i; - } - T den = d * d * d * d * d; // [(2n+1)!]^5 - //cout << "den = " << den << endl; - T term = num/den; - if (n % 2 != 0) - { //term *= -1; - sum -= term; - } - else - { - sum += term; - } - //cout << "term = " << term << endl; - //cout << "sum/64 = " << sum/64 << endl; - if(abs(term) < lim) - { - break; - } - } - return sum / 64; -} - -template <class T> -template<int N> -inline T constant_catalan<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ // http://oeis.org/A006752/constant - //T c("0.915965594177219015054603514932384110774" - //"149374281672134266498119621763019776254769479356512926115106248574"); - - // 9.159655941772190150546035149323841107, 74149374281672134266498119621763019776254769479356512926115106248574422619, -01); - - // This is equation (entry) 31 from - // http://www-2.cs.cmu.edu/~adamchik/articles/catalan/catalan.htm - // See also http://www.mpfr.org/algorithms.pdf - BOOST_MATH_STD_USING - T k_fact = 1; - T tk_fact = 1; - T sum = 1; - T term; - T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits<T>())) : tools::epsilon<T>(); - - for(unsigned k = 1;; ++k) - { - k_fact *= k; - tk_fact *= (2 * k) * (2 * k - 1); - term = k_fact * k_fact / (tk_fact * (2 * k + 1) * (2 * k + 1)); - sum += term; - if(term < lim) - { - break; - } - } - return boost::math::constants::pi<T, boost::math::policies::policy<> >() - * log(2 + boost::math::constants::root_three<T, boost::math::policies::policy<> >()) - / 8 - + 3 * sum / 8; -} - -namespace khinchin_detail{ - -template <class T> -T zeta_polynomial_series(T s, T sc, int digits) -{ - BOOST_MATH_STD_USING - // - // This is algorithm 3 from: - // - // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein, - // Canadian Mathematical Society, Conference Proceedings, 2000. - // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf - // - BOOST_MATH_STD_USING - int n = (digits * 19) / 53; - T sum = 0; - T two_n = ldexp(T(1), n); - int ej_sign = 1; - for(int j = 0; j < n; ++j) - { - sum += ej_sign * -two_n / pow(T(j + 1), s); - ej_sign = -ej_sign; - } - T ej_sum = 1; - T ej_term = 1; - for(int j = n; j <= 2 * n - 1; ++j) - { - sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s); - ej_sign = -ej_sign; - ej_term *= 2 * n - j; - ej_term /= j - n + 1; - ej_sum += ej_term; - } - return -sum / (two_n * (1 - pow(T(2), sc))); -} - -template <class T> -T khinchin(int digits) -{ - BOOST_MATH_STD_USING - T sum = 0; - T term; - T lim = ldexp(T(1), 1-digits); - T factor = 0; - unsigned last_k = 1; - T num = 1; - for(unsigned n = 1;; ++n) - { - for(unsigned k = last_k; k <= 2 * n - 1; ++k) - { - factor += num / k; - num = -num; - } - last_k = 2 * n; - term = (zeta_polynomial_series(T(2 * n), T(1 - T(2 * n)), digits) - 1) * factor / n; - sum += term; - if(term < lim) - break; - } - return exp(sum / boost::math::constants::ln_two<T, boost::math::policies::policy<> >()); -} - -} - -template <class T> -template<int N> -inline T constant_khinchin<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - int n = N ? (std::min)(N, tools::digits<T>()) : tools::digits<T>(); - return khinchin_detail::khinchin<T>(n); -} - -template <class T> -template<int N> -inline T constant_extreme_value_skewness<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ // N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] - BOOST_MATH_STD_USING - T ev(12 * sqrt(static_cast<T>(6)) * zeta_three<T, policies::policy<policies::digits2<N> > >() - / pi_cubed<T, policies::policy<policies::digits2<N> > >() ); - -//T ev( -//"1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150" -//"1894272048688553376986765366075828644841024041679714157616857834895702411080704529137366329462558680" -//"2015498788776135705587959418756809080074611906006528647805347822929577145038743873949415294942796280" -//"0895597703063466053535550338267721294164578901640163603544404938283861127819804918174973533694090594" -//"3094963822672055237678432023017824416203652657301470473548274848068762500300316769691474974950757965" -//"8640779777748741897542093874605477776538884083378029488863880220988107155275203245233994097178778984" -//"3488995668362387892097897322246698071290011857605809901090220903955815127463328974447572119951192970" -//"3684453635456559086126406960279692862247058250100678008419431185138019869693206366891639436908462809" -//"9756051372711251054914491837034685476095423926553367264355374652153595857163724698198860485357368964" -//"3807049634423621246870868566707915720704996296083373077647528285782964567312903914752617978405994377" -//"9064157147206717895272199736902453130842229559980076472936976287378945035706933650987259357729800315"); - - return ev; -} - -namespace detail{ -// -// Calculation of the Glaisher constant depends upon calculating the -// derivative of the zeta function at 2, we can then use the relation: -// zeta'(2) = 1/6 pi^2 [euler + ln(2pi)-12ln(A)] -// To get the constant A. -// See equation 45 at http://mathworld.wolfram.com/RiemannZetaFunction.html. -// -// The derivative of the zeta function is computed by direct differentiation -// of the relation: -// (1-2^(1-s))zeta(s) = SUM(n=0, INF){ (-n)^n / (n+1)^s } -// Which gives us 2 slowly converging but alternating sums to compute, -// for this we use Algorithm 1 from "Convergent Acceleration of Alternating Series", -// Henri Cohen, Fernando Rodriguez Villegas and Don Zagier, Experimental Mathematics 9:1 (1999). -// See http://www.math.utexas.edu/users/villegas/publications/conv-accel.pdf -// -template <class T> -T zeta_series_derivative_2(unsigned digits) -{ - // Derivative of the series part, evaluated at 2: - BOOST_MATH_STD_USING - int n = digits * 301 * 13 / 10000; - T d = pow(3 + sqrt(T(8)), n); - d = (d + 1 / d) / 2; - T b = -1; - T c = -d; - T s = 0; - for(int k = 0; k < n; ++k) - { - T a = -log(T(k+1)) / ((k+1) * (k+1)); - c = b - c; - s = s + c * a; - b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1)); - } - return s / d; -} - -template <class T> -T zeta_series_2(unsigned digits) -{ - // Series part of zeta at 2: - BOOST_MATH_STD_USING - int n = digits * 301 * 13 / 10000; - T d = pow(3 + sqrt(T(8)), n); - d = (d + 1 / d) / 2; - T b = -1; - T c = -d; - T s = 0; - for(int k = 0; k < n; ++k) - { - T a = T(1) / ((k + 1) * (k + 1)); - c = b - c; - s = s + c * a; - b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1)); - } - return s / d; -} - -template <class T> -inline T zeta_series_lead_2() -{ - // lead part at 2: - return 2; -} - -template <class T> -inline T zeta_series_derivative_lead_2() -{ - // derivative of lead part at 2: - return -2 * boost::math::constants::ln_two<T>(); -} - -template <class T> -inline T zeta_derivative_2(unsigned n) -{ - // zeta derivative at 2: - return zeta_series_derivative_2<T>(n) * zeta_series_lead_2<T>() - + zeta_series_derivative_lead_2<T>() * zeta_series_2<T>(n); -} - -} // namespace detail - -template <class T> -template<int N> -inline T constant_glaisher<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - - BOOST_MATH_STD_USING - typedef policies::policy<policies::digits2<N> > forwarding_policy; - int n = N ? (std::min)(N, tools::digits<T>()) : tools::digits<T>(); - T v = detail::zeta_derivative_2<T>(n); - v *= 6; - v /= boost::math::constants::pi<T, forwarding_policy>() * boost::math::constants::pi<T, forwarding_policy>(); - v -= boost::math::constants::euler<T, forwarding_policy>(); - v -= log(2 * boost::math::constants::pi<T, forwarding_policy>()); - v /= -12; - return exp(v); - - /* - // from http://mpmath.googlecode.com/svn/data/glaisher.txt - // 20,000 digits of the Glaisher-Kinkelin constant A = exp(1/2 - zeta'(-1)) - // Computed using A = exp((6 (-zeta'(2))/pi^2 + log 2 pi + gamma)/12) - // with Euler-Maclaurin summation for zeta'(2). - T g( - "1.282427129100622636875342568869791727767688927325001192063740021740406308858826" - "46112973649195820237439420646120399000748933157791362775280404159072573861727522" - "14334327143439787335067915257366856907876561146686449997784962754518174312394652" - "76128213808180219264516851546143919901083573730703504903888123418813674978133050" - "93770833682222494115874837348064399978830070125567001286994157705432053927585405" - "81731588155481762970384743250467775147374600031616023046613296342991558095879293" - "36343887288701988953460725233184702489001091776941712153569193674967261270398013" - "52652668868978218897401729375840750167472114895288815996668743164513890306962645" - "59870469543740253099606800842447417554061490189444139386196089129682173528798629" - "88434220366989900606980888785849587494085307347117090132667567503310523405221054" - "14176776156308191919997185237047761312315374135304725819814797451761027540834943" - "14384965234139453373065832325673954957601692256427736926358821692159870775858274" - "69575162841550648585890834128227556209547002918593263079373376942077522290940187"); - - return g; - */ -} - -template <class T> -template<int N> -inline T constant_rayleigh_skewness<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ // 1100 digits of the Rayleigh distribution skewness - // N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] - - BOOST_MATH_STD_USING - T rs(2 * root_pi<T, policies::policy<policies::digits2<N> > >() - * pi_minus_three<T, policies::policy<policies::digits2<N> > >() - / pow(four_minus_pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(3./2)) - ); - // 6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264, - - //"0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067" - //"9440004726436754739597525250317640394102954301685809920213808351450851396781817932734836994829371322" - //"5797376021347531983451654130317032832308462278373358624120822253764532674177325950686466133508511968" - //"2389168716630349407238090652663422922072397393006683401992961569208109477307776249225072042971818671" - //"4058887072693437217879039875871765635655476241624825389439481561152126886932506682176611183750503553" - //"1218982627032068396407180216351425758181396562859085306247387212297187006230007438534686340210168288" - //"8956816965453815849613622117088096547521391672977226658826566757207615552041767516828171274858145957" - //"6137539156656005855905288420585194082284972984285863898582313048515484073396332610565441264220790791" - //"0194897267890422924599776483890102027823328602965235306539844007677157873140562950510028206251529523" - //"7428049693650605954398446899724157486062545281504433364675815915402937209673727753199567661561209251" - //"4695589950526053470201635372590001578503476490223746511106018091907936826431407434894024396366284848"); ; - return rs; -} - -template <class T> -template<int N> -inline T constant_rayleigh_kurtosis_excess<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ // - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2) - // Might provide and calculate this using pi_minus_four. - BOOST_MATH_STD_USING - return - (((static_cast<T>(6) * pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >()) - - (static_cast<T>(24) * pi<T, policies::policy<policies::digits2<N> > >()) + static_cast<T>(16) ) - / - ((pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4)) - * (pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4))) - ); -} - -template <class T> -template<int N> -inline T constant_rayleigh_kurtosis<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ // 3 - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2) - // Might provide and calculate this using pi_minus_four. - BOOST_MATH_STD_USING - return static_cast<T>(3) - (((static_cast<T>(6) * pi<T, policies::policy<policies::digits2<N> > >() - * pi<T, policies::policy<policies::digits2<N> > >()) - - (static_cast<T>(24) * pi<T, policies::policy<policies::digits2<N> > >()) + static_cast<T>(16) ) - / - ((pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4)) - * (pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4))) - ); -} - -template <class T> -template<int N> -inline T constant_log2_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return 1 / boost::math::constants::ln_two<T>(); -} - -template <class T> -template<int N> -inline T constant_quarter_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return boost::math::constants::pi<T>() / 4; -} - -template <class T> -template<int N> -inline T constant_one_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return 1 / boost::math::constants::pi<T>(); -} - -template <class T> -template<int N> -inline T constant_two_div_root_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - return 2 * boost::math::constants::one_div_root_pi<T>(); -} - -#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) -template <class T> -template<int N> -inline T constant_first_feigenbaum<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // We know the constant to 1018 decimal digits. - // See: http://www.plouffe.fr/simon/constants/feigenbaum.txt - // Also: https://oeis.org/A006890 - // N is in binary digits; so we multiply by log_2(10) - - static_assert(N < 3.321*1018, "\nThe first Feigenbaum constant cannot be computed at runtime; it is too expensive. It is known to 1018 decimal digits; you must request less than that."); - T alpha{"4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171659848551898151344086271420279325223124429888908908599449354632367134115324817142199474556443658237932020095610583305754586176522220703854106467494942849814533917262005687556659523398756038256372256480040951071283890611844702775854285419801113440175002428585382498335715522052236087250291678860362674527213399057131606875345083433934446103706309452019115876972432273589838903794946257251289097948986768334611626889116563123474460575179539122045562472807095202198199094558581946136877445617396074115614074243754435499204869180982648652368438702799649017397793425134723808737136211601860128186102056381818354097598477964173900328936171432159878240789776614391395764037760537119096932066998361984288981837003229412030210655743295550388845849737034727532121925706958414074661841981961006129640161487712944415901405467941800198133253378592493365883070459999938375411726563553016862529032210862320550634510679399023341675"}; - return alpha; -} - -template <class T> -template<int N> -inline T constant_plastic<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - using std::cbrt; - using std::sqrt; - return (cbrt(9-sqrt(T(69))) + cbrt(9+sqrt(T(69))))/cbrt(T(18)); -} - - -template <class T> -template<int N> -inline T constant_gauss<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - using std::sqrt; - T a = sqrt(T(2)); - T g = 1; - const T scale = sqrt(std::numeric_limits<T>::epsilon())/512; - while (a-g > scale*g) - { - T anp1 = (a + g)/2; - g = sqrt(a*g); - a = anp1; - } - - return 2/(a + g); -} - -template <class T> -template<int N> -inline T constant_dottie<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // Error analysis: cos(x(1+d)) - x(1+d) = -(sin(x)+1)xd; plug in x = 0.739 gives -1.236d; take d as half an ulp gives the termination criteria we want. - using std::cos; - using std::abs; - using std::sin; - T x{".739085133215160641655312087673873404013411758900757464965680635773284654883547594599376106931766531849801246"}; - T residual = cos(x) - x; - do { - x += residual/(sin(x)+1); - residual = cos(x) - x; - } while(abs(residual) > std::numeric_limits<T>::epsilon()); - return x; -} - - -template <class T> -template<int N> -inline T constant_reciprocal_fibonacci<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // Wikipedia says Gosper has deviced a faster algorithm for this, but I read the linked paper and couldn't see it! - // In any case, k bits per iteration is fine, though it would be better to sum from smallest to largest. - // That said, the condition number is unity, so it should be fine. - T x0 = 1; - T x1 = 1; - T sum = 2; - T diff = 1; - while (diff > std::numeric_limits<T>::epsilon()) { - T tmp = x1 + x0; - diff = 1/tmp; - sum += diff; - x0 = x1; - x1 = tmp; - } - return sum; -} - -template <class T> -template<int N> -inline T constant_laplace_limit<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>))) -{ - // If x is the exact root, then the approximate root is given by x(1+delta). - // Plugging this into the equation for the Laplace limit gives the residual of approximately - // 2.6389delta. Take delta as half an epsilon and give some leeway so we don't get caught in an infinite loop, - // gives a termination condition as 2eps. - using std::abs; - using std::exp; - using std::sqrt; - T x{"0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168"}; - T tmp = sqrt(1+x*x); - T etmp = exp(tmp); - T residual = x*exp(tmp) - 1 - tmp; - T df = etmp -x/tmp + etmp*x*x/tmp; - do { - x -= residual/df; - tmp = sqrt(1+x*x); - etmp = exp(tmp); - residual = x*exp(tmp) - 1 - tmp; - df = etmp -x/tmp + etmp*x*x/tmp; - } while(abs(residual) > 2*std::numeric_limits<T>::epsilon()); - return x; -} - -#endif - -} -} -} -} // namespaces - -#endif // BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED diff --git a/contrib/restricted/boost/math/include/boost/math/constants/constants.hpp b/contrib/restricted/boost/math/include/boost/math/constants/constants.hpp deleted file mode 100644 index 730256c666..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/constants/constants.hpp +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright John Maddock 2005-2006, 2011. -// Copyright Paul A. Bristow 2006-2011. -// 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_CONSTANTS_CONSTANTS_INCLUDED -#define BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED - -#include <boost/math/tools/config.hpp> -#include <boost/math/tools/cxx03_warn.hpp> -#include <boost/math/policies/policy.hpp> -#include <boost/math/tools/precision.hpp> -#include <boost/math/tools/convert_from_string.hpp> -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4127 4701) -#endif -#ifdef _MSC_VER -#pragma warning(pop) -#endif -#include <utility> -#include <type_traits> - -#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) -// -// This is the only way we can avoid -// warning: non-standard suffix on floating constant [-Wpedantic] -// when building with -Wall -pedantic. Neither __extension__ -// nor #pragma diagnostic ignored work :( -// -#pragma GCC system_header -#endif - -namespace boost{ namespace math -{ - namespace constants - { - // To permit other calculations at about 100 decimal digits with some UDT, - // it is obviously necessary to define constants to this accuracy. - - // However, some compilers do not accept decimal digits strings as long as this. - // So the constant is split into two parts, with the 1st containing at least - // long double precision, and the 2nd zero if not needed or known. - // The 3rd part permits an exponent to be provided if necessary (use zero if none) - - // the other two parameters may only contain decimal digits (and sign and decimal point), - // and may NOT include an exponent like 1.234E99. - // The second digit string is only used if T is a User-Defined Type, - // when the constant is converted to a long string literal and lexical_casted to type T. - // (This is necessary because you can't use a numeric constant - // since even a long double might not have enough digits). - - enum construction_method - { - construct_from_float = 1, - construct_from_double = 2, - construct_from_long_double = 3, - construct_from_string = 4, - construct_from_float128 = 5, - // Must be the largest value above: - construct_max = construct_from_float128 - }; - - // - // Traits class determines how to convert from string based on whether T has a constructor - // from const char* or not: - // - template <int N> - struct dummy_size{}; - - // - // Max number of binary digits in the string representations of our constants: - // - static constexpr int max_string_digits = (101 * 1000L) / 301L; - - template <typename Real, typename Policy> - struct construction_traits - { - private: - using real_precision = typename policies::precision<Real, Policy>::type; - using float_precision = typename policies::precision<float, Policy>::type; - using double_precision = typename policies::precision<double, Policy>::type; - using long_double_precision = typename policies::precision<long double, Policy>::type; - public: - using type = std::integral_constant<int, - (0 == real_precision::value) ? 0 : - std::is_convertible<float, Real>::value && (real_precision::value <= float_precision::value)? construct_from_float : - std::is_convertible<double, Real>::value && (real_precision::value <= double_precision::value)? construct_from_double : - std::is_convertible<long double, Real>::value && (real_precision::value <= long_double_precision::value)? construct_from_long_double : -#ifdef BOOST_MATH_USE_FLOAT128 - std::is_convertible<BOOST_MATH_FLOAT128_TYPE, Real>::value && (real_precision::value <= 113) ? construct_from_float128 : -#endif - (real_precision::value <= max_string_digits) ? construct_from_string : real_precision::value - >; - }; - -#ifdef BOOST_HAS_THREADS -#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) \ - boost::once_flag f = BOOST_ONCE_INIT;\ - boost::call_once(f, &BOOST_JOIN(BOOST_JOIN(string_, get_), name)<T>); -#else -#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) -#endif - - namespace detail{ - - template <class Real, class Policy = boost::math::policies::policy<> > - struct constant_return - { - using construct_type = typename construction_traits<Real, Policy>::type; - using type = typename std::conditional< - (construct_type::value == construct_from_string) || (construct_type::value > construct_max), - const Real&, Real>::type; - }; - - template <typename T, const T& (*F)()> - struct constant_initializer - { - static void force_instantiate() - { - init.force_instantiate(); - } - private: - struct initializer - { - initializer() - { - F(); - } - void force_instantiate()const{} - }; - static const initializer init; - }; - - template <typename T, const T& (*F)()> - typename constant_initializer<T, F>::initializer const constant_initializer<T, F>::init; - - template <typename T, int N, const T& (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))> - struct constant_initializer2 - { - static void force_instantiate() - { - init.force_instantiate(); - } - private: - struct initializer - { - initializer() - { - F(); - } - void force_instantiate()const{} - }; - static const initializer init; - }; - - template <typename T, int N, const T& (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))> - typename constant_initializer2<T, N, F>::initializer const constant_initializer2<T, N, F>::init; - - } - -#ifdef BOOST_MATH_USE_FLOAT128 -# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \ - static inline constexpr T get(const std::integral_constant<int, construct_from_float128>&) noexcept\ - { return BOOST_JOIN(x, Q); } -#else -# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) -#endif - -#ifdef BOOST_NO_CXX11_THREAD_LOCAL -# define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name) constant_initializer<T, & BOOST_JOIN(constant_, name)<T>::get_from_variable_precision>::force_instantiate(); -#else -# define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name) -#endif - -#define BOOST_DEFINE_MATH_CONSTANT(name, x, y)\ - namespace detail{\ - template <typename T> struct BOOST_JOIN(constant_, name){\ - private:\ - /* The default implementations come next: */ \ - static inline const T& get_from_string()\ - {\ - static const T result(boost::math::tools::convert_from_string<T>(y));\ - return result;\ - }\ - /* This one is for very high precision that is none the less known at compile time: */ \ - template <int N> static T compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)));\ - template <int N> static inline const T& get_from_compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)))\ - {\ - static const T result = compute<N>();\ - return result;\ - }\ - static inline const T& get_from_variable_precision()\ - {\ - static BOOST_MATH_THREAD_LOCAL int digits = 0;\ - static BOOST_MATH_THREAD_LOCAL T value;\ - int current_digits = boost::math::tools::digits<T>();\ - if(digits != current_digits)\ - {\ - value = current_digits > max_string_digits ? compute<0>() : T(boost::math::tools::convert_from_string<T>(y));\ - digits = current_digits; \ - }\ - return value;\ - }\ - /* public getters come next */\ - public:\ - static inline const T& get(const std::integral_constant<int, construct_from_string>&)\ - {\ - constant_initializer<T, & BOOST_JOIN(constant_, name)<T>::get_from_string >::force_instantiate();\ - return get_from_string();\ - }\ - static inline constexpr T get(const std::integral_constant<int, construct_from_float>) noexcept\ - { return BOOST_JOIN(x, F); }\ - static inline constexpr T get(const std::integral_constant<int, construct_from_double>&) noexcept\ - { return x; }\ - static inline constexpr T get(const std::integral_constant<int, construct_from_long_double>&) noexcept\ - { return BOOST_JOIN(x, L); }\ - BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \ - template <int N> static inline const T& get(const std::integral_constant<int, N>&)\ - {\ - constant_initializer2<T, N, & BOOST_JOIN(constant_, name)<T>::template get_from_compute<N> >::force_instantiate();\ - return get_from_compute<N>(); \ - }\ - /* This one is for true arbitrary precision, which may well vary at runtime: */ \ - static inline T get(const std::integral_constant<int, 0>&)\ - {\ - BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)\ - return get_from_variable_precision(); }\ - }; /* end of struct */\ - } /* namespace detail */ \ - \ - \ - /* The actual forwarding function: */ \ - template <typename T, typename Policy> inline constexpr typename detail::constant_return<T, Policy>::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy)) BOOST_MATH_NOEXCEPT(T)\ - { return detail:: BOOST_JOIN(constant_, name)<T>::get(typename construction_traits<T, Policy>::type()); }\ - template <typename T> inline constexpr typename detail::constant_return<T>::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)\ - { return name<T, boost::math::policies::policy<> >(); }\ - \ - \ - /* Now the namespace specific versions: */ \ - } namespace float_constants{ static constexpr float name = BOOST_JOIN(x, F); }\ - namespace double_constants{ static constexpr double name = x; } \ - namespace long_double_constants{ static constexpr long double name = BOOST_JOIN(x, L); }\ - namespace constants{ - - BOOST_DEFINE_MATH_CONSTANT(half, 5.000000000000000000000000000000000000e-01, "5.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01") - BOOST_DEFINE_MATH_CONSTANT(third, 3.333333333333333333333333333333333333e-01, "3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333e-01") - BOOST_DEFINE_MATH_CONSTANT(twothirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") - BOOST_DEFINE_MATH_CONSTANT(two_thirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") - BOOST_DEFINE_MATH_CONSTANT(sixth, 1.666666666666666666666666666666666666e-01, "1.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") - BOOST_DEFINE_MATH_CONSTANT(three_quarters, 7.500000000000000000000000000000000000e-01, "7.50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01") - BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078e+00, "1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623e+00") - BOOST_DEFINE_MATH_CONSTANT(root_three, 1.732050807568877293527446341505872366e+00, "1.73205080756887729352744634150587236694280525381038062805580697945193301690880003708114618675724857567562614142e+00") - BOOST_DEFINE_MATH_CONSTANT(half_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01") - BOOST_DEFINE_MATH_CONSTANT(ln_two, 6.931471805599453094172321214581765680e-01, "6.93147180559945309417232121458176568075500134360255254120680009493393621969694715605863326996418687542001481021e-01") - BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -3.665129205816643270124391582326694694e-01, "-3.66512920581664327012439158232669469454263447837105263053677713670561615319352738549455822856698908358302523045e-01") - BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.177410022515474691011569326459699637e+00, "1.17741002251547469101156932645969963774738568938582053852252575650002658854698492680841813836877081106747157858e+00") - BOOST_DEFINE_MATH_CONSTANT(one_div_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01") - BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00") - BOOST_DEFINE_MATH_CONSTANT(half_pi, 1.570796326794896619231321691639751442e+00, "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326e+00") - BOOST_DEFINE_MATH_CONSTANT(third_pi, 1.047197551196597746154214461093167628e+00, "1.04719755119659774615421446109316762806572313312503527365831486410260546876206966620934494178070568932738269550e+00") - BOOST_DEFINE_MATH_CONSTANT(sixth_pi, 5.235987755982988730771072305465838140e-01, "5.23598775598298873077107230546583814032861566562517636829157432051302734381034833104672470890352844663691347752e-01") - BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.283185307179586476925286766559005768e+00, "6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617303e+00") - BOOST_DEFINE_MATH_CONSTANT(two_thirds_pi, 2.094395102393195492308428922186335256e+00, "2.09439510239319549230842892218633525613144626625007054731662972820521093752413933241868988356141137865476539101e+00") - BOOST_DEFINE_MATH_CONSTANT(three_quarters_pi, 2.356194490192344928846982537459627163e+00, "2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488e+00") - BOOST_DEFINE_MATH_CONSTANT(four_thirds_pi, 4.188790204786390984616857844372670512e+00, "4.18879020478639098461685784437267051226289253250014109463325945641042187504827866483737976712282275730953078202e+00") - BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 1.591549430918953357688837633725143620e-01, "1.59154943091895335768883763372514362034459645740456448747667344058896797634226535090113802766253085956072842727e-01") - BOOST_DEFINE_MATH_CONSTANT(one_div_root_two_pi, 3.989422804014326779399460599343818684e-01, "3.98942280401432677939946059934381868475858631164934657665925829670657925899301838501252333907306936430302558863e-01") - BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.772453850905516027298167483341145182e+00, "1.77245385090551602729816748334114518279754945612238712821380778985291128459103218137495065673854466541622682362e+00") - BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626e+00, "1.25331413731550025120788264240552262650349337030496915831496178817114682730392098747329791918902863305800498633e+00") - BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253e+00, "2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659583837805726611600997267e+00") - BOOST_DEFINE_MATH_CONSTANT(log_root_two_pi, 9.189385332046727417803297364056176398e-01, "9.18938533204672741780329736405617639861397473637783412817151540482765695927260397694743298635954197622005646625e-01") - BOOST_DEFINE_MATH_CONSTANT(one_div_root_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01") - BOOST_DEFINE_MATH_CONSTANT(root_one_div_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01") - BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 1.415926535897932384626433832795028841e-01, "1.41592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513e-01") - BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 8.584073464102067615373566167204971158e-01, "8.58407346410206761537356616720497115802830600624894179025055407692183593713791001371965174657882932017851913487e-01") - //BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 7.953167673715975443483953350568065807e-01, "7.95316767371597544348395335056806580727639173327713205445302234388856268267518187590758006888600828436839800178e-01") - BOOST_DEFINE_MATH_CONSTANT(pi_pow_e, 2.245915771836104547342715220454373502e+01, "2.24591577183610454734271522045437350275893151339966922492030025540669260403991179123185197527271430315314500731e+01") - BOOST_DEFINE_MATH_CONSTANT(pi_sqr, 9.869604401089358618834490999876151135e+00, "9.86960440108935861883449099987615113531369940724079062641334937622004482241920524300177340371855223182402591377e+00") - BOOST_DEFINE_MATH_CONSTANT(pi_sqr_div_six, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00") - BOOST_DEFINE_MATH_CONSTANT(pi_cubed, 3.100627668029982017547631506710139520e+01, "3.10062766802998201754763150671013952022252885658851076941445381038063949174657060375667010326028861930301219616e+01") - BOOST_DEFINE_MATH_CONSTANT(cbrt_pi, 1.464591887561523263020142527263790391e+00, "1.46459188756152326302014252726379039173859685562793717435725593713839364979828626614568206782035382089750397002e+00") - BOOST_DEFINE_MATH_CONSTANT(one_div_cbrt_pi, 6.827840632552956814670208331581645981e-01, "6.82784063255295681467020833158164598108367515632448804042681583118899226433403918237673501922595519865685577274e-01") - BOOST_DEFINE_MATH_CONSTANT(log2_e, 1.44269504088896340735992468100189213742664595415298, "1.44269504088896340735992468100189213742664595415298593413544940693110921918118507988552662289350634449699751830965e+00") - BOOST_DEFINE_MATH_CONSTANT(e, 2.718281828459045235360287471352662497e+00, "2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193e+00") - BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 6.065306597126334236037995349911804534e-01, "6.06530659712633423603799534991180453441918135487186955682892158735056519413748423998647611507989456026423789794e-01") - BOOST_DEFINE_MATH_CONSTANT(exp_minus_one, 3.678794411714423215955237701614608674e-01, "3.67879441171442321595523770161460867445811131031767834507836801697461495744899803357147274345919643746627325277e-01") - BOOST_DEFINE_MATH_CONSTANT(e_pow_pi, 2.314069263277926900572908636794854738e+01, "2.31406926327792690057290863679485473802661062426002119934450464095243423506904527835169719970675492196759527048e+01") - BOOST_DEFINE_MATH_CONSTANT(root_e, 1.648721270700128146848650787814163571e+00, "1.64872127070012814684865078781416357165377610071014801157507931164066102119421560863277652005636664300286663776e+00") - BOOST_DEFINE_MATH_CONSTANT(log10_e, 4.342944819032518276511289189166050822e-01, "4.34294481903251827651128918916605082294397005803666566114453783165864649208870774729224949338431748318706106745e-01") - BOOST_DEFINE_MATH_CONSTANT(one_div_log10_e, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00") - BOOST_DEFINE_MATH_CONSTANT(ln_ten, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00") - BOOST_DEFINE_MATH_CONSTANT(degree, 1.745329251994329576923690768488612713e-02, "1.74532925199432957692369076848861271344287188854172545609719144017100911460344944368224156963450948221230449251e-02") - BOOST_DEFINE_MATH_CONSTANT(radian, 5.729577951308232087679815481410517033e+01, "5.72957795130823208767981548141051703324054724665643215491602438612028471483215526324409689958511109441862233816e+01") - BOOST_DEFINE_MATH_CONSTANT(sin_one, 8.414709848078965066525023216302989996e-01, "8.41470984807896506652502321630298999622563060798371065672751709991910404391239668948639743543052695854349037908e-01") - BOOST_DEFINE_MATH_CONSTANT(cos_one, 5.403023058681397174009366074429766037e-01, "5.40302305868139717400936607442976603732310420617922227670097255381100394774471764517951856087183089343571731160e-01") - BOOST_DEFINE_MATH_CONSTANT(sinh_one, 1.175201193643801456882381850595600815e+00, "1.17520119364380145688238185059560081515571798133409587022956541301330756730432389560711745208962339184041953333e+00") - BOOST_DEFINE_MATH_CONSTANT(cosh_one, 1.543080634815243778477905620757061682e+00, "1.54308063481524377847790562075706168260152911236586370473740221471076906304922369896426472643554303558704685860e+00") - BOOST_DEFINE_MATH_CONSTANT(phi, 1.618033988749894848204586834365638117e+00, "1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475408808e+00") - BOOST_DEFINE_MATH_CONSTANT(ln_phi, 4.812118250596034474977589134243684231e-01, "4.81211825059603447497758913424368423135184334385660519661018168840163867608221774412009429122723474997231839958e-01") - BOOST_DEFINE_MATH_CONSTANT(one_div_ln_phi, 2.078086921235027537601322606117795767e+00, "2.07808692123502753760132260611779576774219226778328348027813992191974386928553540901445615414453604821933918634e+00") - BOOST_DEFINE_MATH_CONSTANT(euler, 5.772156649015328606065120900824024310e-01, "5.77215664901532860606512090082402431042159335939923598805767234884867726777664670936947063291746749514631447250e-01") - BOOST_DEFINE_MATH_CONSTANT(one_div_euler, 1.732454714600633473583025315860829681e+00, "1.73245471460063347358302531586082968115577655226680502204843613287065531408655243008832840219409928068072365714e+00") - BOOST_DEFINE_MATH_CONSTANT(euler_sqr, 3.331779238077186743183761363552442266e-01, "3.33177923807718674318376136355244226659417140249629743150833338002265793695756669661263268631715977303039565603e-01") - BOOST_DEFINE_MATH_CONSTANT(zeta_two, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00") - BOOST_DEFINE_MATH_CONSTANT(zeta_three, 1.202056903159594285399738161511449990e+00, "1.20205690315959428539973816151144999076498629234049888179227155534183820578631309018645587360933525814619915780e+00") - BOOST_DEFINE_MATH_CONSTANT(catalan, 9.159655941772190150546035149323841107e-01, "9.15965594177219015054603514932384110774149374281672134266498119621763019776254769479356512926115106248574422619e-01") - BOOST_DEFINE_MATH_CONSTANT(glaisher, 1.282427129100622636875342568869791727e+00, "1.28242712910062263687534256886979172776768892732500119206374002174040630885882646112973649195820237439420646120e+00") - BOOST_DEFINE_MATH_CONSTANT(khinchin, 2.685452001065306445309714835481795693e+00, "2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515346591e+00") - BOOST_DEFINE_MATH_CONSTANT(extreme_value_skewness, 1.139547099404648657492793019389846112e+00, "1.13954709940464865749279301938984611208759979583655182472165571008524800770607068570718754688693851501894272049e+00") - BOOST_DEFINE_MATH_CONSTANT(rayleigh_skewness, 6.311106578189371381918993515442277798e-01, "6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264e-01") - BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis, 3.245089300687638062848660410619754415e+00, "3.24508930068763806284866041061975441541706673178920936177133764493367904540874159051490619368679348977426462633e+00") - BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis_excess, 2.450893006876380628486604106197544154e-01, "2.45089300687638062848660410619754415417066731789209361771337644933679045408741590514906193686793489774264626328e-01") - - BOOST_DEFINE_MATH_CONSTANT(two_div_pi, 6.366197723675813430755350534900574481e-01, "6.36619772367581343075535053490057448137838582961825794990669376235587190536906140360455211065012343824291370907e-01") - BOOST_DEFINE_MATH_CONSTANT(root_two_div_pi, 7.978845608028653558798921198687637369e-01, "7.97884560802865355879892119868763736951717262329869315331851659341315851798603677002504667814613872860605117725e-01") - BOOST_DEFINE_MATH_CONSTANT(quarter_pi, 0.785398163397448309615660845819875721049292, "0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773") - BOOST_DEFINE_MATH_CONSTANT(one_div_pi, 0.3183098861837906715377675267450287240689192, "0.31830988618379067153776752674502872406891929148091289749533468811779359526845307018022760553250617191214568545351") - BOOST_DEFINE_MATH_CONSTANT(two_div_root_pi, 1.12837916709551257389615890312154517168810125, "1.12837916709551257389615890312154517168810125865799771368817144342128493688298682897348732040421472688605669581272") - -#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) - BOOST_DEFINE_MATH_CONSTANT(first_feigenbaum, 4.66920160910299067185320382046620161725818557747576863274, "4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171") - BOOST_DEFINE_MATH_CONSTANT(plastic, 1.324717957244746025960908854478097340734404056901733364534, "1.32471795724474602596090885447809734073440405690173336453401505030282785124554759405469934798178728032991") - BOOST_DEFINE_MATH_CONSTANT(gauss, 0.834626841674073186281429732799046808993993013490347002449, "0.83462684167407318628142973279904680899399301349034700244982737010368199270952641186969116035127532412906785") - BOOST_DEFINE_MATH_CONSTANT(dottie, 0.739085133215160641655312087673873404013411758900757464965, "0.739085133215160641655312087673873404013411758900757464965680635773284654883547594599376106931766531849801246") - BOOST_DEFINE_MATH_CONSTANT(reciprocal_fibonacci, 3.35988566624317755317201130291892717968890513, "3.35988566624317755317201130291892717968890513373196848649555381532513031899668338361541621645679008729704") - BOOST_DEFINE_MATH_CONSTANT(laplace_limit, 0.662743419349181580974742097109252907056233549115022417, "0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168") -#endif - -template <typename T> -inline constexpr T tau() { return two_pi<T>(); } - -} // namespace constants -} // namespace math -} // namespace boost - -// -// We deliberately include this *after* all the declarations above, -// that way the calculation routines can call on other constants above: -// -#include <boost/math/constants/calculate_constants.hpp> - -#endif // BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED - - diff --git a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp b/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp deleted file mode 100644 index a066c57169..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp +++ /dev/null @@ -1,1057 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// Implement quadruple-precision <cmath> support. - -#ifndef BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ -#define BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ - -#include <boost/math/cstdfloat/cstdfloat_types.hpp> -#include <boost/math/cstdfloat/cstdfloat_limits.hpp> - -#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) - -#include <cstdint> -#include <cmath> -#include <stdexcept> -#include <iostream> -#include <type_traits> -#include <memory> -#include <boost/math/tools/assert.hpp> -#include <boost/math/tools/throw_exception.hpp> - -#if defined(_WIN32) && defined(__GNUC__) - // Several versions of Mingw and probably cygwin too have broken - // libquadmath implementations that segfault as soon as you call - // expq or any function that depends on it. -#define BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS -#endif - -// Here is a helper function used for raising the value of a given -// floating-point type to the power of n, where n has integral type. -namespace boost { - namespace math { - namespace cstdfloat { - namespace detail { - - template<class float_type, class integer_type> - inline float_type pown(const float_type& x, const integer_type p) - { - const bool isneg = (x < 0); - const bool isnan = (x != x); - const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)()) - : bool(-x > (std::numeric_limits<float_type>::max)())); - - if (isnan) { return x; } - - if (isinf) { return std::numeric_limits<float_type>::quiet_NaN(); } - - const bool x_is_neg = (x < 0); - const float_type abs_x = (x_is_neg ? -x : x); - - if (p < static_cast<integer_type>(0)) - { - if (abs_x < (std::numeric_limits<float_type>::min)()) - { - return (x_is_neg ? -std::numeric_limits<float_type>::infinity() - : +std::numeric_limits<float_type>::infinity()); - } - else - { - return float_type(1) / pown(x, static_cast<integer_type>(-p)); - } - } - - if (p == static_cast<integer_type>(0)) - { - return float_type(1); - } - else - { - if (p == static_cast<integer_type>(1)) { return x; } - - if (abs_x > (std::numeric_limits<float_type>::max)()) - { - return (x_is_neg ? -std::numeric_limits<float_type>::infinity() - : +std::numeric_limits<float_type>::infinity()); - } - - if (p == static_cast<integer_type>(2)) { return (x * x); } - else if (p == static_cast<integer_type>(3)) { return ((x * x) * x); } - else if (p == static_cast<integer_type>(4)) { const float_type x2 = (x * x); return (x2 * x2); } - else - { - // The variable xn stores the binary powers of x. - float_type result(((p % integer_type(2)) != integer_type(0)) ? x : float_type(1)); - float_type xn(x); - - integer_type p2 = p; - - while (integer_type(p2 /= 2) != integer_type(0)) - { - // Square xn for each binary power. - xn *= xn; - - const bool has_binary_power = (integer_type(p2 % integer_type(2)) != integer_type(0)); - - if (has_binary_power) - { - // Multiply the result with each binary power contained in the exponent. - result *= xn; - } - } - - return result; - } - } - } - - } - } - } -} // boost::math::cstdfloat::detail - -// We will now define preprocessor symbols representing quadruple-precision <cmath> functions. -#if defined(__INTEL_COMPILER) -#define BOOST_CSTDFLOAT_FLOAT128_LDEXP __ldexpq -#define BOOST_CSTDFLOAT_FLOAT128_FREXP __frexpq -#define BOOST_CSTDFLOAT_FLOAT128_FABS __fabsq -#define BOOST_CSTDFLOAT_FLOAT128_FLOOR __floorq -#define BOOST_CSTDFLOAT_FLOAT128_CEIL __ceilq -#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT) -#define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq -#endif -#define BOOST_CSTDFLOAT_FLOAT128_TRUNC __truncq -#define BOOST_CSTDFLOAT_FLOAT128_EXP __expq -#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 __expm1q -#define BOOST_CSTDFLOAT_FLOAT128_POW __powq -#define BOOST_CSTDFLOAT_FLOAT128_LOG __logq -#define BOOST_CSTDFLOAT_FLOAT128_LOG10 __log10q -#define BOOST_CSTDFLOAT_FLOAT128_SIN __sinq -#define BOOST_CSTDFLOAT_FLOAT128_COS __cosq -#define BOOST_CSTDFLOAT_FLOAT128_TAN __tanq -#define BOOST_CSTDFLOAT_FLOAT128_ASIN __asinq -#define BOOST_CSTDFLOAT_FLOAT128_ACOS __acosq -#define BOOST_CSTDFLOAT_FLOAT128_ATAN __atanq -#define BOOST_CSTDFLOAT_FLOAT128_SINH __sinhq -#define BOOST_CSTDFLOAT_FLOAT128_COSH __coshq -#define BOOST_CSTDFLOAT_FLOAT128_TANH __tanhq -#define BOOST_CSTDFLOAT_FLOAT128_ASINH __asinhq -#define BOOST_CSTDFLOAT_FLOAT128_ACOSH __acoshq -#define BOOST_CSTDFLOAT_FLOAT128_ATANH __atanhq -#define BOOST_CSTDFLOAT_FLOAT128_FMOD __fmodq -#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 __atan2q -#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA __lgammaq -#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA __tgammaq -// begin more functions -#define BOOST_CSTDFLOAT_FLOAT128_REMAINDER __remainderq -#define BOOST_CSTDFLOAT_FLOAT128_REMQUO __remquoq -#define BOOST_CSTDFLOAT_FLOAT128_FMA __fmaq -#define BOOST_CSTDFLOAT_FLOAT128_FMAX __fmaxq -#define BOOST_CSTDFLOAT_FLOAT128_FMIN __fminq -#define BOOST_CSTDFLOAT_FLOAT128_FDIM __fdimq -#define BOOST_CSTDFLOAT_FLOAT128_NAN __nanq -//#define BOOST_CSTDFLOAT_FLOAT128_EXP2 __exp2q -#define BOOST_CSTDFLOAT_FLOAT128_LOG2 __log2q -#define BOOST_CSTDFLOAT_FLOAT128_LOG1P __log1pq -#define BOOST_CSTDFLOAT_FLOAT128_CBRT __cbrtq -#define BOOST_CSTDFLOAT_FLOAT128_HYPOT __hypotq -#define BOOST_CSTDFLOAT_FLOAT128_ERF __erfq -#define BOOST_CSTDFLOAT_FLOAT128_ERFC __erfcq -#define BOOST_CSTDFLOAT_FLOAT128_LLROUND __llroundq -#define BOOST_CSTDFLOAT_FLOAT128_LROUND __lroundq -#define BOOST_CSTDFLOAT_FLOAT128_ROUND __roundq -#define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT __nearbyintq -#define BOOST_CSTDFLOAT_FLOAT128_LLRINT __llrintq -#define BOOST_CSTDFLOAT_FLOAT128_LRINT __lrintq -#define BOOST_CSTDFLOAT_FLOAT128_RINT __rintq -#define BOOST_CSTDFLOAT_FLOAT128_MODF __modfq -#define BOOST_CSTDFLOAT_FLOAT128_SCALBLN __scalblnq -#define BOOST_CSTDFLOAT_FLOAT128_SCALBN __scalbnq -#define BOOST_CSTDFLOAT_FLOAT128_ILOGB __ilogbq -#define BOOST_CSTDFLOAT_FLOAT128_LOGB __logbq -#define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER __nextafterq -//#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD __nexttowardq -#define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN __copysignq -#define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT __signbitq -//#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY __fpclassifyq -//#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE __isfiniteq -#define BOOST_CSTDFLOAT_FLOAT128_ISINF __isinfq -#define BOOST_CSTDFLOAT_FLOAT128_ISNAN __isnanq -//#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL __isnormalq -//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER __isgreaterq -//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL __isgreaterequalq -//#define BOOST_CSTDFLOAT_FLOAT128_ISLESS __islessq -//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL __islessequalq -//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER __islessgreaterq -//#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED __isunorderedq -// end more functions -#elif defined(__GNUC__) -#define BOOST_CSTDFLOAT_FLOAT128_LDEXP ldexpq -#define BOOST_CSTDFLOAT_FLOAT128_FREXP frexpq -#define BOOST_CSTDFLOAT_FLOAT128_FABS fabsq -#define BOOST_CSTDFLOAT_FLOAT128_FLOOR floorq -#define BOOST_CSTDFLOAT_FLOAT128_CEIL ceilq -#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT) -#define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq -#endif -#define BOOST_CSTDFLOAT_FLOAT128_TRUNC truncq -#define BOOST_CSTDFLOAT_FLOAT128_POW powq -#define BOOST_CSTDFLOAT_FLOAT128_LOG logq -#define BOOST_CSTDFLOAT_FLOAT128_LOG10 log10q -#define BOOST_CSTDFLOAT_FLOAT128_SIN sinq -#define BOOST_CSTDFLOAT_FLOAT128_COS cosq -#define BOOST_CSTDFLOAT_FLOAT128_TAN tanq -#define BOOST_CSTDFLOAT_FLOAT128_ASIN asinq -#define BOOST_CSTDFLOAT_FLOAT128_ACOS acosq -#define BOOST_CSTDFLOAT_FLOAT128_ATAN atanq -#define BOOST_CSTDFLOAT_FLOAT128_FMOD fmodq -#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 atan2q -#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA lgammaq -#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS) -#define BOOST_CSTDFLOAT_FLOAT128_EXP expq -#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 expm1q -#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq -#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq -#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq -#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq -#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq -#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq -#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq -#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS -#define BOOST_CSTDFLOAT_FLOAT128_EXP expq_patch -#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq_patch -#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq_patch -#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq_patch -#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq_patch -#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq_patch -#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq_patch -#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq_patch -#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS -// begin more functions -#define BOOST_CSTDFLOAT_FLOAT128_REMAINDER remainderq -#define BOOST_CSTDFLOAT_FLOAT128_REMQUO remquoq -#define BOOST_CSTDFLOAT_FLOAT128_FMA fmaq -#define BOOST_CSTDFLOAT_FLOAT128_FMAX fmaxq -#define BOOST_CSTDFLOAT_FLOAT128_FMIN fminq -#define BOOST_CSTDFLOAT_FLOAT128_FDIM fdimq -#define BOOST_CSTDFLOAT_FLOAT128_NAN nanq -//#define BOOST_CSTDFLOAT_FLOAT128_EXP2 exp2q -#define BOOST_CSTDFLOAT_FLOAT128_LOG2 log2q -#define BOOST_CSTDFLOAT_FLOAT128_LOG1P log1pq -#define BOOST_CSTDFLOAT_FLOAT128_CBRT cbrtq -#define BOOST_CSTDFLOAT_FLOAT128_HYPOT hypotq -#define BOOST_CSTDFLOAT_FLOAT128_ERF erfq -#define BOOST_CSTDFLOAT_FLOAT128_ERFC erfcq -#define BOOST_CSTDFLOAT_FLOAT128_LLROUND llroundq -#define BOOST_CSTDFLOAT_FLOAT128_LROUND lroundq -#define BOOST_CSTDFLOAT_FLOAT128_ROUND roundq -#define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT nearbyintq -#define BOOST_CSTDFLOAT_FLOAT128_LLRINT llrintq -#define BOOST_CSTDFLOAT_FLOAT128_LRINT lrintq -#define BOOST_CSTDFLOAT_FLOAT128_RINT rintq -#define BOOST_CSTDFLOAT_FLOAT128_MODF modfq -#define BOOST_CSTDFLOAT_FLOAT128_SCALBLN scalblnq -#define BOOST_CSTDFLOAT_FLOAT128_SCALBN scalbnq -#define BOOST_CSTDFLOAT_FLOAT128_ILOGB ilogbq -#define BOOST_CSTDFLOAT_FLOAT128_LOGB logbq -#define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER nextafterq -//#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD nexttowardq -#define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN copysignq -#define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT signbitq -//#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY fpclassifyq -//#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE isfiniteq -#define BOOST_CSTDFLOAT_FLOAT128_ISINF isinfq -#define BOOST_CSTDFLOAT_FLOAT128_ISNAN isnanq -//#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL isnormalq -//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER isgreaterq -//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL isgreaterequalq -//#define BOOST_CSTDFLOAT_FLOAT128_ISLESS islessq -//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL islessequalq -//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER islessgreaterq -//#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED isunorderedq -// end more functions -#endif - -// Implement quadruple-precision <cmath> functions in the namespace -// boost::math::cstdfloat::detail. Subsequently inject these into the -// std namespace via *using* directive. - -// Begin with some forward function declarations. Also implement patches -// for compilers that have broken float128 exponential functions. - -extern "C" int quadmath_snprintf(char*, std::size_t, const char*, ...) throw(); - -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LDEXP(boost::math::cstdfloat::detail::float_internal128_t, int) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FREXP(boost::math::cstdfloat::detail::float_internal128_t, int*) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FABS(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FLOOR(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CEIL(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TRUNC(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG10(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SIN(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COS(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TAN(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASIN(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOS(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN(boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMOD(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN2(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LGAMMA(boost::math::cstdfloat::detail::float_internal128_t) noexcept; - -// begin more functions -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMAINDER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMQUO(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, int*) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMA(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMAX(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMIN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FDIM(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NAN(const char*) throw(); -//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP2 (boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG2(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG1P(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CBRT(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_HYPOT(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERF(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERFC(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLROUND(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LROUND(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ROUND(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLRINT(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LRINT(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_RINT(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_MODF(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t*) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBLN(boost::math::cstdfloat::detail::float_internal128_t, long int) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBN(boost::math::cstdfloat::detail::float_internal128_t, int) throw(); -extern "C" int BOOST_CSTDFLOAT_FLOAT128_ILOGB(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOGB(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" int BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY (boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISFINITE (boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISINF(boost::math::cstdfloat::detail::float_internal128_t) throw(); -extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISNAN(boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ISNORMAL (boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATER (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESS (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); -//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw(); - // end more functions - -#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS) - -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; -extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) noexcept; - -#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS - -// Forward declaration of the patched exponent function, exp(x). -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x); - -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) -{ - // Compute exp(x) - 1 for x small. - - // Use an order-12 Pade approximation of the exponential function. - // PadeApproximant[Exp[x] - 1, {x, 0, 12, 12}]. - - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - - float_type sum; - - if (x > BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255)) - { - sum = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x) - float_type(1); - } - else - { - const float_type x2 = (x * x); - - const float_type top = ((((( float_type(BOOST_FLOAT128_C(2.4087176110456818621091195109360728010934088788572E-13)) * x2 - + float_type(BOOST_FLOAT128_C(9.2735628025258751691201101171038802842096241836000E-10))) * x2 - + float_type(BOOST_FLOAT128_C(9.0806726962333369656024118266681195742980640005812E-07))) * x2 - + float_type(BOOST_FLOAT128_C(3.1055900621118012422360248447204968944099378881988E-04))) * x2 - + float_type(BOOST_FLOAT128_C(3.6231884057971014492753623188405797101449275362319E-02))) * x2 - + float_type(BOOST_FLOAT128_C(1.00000000000000000000000000000000000000000000000000000))) - ; - - const float_type bot = (((((((((((( float_type(BOOST_FLOAT128_C(+7.7202487533515444298369215094104897470942592271063E-16)) * x - + float_type(BOOST_FLOAT128_C(-1.2043588055228409310545597554680364005467044394286E-13))) * x - + float_type(BOOST_FLOAT128_C(+9.2735628025258751691201101171038802842096241836000E-12))) * x - + float_type(BOOST_FLOAT128_C(-4.6367814012629375845600550585519401421048120918000E-10))) * x - + float_type(BOOST_FLOAT128_C(+1.6692413044546575304416198210786984511577323530480E-08))) * x - + float_type(BOOST_FLOAT128_C(-4.5403363481166684828012059133340597871490320002906E-07))) * x - + float_type(BOOST_FLOAT128_C(+9.5347063310450038138825324180015255530129672006102E-06))) * x - + float_type(BOOST_FLOAT128_C(-1.5527950310559006211180124223602484472049689440994E-04))) * x - + float_type(BOOST_FLOAT128_C(+1.9409937888198757763975155279503105590062111801242E-03))) * x - + float_type(BOOST_FLOAT128_C(-1.8115942028985507246376811594202898550724637681159E-02))) * x - + float_type(BOOST_FLOAT128_C(+1.1956521739130434782608695652173913043478260869565E-01))) * x - + float_type(BOOST_FLOAT128_C(-0.50000000000000000000000000000000000000000000000000000))) * x - + float_type(BOOST_FLOAT128_C(+1.00000000000000000000000000000000000000000000000000000))) - ; - - sum = (x * top) / bot; - } - - return sum; -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) -{ - // Patch the expq() function for a subset of broken GCC compilers - // like GCC 4.7, 4.8 on MinGW. - - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - - // Scale the argument x to the range (-ln2 < x < ln2). - constexpr float_type one_over_ln2 = float_type(BOOST_FLOAT128_C(1.44269504088896340735992468100189213742664595415299)); - const float_type x_over_ln2 = x * one_over_ln2; - - int n; - - if (x != x) - { - // The argument is NaN. - return std::numeric_limits<float_type>::quiet_NaN(); - } - else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) > BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255)) - { - // The absolute value of the argument exceeds ln2. - n = static_cast<int>(::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x_over_ln2)); - } - else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255)) - { - // The absolute value of the argument is less than ln2. - n = 0; - } - else - { - // The absolute value of the argument is exactly equal to ln2 (in the sense of floating-point equality). - return float_type(2); - } - - // Check if the argument is very near an integer. - const float_type floor_of_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); - - if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x - floor_of_x) < float_type(BOOST_CSTDFLOAT_FLOAT128_EPS)) - { - // Return e^n for arguments very near an integer. - return boost::math::cstdfloat::detail::pown(BOOST_FLOAT128_C(2.71828182845904523536028747135266249775724709369996), static_cast<std::int_fast32_t>(floor_of_x)); - } - - // Compute the scaled argument alpha. - const float_type alpha = x - (n * BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255)); - - // Compute the polynomial approximation of expm1(alpha) and add to it - // in order to obtain the scaled result. - const float_type scaled_result = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(alpha) + float_type(1); - - // Rescale the result and return it. - return scaled_result * boost::math::cstdfloat::detail::pown(float_type(2), n); -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) -{ - // Patch the sinhq() function for a subset of broken GCC compilers - // like GCC 4.7, 4.8 on MinGW. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - - // Here, we use the following: - // Set: ex = exp(x) - // Set: em1 = expm1(x) - // Then - // sinh(x) = (ex - 1/ex) / 2 ; for |x| >= 1 - // sinh(x) = (2em1 + em1^2) / (2ex) ; for |x| < 1 - - const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); - - if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < float_type(+1)) - { - const float_type em1 = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); - - return ((em1 * 2) + (em1 * em1)) / (ex * 2); - } - else - { - return (ex - (float_type(1) / ex)) / 2; - } -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) -{ - // Patch the coshq() function for a subset of broken GCC compilers - // like GCC 4.7, 4.8 on MinGW. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); - return (ex + (float_type(1) / ex)) / 2; -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) -{ - // Patch the tanhq() function for a subset of broken GCC compilers - // like GCC 4.7, 4.8 on MinGW. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - const float_type ex_plus = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); - const float_type ex_minus = (float_type(1) / ex_plus); - return (ex_plus - ex_minus) / (ex_plus + ex_minus); -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept -{ - // Patch the asinh() function since quadmath does not have it. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + ::BOOST_CSTDFLOAT_FLOAT128_SQRT((x * x) + float_type(1))); -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept -{ - // Patch the acosh() function since quadmath does not have it. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - const float_type zp(x + float_type(1)); - const float_type zm(x - float_type(1)); - - return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + (zp * ::BOOST_CSTDFLOAT_FLOAT128_SQRT(zm / zp))); -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) noexcept -{ - // Patch the atanh() function since quadmath does not have it. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - return (::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) + x) - - ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) - x)) / 2; -} -inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) noexcept -{ - // Patch the tgammaq() function for a subset of broken GCC compilers - // like GCC 4.7, 4.8 on MinGW. - typedef boost::math::cstdfloat::detail::float_internal128_t float_type; - - if (x > float_type(0)) - { - return ::BOOST_CSTDFLOAT_FLOAT128_EXP(::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x)); - } - else if (x < float_type(0)) - { - // For x < 0, compute tgamma(-x) and use the reflection formula. - const float_type positive_x = -x; - float_type gamma_value = ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(positive_x); - const float_type floor_of_positive_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x); - - // Take the reflection checks (slightly adapted) from <boost/math/gamma.hpp>. - const bool floor_of_z_is_equal_to_z = (positive_x == ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x)); - - constexpr float_type my_pi = BOOST_FLOAT128_C(3.14159265358979323846264338327950288419716939937511); - - if (floor_of_z_is_equal_to_z) - { - const bool is_odd = ((std::int32_t(floor_of_positive_x) % std::int32_t(2)) != std::int32_t(0)); - - return (is_odd ? -std::numeric_limits<float_type>::infinity() - : +std::numeric_limits<float_type>::infinity()); - } - - const float_type sinpx_value = x * ::BOOST_CSTDFLOAT_FLOAT128_SIN(my_pi * x); - - gamma_value *= sinpx_value; - - const bool result_is_too_large_to_represent = ((::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value) < float_type(1)) - && (((std::numeric_limits<float_type>::max)() * ::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value)) < my_pi)); - - if (result_is_too_large_to_represent) - { - const bool is_odd = ((std::int32_t(floor_of_positive_x) % std::int32_t(2)) != std::int32_t(0)); - - return (is_odd ? -std::numeric_limits<float_type>::infinity() - : +std::numeric_limits<float_type>::infinity()); - } - - gamma_value = -my_pi / gamma_value; - - if ((gamma_value > float_type(0)) || (gamma_value < float_type(0))) - { - return gamma_value; - } - else - { - // The value of gamma is too small to represent. Return 0.0 here. - return float_type(0); - } - } - else - { - // Gamma of zero is complex infinity. Return NaN here. - return std::numeric_limits<float_type>::quiet_NaN(); - } -} -#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS - -// Define the quadruple-precision <cmath> functions in the namespace boost::math::cstdfloat::detail. - -namespace boost { - namespace math { - namespace cstdfloat { - namespace detail { - inline boost::math::cstdfloat::detail::float_internal128_t ldexp(boost::math::cstdfloat::detail::float_internal128_t x, int n) { return ::BOOST_CSTDFLOAT_FLOAT128_LDEXP(x, n); } - inline boost::math::cstdfloat::detail::float_internal128_t frexp(boost::math::cstdfloat::detail::float_internal128_t x, int* pn) { return ::BOOST_CSTDFLOAT_FLOAT128_FREXP(x, pn); } - inline boost::math::cstdfloat::detail::float_internal128_t fabs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); } - inline boost::math::cstdfloat::detail::float_internal128_t abs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); } - inline boost::math::cstdfloat::detail::float_internal128_t floor(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); } - inline boost::math::cstdfloat::detail::float_internal128_t ceil(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CEIL(x); } - inline boost::math::cstdfloat::detail::float_internal128_t sqrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x); } - inline boost::math::cstdfloat::detail::float_internal128_t trunc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TRUNC(x); } - inline boost::math::cstdfloat::detail::float_internal128_t exp(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); } - inline boost::math::cstdfloat::detail::float_internal128_t expm1(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); } - inline boost::math::cstdfloat::detail::float_internal128_t pow(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW(x, a); } - inline boost::math::cstdfloat::detail::float_internal128_t pow(boost::math::cstdfloat::detail::float_internal128_t x, int a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW(x, boost::math::cstdfloat::detail::float_internal128_t(a)); } - inline boost::math::cstdfloat::detail::float_internal128_t log(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x); } - inline boost::math::cstdfloat::detail::float_internal128_t log10(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG10(x); } - inline boost::math::cstdfloat::detail::float_internal128_t sin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIN(x); } - inline boost::math::cstdfloat::detail::float_internal128_t cos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COS(x); } - inline boost::math::cstdfloat::detail::float_internal128_t tan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TAN(x); } - inline boost::math::cstdfloat::detail::float_internal128_t asin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASIN(x); } - inline boost::math::cstdfloat::detail::float_internal128_t acos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOS(x); } - inline boost::math::cstdfloat::detail::float_internal128_t atan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN(x); } - inline boost::math::cstdfloat::detail::float_internal128_t sinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SINH(x); } - inline boost::math::cstdfloat::detail::float_internal128_t cosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COSH(x); } - inline boost::math::cstdfloat::detail::float_internal128_t tanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TANH(x); } - inline boost::math::cstdfloat::detail::float_internal128_t asinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASINH(x); } - inline boost::math::cstdfloat::detail::float_internal128_t acosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOSH(x); } - inline boost::math::cstdfloat::detail::float_internal128_t atanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATANH(x); } - inline boost::math::cstdfloat::detail::float_internal128_t fmod(boost::math::cstdfloat::detail::float_internal128_t a, boost::math::cstdfloat::detail::float_internal128_t b) { return ::BOOST_CSTDFLOAT_FLOAT128_FMOD(a, b); } - inline boost::math::cstdfloat::detail::float_internal128_t atan2(boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN2(y, x); } - inline boost::math::cstdfloat::detail::float_internal128_t lgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x); } - inline boost::math::cstdfloat::detail::float_internal128_t tgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(x); } - // begin more functions - inline boost::math::cstdfloat::detail::float_internal128_t remainder(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_REMAINDER(x, y); } - inline boost::math::cstdfloat::detail::float_internal128_t remquo(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, int* z) { return ::BOOST_CSTDFLOAT_FLOAT128_REMQUO(x, y, z); } - inline boost::math::cstdfloat::detail::float_internal128_t fma(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return BOOST_CSTDFLOAT_FLOAT128_FMA(x, y, z); } - - inline boost::math::cstdfloat::detail::float_internal128_t fmax(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - fmax(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - fmax(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } - inline boost::math::cstdfloat::detail::float_internal128_t fmin(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - fmin(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - fmin(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } - - inline boost::math::cstdfloat::detail::float_internal128_t fdim(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FDIM(x, y); } - inline boost::math::cstdfloat::detail::float_internal128_t nanq(const char* x) { return ::BOOST_CSTDFLOAT_FLOAT128_NAN(x); } - inline boost::math::cstdfloat::detail::float_internal128_t exp2(boost::math::cstdfloat::detail::float_internal128_t x) - { - return ::BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t(2), x); - } - inline boost::math::cstdfloat::detail::float_internal128_t log2(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG2(x); } - inline boost::math::cstdfloat::detail::float_internal128_t log1p(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG1P(x); } - inline boost::math::cstdfloat::detail::float_internal128_t cbrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CBRT(x); } - inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x*x + y * y + z * z); } - inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - hypot(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - hypot(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } - - - inline boost::math::cstdfloat::detail::float_internal128_t erf(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERF(x); } - inline boost::math::cstdfloat::detail::float_internal128_t erfc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERFC(x); } - inline long long int llround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLROUND(x); } - inline long int lround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LROUND(x); } - inline boost::math::cstdfloat::detail::float_internal128_t round(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ROUND(x); } - inline boost::math::cstdfloat::detail::float_internal128_t nearbyint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(x); } - inline long long int llrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLRINT(x); } - inline long int lrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LRINT(x); } - inline boost::math::cstdfloat::detail::float_internal128_t rint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_RINT(x); } - inline boost::math::cstdfloat::detail::float_internal128_t modf(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t* y) { return ::BOOST_CSTDFLOAT_FLOAT128_MODF(x, y); } - inline boost::math::cstdfloat::detail::float_internal128_t scalbln(boost::math::cstdfloat::detail::float_internal128_t x, long int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBLN(x, y); } - inline boost::math::cstdfloat::detail::float_internal128_t scalbn(boost::math::cstdfloat::detail::float_internal128_t x, int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBN(x, y); } - inline int ilogb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ILOGB(x); } - inline boost::math::cstdfloat::detail::float_internal128_t logb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOGB(x); } - inline boost::math::cstdfloat::detail::float_internal128_t nextafter(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(x, y); } - inline boost::math::cstdfloat::detail::float_internal128_t nexttoward(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return -(::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(-x, -y)); } - inline boost::math::cstdfloat::detail::float_internal128_t copysign BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(x, y); } - inline bool signbit BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(x); } - inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) - { - if (::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x)) - return FP_NAN; - else if (::BOOST_CSTDFLOAT_FLOAT128_ISINF(x)) - return FP_INFINITE; - else if (x == BOOST_FLOAT128_C(0.0)) - return FP_ZERO; - - if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_CSTDFLOAT_FLOAT128_MIN) - return FP_SUBNORMAL; - else - return FP_NORMAL; - } - inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) - { - return !::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) && !::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); - } - inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); } - inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x); } - inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return boost::math::cstdfloat::detail::fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(x) == FP_NORMAL; } - inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) - { - if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) - return false; - return x > y; - } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } - - inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) - { - if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) - return false; - return x >= y; - } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } - - inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) - { - if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) - return false; - return x < y; - } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isless BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isless BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isless BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isless BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } - - - inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) - { - if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) - return false; - return x <= y; - } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } - - - inline bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) - { - if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) - return false; - return (x < y) || (x > y); - } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } - - - inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) || ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } - template <class T> - inline typename std::enable_if< - std::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value - && !std::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type - isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } - - - // end more functions - } - } - } -} // boost::math::cstdfloat::detail - -// We will now inject the quadruple-precision <cmath> functions -// into the std namespace. This is done via *using* directive. -namespace std -{ - using boost::math::cstdfloat::detail::ldexp; - using boost::math::cstdfloat::detail::frexp; - using boost::math::cstdfloat::detail::fabs; - -#if !(defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && (__GNUC__ >= 7)) -#if (defined(__clang__) && !(!defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128))) || (__GNUC__ <= 6 && !defined(__clang__)) - // workaround for clang using libstdc++ and old GCC - using boost::math::cstdfloat::detail::abs; -#endif -#endif - - using boost::math::cstdfloat::detail::floor; - using boost::math::cstdfloat::detail::ceil; - using boost::math::cstdfloat::detail::sqrt; - using boost::math::cstdfloat::detail::trunc; - using boost::math::cstdfloat::detail::exp; - using boost::math::cstdfloat::detail::expm1; - using boost::math::cstdfloat::detail::pow; - using boost::math::cstdfloat::detail::log; - using boost::math::cstdfloat::detail::log10; - using boost::math::cstdfloat::detail::sin; - using boost::math::cstdfloat::detail::cos; - using boost::math::cstdfloat::detail::tan; - using boost::math::cstdfloat::detail::asin; - using boost::math::cstdfloat::detail::acos; - using boost::math::cstdfloat::detail::atan; - using boost::math::cstdfloat::detail::sinh; - using boost::math::cstdfloat::detail::cosh; - using boost::math::cstdfloat::detail::tanh; - using boost::math::cstdfloat::detail::asinh; - using boost::math::cstdfloat::detail::acosh; - using boost::math::cstdfloat::detail::atanh; - using boost::math::cstdfloat::detail::fmod; - using boost::math::cstdfloat::detail::atan2; - using boost::math::cstdfloat::detail::lgamma; - using boost::math::cstdfloat::detail::tgamma; - - // begin more functions - using boost::math::cstdfloat::detail::remainder; - using boost::math::cstdfloat::detail::remquo; - using boost::math::cstdfloat::detail::fma; - using boost::math::cstdfloat::detail::fmax; - using boost::math::cstdfloat::detail::fmin; - using boost::math::cstdfloat::detail::fdim; - using boost::math::cstdfloat::detail::nanq; - using boost::math::cstdfloat::detail::exp2; - using boost::math::cstdfloat::detail::log2; - using boost::math::cstdfloat::detail::log1p; - using boost::math::cstdfloat::detail::cbrt; - using boost::math::cstdfloat::detail::hypot; - using boost::math::cstdfloat::detail::erf; - using boost::math::cstdfloat::detail::erfc; - using boost::math::cstdfloat::detail::llround; - using boost::math::cstdfloat::detail::lround; - using boost::math::cstdfloat::detail::round; - using boost::math::cstdfloat::detail::nearbyint; - using boost::math::cstdfloat::detail::llrint; - using boost::math::cstdfloat::detail::lrint; - using boost::math::cstdfloat::detail::rint; - using boost::math::cstdfloat::detail::modf; - using boost::math::cstdfloat::detail::scalbln; - using boost::math::cstdfloat::detail::scalbn; - using boost::math::cstdfloat::detail::ilogb; - using boost::math::cstdfloat::detail::logb; - using boost::math::cstdfloat::detail::nextafter; - using boost::math::cstdfloat::detail::nexttoward; - using boost::math::cstdfloat::detail::copysign; - using boost::math::cstdfloat::detail::signbit; - using boost::math::cstdfloat::detail::fpclassify; - using boost::math::cstdfloat::detail::isfinite; - using boost::math::cstdfloat::detail::isinf; - using boost::math::cstdfloat::detail::isnan; - using boost::math::cstdfloat::detail::isnormal; - using boost::math::cstdfloat::detail::isgreater; - using boost::math::cstdfloat::detail::isgreaterequal; - using boost::math::cstdfloat::detail::isless; - using boost::math::cstdfloat::detail::islessequal; - using boost::math::cstdfloat::detail::islessgreater; - using boost::math::cstdfloat::detail::isunordered; - // end more functions - - // - // Very basic iostream operator: - // - inline std::ostream& operator << (std::ostream& os, __float128 m_value) - { - std::streamsize digits = os.precision(); - std::ios_base::fmtflags f = os.flags(); - std::string s; - - char buf[100]; - std::unique_ptr<char[]> buf2; - std::string format = "%"; - if (f & std::ios_base::showpos) - format += "+"; - if (f & std::ios_base::showpoint) - format += "#"; - format += ".*"; - if (digits == 0) - digits = 36; - format += "Q"; - if (f & std::ios_base::scientific) - format += "e"; - else if (f & std::ios_base::fixed) - format += "f"; - else - format += "g"; - - int v = quadmath_snprintf(buf, 100, format.c_str(), digits, m_value); - - if ((v < 0) || (v >= 99)) - { - int v_max = v; - buf2.reset(new char[v + 3]); - v = quadmath_snprintf(&buf2[0], v_max + 3, format.c_str(), digits, m_value); - if (v >= v_max + 3) - { - BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed.")); - } - s = &buf2[0]; - } - else - s = buf; - std::streamsize ss = os.width(); - if (ss > static_cast<std::streamsize>(s.size())) - { - char fill = os.fill(); - if ((os.flags() & std::ios_base::left) == std::ios_base::left) - s.append(static_cast<std::string::size_type>(ss - s.size()), fill); - else - s.insert(static_cast<std::string::size_type>(0), static_cast<std::string::size_type>(ss - s.size()), fill); - } - - return os << s; - } - - -} // namespace std - -// We will now remove the preprocessor symbols representing quadruple-precision <cmath> -// functions from the preprocessor. - -#undef BOOST_CSTDFLOAT_FLOAT128_LDEXP -#undef BOOST_CSTDFLOAT_FLOAT128_FREXP -#undef BOOST_CSTDFLOAT_FLOAT128_FABS -#undef BOOST_CSTDFLOAT_FLOAT128_FLOOR -#undef BOOST_CSTDFLOAT_FLOAT128_CEIL -#undef BOOST_CSTDFLOAT_FLOAT128_SQRT -#undef BOOST_CSTDFLOAT_FLOAT128_TRUNC -#undef BOOST_CSTDFLOAT_FLOAT128_EXP -#undef BOOST_CSTDFLOAT_FLOAT128_EXPM1 -#undef BOOST_CSTDFLOAT_FLOAT128_POW -#undef BOOST_CSTDFLOAT_FLOAT128_LOG -#undef BOOST_CSTDFLOAT_FLOAT128_LOG10 -#undef BOOST_CSTDFLOAT_FLOAT128_SIN -#undef BOOST_CSTDFLOAT_FLOAT128_COS -#undef BOOST_CSTDFLOAT_FLOAT128_TAN -#undef BOOST_CSTDFLOAT_FLOAT128_ASIN -#undef BOOST_CSTDFLOAT_FLOAT128_ACOS -#undef BOOST_CSTDFLOAT_FLOAT128_ATAN -#undef BOOST_CSTDFLOAT_FLOAT128_SINH -#undef BOOST_CSTDFLOAT_FLOAT128_COSH -#undef BOOST_CSTDFLOAT_FLOAT128_TANH -#undef BOOST_CSTDFLOAT_FLOAT128_ASINH -#undef BOOST_CSTDFLOAT_FLOAT128_ACOSH -#undef BOOST_CSTDFLOAT_FLOAT128_ATANH -#undef BOOST_CSTDFLOAT_FLOAT128_FMOD -#undef BOOST_CSTDFLOAT_FLOAT128_ATAN2 -#undef BOOST_CSTDFLOAT_FLOAT128_LGAMMA -#undef BOOST_CSTDFLOAT_FLOAT128_TGAMMA - -// begin more functions -#undef BOOST_CSTDFLOAT_FLOAT128_REMAINDER -#undef BOOST_CSTDFLOAT_FLOAT128_REMQUO -#undef BOOST_CSTDFLOAT_FLOAT128_FMA -#undef BOOST_CSTDFLOAT_FLOAT128_FMAX -#undef BOOST_CSTDFLOAT_FLOAT128_FMIN -#undef BOOST_CSTDFLOAT_FLOAT128_FDIM -#undef BOOST_CSTDFLOAT_FLOAT128_NAN -#undef BOOST_CSTDFLOAT_FLOAT128_EXP2 -#undef BOOST_CSTDFLOAT_FLOAT128_LOG2 -#undef BOOST_CSTDFLOAT_FLOAT128_LOG1P -#undef BOOST_CSTDFLOAT_FLOAT128_CBRT -#undef BOOST_CSTDFLOAT_FLOAT128_HYPOT -#undef BOOST_CSTDFLOAT_FLOAT128_ERF -#undef BOOST_CSTDFLOAT_FLOAT128_ERFC -#undef BOOST_CSTDFLOAT_FLOAT128_LLROUND -#undef BOOST_CSTDFLOAT_FLOAT128_LROUND -#undef BOOST_CSTDFLOAT_FLOAT128_ROUND -#undef BOOST_CSTDFLOAT_FLOAT128_NEARBYINT -#undef BOOST_CSTDFLOAT_FLOAT128_LLRINT -#undef BOOST_CSTDFLOAT_FLOAT128_LRINT -#undef BOOST_CSTDFLOAT_FLOAT128_RINT -#undef BOOST_CSTDFLOAT_FLOAT128_MODF -#undef BOOST_CSTDFLOAT_FLOAT128_SCALBLN -#undef BOOST_CSTDFLOAT_FLOAT128_SCALBN -#undef BOOST_CSTDFLOAT_FLOAT128_ILOGB -#undef BOOST_CSTDFLOAT_FLOAT128_LOGB -#undef BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER -#undef BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD -#undef BOOST_CSTDFLOAT_FLOAT128_COPYSIGN -#undef BOOST_CSTDFLOAT_FLOAT128_SIGNBIT -#undef BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY -#undef BOOST_CSTDFLOAT_FLOAT128_ISFINITE -#undef BOOST_CSTDFLOAT_FLOAT128_ISINF -#undef BOOST_CSTDFLOAT_FLOAT128_ISNAN -#undef BOOST_CSTDFLOAT_FLOAT128_ISNORMAL -#undef BOOST_CSTDFLOAT_FLOAT128_ISGREATER -#undef BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL -#undef BOOST_CSTDFLOAT_FLOAT128_ISLESS -#undef BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL -#undef BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER -#undef BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED -// end more functions - -#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) - -#endif // BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ - diff --git a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex.hpp b/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex.hpp deleted file mode 100644 index f79ff6d423..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// Implement quadruple-precision (and extended) support for <complex>. - -#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ - #define BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ - - #include <boost/math/cstdfloat/cstdfloat_types.hpp> - #include <boost/math/cstdfloat/cstdfloat_limits.hpp> - #include <boost/math/cstdfloat/cstdfloat_cmath.hpp> - #include <boost/math/cstdfloat/cstdfloat_iostream.hpp> - - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) - #error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined. - #endif - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) - #error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. - #endif - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) - #error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined. - #endif - - #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) - - #define BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE boost::math::cstdfloat::detail::float_internal128_t - #include <boost/math/cstdfloat/cstdfloat_complex_std.hpp> - #undef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE - - #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) - -#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ diff --git a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp b/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp deleted file mode 100644 index a4007ee186..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp +++ /dev/null @@ -1,813 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// Implement a specialization of std::complex<> for *anything* that -// is defined as BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE. - -#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ - #define BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ - - #if defined(__GNUC__) - #pragma GCC system_header - #endif - - #include <complex> - #include <boost/math/constants/constants.hpp> - #include <boost/math/tools/cxx03_warn.hpp> - - namespace std - { - // Forward declarations. - template<class float_type> - class complex; - - template<> - class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>; - - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& = 0); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&, - int); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&, - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&, - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - template<class char_type, class traits_type> - inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>&, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - template<class char_type, class traits_type> - inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>&, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&); - - // Template specialization of the complex class. - template<> - class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - { - public: - typedef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE value_type; - - complex(const complex<float>&); - complex(const complex<double>&); - complex(const complex<long double>&); - - #if defined(BOOST_NO_CXX11_CONSTEXPR) - complex(const value_type& r = value_type(), - const value_type& i = value_type()) : re(r), - im(i) { } - - template<typename X> - explicit complex(const complex<X>& x) : re(x.real()), - im(x.imag()) { } - - const value_type& real() const { return re; } - const value_type& imag() const { return im; } - - value_type& real() { return re; } - value_type& imag() { return im; } - #else - constexpr complex(const value_type& r = value_type(), - const value_type& i = value_type()) : re(r), - im(i) { } - - template<typename X> - explicit constexpr complex(const complex<X>& x) : re(x.real()), - im(x.imag()) { } - - value_type real() const { return re; } - value_type imag() const { return im; } - #endif - - void real(value_type r) { re = r; } - void imag(value_type i) { im = i; } - - complex<value_type>& operator=(const value_type& v) - { - re = v; - im = value_type(0); - return *this; - } - - complex<value_type>& operator+=(const value_type& v) - { - re += v; - return *this; - } - - complex<value_type>& operator-=(const value_type& v) - { - re -= v; - return *this; - } - - complex<value_type>& operator*=(const value_type& v) - { - re *= v; - im *= v; - return *this; - } - - complex<value_type>& operator/=(const value_type& v) - { - re /= v; - im /= v; - return *this; - } - - template<typename X> - complex<value_type>& operator=(const complex<X>& x) - { - re = x.real(); - im = x.imag(); - return *this; - } - - template<typename X> - complex<value_type>& operator+=(const complex<X>& x) - { - re += x.real(); - im += x.imag(); - return *this; - } - - template<typename X> - complex<value_type>& operator-=(const complex<X>& x) - { - re -= x.real(); - im -= x.imag(); - return *this; - } - - template<typename X> - complex<value_type>& operator*=(const complex<X>& x) - { - const value_type tmp_real = (re * x.real()) - (im * x.imag()); - im = (re * x.imag()) + (im * x.real()); - re = tmp_real; - return *this; - } - - template<typename X> - complex<value_type>& operator/=(const complex<X>& x) - { - const value_type tmp_real = (re * x.real()) + (im * x.imag()); - const value_type the_norm = std::norm(x); - im = ((im * x.real()) - (re * x.imag())) / the_norm; - re = tmp_real / the_norm; - return *this; - } - - private: - value_type re; - value_type im; - }; - - // Constructors from built-in complex representation of floating-point types. - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<float>& f) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.imag())) { } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<double>& d) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.imag())) { } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<long double>& ld) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.imag())) { } - } // namespace std - - namespace boost { namespace math { namespace cstdfloat { namespace detail { - template<class float_type> inline std::complex<float_type> multiply_by_i(const std::complex<float_type>& x) - { - // Multiply x (in C) by I (the imaginary component), and return the result. - return std::complex<float_type>(-x.imag(), x.real()); - } - } } } } // boost::math::cstdfloat::detail - - namespace std - { - // ISO/IEC 14882:2011, Section 26.4.7, specific values. - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.real(); } - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.imag(); } - - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::sqrt; return sqrt ((real(x) * real(x)) + (imag(x) * imag(x))); } - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::atan2; return atan2(x.imag(), x.real()); } - inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return (real(x) * real(x)) + (imag(x) * imag(x)); } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x.real(), -x.imag()); } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE m = (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)(); - if ( (x.real() > m) - || (x.real() < -m) - || (x.imag() > m) - || (x.imag() < -m)) - { - // We have an infinity, return a normalized infinity, respecting the sign of the imaginary part: - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), x.imag() < 0 ? -0 : 0); - } - return x; - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& rho, - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& theta) - { - using std::sin; - using std::cos; - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rho * cos(theta), rho * sin(theta)); - } - - // Global add, sub, mul, div. - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v.real(), u.imag() + v.imag()); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v.real(), u.imag() - v.imag()); } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) - { - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u.real() * v.real()) - (u.imag() * v.imag()), - (u.real() * v.imag()) + (u.imag() * v.real())); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE the_norm = std::norm(v); - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(((u.real() * v.real()) + (u.imag() * v.imag())) / the_norm, - ((u.imag() * v.real()) - (u.real() * v.imag())) / the_norm); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v, u.imag()); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v, u.imag()); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() * v, u.imag() * v); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() / v, u.imag() / v); } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u + v.real(), v.imag()); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u - v.real(), -v.imag()); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u * v.real(), u * v.imag()); } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE v_norm = norm(v); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u * v.real()) / v_norm, (-u * v.imag()) / v_norm); } - - // Unary plus / minus. - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return u; } - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(-u.real(), -u.imag()); } - - // Equality and inequality. - inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() == y.real()) && (x.imag() == y.imag())); } - inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() == y) && (x.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } - inline bool operator==(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x == y.real()) && (y.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } - inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() != y.real()) || (x.imag() != y.imag())); } - inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() != y) || (x.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } - inline bool operator!=(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x != y.real()) || (y.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } - - // ISO/IEC 14882:2011, Section 26.4.8, transcendentals. - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::fabs; - using std::sqrt; - - // Compute sqrt(x) for x in C: - // sqrt(x) = (s , xi / 2s) : for xr > 0, - // (|xi| / 2s, +-s) : for xr < 0, - // (sqrt(xi), sqrt(xi) : for xr = 0, - // where s = sqrt{ [ |xr| + sqrt(xr^2 + xi^2) ] / 2 }, - // and the +- sign is the same as the sign of xi. - - if(x.real() > 0) - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(s, x.imag() / (s * 2)); - } - else if(x.real() < 0) - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); - - const bool imag_is_neg = (x.imag() < 0); - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); - } - else - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sqrt_xi_half, sqrt_xi_half); - } - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::sin; - using std::cos; - using std::exp; - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::sin; - using std::cos; - using std::exp; - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -(sin_x * sinh_y)); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::sin; - using std::cos; - using std::exp; - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; - - return ( complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y) - / complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -sin_x * sinh_y)); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - return -boost::math::cstdfloat::detail::multiply_by_i(std::log(boost::math::cstdfloat::detail::multiply_by_i(x) + std::sqrt(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - (x * x)))); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - return boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>() - std::asin(x); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> izz = boost::math::cstdfloat::detail::multiply_by_i(x); - - return boost::math::cstdfloat::detail::multiply_by_i(std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - izz) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + izz)) / 2; - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::exp; - - return std::polar(exp(x.real()), x.imag()); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::atan2; - using std::log; - - const bool re_isneg = (x.real() < 0); - const bool re_isnan = (x.real() != x.real()); - const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - const bool im_isneg = (x.imag() < 0); - const bool im_isnan = (x.imag() != x.imag()); - const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - if(re_isnan || im_isnan) { return x; } - - if(re_isinf || im_isinf) - { - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), - BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0)); - } - - const bool re_iszero = ((re_isneg || (x.real() > 0)) == false); - - if(re_iszero) - { - const bool im_iszero = ((im_isneg || (x.imag() > 0)) == false); - - if(im_iszero) - { - return std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), - BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0) - ); - } - else - { - if(im_isneg == false) - { - return std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - log(x.imag()), - boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>() - ); - } - else - { - return std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - log(-x.imag()), - -boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>() - ); - } - } - } - else - { - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(log(std::norm(x)) / 2, atan2(x.imag(), x.real())); - } - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - return std::log(x) / boost::math::constants::ln_ten<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, - int p) - { - const bool re_isneg = (x.real() < 0); - const bool re_isnan = (x.real() != x.real()); - const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - const bool im_isneg = (x.imag() < 0); - const bool im_isnan = (x.imag() != x.imag()); - const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - if(re_isnan || im_isnan) { return x; } - - if(re_isinf || im_isinf) - { - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(), - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN()); - } - - if(p < 0) - { - if(std::abs(x) < (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::min)()) - { - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()); - } - else - { - return BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / std::pow(x, -p); - } - } - - if(p == 0) - { - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)); - } - else - { - if(p == 1) { return x; } - - if(std::abs(x) > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE re = (re_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity() - : +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()); - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE im = (im_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity() - : +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()); - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(re, im); - } - - if (p == 2) { return (x * x); } - else if(p == 3) { return ((x * x) * x); } - else if(p == 4) { const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> x2 = (x * x); return (x2 * x2); } - else - { - // The variable xn stores the binary powers of x. - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> result(((p % 2) != 0) ? x : complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> xn (x); - - int p2 = p; - - while((p2 /= 2) != 0) - { - // Square xn for each binary power. - xn *= xn; - - const bool has_binary_power = ((p2 % 2) != 0); - - if(has_binary_power) - { - // Multiply the result with each binary power contained in the exponent. - result *= xn; - } - } - - return result; - } - } - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& a) - { - const bool x_im_isneg = (x.imag() < 0); - const bool x_im_iszero = ((x_im_isneg || (x.imag() > 0)) == false); - - if(x_im_iszero) - { - using std::pow; - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE pxa = pow(x.real(), a); - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(pxa, BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0)); - } - else - { - return std::exp(a * std::log(x)); - } - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) - { - const bool x_im_isneg = (x.imag() < 0); - const bool x_im_iszero = ((x_im_isneg || (x.imag() > 0)) == false); - - if(x_im_iszero) - { - using std::pow; - - return pow(x.real(), a); - } - else - { - return std::exp(a * std::log(x)); - } - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a) - { - const bool x_isneg = (x < 0); - const bool x_isnan = (x != x); - const bool x_isinf = ((!x_isneg) ? bool(+x > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-x > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - const bool a_re_isneg = (a.real() < 0); - const bool a_re_isnan = (a.real() != a.real()); - const bool a_re_isinf = ((!a_re_isneg) ? bool(+a.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-a.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - const bool a_im_isneg = (a.imag() < 0); - const bool a_im_isnan = (a.imag() != a.imag()); - const bool a_im_isinf = ((!a_im_isneg) ? bool(+a.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()) - : bool(-a.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())); - - const bool args_is_nan = (x_isnan || a_re_isnan || a_im_isnan); - const bool a_is_finite = (!(a_re_isnan || a_re_isinf || a_im_isnan || a_im_isinf)); - - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> result; - - if(args_is_nan) - { - result = - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(), - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN() - ); - } - else if(x_isinf) - { - if(a_is_finite) - { - result = - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity() - ); - } - else - { - result = - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(), - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN() - ); - } - } - else if(x > 0) - { - result = std::exp(a * std::log(x)); - } - else if(x < 0) - { - using std::acos; - using std::log; - - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - cpx_lg_x - ( - log(-x), - acos(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(-1)) - ); - - result = std::exp(a * cpx_lg_x); - } - else - { - if(a_is_finite) - { - result = - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0), - BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0) - ); - } - else - { - result = - complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> - ( - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(), - std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN() - ); - } - } - - return result; - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::sin; - using std::cos; - using std::exp; - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * sinh_x, cosh_x * sin_y); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - using std::sin; - using std::cos; - using std::exp; - - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; - - return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * cosh_x, sin_y * sinh_x); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_plus = std::exp(x); - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_minus = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / ex_plus; - - return (ex_plus - ex_minus) / (ex_plus + ex_minus); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - return std::log(x + std::sqrt((x * x) + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE my_one(1); - - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zp(x.real() + my_one, x.imag()); - const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zm(x.real() - my_one, x.imag()); - - return std::log(x + (zp * std::sqrt(zm / zp))); - } - - inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - return (std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + x) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - x)) / 2.0; - } - - template<class char_type, class traits_type> - inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - std::basic_ostringstream<char_type, traits_type> ostr; - - ostr.flags(os.flags()); - ostr.imbue(os.getloc()); - ostr.precision(os.precision()); - - ostr << char_type('(') - << x.real() - << char_type(',') - << x.imag() - << char_type(')'); - - return (os << ostr.str()); - } - - template<class char_type, class traits_type> - inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) - { - BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE rx; - BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE ix; - - char_type the_char; - - static_cast<void>(is >> the_char); - - if(the_char == static_cast<char_type>('(')) - { - static_cast<void>(is >> rx >> the_char); - - if(the_char == static_cast<char_type>(',')) - { - static_cast<void>(is >> ix >> the_char); - - if(the_char == static_cast<char_type>(')')) - { - x = complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rx, ix); - } - else - { - is.setstate(ios_base::failbit); - } - } - else if(the_char == static_cast<char_type>(')')) - { - x = rx; - } - else - { - is.setstate(ios_base::failbit); - } - } - else - { - static_cast<void>(is.putback(the_char)); - - static_cast<void>(is >> rx); - - x = rx; - } - - return is; - } - } // namespace std - -#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ diff --git a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp b/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp deleted file mode 100644 index 4d46c38829..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp +++ /dev/null @@ -1,774 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// Implement quadruple-precision I/O stream operations. - -#ifndef BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ - #define BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ - - #include <boost/math/cstdfloat/cstdfloat_types.hpp> - #include <boost/math/cstdfloat/cstdfloat_limits.hpp> - #include <boost/math/cstdfloat/cstdfloat_cmath.hpp> - - #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) - #error You can not use <boost/math/cstdfloat/cstdfloat_iostream.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. - #endif - - #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) - - #include <cstddef> - #include <istream> - #include <ostream> - #include <sstream> - #include <stdexcept> - #include <string> - #include <boost/math/tools/assert.hpp> - #include <boost/math/tools/throw_exception.hpp> - -// #if (0) - #if defined(__GNUC__) - - // Forward declarations of quadruple-precision string functions. - extern "C" int quadmath_snprintf(char *str, size_t size, const char *format, ...) noexcept; - extern "C" boost::math::cstdfloat::detail::float_internal128_t strtoflt128(const char*, char **) noexcept; - - namespace std - { - template<typename char_type, class traits_type> - inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const boost::math::cstdfloat::detail::float_internal128_t& x) - { - std::basic_ostringstream<char_type, traits_type> ostr; - ostr.flags(os.flags()); - ostr.imbue(os.getloc()); - ostr.precision(os.precision()); - - char my_buffer[64U]; - - const int my_prec = static_cast<int>(os.precision()); - const int my_digits = ((my_prec == 0) ? 36 : my_prec); - - const std::ios_base::fmtflags my_flags = os.flags(); - - char my_format_string[8U]; - - std::size_t my_format_string_index = 0U; - - my_format_string[my_format_string_index] = '%'; - ++my_format_string_index; - - if(my_flags & std::ios_base::showpos) { my_format_string[my_format_string_index] = '+'; ++my_format_string_index; } - if(my_flags & std::ios_base::showpoint) { my_format_string[my_format_string_index] = '#'; ++my_format_string_index; } - - my_format_string[my_format_string_index + 0U] = '.'; - my_format_string[my_format_string_index + 1U] = '*'; - my_format_string[my_format_string_index + 2U] = 'Q'; - - my_format_string_index += 3U; - - char the_notation_char; - - if (my_flags & std::ios_base::scientific) { the_notation_char = 'e'; } - else if(my_flags & std::ios_base::fixed) { the_notation_char = 'f'; } - else { the_notation_char = 'g'; } - - my_format_string[my_format_string_index + 0U] = the_notation_char; - my_format_string[my_format_string_index + 1U] = 0; - - const int v = ::quadmath_snprintf(my_buffer, - static_cast<int>(sizeof(my_buffer)), - my_format_string, - my_digits, - x); - - if(v < 0) { BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed internally in quadmath_snprintf().")); } - - if(v >= static_cast<int>(sizeof(my_buffer) - 1U)) - { - // Evidently there is a really long floating-point string here, - // such as a small decimal representation in non-scientific notation. - // So we have to use dynamic memory allocation for the output - // string buffer. - - char* my_buffer2 = static_cast<char*>(0U); - -#ifndef BOOST_NO_EXCEPTIONS - try - { -#endif - my_buffer2 = new char[v + 3]; -#ifndef BOOST_NO_EXCEPTIONS - } - catch(const std::bad_alloc&) - { - BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed while allocating memory.")); - } -#endif - const int v2 = ::quadmath_snprintf(my_buffer2, - v + 3, - my_format_string, - my_digits, - x); - - if(v2 >= v + 3) - { - BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed.")); - } - - static_cast<void>(ostr << my_buffer2); - - delete [] my_buffer2; - } - else - { - static_cast<void>(ostr << my_buffer); - } - - return (os << ostr.str()); - } - - template<typename char_type, class traits_type> - inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, boost::math::cstdfloat::detail::float_internal128_t& x) - { - std::string str; - - static_cast<void>(is >> str); - - char* p_end; - - x = strtoflt128(str.c_str(), &p_end); - - if(static_cast<std::ptrdiff_t>(p_end - str.c_str()) != static_cast<std::ptrdiff_t>(str.length())) - { - for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it) - { - static_cast<void>(is.putback(*it)); - } - - is.setstate(ios_base::failbit); - - BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t")); - } - - return is; - } - } - -// #elif defined(__GNUC__) - #elif defined(__INTEL_COMPILER) - - // The section for I/O stream support for the ICC compiler is particularly - // long, because these functions must be painstakingly synthesized from - // manually-written routines (ICC does not support I/O stream operations - // for its _Quad type). - - // The following string-extraction routines are based on the methodology - // used in Boost.Multiprecision by John Maddock and Christopher Kormanyos. - // This methodology has been slightly modified here for boost::float128_t. - - #include <cstring> - #include <cctype> - - namespace boost { namespace math { namespace cstdfloat { namespace detail { - - template<class string_type> - void format_float_string(string_type& str, - int my_exp, - int digits, - const std::ios_base::fmtflags f, - const bool iszero) - { - typedef typename string_type::size_type size_type; - - const bool scientific = ((f & std::ios_base::scientific) == std::ios_base::scientific); - const bool fixed = ((f & std::ios_base::fixed) == std::ios_base::fixed); - const bool showpoint = ((f & std::ios_base::showpoint) == std::ios_base::showpoint); - const bool showpos = ((f & std::ios_base::showpos) == std::ios_base::showpos); - - const bool b_neg = ((str.size() != 0U) && (str[0] == '-')); - - if(b_neg) - { - str.erase(0, 1); - } - - if(digits == 0) - { - digits = static_cast<int>((std::max)(str.size(), size_type(16))); - } - - if(iszero || str.empty() || (str.find_first_not_of('0') == string_type::npos)) - { - // We will be printing zero, even though the value might not - // actually be zero (it just may have been rounded to zero). - str = "0"; - - if(scientific || fixed) - { - str.append(1, '.'); - str.append(size_type(digits), '0'); - - if(scientific) - { - str.append("e+00"); - } - } - else - { - if(showpoint) - { - str.append(1, '.'); - if(digits > 1) - { - str.append(size_type(digits - 1), '0'); - } - } - } - - if(b_neg) - { - str.insert(0U, 1U, '-'); - } - else if(showpos) - { - str.insert(0U, 1U, '+'); - } - - return; - } - - if(!fixed && !scientific && !showpoint) - { - // Suppress trailing zeros. - typename string_type::iterator pos = str.end(); - - while(pos != str.begin() && *--pos == '0') { ; } - - if(pos != str.end()) - { - ++pos; - } - - str.erase(pos, str.end()); - - if(str.empty()) - { - str = '0'; - } - } - else if(!fixed || (my_exp >= 0)) - { - // Pad out the end with zero's if we need to. - - int chars = static_cast<int>(str.size()); - chars = digits - chars; - - if(scientific) - { - ++chars; - } - - if(chars > 0) - { - str.append(static_cast<size_type>(chars), '0'); - } - } - - if(fixed || (!scientific && (my_exp >= -4) && (my_exp < digits))) - { - if((1 + my_exp) > static_cast<int>(str.size())) - { - // Just pad out the end with zeros. - str.append(static_cast<size_type>((1 + my_exp) - static_cast<int>(str.size())), '0'); - - if(showpoint || fixed) - { - str.append("."); - } - } - else if(my_exp + 1 < static_cast<int>(str.size())) - { - if(my_exp < 0) - { - str.insert(0U, static_cast<size_type>(-1 - my_exp), '0'); - str.insert(0U, "0."); - } - else - { - // Insert the decimal point: - str.insert(static_cast<size_type>(my_exp + 1), 1, '.'); - } - } - else if(showpoint || fixed) // we have exactly the digits we require to left of the point - { - str += "."; - } - - if(fixed) - { - // We may need to add trailing zeros. - int l = static_cast<int>(str.find('.') + 1U); - l = digits - (static_cast<int>(str.size()) - l); - - if(l > 0) - { - str.append(size_type(l), '0'); - } - } - } - else - { - // Scientific format: - if(showpoint || (str.size() > 1)) - { - str.insert(1U, 1U, '.'); - } - - str.append(1U, 'e'); - - string_type e = std::to_string(std::abs(my_exp)); - - if(e.size() < 2U) - { - e.insert(0U, 2U - e.size(), '0'); - } - - if(my_exp < 0) - { - e.insert(0U, 1U, '-'); - } - else - { - e.insert(0U, 1U, '+'); - } - - str.append(e); - } - - if(b_neg) - { - str.insert(0U, 1U, '-'); - } - else if(showpos) - { - str.insert(0U, 1U, '+'); - } - } - - template<class float_type, class type_a> inline void eval_convert_to(type_a* pa, const float_type& cb) { *pa = static_cast<type_a>(cb); } - template<class float_type, class type_a> inline void eval_add (float_type& b, const type_a& a) { b += a; } - template<class float_type, class type_a> inline void eval_subtract (float_type& b, const type_a& a) { b -= a; } - template<class float_type, class type_a> inline void eval_multiply (float_type& b, const type_a& a) { b *= a; } - template<class float_type> inline void eval_multiply (float_type& b, const float_type& cb, const float_type& cb2) { b = (cb * cb2); } - template<class float_type, class type_a> inline void eval_divide (float_type& b, const type_a& a) { b /= a; } - template<class float_type> inline void eval_log10 (float_type& b, const float_type& cb) { b = std::log10(cb); } - template<class float_type> inline void eval_floor (float_type& b, const float_type& cb) { b = std::floor(cb); } - - inline void round_string_up_at(std::string& s, int pos, int& expon) - { - // This subroutine rounds up a string representation of a - // number at the given position pos. - - if(pos < 0) - { - s.insert(0U, 1U, '1'); - s.erase(s.size() - 1U); - ++expon; - } - else if(s[pos] == '9') - { - s[pos] = '0'; - round_string_up_at(s, pos - 1, expon); - } - else - { - if((pos == 0) && (s[pos] == '0') && (s.size() == 1)) - { - ++expon; - } - - ++s[pos]; - } - } - - template<class float_type> - std::string convert_to_string(float_type& x, - std::streamsize digits, - const std::ios_base::fmtflags f) - { - const bool isneg = (x < 0); - const bool iszero = ((!isneg) ? bool(+x < (std::numeric_limits<float_type>::min)()) - : bool(-x < (std::numeric_limits<float_type>::min)())); - const bool isnan = (x != x); - const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)()) - : bool(-x > (std::numeric_limits<float_type>::max)())); - - int expon = 0; - - if(digits <= 0) { digits = std::numeric_limits<float_type>::max_digits10; } - - const int org_digits = static_cast<int>(digits); - - std::string result; - - if(iszero) - { - result = "0"; - } - else if(isinf) - { - if(x < 0) - { - return "-inf"; - } - else - { - return ((f & std::ios_base::showpos) == std::ios_base::showpos) ? "+inf" : "inf"; - } - } - else if(isnan) - { - return "nan"; - } - else - { - // Start by figuring out the base-10 exponent. - if(isneg) { x = -x; } - - float_type t; - float_type ten = 10; - - eval_log10(t, x); - eval_floor(t, t); - eval_convert_to(&expon, t); - - if(-expon > std::numeric_limits<float_type>::max_exponent10 - 3) - { - int e = -expon / 2; - - const float_type t2 = boost::math::cstdfloat::detail::pown(ten, e); - - eval_multiply(t, t2, x); - eval_multiply(t, t2); - - if((expon & 1) != 0) - { - eval_multiply(t, ten); - } - } - else - { - t = boost::math::cstdfloat::detail::pown(ten, -expon); - eval_multiply(t, x); - } - - // Make sure that the value lies between [1, 10), and adjust if not. - if(t < 1) - { - eval_multiply(t, 10); - - --expon; - } - else if(t >= 10) - { - eval_divide(t, 10); - - ++expon; - } - - float_type digit; - int cdigit; - - // Adjust the number of digits required based on formatting options. - if(((f & std::ios_base::fixed) == std::ios_base::fixed) && (expon != -1)) - { - digits += (expon + 1); - } - - if((f & std::ios_base::scientific) == std::ios_base::scientific) - { - ++digits; - } - - // Extract the base-10 digits one at a time. - for(int i = 0; i < digits; ++i) - { - eval_floor(digit, t); - eval_convert_to(&cdigit, digit); - - result += static_cast<char>('0' + cdigit); - - eval_subtract(t, digit); - eval_multiply(t, ten); - } - - // Possibly round the result. - if(digits >= 0) - { - eval_floor(digit, t); - eval_convert_to(&cdigit, digit); - eval_subtract(t, digit); - - if((cdigit == 5) && (t == 0)) - { - // Use simple bankers rounding. - - if((static_cast<int>(*result.rbegin() - '0') & 1) != 0) - { - round_string_up_at(result, static_cast<int>(result.size() - 1U), expon); - } - } - else if(cdigit >= 5) - { - round_string_up_at(result, static_cast<int>(result.size() - 1), expon); - } - } - } - - while((result.size() > static_cast<std::string::size_type>(digits)) && result.size()) - { - // We may get here as a result of rounding. - - if(result.size() > 1U) - { - result.erase(result.size() - 1U); - } - else - { - if(expon > 0) - { - --expon; // so we put less padding in the result. - } - else - { - ++expon; - } - - ++digits; - } - } - - if(isneg) - { - result.insert(0U, 1U, '-'); - } - - format_float_string(result, expon, org_digits, f, iszero); - - return result; - } - - template <class float_type> - bool convert_from_string(float_type& value, const char* p) - { - value = 0; - - if((p == static_cast<const char*>(0U)) || (*p == static_cast<char>(0))) - { - return; - } - - bool is_neg = false; - bool is_neg_expon = false; - - constexpr int ten = 10; - - int expon = 0; - int digits_seen = 0; - - constexpr int max_digits = std::numeric_limits<float_type>::max_digits10 + 1; - - if(*p == static_cast<char>('+')) - { - ++p; - } - else if(*p == static_cast<char>('-')) - { - is_neg = true; - ++p; - } - - const bool isnan = ((std::strcmp(p, "nan") == 0) || (std::strcmp(p, "NaN") == 0) || (std::strcmp(p, "NAN") == 0)); - - if(isnan) - { - eval_divide(value, 0); - - if(is_neg) - { - value = -value; - } - - return true; - } - - const bool isinf = ((std::strcmp(p, "inf") == 0) || (std::strcmp(p, "Inf") == 0) || (std::strcmp(p, "INF") == 0)); - - if(isinf) - { - value = 1; - eval_divide(value, 0); - - if(is_neg) - { - value = -value; - } - - return true; - } - - // Grab all the leading digits before the decimal point. - while(std::isdigit(*p)) - { - eval_multiply(value, ten); - eval_add(value, static_cast<int>(*p - '0')); - ++p; - ++digits_seen; - } - - if(*p == static_cast<char>('.')) - { - // Grab everything after the point, stop when we've seen - // enough digits, even if there are actually more available. - - ++p; - - while(std::isdigit(*p)) - { - eval_multiply(value, ten); - eval_add(value, static_cast<int>(*p - '0')); - ++p; - --expon; - - if(++digits_seen > max_digits) - { - break; - } - } - - while(std::isdigit(*p)) - { - ++p; - } - } - - // Parse the exponent. - if((*p == static_cast<char>('e')) || (*p == static_cast<char>('E'))) - { - ++p; - - if(*p == static_cast<char>('+')) - { - ++p; - } - else if(*p == static_cast<char>('-')) - { - is_neg_expon = true; - ++p; - } - - int e2 = 0; - - while(std::isdigit(*p)) - { - e2 *= 10; - e2 += (*p - '0'); - ++p; - } - - if(is_neg_expon) - { - e2 = -e2; - } - - expon += e2; - } - - if(expon) - { - // Scale by 10^expon. Note that 10^expon can be outside the range - // of our number type, even though the result is within range. - // If that looks likely, then split the calculation in two parts. - float_type t; - t = ten; - - if(expon > (std::numeric_limits<float_type>::min_exponent10 + 2)) - { - t = boost::math::cstdfloat::detail::pown(t, expon); - eval_multiply(value, t); - } - else - { - t = boost::math::cstdfloat::detail::pown(t, (expon + digits_seen + 1)); - eval_multiply(value, t); - t = ten; - t = boost::math::cstdfloat::detail::pown(t, (-digits_seen - 1)); - eval_multiply(value, t); - } - } - - if(is_neg) - { - value = -value; - } - - return (*p == static_cast<char>(0)); - } - } } } } // boost::math::cstdfloat::detail - - namespace std - { - template<typename char_type, class traits_type> - inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const boost::math::cstdfloat::detail::float_internal128_t& x) - { - boost::math::cstdfloat::detail::float_internal128_t non_const_x = x; - - const std::string str = boost::math::cstdfloat::detail::convert_to_string(non_const_x, - os.precision(), - os.flags()); - - std::basic_ostringstream<char_type, traits_type> ostr; - ostr.flags(os.flags()); - ostr.imbue(os.getloc()); - ostr.precision(os.precision()); - - static_cast<void>(ostr << str); - - return (os << ostr.str()); - } - - template<typename char_type, class traits_type> - inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, boost::math::cstdfloat::detail::float_internal128_t& x) - { - std::string str; - - static_cast<void>(is >> str); - - const bool conversion_is_ok = boost::math::cstdfloat::detail::convert_from_string(x, str.c_str()); - - if(false == conversion_is_ok) - { - for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it) - { - static_cast<void>(is.putback(*it)); - } - - is.setstate(ios_base::failbit); - - BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t")); - } - - return is; - } - } - - #endif // Use __GNUC__ or __INTEL_COMPILER libquadmath - - #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) - -#endif // BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ diff --git a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_limits.hpp b/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_limits.hpp deleted file mode 100644 index ef26a99d6f..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_limits.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// Implement quadruple-precision std::numeric_limits<> support. - -#ifndef BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ - #define BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ - - #include <boost/math/cstdfloat/cstdfloat_types.hpp> - -#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) -// -// This is the only way we can avoid -// warning: non-standard suffix on floating constant [-Wpedantic] -// when building with -Wall -pedantic. Neither __extension__ -// nor #pragma diagnostic ignored work :( -// -#pragma GCC system_header -#endif - - #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) - - #include <limits> - - // Define the name of the global quadruple-precision function to be used for - // calculating quiet_NaN() in the specialization of std::numeric_limits<>. - #if defined(__INTEL_COMPILER) - #define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq - #elif defined(__GNUC__) - #define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq - #endif - - // Forward declaration of the quadruple-precision square root function. - extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) noexcept; - - namespace std - { - template<> - class numeric_limits<boost::math::cstdfloat::detail::float_internal128_t> - { - public: - static constexpr bool is_specialized = true; - static boost::math::cstdfloat::detail::float_internal128_t (min) () noexcept { return BOOST_CSTDFLOAT_FLOAT128_MIN; } - static boost::math::cstdfloat::detail::float_internal128_t (max) () noexcept { return BOOST_CSTDFLOAT_FLOAT128_MAX; } - static boost::math::cstdfloat::detail::float_internal128_t lowest() noexcept { return -(max)(); } - static constexpr int digits = 113; - static constexpr int digits10 = 33; - static constexpr int max_digits10 = 36; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr int radix = 2; - static boost::math::cstdfloat::detail::float_internal128_t epsilon () { return BOOST_CSTDFLOAT_FLOAT128_EPS; } - static boost::math::cstdfloat::detail::float_internal128_t round_error() { return BOOST_FLOAT128_C(0.5); } - static constexpr int min_exponent = -16381; - static constexpr int min_exponent10 = static_cast<int>((min_exponent * 301L) / 1000L); - static constexpr int max_exponent = +16384; - static constexpr int max_exponent10 = static_cast<int>((max_exponent * 301L) / 1000L); - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = false; - static constexpr float_denorm_style has_denorm = denorm_present; - static constexpr bool has_denorm_loss = false; - static boost::math::cstdfloat::detail::float_internal128_t infinity () { return BOOST_FLOAT128_C(1.0) / BOOST_FLOAT128_C(0.0); } - static boost::math::cstdfloat::detail::float_internal128_t quiet_NaN () { return -(::BOOST_CSTDFLOAT_FLOAT128_SQRT(BOOST_FLOAT128_C(-1.0))); } - static boost::math::cstdfloat::detail::float_internal128_t signaling_NaN() { return BOOST_FLOAT128_C(0.0); } - static boost::math::cstdfloat::detail::float_internal128_t denorm_min () { return BOOST_CSTDFLOAT_FLOAT128_DENORM_MIN; } - static constexpr bool is_iec559 = true; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_to_nearest; - }; - } // namespace std - - #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) - -#endif // BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ - diff --git a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_types.hpp b/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_types.hpp deleted file mode 100644 index bc32c71fe9..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_types.hpp +++ /dev/null @@ -1,441 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2014. -// Copyright John Maddock 2014. -// Copyright Paul Bristow 2014. -// 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) -// - -// Implement the types for floating-point typedefs having specified widths. - -#ifndef BOOST_MATH_CSTDFLOAT_TYPES_2014_01_09_HPP_ - #define BOOST_MATH_CSTDFLOAT_TYPES_2014_01_09_HPP_ - - #include <float.h> - #include <limits> - #include <boost/math/tools/config.hpp> - - // This is the beginning of the preamble. - - // In this preamble, the preprocessor is used to query certain - // preprocessor definitions from <float.h>. Based on the results - // of these queries, an attempt is made to automatically detect - // the presence of built-in floating-point types having specified - // widths. These are *thought* to be conformant with IEEE-754, - // whereby an unequivocal test based on std::numeric_limits<> - // follows below. - - // In addition, various macros that are used for initializing - // floating-point literal values having specified widths and - // some basic min/max values are defined. - - // First, we will pre-load certain preprocessor definitions - // with a dummy value. - - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 0 - - #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 0 - #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 0 - #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 0 - #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0 - #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0 - - // Ensure that the compiler has a radix-2 floating-point representation. - #if (!defined(FLT_RADIX) || ((defined(FLT_RADIX) && (FLT_RADIX != 2)))) - #error The compiler does not support any radix-2 floating-point types required for <boost/cstdfloat.hpp>. - #endif - - // Check if built-in float is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. - #if(defined(FLT_MANT_DIG) && defined(FLT_MAX_EXP)) - #if ((FLT_MANT_DIG == 11) && (FLT_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 - #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 - #define BOOST_FLOAT16_C(x) (x ## F) - #define BOOST_CSTDFLOAT_FLOAT_16_MIN FLT_MIN - #define BOOST_CSTDFLOAT_FLOAT_16_MAX FLT_MAX - #elif((FLT_MANT_DIG == 24) && (FLT_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 - #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 - #define BOOST_FLOAT32_C(x) (x ## F) - #define BOOST_CSTDFLOAT_FLOAT_32_MIN FLT_MIN - #define BOOST_CSTDFLOAT_FLOAT_32_MAX FLT_MAX - #elif((FLT_MANT_DIG == 53) && (FLT_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 - #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 - #define BOOST_FLOAT64_C(x) (x ## F) - #define BOOST_CSTDFLOAT_FLOAT_64_MIN FLT_MIN - #define BOOST_CSTDFLOAT_FLOAT_64_MAX FLT_MAX - #elif((FLT_MANT_DIG == 64) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 - #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 - #define BOOST_FLOAT80_C(x) (x ## F) - #define BOOST_CSTDFLOAT_FLOAT_80_MIN FLT_MIN - #define BOOST_CSTDFLOAT_FLOAT_80_MAX FLT_MAX - #elif((FLT_MANT_DIG == 113) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 - #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 - #define BOOST_FLOAT128_C(x) (x ## F) - #define BOOST_CSTDFLOAT_FLOAT_128_MIN FLT_MIN - #define BOOST_CSTDFLOAT_FLOAT_128_MAX FLT_MAX - #endif - #endif - - // Check if built-in double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. - #if(defined(DBL_MANT_DIG) && defined(DBL_MAX_EXP)) - #if ((DBL_MANT_DIG == 11) && (DBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 - #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 - #define BOOST_FLOAT16_C(x) (x) - #define BOOST_CSTDFLOAT_FLOAT_16_MIN DBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_16_MAX DBL_MAX - #elif((DBL_MANT_DIG == 24) && (DBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 - #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 - #define BOOST_FLOAT32_C(x) (x) - #define BOOST_CSTDFLOAT_FLOAT_32_MIN DBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_32_MAX DBL_MAX - #elif((DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 - #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 - #define BOOST_FLOAT64_C(x) (x) - #define BOOST_CSTDFLOAT_FLOAT_64_MIN DBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_64_MAX DBL_MAX - #elif((DBL_MANT_DIG == 64) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 - #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 - #define BOOST_FLOAT80_C(x) (x) - #define BOOST_CSTDFLOAT_FLOAT_80_MIN DBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_80_MAX DBL_MAX - #elif((DBL_MANT_DIG == 113) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 - #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 - #define BOOST_FLOAT128_C(x) (x) - #define BOOST_CSTDFLOAT_FLOAT_128_MIN DBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_128_MAX DBL_MAX - #endif - #endif - - // Disable check long double capability even if supported by compiler since some math runtime - // implementations are broken for long double. - #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - // Check if built-in long double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. - #if(defined(LDBL_MANT_DIG) && defined(LDBL_MAX_EXP)) - #if ((LDBL_MANT_DIG == 11) && (LDBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE long double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 - #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 - #define BOOST_FLOAT16_C(x) (x ## L) - #define BOOST_CSTDFLOAT_FLOAT_16_MIN LDBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_16_MAX LDBL_MAX - #elif((LDBL_MANT_DIG == 24) && (LDBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE long double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 - #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 - #define BOOST_FLOAT32_C(x) (x ## L) - #define BOOST_CSTDFLOAT_FLOAT_32_MIN LDBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_32_MAX LDBL_MAX - #elif((LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE long double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 - #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 - #define BOOST_FLOAT64_C(x) (x ## L) - #define BOOST_CSTDFLOAT_FLOAT_64_MIN LDBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_64_MAX LDBL_MAX - #elif((LDBL_MANT_DIG == 64) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE long double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 - #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 - #define BOOST_FLOAT80_C(x) (x ## L) - #define BOOST_CSTDFLOAT_FLOAT_80_MIN LDBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_80_MAX LDBL_MAX - #elif((LDBL_MANT_DIG == 113) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) - #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE long double - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 - #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 - #define BOOST_FLOAT128_C(x) (x ## L) - #define BOOST_CSTDFLOAT_FLOAT_128_MIN LDBL_MIN - #define BOOST_CSTDFLOAT_FLOAT_128_MAX LDBL_MAX - #endif - #endif - #endif - - // Check if quadruple-precision is supported. Here, we are checking - // for the presence of __float128 from GCC's quadmath.h or _Quad - // from ICC's /Qlong-double flag). To query these, we use the - // BOOST_MATH_USE_FLOAT128 pre-processor definition from - // <boost/math/tools/config.hpp>. - - #if (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) - - // Specify the underlying name of the internal 128-bit floating-point type definition. - namespace boost { namespace math { namespace cstdfloat { namespace detail { - #if defined(__GNUC__) - typedef __float128 float_internal128_t; - #elif defined(__INTEL_COMPILER) - typedef _Quad float_internal128_t; - #else - #error "Sorry, the compiler is neither GCC, nor Intel, I don't know how to configure <boost/cstdfloat.hpp>." - #endif - } } } } // boost::math::cstdfloat::detail - - #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE boost::math::cstdfloat::detail::float_internal128_t - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 - #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE - #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 - #define BOOST_FLOAT128_C(x) (x ## Q) - #define BOOST_CSTDFLOAT_FLOAT128_MIN 3.36210314311209350626267781732175260e-4932Q - #define BOOST_CSTDFLOAT_FLOAT128_MAX 1.18973149535723176508575932662800702e+4932Q - #define BOOST_CSTDFLOAT_FLOAT128_EPS 1.92592994438723585305597794258492732e-0034Q - #define BOOST_CSTDFLOAT_FLOAT128_DENORM_MIN 6.475175119438025110924438958227646552e-4966Q - - #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) - - // This is the end of the preamble, and also the end of the - // sections providing support for the C++ standard library - // for quadruple-precision. - - // Now we use the results of the queries that have been obtained - // in the preamble (far above) for the final type definitions in - // the namespace boost. - - // Make sure that the compiler has any floating-point type(s) whatsoever. - #if ( (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0) \ - && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0) \ - && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0) \ - && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0) \ - && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) - #error The compiler does not support any of the floating-point types required for <boost/cstdfloat.hpp>. - #endif - - // The following section contains the various min/max macros - // for the *leastN and *fastN types. - - #if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1) - #define BOOST_FLOAT_FAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN - #define BOOST_FLOAT_LEAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN - #define BOOST_FLOAT_FAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX - #define BOOST_FLOAT_LEAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1) - #define BOOST_FLOAT_FAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN - #define BOOST_FLOAT_LEAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN - #define BOOST_FLOAT_FAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX - #define BOOST_FLOAT_LEAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1) - #define BOOST_FLOAT_FAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN - #define BOOST_FLOAT_LEAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN - #define BOOST_FLOAT_FAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX - #define BOOST_FLOAT_LEAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1) - #define BOOST_FLOAT_FAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN - #define BOOST_FLOAT_LEAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN - #define BOOST_FLOAT_FAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX - #define BOOST_FLOAT_LEAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1) - #define BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T - - #define BOOST_FLOAT_FAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN - #define BOOST_FLOAT_LEAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN - #define BOOST_FLOAT_FAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX - #define BOOST_FLOAT_LEAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX - #endif - - // The following section contains the various min/max macros - // for the *floatmax types. - - #if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16) - #define BOOST_FLOATMAX_C(x) BOOST_FLOAT16_C(x) - #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN - #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32) - #define BOOST_FLOATMAX_C(x) BOOST_FLOAT32_C(x) - #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN - #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64) - #define BOOST_FLOATMAX_C(x) BOOST_FLOAT64_C(x) - #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN - #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80) - #define BOOST_FLOATMAX_C(x) BOOST_FLOAT80_C(x) - #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN - #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128) - #define BOOST_FLOATMAX_C(x) BOOST_FLOAT128_C(x) - #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN - #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX - #else - #error The maximum available floating-point width for <boost/cstdfloat.hpp> is undefined. - #endif - - // And finally..., we define the floating-point typedefs having - // specified widths. The types are defined in the namespace boost. - - // For simplicity, the least and fast types are type defined identically - // as the corresponding fixed-width type. This behavior may, however, - // be modified when being optimized for a given compiler implementation. - - // In addition, a clear assessment of IEEE-754 conformance is carried out - // using compile-time assertion. - - namespace boost - { - #if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1) - typedef BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float16_t; - typedef boost::float16_t float_fast16_t; - typedef boost::float16_t float_least16_t; - - static_assert(std::numeric_limits<boost::float16_t>::is_iec559 == true, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float16_t>::radix == 2, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float16_t>::digits == 11, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float16_t>::max_exponent == 16, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - - #undef BOOST_CSTDFLOAT_FLOAT_16_MIN - #undef BOOST_CSTDFLOAT_FLOAT_16_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1) - typedef BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float32_t; - typedef boost::float32_t float_fast32_t; - typedef boost::float32_t float_least32_t; - - static_assert(std::numeric_limits<boost::float32_t>::is_iec559 == true, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float32_t>::radix == 2, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float32_t>::digits == 24, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float32_t>::max_exponent == 128, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - - #undef BOOST_CSTDFLOAT_FLOAT_32_MIN - #undef BOOST_CSTDFLOAT_FLOAT_32_MAX - #endif - -#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && defined(__SUNPRO_CC) -#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE -#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0 -#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE -#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0 -#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH -#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 -#endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1) - typedef BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float64_t; - typedef boost::float64_t float_fast64_t; - typedef boost::float64_t float_least64_t; - - static_assert(std::numeric_limits<boost::float64_t>::is_iec559 == true, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float64_t>::radix == 2, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float64_t>::digits == 53, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float64_t>::max_exponent == 1024, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - - #undef BOOST_CSTDFLOAT_FLOAT_64_MIN - #undef BOOST_CSTDFLOAT_FLOAT_64_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1) - typedef BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float80_t; - typedef boost::float80_t float_fast80_t; - typedef boost::float80_t float_least80_t; - - static_assert(std::numeric_limits<boost::float80_t>::is_iec559 == true, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float80_t>::radix == 2, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float80_t>::digits == 64, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float80_t>::max_exponent == 16384, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - - #undef BOOST_CSTDFLOAT_FLOAT_80_MIN - #undef BOOST_CSTDFLOAT_FLOAT_80_MAX - #endif - - #if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1) - typedef BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float128_t; - typedef boost::float128_t float_fast128_t; - typedef boost::float128_t float_least128_t; - - #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) - // This configuration does not *yet* support std::numeric_limits<boost::float128_t>. - // Support for std::numeric_limits<boost::float128_t> is added in the detail - // file <boost/math/cstdfloat/cstdfloat_limits.hpp>. - #else - static_assert(std::numeric_limits<boost::float128_t>::is_iec559 == true, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float128_t>::radix == 2, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float128_t>::digits == 113, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - static_assert(std::numeric_limits<boost::float128_t>::max_exponent == 16384, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails"); - #endif - - #undef BOOST_CSTDFLOAT_FLOAT_128_MIN - #undef BOOST_CSTDFLOAT_FLOAT_128_MAX - #endif - - #if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16) - typedef boost::float16_t floatmax_t; - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32) - typedef boost::float32_t floatmax_t; - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64) - typedef boost::float64_t floatmax_t; - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80) - typedef boost::float80_t floatmax_t; - #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128) - typedef boost::float128_t floatmax_t; - #else - #error The maximum available floating-point width for <boost/cstdfloat.hpp> is undefined. - #endif - - #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE - #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE - #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE - #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE - #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE - - #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH - } - // namespace boost - -#endif // BOOST_MATH_CSTDFLOAT_BASE_TYPES_2014_01_09_HPP_ - diff --git a/contrib/restricted/boost/math/include/boost/math/policies/error_handling.hpp b/contrib/restricted/boost/math/include/boost/math/policies/error_handling.hpp deleted file mode 100644 index 3af1f976b5..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/policies/error_handling.hpp +++ /dev/null @@ -1,892 +0,0 @@ -// 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_POLICY_ERROR_HANDLING_HPP -#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP - -#include <boost/math/tools/config.hpp> -#include <iomanip> -#include <string> -#include <cstring> -#ifndef BOOST_NO_RTTI -#include <typeinfo> -#endif -#include <cerrno> -#include <complex> -#include <cmath> -#include <cstdint> -#include <boost/math/policies/policy.hpp> -#include <boost/math/tools/precision.hpp> -#ifndef BOOST_NO_EXCEPTIONS -#include <stdexcept> -#include <boost/math/tools/throw_exception.hpp> -#endif - -#ifdef _MSC_VER -# pragma warning(push) // Quiet warnings in boost/format.hpp -# pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE -# pragma warning(disable: 4512) // assignment operator could not be generated. -# pragma warning(disable: 4127) // conditional expression is constant -// And warnings in error handling: -# pragma warning(disable: 4702) // unreachable code. -// Note that this only occurs when the compiler can deduce code is unreachable, -// for example when policy macros are used to ignore errors rather than throw. -#endif -#include <sstream> - -namespace boost{ namespace math{ - -#ifndef BOOST_NO_EXCEPTIONS - -class evaluation_error : public std::runtime_error -{ -public: - evaluation_error(const std::string& s) : std::runtime_error(s){} -}; - -class rounding_error : public std::runtime_error -{ -public: - rounding_error(const std::string& s) : std::runtime_error(s){} -}; - -#endif - -namespace policies{ -// -// Forward declarations of user error handlers, -// it's up to the user to provide the definition of these: -// -template <class T> -T user_domain_error(const char* function, const char* message, const T& val); -template <class T> -T user_pole_error(const char* function, const char* message, const T& val); -template <class T> -T user_overflow_error(const char* function, const char* message, const T& val); -template <class T> -T user_underflow_error(const char* function, const char* message, const T& val); -template <class T> -T user_denorm_error(const char* function, const char* message, const T& val); -template <class T> -T user_evaluation_error(const char* function, const char* message, const T& val); -template <class T, class TargetType> -T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t); -template <class T> -T user_indeterminate_result_error(const char* function, const char* message, const T& val); - -namespace detail -{ - -template <class T> -std::string prec_format(const T& val) -{ - typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type prec_type; - std::stringstream ss; - if(prec_type::value) - { - int prec = 2 + (prec_type::value * 30103UL) / 100000UL; - ss << std::setprecision(prec); - } - ss << val; - return ss.str(); -} - -inline void replace_all_in_string(std::string& result, const char* what, const char* with) -{ - std::string::size_type pos = 0; - std::string::size_type slen = std::strlen(what); - std::string::size_type rlen = std::strlen(with); - while((pos = result.find(what, pos)) != std::string::npos) - { - result.replace(pos, slen, with); - pos += rlen; - } -} - -template <class T> -inline const char* name_of() -{ -#ifndef BOOST_NO_RTTI - return typeid(T).name(); -#else - return "unknown"; -#endif -} -template <> inline const char* name_of<float>(){ return "float"; } -template <> inline const char* name_of<double>(){ return "double"; } -template <> inline const char* name_of<long double>(){ return "long double"; } - -#ifdef BOOST_MATH_USE_FLOAT128 -template <> -inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>() -{ - return "__float128"; -} -#endif - -#ifndef BOOST_NO_EXCEPTIONS -template <class E, class T> -void raise_error(const char* pfunction, const char* message) -{ - if(pfunction == 0) - pfunction = "Unknown function operating on type %1%"; - if(message == 0) - message = "Cause unknown"; - - std::string function(pfunction); - std::string msg("Error in function "); -#ifndef BOOST_NO_RTTI - replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>()); -#else - replace_all_in_string(function, "%1%", "Unknown"); -#endif - msg += function; - msg += ": "; - msg += message; - - E e(msg); - BOOST_MATH_THROW_EXCEPTION(e) -} - -template <class E, class T> -void raise_error(const char* pfunction, const char* pmessage, const T& val) -{ - if(pfunction == 0) - pfunction = "Unknown function operating on type %1%"; - if(pmessage == 0) - pmessage = "Cause unknown: error caused by bad argument with value %1%"; - - std::string function(pfunction); - std::string message(pmessage); - std::string msg("Error in function "); -#ifndef BOOST_NO_RTTI - replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>()); -#else - replace_all_in_string(function, "%1%", "Unknown"); -#endif - msg += function; - msg += ": "; - - std::string sval = prec_format(val); - replace_all_in_string(message, "%1%", sval.c_str()); - msg += message; - - E e(msg); - BOOST_MATH_THROW_EXCEPTION(e) -} -#endif - -template <class T> -inline T raise_domain_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<std::domain_error, T>(function, message, val); - // we never get here: - return std::numeric_limits<T>::quiet_NaN(); -#endif -} - -template <class T> -inline constexpr T raise_domain_error( - const char* , - const char* , - const T& , - const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return std::numeric_limits<T>::quiet_NaN(); -} - -template <class T> -inline T raise_domain_error( - const char* , - const char* , - const T& , - const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = EDOM; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return std::numeric_limits<T>::quiet_NaN(); -} - -template <class T> -inline T raise_domain_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&) -{ - return user_domain_error(function, message, val); -} - -template <class T> -inline T raise_pole_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>()); -#endif -} - -template <class T> -inline constexpr T raise_pole_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>()); -} - -template <class T> -inline constexpr T raise_pole_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>()); -} - -template <class T> -inline T raise_pole_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&) -{ - return user_pole_error(function, message, val); -} - -template <class T> -inline T raise_overflow_error( - const char* function, - const char* message, - const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow"); - // We should never get here: - return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>(); -#endif -} - -template <class T> -inline T raise_overflow_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow", val); - // We should never get here: - return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>(); -#endif -} - -template <class T> -inline constexpr T raise_overflow_error( - const char* , - const char* , - const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>(); -} - -template <class T> -inline constexpr T raise_overflow_error( - const char* , - const char* , - const T&, - const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>(); -} - -template <class T> -inline T raise_overflow_error( - const char* , - const char* , - const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = ERANGE; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>(); -} - -template <class T> -inline T raise_overflow_error( - const char* , - const char* , - const T&, - const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = ERANGE; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>(); -} - -template <class T> -inline T raise_overflow_error( - const char* function, - const char* message, - const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) -{ - return user_overflow_error(function, message, std::numeric_limits<T>::infinity()); -} - -template <class T> -inline T raise_overflow_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) -{ - std::string m(message ? message : ""); - std::string sval = prec_format(val); - replace_all_in_string(m, "%1%", sval.c_str()); - - return user_overflow_error(function, m.c_str(), std::numeric_limits<T>::infinity()); -} - -template <class T> -inline T raise_underflow_error( - const char* function, - const char* message, - const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow"); - // We should never get here: - return 0; -#endif -} - -template <class T> -inline constexpr T raise_underflow_error( - const char* , - const char* , - const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return T(0); -} - -template <class T> -inline T raise_underflow_error( - const char* /* function */, - const char* /* message */, - const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = ERANGE; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return T(0); -} - -template <class T> -inline T raise_underflow_error( - const char* function, - const char* message, - const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&) -{ - return user_underflow_error(function, message, T(0)); -} - -template <class T> -inline T raise_denorm_error( - const char* function, - const char* message, - const T& /* val */, - const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<std::underflow_error, T>(function, message ? message : "denormalised result"); - // we never get here: - return T(0); -#endif -} - -template <class T> -inline constexpr T raise_denorm_error( - const char* , - const char* , - const T& val, - const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return val; -} - -template <class T> -inline T raise_denorm_error( - const char* , - const char* , - const T& val, - const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = ERANGE; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return val; -} - -template <class T> -inline T raise_denorm_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&) -{ - return user_denorm_error(function, message, val); -} - -template <class T> -inline T raise_evaluation_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<boost::math::evaluation_error, T>(function, message, val); - // we never get here: - return T(0); -#endif -} - -template <class T> -inline constexpr T raise_evaluation_error( - const char* , - const char* , - const T& val, - const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return val; -} - -template <class T> -inline T raise_evaluation_error( - const char* , - const char* , - const T& val, - const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = EDOM; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return val; -} - -template <class T> -inline T raise_evaluation_error( - const char* function, - const char* message, - const T& val, - const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&) -{ - return user_evaluation_error(function, message, val); -} - -template <class T, class TargetType> -inline TargetType raise_rounding_error( - const char* function, - const char* message, - const T& val, - const TargetType&, - const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<boost::math::rounding_error, T>(function, message, val); - // we never get here: - return TargetType(0); -#endif -} - -template <class T, class TargetType> -inline constexpr TargetType raise_rounding_error( - const char* , - const char* , - const T& val, - const TargetType&, - const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - static_assert(std::numeric_limits<TargetType>::is_specialized, "The target type must be specialized."); - return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)()); -} - -template <class T, class TargetType> -inline TargetType raise_rounding_error( - const char* , - const char* , - const T& val, - const TargetType&, - const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = ERANGE; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - static_assert(std::numeric_limits<TargetType>::is_specialized, "The target type must be specialized."); - return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)()); -} - -template <class T> -inline T raise_rounding_error( - const char* , - const char* , - const T& val, - const T&, - const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) -{ - errno = ERANGE; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return val > 0 ? boost::math::tools::max_value<T>() : -boost::math::tools::max_value<T>(); -} - -template <class T, class TargetType> -inline TargetType raise_rounding_error( - const char* function, - const char* message, - const T& val, - const TargetType& t, - const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&) -{ - return user_rounding_error(function, message, val, t); -} - -template <class T, class R> -inline T raise_indeterminate_result_error( - const char* function, - const char* message, - const T& val, - const R& , - const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&) -{ -#ifdef BOOST_NO_EXCEPTIONS - static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); -#else - raise_error<std::domain_error, T>(function, message, val); - // we never get here: - return std::numeric_limits<T>::quiet_NaN(); -#endif -} - -template <class T, class R> -inline constexpr T raise_indeterminate_result_error( - const char* , - const char* , - const T& , - const R& result, - const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) -{ - // This may or may not do the right thing, but the user asked for the error - // to be ignored so here we go anyway: - return result; -} - -template <class T, class R> -inline T raise_indeterminate_result_error( - const char* , - const char* , - const T& , - const R& result, - const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&) -{ - errno = EDOM; - // This may or may not do the right thing, but the user asked for the error - // to be silent so here we go anyway: - return result; -} - -template <class T, class R> -inline T raise_indeterminate_result_error( - const char* function, - const char* message, - const T& val, - const R& , - const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&) -{ - return user_indeterminate_result_error(function, message, val); -} - -} // namespace detail - -template <class T, class Policy> -inline constexpr T raise_domain_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::domain_error_type policy_type; - return detail::raise_domain_error( - function, message ? message : "Domain Error evaluating function at %1%", - val, policy_type()); -} - -template <class T, class Policy> -inline constexpr T raise_pole_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::pole_error_type policy_type; - return detail::raise_pole_error( - function, message ? message : "Evaluation of function at pole %1%", - val, policy_type()); -} - -template <class T, class Policy> -inline constexpr T raise_overflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::overflow_error_type policy_type; - return detail::raise_overflow_error<T>( - function, message ? message : "Overflow Error", - policy_type()); -} - -template <class T, class Policy> -inline constexpr T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::overflow_error_type policy_type; - return detail::raise_overflow_error( - function, message ? message : "Overflow evaluating function at %1%", - val, policy_type()); -} - -template <class T, class Policy> -inline constexpr T raise_underflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::underflow_error_type policy_type; - return detail::raise_underflow_error<T>( - function, message ? message : "Underflow Error", - policy_type()); -} - -template <class T, class Policy> -inline constexpr T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::denorm_error_type policy_type; - return detail::raise_denorm_error<T>( - function, message ? message : "Denorm Error", - val, - policy_type()); -} - -template <class T, class Policy> -inline constexpr T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::evaluation_error_type policy_type; - return detail::raise_evaluation_error( - function, message ? message : "Internal Evaluation Error, best value so far was %1%", - val, policy_type()); -} - -template <class T, class TargetType, class Policy> -inline constexpr TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::rounding_error_type policy_type; - return detail::raise_rounding_error( - function, message ? message : "Value %1% can not be represented in the target integer type.", - val, t, policy_type()); -} - -template <class T, class R, class Policy> -inline constexpr T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T)) -{ - typedef typename Policy::indeterminate_result_error_type policy_type; - return detail::raise_indeterminate_result_error( - function, message ? message : "Indeterminate result with value %1%", - val, result, policy_type()); -} - -// -// checked_narrowing_cast: -// -namespace detail -{ - -template <class R, class T, class Policy> -inline bool check_overflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) -{ - BOOST_MATH_STD_USING - if(fabs(val) > tools::max_value<R>()) - { - boost::math::policies::detail::raise_overflow_error<R>(function, 0, pol); - *result = static_cast<R>(val); - return true; - } - return false; -} -template <class R, class T, class Policy> -inline bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) -{ - typedef typename R::value_type r_type; - r_type re, im; - bool r = check_overflow<r_type>(val.real(), &re, function, pol); - r = check_overflow<r_type>(val.imag(), &im, function, pol) || r; - *result = R(re, im); - return r; -} -template <class R, class T, class Policy> -inline bool check_underflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) -{ - if((val != 0) && (static_cast<R>(val) == 0)) - { - *result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, 0, pol)); - return true; - } - return false; -} -template <class R, class T, class Policy> -inline bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) -{ - typedef typename R::value_type r_type; - r_type re, im; - bool r = check_underflow<r_type>(val.real(), &re, function, pol); - r = check_underflow<r_type>(val.imag(), &im, function, pol) || r; - *result = R(re, im); - return r; -} -template <class R, class T, class Policy> -inline bool check_denorm(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) -{ - BOOST_MATH_STD_USING - if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0)) - { - *result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol)); - return true; - } - return false; -} -template <class R, class T, class Policy> -inline bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) -{ - typedef typename R::value_type r_type; - r_type re, im; - bool r = check_denorm<r_type>(val.real(), &re, function, pol); - r = check_denorm<r_type>(val.imag(), &im, function, pol) || r; - *result = R(re, im); - return r; -} - -// Default instantiations with ignore_error policy. -template <class R, class T> -inline constexpr bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) -{ return false; } -template <class R, class T> -inline constexpr bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) -{ return false; } -template <class R, class T> -inline constexpr bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) -{ return false; } -template <class R, class T> -inline constexpr bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) -{ return false; } -template <class R, class T> -inline constexpr bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) -{ return false; } -template <class R, class T> -inline constexpr bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) -{ return false; } - -} // namespace detail - -template <class R, class Policy, class T> -inline R checked_narrowing_cast(T val, const char* function) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value) -{ - typedef typename Policy::overflow_error_type overflow_type; - typedef typename Policy::underflow_error_type underflow_type; - typedef typename Policy::denorm_error_type denorm_type; - // - // Most of what follows will evaluate to a no-op: - // - R result = 0; - if(detail::check_overflow<R>(val, &result, function, overflow_type())) - return result; - if(detail::check_underflow<R>(val, &result, function, underflow_type())) - return result; - if(detail::check_denorm<R>(val, &result, function, denorm_type())) - return result; - - return static_cast<R>(val); -} - -template <class T, class Policy> -inline void check_series_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value) -{ - if(max_iter >= policies::get_max_series_iterations<Policy>()) - raise_evaluation_error<T>( - function, - "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol); -} - -template <class T, class Policy> -inline void check_root_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value) -{ - if(max_iter >= policies::get_max_root_iterations<Policy>()) - raise_evaluation_error<T>( - function, - "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol); -} - -} //namespace policies - -namespace detail{ - -// -// Simple helper function to assist in returning a pair from a single value, -// that value usually comes from one of the error handlers above: -// -template <class T> -std::pair<T, T> pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T) -{ - return std::make_pair(val, val); -} - -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -}} // namespaces boost/math - -#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP - diff --git a/contrib/restricted/boost/math/include/boost/math/special_functions/hypot.hpp b/contrib/restricted/boost/math/include/boost/math/special_functions/hypot.hpp deleted file mode 100644 index bfa797de80..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/special_functions/hypot.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// (C) Copyright John Maddock 2005-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_HYPOT_INCLUDED -#define BOOST_MATH_HYPOT_INCLUDED - -#ifdef _MSC_VER -#pragma once -#endif - -#include <boost/math/tools/config.hpp> -#include <boost/math/tools/precision.hpp> -#include <boost/math/policies/error_handling.hpp> -#include <boost/math/special_functions/math_fwd.hpp> -#include <algorithm> // for swap -#include <cmath> - -namespace boost{ namespace math{ namespace detail{ - -template <class T, class Policy> -T hypot_imp(T x, T y, const Policy& pol) -{ - // - // Normalize x and y, so that both are positive and x >= y: - // - using std::fabs; using std::sqrt; // ADL of std names - - x = fabs(x); - y = fabs(y); - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4127) -#endif - // special case, see C99 Annex F: - if(std::numeric_limits<T>::has_infinity - && ((x == std::numeric_limits<T>::infinity()) - || (y == std::numeric_limits<T>::infinity()))) - return policies::raise_overflow_error<T>("boost::math::hypot<%1%>(%1%,%1%)", 0, pol); -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - if(y > x) - (std::swap)(x, y); - - if(x * tools::epsilon<T>() >= y) - return x; - - T rat = y / x; - return x * sqrt(1 + rat*rat); -} // template <class T> T hypot(T x, T y) - -} - -template <class T1, class T2> -inline typename tools::promote_args<T1, T2>::type - hypot(T1 x, T2 y) -{ - typedef typename tools::promote_args<T1, T2>::type result_type; - return detail::hypot_imp( - static_cast<result_type>(x), static_cast<result_type>(y), policies::policy<>()); -} - -template <class T1, class T2, class Policy> -inline typename tools::promote_args<T1, T2>::type - hypot(T1 x, T2 y, const Policy& pol) -{ - typedef typename tools::promote_args<T1, T2>::type result_type; - return detail::hypot_imp( - static_cast<result_type>(x), static_cast<result_type>(y), pol); -} - -} // namespace math -} // namespace boost - -#endif // BOOST_MATH_HYPOT_INCLUDED - - - diff --git a/contrib/restricted/boost/math/include/boost/math/special_functions/next.hpp b/contrib/restricted/boost/math/include/boost/math/special_functions/next.hpp deleted file mode 100644 index 238766cfc9..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/special_functions/next.hpp +++ /dev/null @@ -1,906 +0,0 @@ -// (C) 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_NEXT_HPP -#define BOOST_MATH_SPECIAL_NEXT_HPP - -#ifdef _MSC_VER -#pragma once -#endif - -#include <boost/math/special_functions/math_fwd.hpp> -#include <boost/math/policies/error_handling.hpp> -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/math/special_functions/sign.hpp> -#include <boost/math/special_functions/trunc.hpp> -#include <boost/math/tools/traits.hpp> -#include <type_traits> -#include <cfloat> - - -#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) -#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) -#include "xmmintrin.h" -#define BOOST_MATH_CHECK_SSE2 -#endif -#endif - -namespace boost{ namespace math{ - - namespace concepts { - - class real_concept; - class std_real_concept; - - } - -namespace detail{ - -template <class T> -struct has_hidden_guard_digits; -template <> -struct has_hidden_guard_digits<float> : public std::false_type {}; -template <> -struct has_hidden_guard_digits<double> : public std::false_type {}; -template <> -struct has_hidden_guard_digits<long double> : public std::false_type {}; -#ifdef BOOST_HAS_FLOAT128 -template <> -struct has_hidden_guard_digits<__float128> : public std::false_type {}; -#endif -template <> -struct has_hidden_guard_digits<boost::math::concepts::real_concept> : public std::false_type {}; -template <> -struct has_hidden_guard_digits<boost::math::concepts::std_real_concept> : public std::false_type {}; - -template <class T, bool b> -struct has_hidden_guard_digits_10 : public std::false_type {}; -template <class T> -struct has_hidden_guard_digits_10<T, true> : public std::integral_constant<bool, (std::numeric_limits<T>::digits10 != std::numeric_limits<T>::max_digits10)> {}; - -template <class T> -struct has_hidden_guard_digits - : public has_hidden_guard_digits_10<T, - std::numeric_limits<T>::is_specialized - && (std::numeric_limits<T>::radix == 10) > -{}; - -template <class T> -inline const T& normalize_value(const T& val, const std::false_type&) { return val; } -template <class T> -inline T normalize_value(const T& val, const std::true_type&) -{ - static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized."); - static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized."); - - std::intmax_t shift = (std::intmax_t)std::numeric_limits<T>::digits - (std::intmax_t)ilogb(val) - 1; - T result = scalbn(val, shift); - result = round(result); - return scalbn(result, -shift); -} - -template <class T> -inline T get_smallest_value(std::true_type const&) -{ - // - // numeric_limits lies about denorms being present - particularly - // when this can be turned on or off at runtime, as is the case - // when using the SSE2 registers in DAZ or FTZ mode. - // - static const T m = std::numeric_limits<T>::denorm_min(); -#ifdef BOOST_MATH_CHECK_SSE2 - return (_mm_getcsr() & (_MM_FLUSH_ZERO_ON | 0x40)) ? tools::min_value<T>() : m; -#else - return ((tools::min_value<T>() / 2) == 0) ? tools::min_value<T>() : m; -#endif -} - -template <class T> -inline T get_smallest_value(std::false_type const&) -{ - return tools::min_value<T>(); -} - -template <class T> -inline T get_smallest_value() -{ -#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1310) - return get_smallest_value<T>(std::integral_constant<bool, std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_denorm == 1)>()); -#else - return get_smallest_value<T>(std::integral_constant<bool, std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_denorm == std::denorm_present)>()); -#endif -} - -// -// Returns the smallest value that won't generate denorms when -// we calculate the value of the least-significant-bit: -// -template <class T> -T get_min_shift_value(); - -template <class T> -struct min_shift_initializer -{ - struct init - { - init() - { - do_init(); - } - static void do_init() - { - get_min_shift_value<T>(); - } - void force_instantiate()const{} - }; - static const init initializer; - static void force_instantiate() - { - initializer.force_instantiate(); - } -}; - -template <class T> -const typename min_shift_initializer<T>::init min_shift_initializer<T>::initializer; - -template <class T> -inline T calc_min_shifted(const std::true_type&) -{ - BOOST_MATH_STD_USING - return ldexp(tools::min_value<T>(), tools::digits<T>() + 1); -} -template <class T> -inline T calc_min_shifted(const std::false_type&) -{ - static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized."); - static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized."); - - return scalbn(tools::min_value<T>(), std::numeric_limits<T>::digits + 1); -} - - -template <class T> -inline T get_min_shift_value() -{ - static const T val = calc_min_shifted<T>(std::integral_constant<bool, !std::numeric_limits<T>::is_specialized || std::numeric_limits<T>::radix == 2>()); - min_shift_initializer<T>::force_instantiate(); - - return val; -} - -template <class T, bool b = boost::math::tools::detail::has_backend_type<T>::value> -struct exponent_type -{ - typedef int type; -}; - -template <class T> -struct exponent_type<T, true> -{ - typedef typename T::backend_type::exponent_type type; -}; - -template <class T, class Policy> -T float_next_imp(const T& val, const std::true_type&, const Policy& pol) -{ - typedef typename exponent_type<T>::type exponent_type; - - BOOST_MATH_STD_USING - exponent_type expon; - static const char* function = "float_next<%1%>(%1%)"; - - int fpclass = (boost::math::fpclassify)(val); - - if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) - { - if(val < 0) - return -tools::max_value<T>(); - return policies::raise_domain_error<T>( - function, - "Argument must be finite, but got %1%", val, pol); - } - - if(val >= tools::max_value<T>()) - return policies::raise_overflow_error<T>(function, 0, pol); - - if(val == 0) - return detail::get_smallest_value<T>(); - - if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>())) - { - // - // Special case: if the value of the least significant bit is a denorm, and the result - // would not be a denorm, then shift the input, increment, and shift back. - // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. - // - return ldexp(float_next(T(ldexp(val, 2 * tools::digits<T>())), pol), -2 * tools::digits<T>()); - } - - if(-0.5f == frexp(val, &expon)) - --expon; // reduce exponent when val is a power of two, and negative. - T diff = ldexp(T(1), expon - tools::digits<T>()); - if(diff == 0) - diff = detail::get_smallest_value<T>(); - return val + diff; -} // float_next_imp -// -// Special version for some base other than 2: -// -template <class T, class Policy> -T float_next_imp(const T& val, const std::false_type&, const Policy& pol) -{ - typedef typename exponent_type<T>::type exponent_type; - - static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized."); - static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized."); - - BOOST_MATH_STD_USING - exponent_type expon; - static const char* function = "float_next<%1%>(%1%)"; - - int fpclass = (boost::math::fpclassify)(val); - - if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) - { - if(val < 0) - return -tools::max_value<T>(); - return policies::raise_domain_error<T>( - function, - "Argument must be finite, but got %1%", val, pol); - } - - if(val >= tools::max_value<T>()) - return policies::raise_overflow_error<T>(function, 0, pol); - - if(val == 0) - return detail::get_smallest_value<T>(); - - if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>())) - { - // - // Special case: if the value of the least significant bit is a denorm, and the result - // would not be a denorm, then shift the input, increment, and shift back. - // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. - // - return scalbn(float_next(T(scalbn(val, 2 * std::numeric_limits<T>::digits)), pol), -2 * std::numeric_limits<T>::digits); - } - - expon = 1 + ilogb(val); - if(-1 == scalbn(val, -expon) * std::numeric_limits<T>::radix) - --expon; // reduce exponent when val is a power of base, and negative. - T diff = scalbn(T(1), expon - std::numeric_limits<T>::digits); - if(diff == 0) - diff = detail::get_smallest_value<T>(); - return val + diff; -} // float_next_imp - -} // namespace detail - -template <class T, class Policy> -inline typename tools::promote_args<T>::type float_next(const T& val, const Policy& pol) -{ - typedef typename tools::promote_args<T>::type result_type; - return detail::float_next_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), std::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol); -} - -#if 0 //def BOOST_MSVC -// -// We used to use ::_nextafter here, but doing so fails when using -// the SSE2 registers if the FTZ or DAZ flags are set, so use our own -// - albeit slower - code instead as at least that gives the correct answer. -// -template <class Policy> -inline double float_next(const double& val, const Policy& pol) -{ - static const char* function = "float_next<%1%>(%1%)"; - - if(!(boost::math::isfinite)(val) && (val > 0)) - return policies::raise_domain_error<double>( - function, - "Argument must be finite, but got %1%", val, pol); - - if(val >= tools::max_value<double>()) - return policies::raise_overflow_error<double>(function, 0, pol); - - return ::_nextafter(val, tools::max_value<double>()); -} -#endif - -template <class T> -inline typename tools::promote_args<T>::type float_next(const T& val) -{ - return float_next(val, policies::policy<>()); -} - -namespace detail{ - -template <class T, class Policy> -T float_prior_imp(const T& val, const std::true_type&, const Policy& pol) -{ - typedef typename exponent_type<T>::type exponent_type; - - BOOST_MATH_STD_USING - exponent_type expon; - static const char* function = "float_prior<%1%>(%1%)"; - - int fpclass = (boost::math::fpclassify)(val); - - if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) - { - if(val > 0) - return tools::max_value<T>(); - return policies::raise_domain_error<T>( - function, - "Argument must be finite, but got %1%", val, pol); - } - - if(val <= -tools::max_value<T>()) - return -policies::raise_overflow_error<T>(function, 0, pol); - - if(val == 0) - return -detail::get_smallest_value<T>(); - - if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>())) - { - // - // Special case: if the value of the least significant bit is a denorm, and the result - // would not be a denorm, then shift the input, increment, and shift back. - // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. - // - return ldexp(float_prior(T(ldexp(val, 2 * tools::digits<T>())), pol), -2 * tools::digits<T>()); - } - - T remain = frexp(val, &expon); - if(remain == 0.5f) - --expon; // when val is a power of two we must reduce the exponent - T diff = ldexp(T(1), expon - tools::digits<T>()); - if(diff == 0) - diff = detail::get_smallest_value<T>(); - return val - diff; -} // float_prior_imp -// -// Special version for bases other than 2: -// -template <class T, class Policy> -T float_prior_imp(const T& val, const std::false_type&, const Policy& pol) -{ - typedef typename exponent_type<T>::type exponent_type; - - static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized."); - static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized."); - - BOOST_MATH_STD_USING - exponent_type expon; - static const char* function = "float_prior<%1%>(%1%)"; - - int fpclass = (boost::math::fpclassify)(val); - - if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) - { - if(val > 0) - return tools::max_value<T>(); - return policies::raise_domain_error<T>( - function, - "Argument must be finite, but got %1%", val, pol); - } - - if(val <= -tools::max_value<T>()) - return -policies::raise_overflow_error<T>(function, 0, pol); - - if(val == 0) - return -detail::get_smallest_value<T>(); - - if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>())) - { - // - // Special case: if the value of the least significant bit is a denorm, and the result - // would not be a denorm, then shift the input, increment, and shift back. - // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. - // - return scalbn(float_prior(T(scalbn(val, 2 * std::numeric_limits<T>::digits)), pol), -2 * std::numeric_limits<T>::digits); - } - - expon = 1 + ilogb(val); - T remain = scalbn(val, -expon); - if(remain * std::numeric_limits<T>::radix == 1) - --expon; // when val is a power of two we must reduce the exponent - T diff = scalbn(T(1), expon - std::numeric_limits<T>::digits); - if(diff == 0) - diff = detail::get_smallest_value<T>(); - return val - diff; -} // float_prior_imp - -} // namespace detail - -template <class T, class Policy> -inline typename tools::promote_args<T>::type float_prior(const T& val, const Policy& pol) -{ - typedef typename tools::promote_args<T>::type result_type; - return detail::float_prior_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), std::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol); -} - -#if 0 //def BOOST_MSVC -// -// We used to use ::_nextafter here, but doing so fails when using -// the SSE2 registers if the FTZ or DAZ flags are set, so use our own -// - albeit slower - code instead as at least that gives the correct answer. -// -template <class Policy> -inline double float_prior(const double& val, const Policy& pol) -{ - static const char* function = "float_prior<%1%>(%1%)"; - - if(!(boost::math::isfinite)(val) && (val < 0)) - return policies::raise_domain_error<double>( - function, - "Argument must be finite, but got %1%", val, pol); - - if(val <= -tools::max_value<double>()) - return -policies::raise_overflow_error<double>(function, 0, pol); - - return ::_nextafter(val, -tools::max_value<double>()); -} -#endif - -template <class T> -inline typename tools::promote_args<T>::type float_prior(const T& val) -{ - return float_prior(val, policies::policy<>()); -} - -template <class T, class U, class Policy> -inline typename tools::promote_args<T, U>::type nextafter(const T& val, const U& direction, const Policy& pol) -{ - typedef typename tools::promote_args<T, U>::type result_type; - return val < direction ? boost::math::float_next<result_type>(val, pol) : val == direction ? val : boost::math::float_prior<result_type>(val, pol); -} - -template <class T, class U> -inline typename tools::promote_args<T, U>::type nextafter(const T& val, const U& direction) -{ - return nextafter(val, direction, policies::policy<>()); -} - -namespace detail{ - -template <class T, class Policy> -T float_distance_imp(const T& a, const T& b, const std::true_type&, const Policy& pol) -{ - BOOST_MATH_STD_USING - // - // Error handling: - // - static const char* function = "float_distance<%1%>(%1%, %1%)"; - if(!(boost::math::isfinite)(a)) - return policies::raise_domain_error<T>( - function, - "Argument a must be finite, but got %1%", a, pol); - if(!(boost::math::isfinite)(b)) - return policies::raise_domain_error<T>( - function, - "Argument b must be finite, but got %1%", b, pol); - // - // Special cases: - // - if(a > b) - return -float_distance(b, a, pol); - if(a == b) - return T(0); - if(a == 0) - return 1 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol)); - if(b == 0) - return 1 + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol)); - if(boost::math::sign(a) != boost::math::sign(b)) - return 2 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol)) - + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol)); - // - // By the time we get here, both a and b must have the same sign, we want - // b > a and both positive for the following logic: - // - if(a < 0) - return float_distance(static_cast<T>(-b), static_cast<T>(-a), pol); - - BOOST_MATH_ASSERT(a >= 0); - BOOST_MATH_ASSERT(b >= a); - - int expon; - // - // Note that if a is a denorm then the usual formula fails - // because we actually have fewer than tools::digits<T>() - // significant bits in the representation: - // - (void)frexp(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value<T>() : a, &expon); - T upper = ldexp(T(1), expon); - T result = T(0); - // - // If b is greater than upper, then we *must* split the calculation - // as the size of the ULP changes with each order of magnitude change: - // - if(b > upper) - { - int expon2; - (void)frexp(b, &expon2); - T upper2 = ldexp(T(0.5), expon2); - result = float_distance(upper2, b); - result += (expon2 - expon - 1) * ldexp(T(1), tools::digits<T>() - 1); - } - // - // Use compensated double-double addition to avoid rounding - // errors in the subtraction: - // - expon = tools::digits<T>() - expon; - T mb, x, y, z; - if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value<T>())) - { - // - // Special case - either one end of the range is a denormal, or else the difference is. - // The regular code will fail if we're using the SSE2 registers on Intel and either - // the FTZ or DAZ flags are set. - // - T a2 = ldexp(a, tools::digits<T>()); - T b2 = ldexp(b, tools::digits<T>()); - mb = -(std::min)(T(ldexp(upper, tools::digits<T>())), b2); - x = a2 + mb; - z = x - a2; - y = (a2 - (x - z)) + (mb - z); - - expon -= tools::digits<T>(); - } - else - { - mb = -(std::min)(upper, b); - x = a + mb; - z = x - a; - y = (a - (x - z)) + (mb - z); - } - if(x < 0) - { - x = -x; - y = -y; - } - result += ldexp(x, expon) + ldexp(y, expon); - // - // Result must be an integer: - // - BOOST_MATH_ASSERT(result == floor(result)); - return result; -} // float_distance_imp -// -// Special versions for bases other than 2: -// -template <class T, class Policy> -T float_distance_imp(const T& a, const T& b, const std::false_type&, const Policy& pol) -{ - static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized."); - static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized."); - - BOOST_MATH_STD_USING - // - // Error handling: - // - static const char* function = "float_distance<%1%>(%1%, %1%)"; - if(!(boost::math::isfinite)(a)) - return policies::raise_domain_error<T>( - function, - "Argument a must be finite, but got %1%", a, pol); - if(!(boost::math::isfinite)(b)) - return policies::raise_domain_error<T>( - function, - "Argument b must be finite, but got %1%", b, pol); - // - // Special cases: - // - if(a > b) - return -float_distance(b, a, pol); - if(a == b) - return T(0); - if(a == 0) - return 1 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol)); - if(b == 0) - return 1 + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol)); - if(boost::math::sign(a) != boost::math::sign(b)) - return 2 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol)) - + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol)); - // - // By the time we get here, both a and b must have the same sign, we want - // b > a and both positive for the following logic: - // - if(a < 0) - return float_distance(static_cast<T>(-b), static_cast<T>(-a), pol); - - BOOST_MATH_ASSERT(a >= 0); - BOOST_MATH_ASSERT(b >= a); - - std::intmax_t expon; - // - // Note that if a is a denorm then the usual formula fails - // because we actually have fewer than tools::digits<T>() - // significant bits in the representation: - // - expon = 1 + ilogb(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value<T>() : a); - T upper = scalbn(T(1), expon); - T result = T(0); - // - // If b is greater than upper, then we *must* split the calculation - // as the size of the ULP changes with each order of magnitude change: - // - if(b > upper) - { - std::intmax_t expon2 = 1 + ilogb(b); - T upper2 = scalbn(T(1), expon2 - 1); - result = float_distance(upper2, b); - result += (expon2 - expon - 1) * scalbn(T(1), std::numeric_limits<T>::digits - 1); - } - // - // Use compensated double-double addition to avoid rounding - // errors in the subtraction: - // - expon = std::numeric_limits<T>::digits - expon; - T mb, x, y, z; - if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value<T>())) - { - // - // Special case - either one end of the range is a denormal, or else the difference is. - // The regular code will fail if we're using the SSE2 registers on Intel and either - // the FTZ or DAZ flags are set. - // - T a2 = scalbn(a, std::numeric_limits<T>::digits); - T b2 = scalbn(b, std::numeric_limits<T>::digits); - mb = -(std::min)(T(scalbn(upper, std::numeric_limits<T>::digits)), b2); - x = a2 + mb; - z = x - a2; - y = (a2 - (x - z)) + (mb - z); - - expon -= std::numeric_limits<T>::digits; - } - else - { - mb = -(std::min)(upper, b); - x = a + mb; - z = x - a; - y = (a - (x - z)) + (mb - z); - } - if(x < 0) - { - x = -x; - y = -y; - } - result += scalbn(x, expon) + scalbn(y, expon); - // - // Result must be an integer: - // - BOOST_MATH_ASSERT(result == floor(result)); - return result; -} // float_distance_imp - -} // namespace detail - -template <class T, class U, class Policy> -inline typename tools::promote_args<T, U>::type float_distance(const T& a, const U& b, const Policy& pol) -{ - // - // We allow ONE of a and b to be an integer type, otherwise both must be the SAME type. - // - static_assert( - (std::is_same<T, U>::value - || (std::is_integral<T>::value && !std::is_integral<U>::value) - || (!std::is_integral<T>::value && std::is_integral<U>::value) - || (std::numeric_limits<T>::is_specialized && std::numeric_limits<U>::is_specialized - && (std::numeric_limits<T>::digits == std::numeric_limits<U>::digits) - && (std::numeric_limits<T>::radix == std::numeric_limits<U>::radix) - && !std::numeric_limits<T>::is_integer && !std::numeric_limits<U>::is_integer)), - "Float distance between two different floating point types is undefined."); - - BOOST_IF_CONSTEXPR (!std::is_same<T, U>::value) - { - BOOST_IF_CONSTEXPR(std::is_integral<T>::value) - { - return float_distance(static_cast<U>(a), b, pol); - } - else - { - return float_distance(a, static_cast<T>(b), pol); - } - } - else - { - typedef typename tools::promote_args<T, U>::type result_type; - return detail::float_distance_imp(detail::normalize_value(static_cast<result_type>(a), typename detail::has_hidden_guard_digits<result_type>::type()), detail::normalize_value(static_cast<result_type>(b), typename detail::has_hidden_guard_digits<result_type>::type()), std::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol); - } -} - -template <class T, class U> -typename tools::promote_args<T, U>::type float_distance(const T& a, const U& b) -{ - return boost::math::float_distance(a, b, policies::policy<>()); -} - -namespace detail{ - -template <class T, class Policy> -T float_advance_imp(T val, int distance, const std::true_type&, const Policy& pol) -{ - BOOST_MATH_STD_USING - // - // Error handling: - // - static const char* function = "float_advance<%1%>(%1%, int)"; - - int fpclass = (boost::math::fpclassify)(val); - - if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) - return policies::raise_domain_error<T>( - function, - "Argument val must be finite, but got %1%", val, pol); - - if(val < 0) - return -float_advance(-val, -distance, pol); - if(distance == 0) - return val; - if(distance == 1) - return float_next(val, pol); - if(distance == -1) - return float_prior(val, pol); - - if(fabs(val) < detail::get_min_shift_value<T>()) - { - // - // Special case: if the value of the least significant bit is a denorm, - // implement in terms of float_next/float_prior. - // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. - // - if(distance > 0) - { - do{ val = float_next(val, pol); } while(--distance); - } - else - { - do{ val = float_prior(val, pol); } while(++distance); - } - return val; - } - - int expon; - (void)frexp(val, &expon); - T limit = ldexp((distance < 0 ? T(0.5f) : T(1)), expon); - if(val <= tools::min_value<T>()) - { - limit = sign(T(distance)) * tools::min_value<T>(); - } - T limit_distance = float_distance(val, limit); - while(fabs(limit_distance) < abs(distance)) - { - distance -= itrunc(limit_distance); - val = limit; - if(distance < 0) - { - limit /= 2; - expon--; - } - else - { - limit *= 2; - expon++; - } - limit_distance = float_distance(val, limit); - if(distance && (limit_distance == 0)) - { - return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); - } - } - if((0.5f == frexp(val, &expon)) && (distance < 0)) - --expon; - T diff = 0; - if(val != 0) - diff = distance * ldexp(T(1), expon - tools::digits<T>()); - if(diff == 0) - diff = distance * detail::get_smallest_value<T>(); - return val += diff; -} // float_advance_imp -// -// Special version for bases other than 2: -// -template <class T, class Policy> -T float_advance_imp(T val, int distance, const std::false_type&, const Policy& pol) -{ - static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized."); - static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized."); - - BOOST_MATH_STD_USING - // - // Error handling: - // - static const char* function = "float_advance<%1%>(%1%, int)"; - - int fpclass = (boost::math::fpclassify)(val); - - if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) - return policies::raise_domain_error<T>( - function, - "Argument val must be finite, but got %1%", val, pol); - - if(val < 0) - return -float_advance(-val, -distance, pol); - if(distance == 0) - return val; - if(distance == 1) - return float_next(val, pol); - if(distance == -1) - return float_prior(val, pol); - - if(fabs(val) < detail::get_min_shift_value<T>()) - { - // - // Special case: if the value of the least significant bit is a denorm, - // implement in terms of float_next/float_prior. - // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. - // - if(distance > 0) - { - do{ val = float_next(val, pol); } while(--distance); - } - else - { - do{ val = float_prior(val, pol); } while(++distance); - } - return val; - } - - std::intmax_t expon = 1 + ilogb(val); - T limit = scalbn(T(1), distance < 0 ? expon - 1 : expon); - if(val <= tools::min_value<T>()) - { - limit = sign(T(distance)) * tools::min_value<T>(); - } - T limit_distance = float_distance(val, limit); - while(fabs(limit_distance) < abs(distance)) - { - distance -= itrunc(limit_distance); - val = limit; - if(distance < 0) - { - limit /= std::numeric_limits<T>::radix; - expon--; - } - else - { - limit *= std::numeric_limits<T>::radix; - expon++; - } - limit_distance = float_distance(val, limit); - if(distance && (limit_distance == 0)) - { - return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); - } - } - /*expon = 1 + ilogb(val); - if((1 == scalbn(val, 1 + expon)) && (distance < 0)) - --expon;*/ - T diff = 0; - if(val != 0) - diff = distance * scalbn(T(1), expon - std::numeric_limits<T>::digits); - if(diff == 0) - diff = distance * detail::get_smallest_value<T>(); - return val += diff; -} // float_advance_imp - -} // namespace detail - -template <class T, class Policy> -inline typename tools::promote_args<T>::type float_advance(T val, int distance, const Policy& pol) -{ - typedef typename tools::promote_args<T>::type result_type; - return detail::float_advance_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), distance, std::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol); -} - -template <class T> -inline typename tools::promote_args<T>::type float_advance(const T& val, int distance) -{ - return boost::math::float_advance(val, distance, policies::policy<>()); -} - -}} // boost math namespaces - -#endif // BOOST_MATH_SPECIAL_NEXT_HPP diff --git a/contrib/restricted/boost/math/include/boost/math/special_functions/trunc.hpp b/contrib/restricted/boost/math/include/boost/math/special_functions/trunc.hpp deleted file mode 100644 index 46a2a991f8..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/special_functions/trunc.hpp +++ /dev/null @@ -1,160 +0,0 @@ -// 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_TRUNC_HPP -#define BOOST_MATH_TRUNC_HPP - -#ifdef _MSC_VER -#pragma once -#endif - -#include <type_traits> -#include <boost/math/special_functions/math_fwd.hpp> -#include <boost/math/tools/config.hpp> -#include <boost/math/policies/error_handling.hpp> -#include <boost/math/special_functions/fpclassify.hpp> - -namespace boost{ namespace math{ namespace detail{ - -template <class T, class Policy> -inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol, const std::false_type&) -{ - BOOST_MATH_STD_USING - typedef typename tools::promote_args<T>::type result_type; - if(!(boost::math::isfinite)(v)) - return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", 0, static_cast<result_type>(v), static_cast<result_type>(v), pol); - return (v >= 0) ? static_cast<result_type>(floor(v)) : static_cast<result_type>(ceil(v)); -} - -template <class T, class Policy> -inline typename tools::promote_args<T>::type trunc(const T& v, const Policy&, const std::true_type&) -{ - return v; -} - -} - -template <class T, class Policy> -inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol) -{ - return detail::trunc(v, pol, std::integral_constant<bool, detail::is_integer_for_rounding<T>::value>()); -} -template <class T> -inline typename tools::promote_args<T>::type trunc(const T& v) -{ - return trunc(v, policies::policy<>()); -} -// -// The following functions will not compile unless T has an -// implicit conversion to the integer types. For user-defined -// number types this will likely not be the case. In that case -// these functions should either be specialized for the UDT in -// question, or else overloads should be placed in the same -// namespace as the UDT: these will then be found via argument -// dependent lookup. See our concept archetypes for examples. -// -// Non-standard numeric limits syntax "(std::numeric_limits<int>::max)()" -// is to avoid macro substiution from MSVC -// https://stackoverflow.com/questions/27442885/syntax-error-with-stdnumeric-limitsmax -// -template <class T, class Policy> -inline int itrunc(const T& v, const Policy& pol) -{ - BOOST_MATH_STD_USING - typedef typename tools::promote_args<T>::type result_type; - result_type r = boost::math::trunc(v, pol); - if(r > static_cast<result_type>((std::numeric_limits<int>::max)()) || r < static_cast<result_type>((std::numeric_limits<int>::min)())) - return static_cast<int>(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0, pol)); - return static_cast<int>(r); -} -template <class T> -inline int itrunc(const T& v) -{ - return itrunc(v, policies::policy<>()); -} - -template <class T, class Policy> -inline long ltrunc(const T& v, const Policy& pol) -{ - BOOST_MATH_STD_USING - typedef typename tools::promote_args<T>::type result_type; - result_type r = boost::math::trunc(v, pol); - if(r > static_cast<result_type>((std::numeric_limits<long>::max)()) || r < static_cast<result_type>((std::numeric_limits<long>::min)())) - return static_cast<long>(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0L, pol)); - return static_cast<long>(r); -} -template <class T> -inline long ltrunc(const T& v) -{ - return ltrunc(v, policies::policy<>()); -} - -template <class T, class Policy> -inline long long lltrunc(const T& v, const Policy& pol) -{ - BOOST_MATH_STD_USING - typedef typename tools::promote_args<T>::type result_type; - result_type r = boost::math::trunc(v, pol); - if(r > static_cast<result_type>((std::numeric_limits<long long>::max)()) || - r < static_cast<result_type>((std::numeric_limits<long long>::min)())) - { - return static_cast<long long>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, static_cast<long long>(0), pol)); - } - return static_cast<long long>(r); -} -template <class T> -inline long long lltrunc(const T& v) -{ - return lltrunc(v, policies::policy<>()); -} - -template <class T, class Policy> -inline typename std::enable_if<std::is_constructible<int, T>::value, int>::type - iconvert(const T& v, const Policy&) -{ - return static_cast<int>(v); -} - -template <class T, class Policy> -inline typename std::enable_if<!std::is_constructible<int, T>::value, int>::type - iconvert(const T& v, const Policy& pol) -{ - using boost::math::itrunc; - return itrunc(v, pol); -} - -template <class T, class Policy> -inline typename std::enable_if<std::is_constructible<long, T>::value, long>::type - lconvert(const T& v, const Policy&) -{ - return static_cast<long>(v); -} - -template <class T, class Policy> -inline typename std::enable_if<!std::is_constructible<long, T>::value, long>::type - lconvert(const T& v, const Policy& pol) -{ - using boost::math::ltrunc; - return ltrunc(v, pol); -} - -template <class T, class Policy> -inline typename std::enable_if<std::is_constructible<long long, T>::value, long long>::type - llconvertert(const T& v, const Policy&) -{ - return static_cast<long long>(v); -} - -template <class T, class Policy> -inline typename std::enable_if<!std::is_constructible<long long, T>::value, long long>::type - llconvertert(const T& v, const Policy& pol) -{ - using boost::math::lltrunc; - return lltrunc(v, pol); -} - -}} // namespaces - -#endif // BOOST_MATH_TRUNC_HPP diff --git a/contrib/restricted/boost/math/include/boost/math/tools/complex.hpp b/contrib/restricted/boost/math/include/boost/math/tools/complex.hpp deleted file mode 100644 index d462ca8092..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/complex.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright John Maddock 2018. -// 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) - -// -// Tools for operator on complex as well as scalar types. -// - -#ifndef BOOST_MATH_TOOLS_COMPLEX_HPP -#define BOOST_MATH_TOOLS_COMPLEX_HPP - -#include <utility> -#include <boost/math/tools/is_detected.hpp> - -namespace boost { - namespace math { - namespace tools { - - namespace detail { - template <typename T, typename = void> - struct is_complex_type_impl - { - static constexpr bool value = false; - }; - - template <typename T> - struct is_complex_type_impl<T, void_t<decltype(std::declval<T>().real()), - decltype(std::declval<T>().imag())>> - { - static constexpr bool value = true; - }; - } // Namespace detail - - template <typename T> - struct is_complex_type : public detail::is_complex_type_impl<T> {}; - - // - // Use this trait to typecast integer literals to something - // that will interoperate with T: - // - template <class T, bool = is_complex_type<T>::value> - struct integer_scalar_type - { - typedef int type; - }; - template <class T> - struct integer_scalar_type<T, true> - { - typedef typename T::value_type type; - }; - template <class T, bool = is_complex_type<T>::value> - struct unsigned_scalar_type - { - typedef unsigned type; - }; - template <class T> - struct unsigned_scalar_type<T, true> - { - typedef typename T::value_type type; - }; - template <class T, bool = is_complex_type<T>::value> - struct scalar_type - { - typedef T type; - }; - template <class T> - struct scalar_type<T, true> - { - typedef typename T::value_type type; - }; - - -} } } - -#endif // BOOST_MATH_TOOLS_COMPLEX_HPP diff --git a/contrib/restricted/boost/math/include/boost/math/tools/convert_from_string.hpp b/contrib/restricted/boost/math/include/boost/math/tools/convert_from_string.hpp deleted file mode 100644 index fa6af219ea..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/convert_from_string.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright John Maddock 2016. -// 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_CONVERT_FROM_STRING_INCLUDED -#define BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED - -#ifdef _MSC_VER -#pragma once -#endif - -#include <type_traits> -#ifndef BOOST_MATH_STANDALONE -#include <boost/lexical_cast.hpp> -#endif - -namespace boost{ namespace math{ namespace tools{ - - template <class T> - struct convert_from_string_result - { - typedef typename std::conditional<std::is_constructible<T, const char*>::value, const char*, T>::type type; - }; - - template <class Real> - Real convert_from_string(const char* p, const std::false_type&) - { -#ifdef BOOST_MATH_NO_LEXICAL_CAST - // This function should not compile, we don't have the necessary functionality to support it: - static_assert(sizeof(Real) == 0, "boost.lexical_cast is not supported in standalone mode."); - (void)p; // Supresses -Wunused-parameter - return Real(0); -#else - return boost::lexical_cast<Real>(p); -#endif - } - template <class Real> - constexpr const char* convert_from_string(const char* p, const std::true_type&) noexcept - { - return p; - } - template <class Real> - constexpr typename convert_from_string_result<Real>::type convert_from_string(const char* p) noexcept((std::is_constructible<Real, const char*>::value)) - { - return convert_from_string<Real>(p, std::is_constructible<Real, const char*>()); - } - -} // namespace tools -} // namespace math -} // namespace boost - -#endif // BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED - diff --git a/contrib/restricted/boost/math/include/boost/math/tools/cxx03_warn.hpp b/contrib/restricted/boost/math/include/boost/math/tools/cxx03_warn.hpp deleted file mode 100644 index 7aafea7553..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/cxx03_warn.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2020 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_CXX03_WARN_HPP -#define BOOST_MATH_TOOLS_CXX03_WARN_HPP - -#include <boost/math/tools/config.hpp> - -#if defined(BOOST_NO_CXX11_NOEXCEPT) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" -#endif -#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" -#endif -#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" -#endif -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_RVALUE_REFERENCES" -#endif -#if defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_SFINAE_EXPR" -#endif -#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_AUTO_DECLARATIONS" -#endif -#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_LAMBDAS" -#endif -#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX" -#endif -#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_TUPLE" -#endif -#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_INITIALIZER_LIST" -#endif -#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_CHRONO" -#endif -#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_CONSTEXPR" -#endif -#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NULLPTR" -#endif -#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NUMERIC_LIMITS" -#endif -#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_DECLTYPE" -#endif -#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_ARRAY" -#endif -#if defined(BOOST_NO_CXX11_ALLOCATOR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_ALLOCATOR" -#endif -#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) -# define BOOST_MATH_SHOW_CXX03_WARNING -# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS" -#endif - -#ifdef BOOST_MATH_SHOW_CXX03_WARNING -// -// The above list includes everything we use, plus a few we're likely to use soon. -// As from March 2020, C++03 support is deprecated, and as from March 2021 will be removed, -// so mark up as such: -// -// March 2021(mborland): C++03 support has been removed. Replace warning with hard error. -// -#error Support for C++03 has been removed. The minimum requirement for this library is fully compliant C++11. -#endif - -#endif diff --git a/contrib/restricted/boost/math/include/boost/math/tools/is_detected.hpp b/contrib/restricted/boost/math/include/boost/math/tools/is_detected.hpp deleted file mode 100644 index 8dfe86b740..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/is_detected.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright Matt Borland 2021. -// 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) -// -// https://en.cppreference.com/w/cpp/experimental/is_detected - -#ifndef BOOST_MATH_TOOLS_IS_DETECTED_HPP -#define BOOST_MATH_TOOLS_IS_DETECTED_HPP - -#include <type_traits> - -namespace boost { namespace math { namespace tools { - -template <typename...> -using void_t = void; - -namespace detail { - -template <typename Default, typename AlwaysVoid, template<typename...> class Op, typename... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template <typename Default, template<typename...> class Op, typename... Args> -struct detector<Default, void_t<Op<Args...>>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op<Args...>; -}; - -} // Namespace detail - -// Special type to indicate detection failure -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(const nonesuch&) = delete; - void operator=(const nonesuch&) = delete; -}; - -template <template<typename...> class Op, typename... Args> -using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t; - -template <template<typename...> class Op, typename... Args> -using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type; - -template <typename Default, template<typename...> class Op, typename... Args> -using detected_or = detail::detector<Default, void, Op, Args...>; - -}}} // Namespaces boost math tools - -#endif // BOOST_MATH_TOOLS_IS_DETECTED_HPP diff --git a/contrib/restricted/boost/math/include/boost/math/tools/precision.hpp b/contrib/restricted/boost/math/include/boost/math/tools/precision.hpp deleted file mode 100644 index 1bc35d9ae1..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/precision.hpp +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright John Maddock 2005-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_PRECISION_INCLUDED -#define BOOST_MATH_TOOLS_PRECISION_INCLUDED - -#ifdef _MSC_VER -#pragma once -#endif - -#include <boost/math/tools/assert.hpp> -#include <boost/math/policies/policy.hpp> -#include <type_traits> -#include <limits> -#include <climits> -#include <cmath> -#include <cstdint> -#include <cfloat> // LDBL_MANT_DIG - -namespace boost{ namespace math -{ -namespace tools -{ -// If T is not specialized, the functions digits, max_value and min_value, -// all get synthesised automatically from std::numeric_limits. -// However, if numeric_limits is not specialised for type RealType, -// for example with NTL::RR type, then you will get a compiler error -// when code tries to use these functions, unless you explicitly specialise them. - -// For example if the precision of RealType varies at runtime, -// then numeric_limits support may not be appropriate, -// see boost/math/tools/ntl.hpp for examples like -// template <> NTL::RR max_value<NTL::RR> ... -// See Conceptual Requirements for Real Number Types. - -template <class T> -inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept -{ - static_assert( ::std::numeric_limits<T>::is_specialized, "Type T must be specialized"); - static_assert( ::std::numeric_limits<T>::radix == 2 || ::std::numeric_limits<T>::radix == 10, "Type T must have a radix of 2 or 10"); - - return std::numeric_limits<T>::radix == 2 - ? std::numeric_limits<T>::digits - : ((std::numeric_limits<T>::digits + 1) * 1000L) / 301L; -} - -template <class T> -inline constexpr T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - static_assert( ::std::numeric_limits<T>::is_specialized, "Type T must be specialized"); - return (std::numeric_limits<T>::max)(); -} // Also used as a finite 'infinite' value for - and +infinity, for example: -// -max_value<double> = -1.79769e+308, max_value<double> = 1.79769e+308. - -template <class T> -inline constexpr T min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - static_assert( ::std::numeric_limits<T>::is_specialized, "Type T must be specialized"); - - return (std::numeric_limits<T>::min)(); -} - -namespace detail{ -// -// Logarithmic limits come next, note that although -// we can compute these from the log of the max value -// that is not in general thread safe (if we cache the value) -// so it's better to specialise these: -// -// For type float first: -// -template <class T> -inline constexpr T log_max_value(const std::integral_constant<int, 128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return 88.0f; -} - -template <class T> -inline constexpr T log_min_value(const std::integral_constant<int, 128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return -87.0f; -} -// -// Now double: -// -template <class T> -inline constexpr T log_max_value(const std::integral_constant<int, 1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return 709.0; -} - -template <class T> -inline constexpr T log_min_value(const std::integral_constant<int, 1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return -708.0; -} -// -// 80 and 128-bit long doubles: -// -template <class T> -inline constexpr T log_max_value(const std::integral_constant<int, 16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return 11356.0L; -} - -template <class T> -inline constexpr T log_min_value(const std::integral_constant<int, 16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return -11355.0L; -} - -template <class T> -inline T log_max_value(const std::integral_constant<int, 0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) -{ - BOOST_MATH_STD_USING -#ifdef __SUNPRO_CC - static const T m = boost::math::tools::max_value<T>(); - static const T val = log(m); -#else - static const T val = log(boost::math::tools::max_value<T>()); -#endif - return val; -} - -template <class T> -inline T log_min_value(const std::integral_constant<int, 0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) -{ - BOOST_MATH_STD_USING -#ifdef __SUNPRO_CC - static const T m = boost::math::tools::min_value<T>(); - static const T val = log(m); -#else - static const T val = log(boost::math::tools::min_value<T>()); -#endif - return val; -} - -template <class T> -inline constexpr T epsilon(const std::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point<T>::value) -{ - return std::numeric_limits<T>::epsilon(); -} - -#if defined(__GNUC__) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) -template <> -inline constexpr long double epsilon<long double>(const std::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(long double)) noexcept(std::is_floating_point<long double>::value) -{ - // numeric_limits on Darwin (and elsewhere) tells lies here: - // the issue is that long double on a few platforms is - // really a "double double" which has a non-contiguous - // mantissa: 53 bits followed by an unspecified number of - // zero bits, followed by 53 more bits. Thus the apparent - // precision of the type varies depending where it's been. - // Set epsilon to the value that a 106 bit fixed mantissa - // type would have, as that will give us sensible behaviour everywhere. - // - // This static assert fails for some unknown reason, so - // disabled for now... - // static_assert(std::numeric_limits<long double>::digits == 106); - return 2.4651903288156618919116517665087e-32L; -} -#endif - -template <class T> -inline T epsilon(const std::false_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) -{ - // Note: don't cache result as precision may vary at runtime: - BOOST_MATH_STD_USING // for ADL of std names - return ldexp(static_cast<T>(1), 1-policies::digits<T, policies::policy<> >()); -} - -template <class T> -struct log_limit_traits -{ - typedef typename std::conditional< - (std::numeric_limits<T>::radix == 2) && - (std::numeric_limits<T>::max_exponent == 128 - || std::numeric_limits<T>::max_exponent == 1024 - || std::numeric_limits<T>::max_exponent == 16384), - std::integral_constant<int, (std::numeric_limits<T>::max_exponent > INT_MAX ? INT_MAX : static_cast<int>(std::numeric_limits<T>::max_exponent))>, - std::integral_constant<int, 0> - >::type tag_type; - static constexpr bool value = tag_type::value ? true : false; - static_assert(::std::numeric_limits<T>::is_specialized || (value == 0), "Type T must be specialized or equal to 0"); -}; - -template <class T, bool b> struct log_limit_noexcept_traits_imp : public log_limit_traits<T> {}; -template <class T> struct log_limit_noexcept_traits_imp<T, false> : public std::integral_constant<bool, false> {}; - -template <class T> -struct log_limit_noexcept_traits : public log_limit_noexcept_traits_imp<T, std::is_floating_point<T>::value> {}; - -} // namespace detail - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4309) -#endif - -template <class T> -inline constexpr T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(detail::log_limit_noexcept_traits<T>::value) -{ -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - return detail::log_max_value<T>(typename detail::log_limit_traits<T>::tag_type()); -#else - BOOST_MATH_ASSERT(::std::numeric_limits<T>::is_specialized); - BOOST_MATH_STD_USING - static const T val = log((std::numeric_limits<T>::max)()); - return val; -#endif -} - -template <class T> -inline constexpr T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(detail::log_limit_noexcept_traits<T>::value) -{ -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - return detail::log_min_value<T>(typename detail::log_limit_traits<T>::tag_type()); -#else - BOOST_MATH_ASSERT(::std::numeric_limits<T>::is_specialized); - BOOST_MATH_STD_USING - static const T val = log((std::numeric_limits<T>::min)()); - return val; -#endif -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -template <class T> -inline constexpr T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept(std::is_floating_point<T>::value) -{ -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - return detail::epsilon<T>(std::integral_constant<bool, ::std::numeric_limits<T>::is_specialized>()); -#else - return ::std::numeric_limits<T>::is_specialized ? - detail::epsilon<T>(std::true_type()) : - detail::epsilon<T>(std::false_type()); -#endif -} - -namespace detail{ - -template <class T> -inline constexpr T root_epsilon_imp(const std::integral_constant<int, 24>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.00034526698300124390839884978618400831996329879769945L); -} - -template <class T> -inline constexpr T root_epsilon_imp(const T*, const std::integral_constant<int, 53>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.1490116119384765625e-7L); -} - -template <class T> -inline constexpr T root_epsilon_imp(const T*, const std::integral_constant<int, 64>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.32927225399135962333569506281281311031656150598474e-9L); -} - -template <class T> -inline constexpr T root_epsilon_imp(const T*, const std::integral_constant<int, 113>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.1387778780781445675529539585113525390625e-16L); -} - -template <class T, class Tag> -inline T root_epsilon_imp(const T*, const Tag&) -{ - BOOST_MATH_STD_USING - static const T r_eps = sqrt(tools::epsilon<T>()); - return r_eps; -} - -template <class T> -inline T root_epsilon_imp(const T*, const std::integral_constant<int, 0>&) -{ - BOOST_MATH_STD_USING - return sqrt(tools::epsilon<T>()); -} - -template <class T> -inline constexpr T cbrt_epsilon_imp(const std::integral_constant<int, 24>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.0049215666011518482998719164346805794944150447839903L); -} - -template <class T> -inline constexpr T cbrt_epsilon_imp(const T*, const std::integral_constant<int, 53>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(6.05545445239333906078989272793696693569753008995e-6L); -} - -template <class T> -inline constexpr T cbrt_epsilon_imp(const T*, const std::integral_constant<int, 64>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(4.76837158203125e-7L); -} - -template <class T> -inline constexpr T cbrt_epsilon_imp(const T*, const std::integral_constant<int, 113>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(5.7749313854154005630396773604745549542403508090496e-12L); -} - -template <class T, class Tag> -inline T cbrt_epsilon_imp(const T*, const Tag&) -{ - BOOST_MATH_STD_USING; - static const T cbrt_eps = pow(tools::epsilon<T>(), T(1) / 3); - return cbrt_eps; -} - -template <class T> -inline T cbrt_epsilon_imp(const T*, const std::integral_constant<int, 0>&) -{ - BOOST_MATH_STD_USING; - return pow(tools::epsilon<T>(), T(1) / 3); -} - -template <class T> -inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant<int, 24>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.018581361171917516667460937040007436176452688944747L); -} - -template <class T> -inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant<int, 53>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.0001220703125L); -} - -template <class T> -inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant<int, 64>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.18145860519450699870567321328132261891067079047605e-4L); -} - -template <class T> -inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant<int, 113>&) noexcept(std::is_floating_point<T>::value) -{ - return static_cast<T>(0.37252902984619140625e-8L); -} - -template <class T, class Tag> -inline T forth_root_epsilon_imp(const T*, const Tag&) -{ - BOOST_MATH_STD_USING - static const T r_eps = sqrt(sqrt(tools::epsilon<T>())); - return r_eps; -} - -template <class T> -inline T forth_root_epsilon_imp(const T*, const std::integral_constant<int, 0>&) -{ - BOOST_MATH_STD_USING - return sqrt(sqrt(tools::epsilon<T>())); -} - -template <class T> -struct root_epsilon_traits -{ - typedef std::integral_constant<int, (::std::numeric_limits<T>::radix == 2) && (::std::numeric_limits<T>::digits != INT_MAX) ? std::numeric_limits<T>::digits : 0> tag_type; - static constexpr bool has_noexcept = (tag_type::value == 113) || (tag_type::value == 64) || (tag_type::value == 53) || (tag_type::value == 24); -}; - -} - -template <class T> -inline constexpr T root_epsilon() noexcept(std::is_floating_point<T>::value && detail::root_epsilon_traits<T>::has_noexcept) -{ - return detail::root_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type()); -} - -template <class T> -inline constexpr T cbrt_epsilon() noexcept(std::is_floating_point<T>::value && detail::root_epsilon_traits<T>::has_noexcept) -{ - return detail::cbrt_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type()); -} - -template <class T> -inline constexpr T forth_root_epsilon() noexcept(std::is_floating_point<T>::value && detail::root_epsilon_traits<T>::has_noexcept) -{ - return detail::forth_root_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type()); -} - -} // namespace tools -} // namespace math -} // namespace boost - -#endif // BOOST_MATH_TOOLS_PRECISION_INCLUDED - diff --git a/contrib/restricted/boost/math/include/boost/math/tools/throw_exception.hpp b/contrib/restricted/boost/math/include/boost/math/tools/throw_exception.hpp deleted file mode 100644 index 56a2c9c3e0..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/throw_exception.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// (C) Copyright Matt Borland 2021. -// 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_THROW_EXCEPTION_HPP -#define BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP - -#include <boost/math/tools/is_standalone.hpp> - -#ifndef BOOST_MATH_STANDALONE - -#include <boost/throw_exception.hpp> -#define BOOST_MATH_THROW_EXCEPTION(expr) boost::throw_exception(expr); - -#else // Standalone mode - use standard library facilities - -#define BOOST_MATH_THROW_EXCEPTION(expr) throw expr; - -#endif // BOOST_MATH_STANDALONE - -#endif // BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP diff --git a/contrib/restricted/boost/math/include/boost/math/tools/traits.hpp b/contrib/restricted/boost/math/include/boost/math/tools/traits.hpp deleted file mode 100644 index cd40f7f1f3..0000000000 --- a/contrib/restricted/boost/math/include/boost/math/tools/traits.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright John Maddock 2007. -// Copyright Matt Borland 2021. -// 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) - -/* -This header defines two traits classes, both in namespace boost::math::tools. - -is_distribution<D>::value is true iff D has overloaded "cdf" and -"quantile" functions, plus member typedefs value_type and policy_type. -It's not much of a definitive test frankly, -but if it looks like a distribution and quacks like a distribution -then it must be a distribution. - -is_scaled_distribution<D>::value is true iff D is a distribution -as defined above, and has member functions "scale" and "location". - -*/ - -#ifndef BOOST_STATS_IS_DISTRIBUTION_HPP -#define BOOST_STATS_IS_DISTRIBUTION_HPP - -#ifdef _MSC_VER -#pragma once -#endif - -#include <type_traits> - -namespace boost{ namespace math{ namespace tools{ - -namespace detail{ - -#define BOOST_MATH_HAS_NAMED_TRAIT(trait, name) \ -template <typename T> \ -class trait \ -{ \ -private: \ - using yes = char; \ - struct no { char x[2]; }; \ - \ - template <typename U> \ - static yes test(typename U::name* = nullptr); \ - \ - template <typename U> \ - static no test(...); \ - \ -public: \ - static constexpr bool value = (sizeof(test<T>(0)) == sizeof(char)); \ -}; - -BOOST_MATH_HAS_NAMED_TRAIT(has_value_type, value_type) -BOOST_MATH_HAS_NAMED_TRAIT(has_policy_type, policy_type) -BOOST_MATH_HAS_NAMED_TRAIT(has_backend_type, backend_type) - -template <typename D> -char cdf(const D& ...); -template <typename D> -char quantile(const D& ...); - -template <typename D> -struct has_cdf -{ - static D d; - static constexpr bool value = sizeof(cdf(d, 0.0f)) != 1; -}; - -template <typename D> -struct has_quantile -{ - static D d; - static constexpr bool value = sizeof(quantile(d, 0.0f)) != 1; -}; - -template <typename D> -struct is_distribution_imp -{ - static constexpr bool value = - has_quantile<D>::value - && has_cdf<D>::value - && has_value_type<D>::value - && has_policy_type<D>::value; -}; - -template <typename sig, sig val> -struct result_tag{}; - -template <typename D> -double test_has_location(const volatile result_tag<typename D::value_type (D::*)()const, &D::location>*); -template <typename D> -char test_has_location(...); - -template <typename D> -double test_has_scale(const volatile result_tag<typename D::value_type (D::*)()const, &D::scale>*); -template <typename D> -char test_has_scale(...); - -template <typename D, bool b> -struct is_scaled_distribution_helper -{ - static constexpr bool value = false; -}; - -template <typename D> -struct is_scaled_distribution_helper<D, true> -{ - static constexpr bool value = - (sizeof(test_has_location<D>(0)) != 1) - && - (sizeof(test_has_scale<D>(0)) != 1); -}; - -template <typename D> -struct is_scaled_distribution_imp -{ - static constexpr bool value = (::boost::math::tools::detail::is_scaled_distribution_helper<D, ::boost::math::tools::detail::is_distribution_imp<D>::value>::value); -}; - -} // namespace detail - -template <typename T> struct is_distribution : public std::integral_constant<bool, ::boost::math::tools::detail::is_distribution_imp<T>::value> {}; -template <typename T> struct is_scaled_distribution : public std::integral_constant<bool, ::boost::math::tools::detail::is_scaled_distribution_imp<T>::value> {}; - -}}} - -#endif - - diff --git a/contrib/restricted/boost/multiprecision/CMakeLists.txt b/contrib/restricted/boost/multiprecision/CMakeLists.txt deleted file mode 100644 index b7fb0528f6..0000000000 --- a/contrib/restricted/boost/multiprecision/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ - -# This file was gererated by the build system used internally in the Yandex monorepo. -# Only simple modifications are allowed (adding source-files to targets, adding simple properties -# like target_include_directories). These modifications will be ported to original -# ya.make files by maintainers. Any complex modifications which can't be ported back to the -# original buildsystem will not be accepted. - - - -add_library(restricted-boost-multiprecision INTERFACE) -target_include_directories(restricted-boost-multiprecision INTERFACE - ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/multiprecision/include -) -target_link_libraries(restricted-boost-multiprecision INTERFACE - contrib-libs-cxxsupp - yutil - restricted-boost-array - restricted-boost-assert - restricted-boost-config - restricted-boost-container_hash - restricted-boost-core - restricted-boost-integer - restricted-boost-lexical_cast - restricted-boost-math - restricted-boost-mpl - restricted-boost-predef - restricted-boost-random - restricted-boost-rational - restricted-boost-smart_ptr - restricted-boost-static_assert - restricted-boost-throw_exception - restricted-boost-type_traits -) diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int.hpp deleted file mode 100644 index 103136e16b..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int.hpp +++ /dev/null @@ -1,2358 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Copyright 2012 - 2022 John Maddock. -// Copyright 2022 Christopher Kormanyos. -// Distributed under the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt -// or copy at https://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_MP_CPP_INT_HPP -#define BOOST_MP_CPP_INT_HPP - -#include <cstdint> -#include <cstring> -#include <iostream> -#include <iomanip> -#include <type_traits> -#include <string> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/endian.hpp> -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/detail/integer_ops.hpp> -#include <boost/multiprecision/detail/rebind.hpp> -#include <boost/multiprecision/cpp_int/cpp_int_config.hpp> -#include <boost/multiprecision/rational_adaptor.hpp> -#include <boost/multiprecision/traits/is_byte_container.hpp> -#include <boost/multiprecision/cpp_int/checked.hpp> -#include <boost/multiprecision/detail/constexpr.hpp> -#include <boost/multiprecision/detail/float128_functions.hpp> -#include <boost/multiprecision/cpp_int/value_pack.hpp> -#include <boost/multiprecision/detail/empty_value.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/assert.hpp> -#include <boost/multiprecision/detail/fpclassify.hpp> - -namespace boost { -namespace multiprecision { -namespace backends { - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4307) // integral constant overflow (oveflow is in a branch not taken when it would overflow) -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4702) // Unreachable code (reachability depends on template params) -#endif -#if defined(__GNUC__) && !defined(__clang__) -// see https://github.com/boostorg/multiprecision/issues/413 -// and https://github.com/boostorg/multiprecision/issues/431 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - -template <std::size_t MinBits = 0, std::size_t MaxBits = 0, boost::multiprecision::cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = typename std::conditional<MinBits && (MinBits == MaxBits), void, std::allocator<limb_type> >::type> -struct cpp_int_backend; - -} // namespace backends - -namespace detail { - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct is_byte_container<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public std::false_type -{}; - -} // namespace detail - -namespace backends { - -namespace detail { - template <std::size_t Value1, std::size_t Value2> - struct static_unsigned_max - { - static constexpr std::size_t value = (Value1 > Value2) ? Value1 : Value2; - }; -} // Namespace detail - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, bool trivial = false> -struct cpp_int_base; -// -// Traits class determines the maximum and minimum precision values: -// -template <class T> -struct max_precision; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > -{ - static constexpr std::size_t value = std::is_void<Allocator>::value ? detail::static_unsigned_max<MinBits, MaxBits>::value - : (((MaxBits >= MinBits) && MaxBits) ? MaxBits : SIZE_MAX); -}; - -template <class T> -struct min_precision; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > -{ - static constexpr std::size_t value = (std::is_void<Allocator>::value ? detail::static_unsigned_max<MinBits, MaxBits>::value : MinBits); -}; -// -// Traits class determines whether the number of bits precision requested could fit in a native type, -// we call this a "trivial" cpp_int: -// -template <class T> -struct is_trivial_cpp_int -{ - static constexpr bool value = false; -}; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > -{ - using self = cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>; - static constexpr bool value = std::is_void<Allocator>::value && (max_precision<self>::value <= (sizeof(double_limb_type) * CHAR_BIT) - (SignType == signed_packed ? 1 : 0)); -}; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct is_trivial_cpp_int<cpp_int_base<MinBits, MaxBits, SignType, Checked, Allocator, true> > -{ - static constexpr bool value = true; -}; - -} // namespace backends -// -// Traits class to determine whether a cpp_int_backend is signed or not: -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct is_unsigned_number<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > - : public std::integral_constant<bool, (SignType == unsigned_magnitude) || (SignType == unsigned_packed)> -{}; - -namespace backends { -// -// Traits class determines whether T should be implicitly convertible to U, or -// whether the constructor should be made explicit. The latter happens if we -// are losing the sign, or have fewer digits precision in the target type: -// -template <class T, class U> -struct is_implicit_cpp_int_conversion; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -struct is_implicit_cpp_int_conversion<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > -{ - using t1 = cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>; - using t2 = cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>; - static constexpr bool value = - (is_signed_number<t2>::value || !is_signed_number<t1>::value) && (max_precision<t1>::value <= max_precision<t2>::value); -}; - -// -// Traits class to determine whether operations on a cpp_int may throw: -// -template <class T> -struct is_non_throwing_cpp_int : public std::integral_constant<bool, false> -{}; -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType> -struct is_non_throwing_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, unchecked, void> > : public std::integral_constant<bool, true> -{}; - -// -// Traits class, determines whether the cpp_int is fixed precision or not: -// -template <class T> -struct is_fixed_precision; -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct is_fixed_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > - : public std::integral_constant<bool, max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value != SIZE_MAX> -{}; - -namespace detail { - -inline BOOST_MP_CXX14_CONSTEXPR void verify_new_size(std::size_t new_size, std::size_t min_size, const std::integral_constant<int, checked>&) -{ - if (new_size < min_size) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Unable to allocate sufficient storage for the value of the result: value overflows the maximum allowable magnitude.")); -} -inline BOOST_MP_CXX14_CONSTEXPR void verify_new_size(std::size_t /*new_size*/, std::size_t /*min_size*/, const std::integral_constant<int, unchecked>&) {} - -template <class U> -inline BOOST_MP_CXX14_CONSTEXPR void verify_limb_mask(bool b, U limb, U mask, const std::integral_constant<int, checked>&) -{ - // When we mask out "limb" with "mask", do we loose bits? If so it's an overflow error: - if (b && (limb & ~mask)) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Overflow in cpp_int arithmetic: there is insufficient precision in the target type to hold all of the bits of the result.")); -} -template <class U> -inline BOOST_MP_CXX14_CONSTEXPR void verify_limb_mask(bool /*b*/, U /*limb*/, U /*mask*/, const std::integral_constant<int, unchecked>&) {} - -} // namespace detail - -// -// Now define the various data layouts that are possible as partial specializations of the base class, -// starting with the default arbitrary precision signed integer type: -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -struct cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false> - : private boost::multiprecision::detail::empty_value<typename detail::rebind<limb_type, Allocator>::type> -{ - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, bool trivial2> - friend struct cpp_int_base; - - using allocator_type = typename detail::rebind<limb_type, Allocator>::type; - using limb_pointer = typename std::allocator_traits<allocator_type>::pointer ; - using const_limb_pointer = typename std::allocator_traits<allocator_type>::const_pointer; - using checked_type = std::integral_constant<int, Checked>; - - // - // Interface invariants: - // - static_assert(!std::is_void<Allocator>::value, "Allocator must not be void here"); - - using base_type = boost::multiprecision::detail::empty_value<allocator_type>; - -private: - struct limb_data - { - std::size_t capacity; - limb_pointer data; - }; - - public: - static constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT; - static constexpr limb_type max_limb_value = ~static_cast<limb_type>(0u); - static constexpr limb_type sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1); - static constexpr std::size_t internal_limb_count = - MinBits - ? (MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)) - : (sizeof(limb_data) / sizeof(limb_type)) > 1 ? (sizeof(limb_data) / sizeof(limb_type)) : 2; - private: - union data_type - { - limb_data ld; - limb_type la[internal_limb_count]; - limb_type first; - double_limb_type double_first; - - constexpr data_type() noexcept : first(0) {} - constexpr data_type(limb_type i) noexcept : first(i) {} - constexpr data_type(signed_limb_type i) noexcept : first(static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i))) {} -#if BOOST_MP_ENDIAN_LITTLE_BYTE - constexpr data_type(double_limb_type i) noexcept : double_first(i) - {} - constexpr data_type(signed_double_limb_type i) noexcept : double_first(static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i))) {} -#endif -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900)) - constexpr data_type(limb_type* limbs, std::size_t len) noexcept : ld{ len, limbs } - {} -#else - constexpr data_type(limb_type* limbs, std::size_t len) noexcept - { - ld.capacity = len; - ld.data = limbs; - } -#endif - }; - - data_type m_data; - std::size_t m_limbs; - bool m_sign, m_internal, m_alias; - - public: - // - // Direct construction: - // - BOOST_MP_FORCEINLINE constexpr cpp_int_base(limb_type i) noexcept - : m_data(i), - m_limbs(1), - m_sign(false), - m_internal(true), - m_alias(false) {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_limb_type i) noexcept - : m_data(i), - m_limbs(1), - m_sign(i < 0), - m_internal(true), - m_alias(false) {} -#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE) - BOOST_MP_FORCEINLINE constexpr cpp_int_base(double_limb_type i) noexcept - : m_data(i), - m_limbs(i > max_limb_value ? 2 : 1), - m_sign(false), - m_internal(true), - m_alias(false) - {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_double_limb_type i) noexcept - : m_data(i), - m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > static_cast<double_limb_type>(max_limb_value) ? 2 : 1) : (i > max_limb_value ? 2 : 1)), - m_sign(i < 0), - m_internal(true), - m_alias(false) {} -#endif - // - // Aliasing constructor aliases data: - // - struct scoped_shared_storage : private boost::multiprecision::detail::empty_value<allocator_type> - { - private: - limb_type* data; - std::size_t capacity; - std::size_t allocated; - bool is_alias; - allocator_type& allocator() noexcept { return boost::multiprecision::detail::empty_value<allocator_type>::get(); } - - public: - scoped_shared_storage(const allocator_type& a, std::size_t len) - : boost::multiprecision::detail::empty_value<allocator_type>(boost::multiprecision::detail::empty_init_t(), a), capacity(len), allocated(0), is_alias(false) - { - data = allocator().allocate(len); - } - scoped_shared_storage(const cpp_int_base& i, std::size_t len) - : boost::multiprecision::detail::empty_value<allocator_type>(boost::multiprecision::detail::empty_init_t(), i.allocator()), capacity(len), allocated(0), is_alias(false) - { - data = allocator().allocate(len); - } - scoped_shared_storage(limb_type* limbs, std::size_t n) : data(limbs), capacity(n), allocated(0), is_alias(true) {} - ~scoped_shared_storage() - { - if(!is_alias) - allocator().deallocate(data, capacity); - } - limb_type* allocate(std::size_t n) noexcept - { - limb_type* result = data + allocated; - allocated += n; - BOOST_MP_ASSERT(allocated <= capacity); - return result; - } - void deallocate(std::size_t n) - { - BOOST_MP_ASSERT(n <= allocated); - allocated -= n; - } - }; - explicit constexpr cpp_int_base(limb_type* data, std::size_t offset, std::size_t len) noexcept - : m_data(data + offset, len), - m_limbs(len), - m_sign(false), - m_internal(false), - m_alias(true) {} - // This next constructor is for constructing const objects from const limb_type*'s only. - // Unfortunately we appear to have no way to assert that within the language, and the const_cast - // is a side effect of that :( - explicit constexpr cpp_int_base(const limb_type* data, std::size_t offset, std::size_t len) noexcept - : m_data(const_cast<limb_type*>(data) + offset, len), - m_limbs(len), - m_sign(false), - m_internal(false), - m_alias(true) {} - explicit cpp_int_base(scoped_shared_storage& data, std::size_t len) noexcept - : m_data(data.allocate(len), len), - m_limbs(len), - m_sign(false), - m_internal(false), - m_alias(true) {} - // - // Helper functions for getting at our internal data, and manipulating storage: - // - BOOST_MP_FORCEINLINE allocator_type& allocator() noexcept { return base_type::get(); } - BOOST_MP_FORCEINLINE const allocator_type& allocator() const noexcept { return base_type::get(); } - BOOST_MP_FORCEINLINE std::size_t size() const noexcept { return m_limbs; } - BOOST_MP_FORCEINLINE limb_pointer limbs() noexcept { return m_internal ? m_data.la : m_data.ld.data; } - BOOST_MP_FORCEINLINE const_limb_pointer limbs() const noexcept { return m_internal ? m_data.la : m_data.ld.data; } - BOOST_MP_FORCEINLINE std::size_t capacity() const noexcept { return m_internal ? internal_limb_count : m_data.ld.capacity; } - BOOST_MP_FORCEINLINE bool sign() const noexcept { return m_sign; } - void sign(bool b) noexcept - { - m_sign = b; - // Check for zero value: - if (m_sign && (m_limbs == 1)) - { - if (limbs()[0] == 0) - m_sign = false; - } - } - void resize(std::size_t new_size, std::size_t min_size) - { - constexpr std::size_t max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0); - // We never resize beyond MaxSize: - if (new_size > max_limbs) - new_size = max_limbs; - detail::verify_new_size(new_size, min_size, checked_type()); - // See if we have enough capacity already: - std::size_t cap = capacity(); - if (new_size > cap) - { - // We must not be an alias, memory allocation here defeats the whole point of aliasing: - BOOST_MP_ASSERT(!m_alias); - // Allocate a new buffer and copy everything over: - cap = (std::min)((std::max)(cap * 4, new_size), max_limbs); - limb_pointer pl = allocator().allocate(cap); - std::memcpy(pl, limbs(), size() * sizeof(limbs()[0])); - if (!m_internal && !m_alias) - allocator().deallocate(limbs(), capacity()); - else - m_internal = false; - m_limbs = new_size; - m_data.ld.capacity = cap; - m_data.ld.data = pl; - } - else - { - m_limbs = new_size; - } - } - BOOST_MP_FORCEINLINE void normalize() noexcept - { - limb_pointer p = limbs(); - while ((m_limbs - 1) && !p[m_limbs - 1]) - --m_limbs; - } - BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_data(), m_limbs(1), m_sign(false), m_internal(true), m_alias(false){} - BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) : base_type(o), m_limbs(o.m_alias ? o.m_limbs : 0), m_sign(o.m_sign), m_internal(o.m_alias ? false : true), m_alias(o.m_alias) - { - if (m_alias) - { - m_data.ld = o.m_data.ld; - } - else - { - resize(o.size(), o.size()); - std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0])); - } - } - // rvalue copy: - cpp_int_base(cpp_int_base&& o) - : base_type(static_cast<base_type&&>(o)), m_limbs(o.m_limbs), m_sign(o.m_sign), m_internal(o.m_internal), m_alias(o.m_alias) - { - if (m_internal) - { - std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0])); - } - else - { - m_data.ld = o.m_data.ld; - o.m_limbs = 0; - o.m_internal = true; - } - } - cpp_int_base& operator=(cpp_int_base&& o) noexcept - { - if (!m_internal && !m_alias) - allocator().deallocate(m_data.ld.data, m_data.ld.capacity); - *static_cast<base_type*>(this) = static_cast<base_type&&>(o); - m_limbs = o.m_limbs; - m_sign = o.m_sign; - m_internal = o.m_internal; - m_alias = o.m_alias; - if (m_internal) - { - std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0])); - } - else - { - m_data.ld = o.m_data.ld; - o.m_limbs = 0; - o.m_internal = true; - } - return *this; - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_int_check_type Checked2> - cpp_int_base& operator=(cpp_int_base<MinBits2, MaxBits2, signed_magnitude, Checked2, Allocator>&& o) noexcept - { - if(o.m_internal) - { - m_sign = o.m_sign; - this->resize(o.size(), o.size()); - std::memcpy(this->limbs(), o.limbs(), o.size() * sizeof(*(o.limbs()))); - return *this; - } - if (!m_internal && !m_alias) - allocator().deallocate(m_data.ld.data, m_data.ld.capacity); - *static_cast<base_type*>(this) = static_cast<typename cpp_int_base<MinBits2, MaxBits2, signed_magnitude, Checked2, Allocator>::base_type&&>(o); - m_limbs = o.m_limbs; - m_sign = o.m_sign; - m_internal = o.m_internal; - m_alias = o.m_alias; - m_data.ld.capacity = o.m_data.ld.capacity; - m_data.ld.data = o.limbs(); - o.m_limbs = 0; - o.m_internal = true; - return *this; - } - BOOST_MP_FORCEINLINE ~cpp_int_base() noexcept - { - if (!m_internal && !m_alias) - allocator().deallocate(limbs(), capacity()); - } - void assign(const cpp_int_base& o) - { - if (this != &o) - { - static_cast<base_type&>(*this) = static_cast<const base_type&>(o); - m_limbs = 0; - resize(o.size(), o.size()); - std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0])); - m_sign = o.m_sign; - } - } - BOOST_MP_FORCEINLINE void negate() noexcept - { - m_sign = !m_sign; - // Check for zero value: - if (m_sign && (m_limbs == 1)) - { - if (limbs()[0] == 0) - m_sign = false; - } - } - BOOST_MP_FORCEINLINE bool isneg() const noexcept - { - return m_sign; - } - BOOST_MP_FORCEINLINE void do_swap(cpp_int_base& o) noexcept - { - std::swap(m_data, o.m_data); - std::swap(m_sign, o.m_sign); - std::swap(m_internal, o.m_internal); - std::swap(m_limbs, o.m_limbs); - std::swap(m_alias, o.m_alias); - } - - protected: - template <class A> - void check_in_range(const A&) noexcept {} -}; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -constexpr std::size_t cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::limb_bits; -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -constexpr limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::max_limb_value; -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -constexpr limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::sign_bit_mask; -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -constexpr std::size_t cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::internal_limb_count; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -struct cpp_int_base<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator, false> - : private boost::multiprecision::detail::empty_value<typename detail::rebind<limb_type, Allocator>::type> -{ - // - // There is currently no support for unsigned arbitrary precision arithmetic, largely - // because it's not clear what subtraction should do: - // - static_assert(((sizeof(Allocator) == 0) && !std::is_void<Allocator>::value), "There is curently no support for unsigned arbitrary precision integers."); -}; -// -// Fixed precision (i.e. no allocator), signed-magnitude type with limb-usage count: -// -template <std::size_t MinBits, cpp_int_check_type Checked> -struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false> -{ - using limb_pointer = limb_type* ; - using const_limb_pointer = const limb_type* ; - using checked_type = std::integral_constant<int, Checked>; - - struct scoped_shared_storage - { - BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {} - BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {} - }; - - // - // Interface invariants: - // - static_assert(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?"); - - public: - static constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT; - static constexpr limb_type max_limb_value = ~static_cast<limb_type>(0u); - static constexpr limb_type sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1); - static constexpr std::size_t internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0); - static constexpr limb_type upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) - 1 : (~limb_type(0)); - static_assert(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs"); - - private: - union data_type - { - limb_type m_data[internal_limb_count]; - limb_type m_first_limb; - double_limb_type m_double_first_limb; - - constexpr data_type() - : m_data{0} - {} - constexpr data_type(limb_type i) - : m_data{i} - {} -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - constexpr data_type(limb_type i, limb_type j) : m_data{i, j} - {} -#endif - constexpr data_type(double_limb_type i) : m_double_first_limb(i) - { -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(m_double_first_limb)) - { - data_type t(static_cast<limb_type>(i & max_limb_value), static_cast<limb_type>(i >> limb_bits)); - *this = t; - } -#endif - } - template <limb_type... VALUES> - constexpr data_type(literals::detail::value_pack<VALUES...>) : m_data{VALUES...} - {} - } m_wrapper; - std::uint16_t m_limbs; - bool m_sign; - - public: - // - // Direct construction: - // - BOOST_MP_FORCEINLINE constexpr cpp_int_base(limb_type i) noexcept - : m_wrapper(i), - m_limbs(1), - m_sign(false) {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_limb_type i) noexcept - : m_wrapper(limb_type(i < 0 ? static_cast<limb_type>(-static_cast<signed_double_limb_type>(i)) : i)), - m_limbs(1), - m_sign(i < 0) {} -#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE) - BOOST_MP_FORCEINLINE constexpr cpp_int_base(double_limb_type i) noexcept - : m_wrapper(i), - m_limbs(i > max_limb_value ? 2 : 1), - m_sign(false) - {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(signed_double_limb_type i) noexcept - : m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)), - m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)), - m_sign(i < 0) {} -#endif - template <limb_type... VALUES> - constexpr cpp_int_base(literals::detail::value_pack<VALUES...> i) - : m_wrapper(i), m_limbs(sizeof...(VALUES)), m_sign(false) - {} - constexpr cpp_int_base(literals::detail::value_pack<> i) - : m_wrapper(i), m_limbs(1), m_sign(false) {} - constexpr cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&) - : m_wrapper(a.m_wrapper), m_limbs(a.m_limbs), m_sign((a.m_limbs == 1) && (*a.limbs() == 0) ? false : !a.m_sign) {} - explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_wrapper(), m_limbs(0), m_sign(false) - {} - // - // These are deprecated in C++20 unless we make them explicit: - // - BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default; - // - // Helper functions for getting at our internal data, and manipulating storage: - // - BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return m_limbs; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return m_wrapper.m_data; } - BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return m_wrapper.m_data; } - BOOST_MP_FORCEINLINE constexpr bool sign() const noexcept { return m_sign; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept - { - m_sign = b; - // Check for zero value: - if (m_sign && (m_limbs == 1)) - { - if (limbs()[0] == 0) - m_sign = false; - } - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(std::size_t new_size, std::size_t min_size) noexcept((Checked == unchecked)) - { - m_limbs = static_cast<std::uint16_t>((std::min)(new_size, internal_limb_count)); - detail::verify_new_size(m_limbs, min_size, checked_type()); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked)) - { - limb_pointer p = limbs(); - detail::verify_limb_mask(m_limbs == internal_limb_count, p[m_limbs - 1], upper_limb_mask, checked_type()); - p[internal_limb_count - 1] &= upper_limb_mask; - while ((m_limbs - 1) && !p[m_limbs - 1]) - --m_limbs; - if ((m_limbs == 1) && (!*p)) - m_sign = false; // zero is always unsigned - } - - BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_wrapper(limb_type(0u)), m_limbs(1), m_sign(false) {} - // Not defaulted, it breaks constexpr support in the Intel compiler for some reason: - BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept - : m_wrapper(o.m_wrapper), - m_limbs(o.m_limbs), - m_sign(o.m_sign) {} - // Defaulted functions: - //~cpp_int_base() noexcept {} - - void BOOST_MP_CXX14_CONSTEXPR assign(const cpp_int_base& o) noexcept - { - if (this != &o) - { - m_limbs = o.m_limbs; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(m_limbs)) - { - for (std::size_t i = 0; i < m_limbs; ++i) - limbs()[i] = o.limbs()[i]; - } - else -#endif - std::memcpy(limbs(), o.limbs(), o.size() * sizeof(o.limbs()[0])); - m_sign = o.m_sign; - } - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate() noexcept - { - m_sign = !m_sign; - // Check for zero value: - if (m_sign && (m_limbs == 1)) - { - if (limbs()[0] == 0) - m_sign = false; - } - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool isneg() const noexcept - { - return m_sign; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept - { - for (std::size_t i = 0; i < (std::max)(size(), o.size()); ++i) - std_constexpr::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]); - std_constexpr::swap(m_sign, o.m_sign); - std_constexpr::swap(m_limbs, o.m_limbs); - } - - protected: - template <class A> - BOOST_MP_CXX14_CONSTEXPR void check_in_range(const A&) noexcept {} -}; - -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr std::size_t cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::limb_bits; -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::max_limb_value; -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::sign_bit_mask; -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr std::size_t cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::internal_limb_count; -// -// Fixed precision (i.e. no allocator), unsigned type with limb-usage count: -// -template <std::size_t MinBits, cpp_int_check_type Checked> -struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false> -{ - using limb_pointer = limb_type* ; - using const_limb_pointer = const limb_type* ; - using checked_type = std::integral_constant<int, Checked>; - - struct scoped_shared_storage - { - BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {} - BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {} - }; - // - // Interface invariants: - // - static_assert(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?"); - - public: - static constexpr std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT; - static constexpr limb_type max_limb_value = ~static_cast<limb_type>(0u); - static constexpr limb_type sign_bit_mask = static_cast<limb_type>(1u) << (limb_bits - 1); - static constexpr std::size_t internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0); - static constexpr limb_type upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) - 1 : (~limb_type(0)); - static_assert(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs"); - - private: - union data_type - { - limb_type m_data[internal_limb_count]; - limb_type m_first_limb; - double_limb_type m_double_first_limb; - - constexpr data_type() - : m_data{0} - {} - constexpr data_type(limb_type i) - : m_data{i} - {} -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - constexpr data_type(limb_type i, limb_type j) : m_data{i, j} - {} -#endif - constexpr data_type(double_limb_type i) : m_double_first_limb(i) - { -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(m_double_first_limb)) - { - data_type t(static_cast<limb_type>(i & max_limb_value), static_cast<limb_type>(i >> limb_bits)); - *this = t; - } -#endif - } - template <limb_type... VALUES> - constexpr data_type(literals::detail::value_pack<VALUES...>) : m_data{VALUES...} - {} - } m_wrapper; - std::size_t m_limbs; - - public: - // - // Direct construction: - // - BOOST_MP_FORCEINLINE constexpr cpp_int_base(limb_type i) noexcept - : m_wrapper(i), - m_limbs(1) {} - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(signed_limb_type i) noexcept((Checked == unchecked)) - : m_wrapper(static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i))), - m_limbs(1) - { - if (i < 0) - negate(); - } -#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE) - BOOST_MP_FORCEINLINE constexpr cpp_int_base(double_limb_type i) noexcept - : m_wrapper(i), - m_limbs(i > max_limb_value ? 2 : 1) - {} - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(signed_double_limb_type i) noexcept((Checked == unchecked)) - : m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)), - m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)) - { - if (i < 0) - negate(); - } -#endif - template <limb_type... VALUES> - constexpr cpp_int_base(literals::detail::value_pack<VALUES...> i) - : m_wrapper(i), m_limbs(sizeof...(VALUES)) - {} - constexpr cpp_int_base(literals::detail::value_pack<>) - : m_wrapper(static_cast<limb_type>(0u)), m_limbs(1) {} - explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_wrapper(), m_limbs(1) - {} - // - // Helper functions for getting at our internal data, and manipulating storage: - // - BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return m_limbs; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return m_wrapper.m_data; } - BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return m_wrapper.m_data; } - BOOST_MP_FORCEINLINE constexpr bool sign() const noexcept { return false; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept((Checked == unchecked)) - { - if (b) - negate(); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(std::size_t new_size, std::size_t min_size) noexcept((Checked == unchecked)) - { - m_limbs = (std::min)(new_size, internal_limb_count); - detail::verify_new_size(m_limbs, min_size, checked_type()); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked)) - { - limb_pointer p = limbs(); - detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count - 1], upper_limb_mask, checked_type()); - p[internal_limb_count - 1] &= upper_limb_mask; - while ((m_limbs - 1) && !p[m_limbs - 1]) - --m_limbs; - } - - BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept - : m_wrapper(limb_type(0u)), - m_limbs(1) {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept - : m_wrapper(o.m_wrapper), - m_limbs(o.m_limbs) {} - // Defaulted functions: - //~cpp_int_base() noexcept {} - // - // These are deprecated in C++20 unless we make them explicit: - // - BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default; - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void assign(const cpp_int_base& o) noexcept - { - if (this != &o) - { - m_limbs = o.m_limbs; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(m_limbs)) - { - for (std::size_t i = 0; i < m_limbs; ++i) - limbs()[i] = o.limbs()[i]; - } - else -#endif - std::memcpy(limbs(), o.limbs(), o.size() * sizeof(limbs()[0])); - } - } - - private: - void check_negate(const std::integral_constant<int, checked>&) - { - BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned number.")); - } - BOOST_MP_CXX14_CONSTEXPR void check_negate(const std::integral_constant<int, unchecked>&) {} - - public: - BOOST_MP_CXX14_CONSTEXPR void negate() noexcept((Checked == unchecked)) - { - // Not so much a negate as a complement - this gets called when subtraction - // would result in a "negative" number: - if ((m_limbs == 1) && (m_wrapper.m_data[0] == 0)) - return; // negating zero is always zero, and always OK. - check_negate(checked_type()); - std::size_t i = m_limbs; - for (; i < internal_limb_count; ++i) - m_wrapper.m_data[i] = 0; - m_limbs = internal_limb_count; - for (i = 0; i < internal_limb_count; ++i) - m_wrapper.m_data[i] = ~m_wrapper.m_data[i]; - normalize(); - eval_increment(static_cast<cpp_int_backend<MinBits, MinBits, unsigned_magnitude, Checked, void>&>(*this)); - } - BOOST_MP_FORCEINLINE constexpr bool isneg() const noexcept - { - return false; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept - { - for (std::size_t i = 0; i < (std::max)(size(), o.size()); ++i) - std_constexpr::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]); - std_constexpr::swap(m_limbs, o.m_limbs); - } - - protected: - template <class A> - BOOST_MP_CXX14_CONSTEXPR void check_in_range(const A&) noexcept {} -}; - -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr std::size_t cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::limb_bits; -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::max_limb_value; -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::sign_bit_mask; -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr std::size_t cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::internal_limb_count; -// -// Traits classes to figure out a native type with N bits, these vary from boost::uint_t<N> only -// because some platforms have native integer types longer than long long, "really long long" anyone?? -// -template <unsigned N, bool s> -struct trivial_limb_type_imp -{ - using type = double_limb_type; -}; - -template <unsigned N> -struct trivial_limb_type_imp<N, true> -{ - using type = typename boost::multiprecision::detail::uint_t<N>::least; -}; - -template <unsigned N> -struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT> -{}; -// -// Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type": -// -template <std::size_t MinBits, cpp_int_check_type Checked> -struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, true> -{ - using local_limb_type = typename trivial_limb_type<static_cast<unsigned>(MinBits)>::type; - using limb_pointer = local_limb_type*; - using const_limb_pointer = const local_limb_type*; - using checked_type = std::integral_constant<int, Checked>; - - struct scoped_shared_storage - { - BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {} - BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {} - }; - - protected: - static constexpr std::size_t limb_bits = sizeof(local_limb_type) * CHAR_BIT; - static constexpr local_limb_type limb_mask = (MinBits < limb_bits) ? local_limb_type((local_limb_type(~local_limb_type(0))) >> (limb_bits - MinBits)) : local_limb_type(~local_limb_type(0)); - - private: - local_limb_type m_data; - bool m_sign; - - // - // Interface invariants: - // - static_assert(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?"); - - protected: - template <class T> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(!boost::multiprecision::detail::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= static_cast<int>(MinBits))))>::type - check_in_range(T val, const std::integral_constant<int, checked>&) - { - using common_type = typename std::common_type<typename boost::multiprecision::detail::make_unsigned<T>::type, local_limb_type>::type; - - if (static_cast<common_type>(boost::multiprecision::detail::unsigned_abs(val)) > static_cast<common_type>(limb_mask)) - BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent.")); - } - template <class T> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::detail::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= static_cast<int>(MinBits))))>::type - check_in_range(T val, const std::integral_constant<int, checked>&) - { - using std::abs; - using common_type = typename std::common_type<T, local_limb_type>::type; - - if (static_cast<common_type>(abs(val)) > static_cast<common_type>(limb_mask)) - BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent.")); - } - template <class T, int C> - BOOST_MP_CXX14_CONSTEXPR void check_in_range(T, const std::integral_constant<int, C>&) noexcept {} - - template <class T> - BOOST_MP_CXX14_CONSTEXPR void check_in_range(T val) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type()))) - { - check_in_range(val, checked_type()); - } - - public: - // - // Direct construction: - // - template <class SI> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) - : m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename boost::multiprecision::detail::make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0) {} - template <class SI> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) - : m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename boost::multiprecision::detail::make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0) - { - check_in_range(i); - } - template <class UI> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(static_cast<local_limb_type>(i) & limb_mask), - m_sign(false) {} - template <class UI> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) - : m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) { check_in_range(i); } -#if !(defined(__clang__) && defined(__MINGW32__)) - template <class F> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(static_cast<local_limb_type>(i < 0 ? -i : i) & limb_mask), - m_sign(i < 0) {} - template <class F> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == checked)>::type const* = nullptr) - : m_data(static_cast<local_limb_type>(i < 0 ? -i : i) & limb_mask), m_sign(i < 0) { check_in_range(i); } -#else - // - // conversion from float to __int128 is broken on clang/mingw, - // see: https://bugs.llvm.org/show_bug.cgi?id=48940 - // Since no floating point type has more than 64 bits of - // precision, we can simply cast to an intermediate type to - // solve the issue: - // - template <class F> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(static_cast<local_limb_type>(static_cast<std::uint64_t>(i < 0 ? -i : i)) & limb_mask), - m_sign(i < 0) {} - template <class F> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value && (Checked == checked)>::type const* = nullptr) - : m_data(static_cast<local_limb_type>(static_cast<std::uint64_t>(i < 0 ? -i : i)) & limb_mask), m_sign(i < 0) { check_in_range(i); } -#endif - - constexpr cpp_int_base(literals::detail::value_pack<>) noexcept - : m_data(static_cast<local_limb_type>(0u)), - m_sign(false) - {} - template <limb_type a> - constexpr cpp_int_base(literals::detail::value_pack<a>) noexcept - : m_data(static_cast<local_limb_type>(a)), - m_sign(false) {} - template <limb_type a, limb_type b> - constexpr cpp_int_base(literals::detail::value_pack<a, b>) noexcept - : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)), - m_sign(false) {} - constexpr cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&) noexcept - : m_data(a.m_data), - m_sign(a.m_data ? !a.m_sign : false) {} - // - // These are deprecated in C++20 unless we make them explicit: - // - BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default; - - explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_data(0), m_sign(false) - {} - // - // Helper functions for getting at our internal data, and manipulating storage: - // - BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return 1; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return &m_data; } - BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return &m_data; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool sign() const noexcept { return m_sign; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept - { - m_sign = b; - // Check for zero value: - if (m_sign && !m_data) - { - m_sign = false; - } - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(std::size_t /* new_size */, std::size_t min_size) - { - detail::verify_new_size(2, min_size, checked_type()); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked)) - { - if (!m_data) - m_sign = false; // zero is always unsigned - detail::verify_limb_mask(true, m_data, limb_mask, checked_type()); - m_data &= limb_mask; - } - - BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_data(0), m_sign(false) {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept - : m_data(o.m_data), - m_sign(o.m_sign) {} - //~cpp_int_base() noexcept {} - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void assign(const cpp_int_base& o) noexcept - { - m_data = o.m_data; - m_sign = o.m_sign; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate() noexcept - { - m_sign = !m_sign; - // Check for zero value: - if (m_data == 0) - { - m_sign = false; - } - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool isneg() const noexcept - { - return m_sign; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept - { - std_constexpr::swap(m_sign, o.m_sign); - std_constexpr::swap(m_data, o.m_data); - } -}; -// -// Backend for unsigned fixed precision (i.e. no allocator) type which will fit entirely inside a "double_limb_type": -// -template <std::size_t MinBits, cpp_int_check_type Checked> -struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, true> -{ - using local_limb_type = typename trivial_limb_type<static_cast<unsigned>(MinBits)>::type; - using limb_pointer = local_limb_type* ; - using const_limb_pointer = const local_limb_type* ; - - struct scoped_shared_storage - { - BOOST_MP_CXX14_CONSTEXPR scoped_shared_storage(const cpp_int_base&, std::size_t) {} - BOOST_MP_CXX14_CONSTEXPR void deallocate(std::size_t) {} - }; - - private: - static constexpr std::size_t limb_bits = sizeof(local_limb_type) * CHAR_BIT; - static constexpr local_limb_type limb_mask = limb_bits != MinBits ? static_cast<local_limb_type>(static_cast<local_limb_type>(~local_limb_type(0)) >> (limb_bits - MinBits)) - : static_cast<local_limb_type>(~local_limb_type(0)); - - local_limb_type m_data; - - using checked_type = std::integral_constant<int, Checked>; - - // - // Interface invariants: - // - static_assert(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?"); - - protected: - template <class T> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !(std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= static_cast<int>(MinBits)))>::type - check_in_range(T val, const std::integral_constant<int, checked>&, const std::integral_constant<bool, false>&) - { - using common_type = typename std::common_type<T, local_limb_type>::type; - - if (static_cast<common_type>(val) > limb_mask) - BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent.")); - } - template <class T> - BOOST_MP_CXX14_CONSTEXPR void check_in_range(T val, const std::integral_constant<int, checked>&, const std::integral_constant<bool, true>&) - { - using common_type = typename std::common_type<T, local_limb_type>::type; - - if (static_cast<common_type>(val) > static_cast<common_type>(limb_mask)) - BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent.")); - if (val < 0) - BOOST_MP_THROW_EXCEPTION(std::range_error("The argument to an unsigned cpp_int constructor was negative.")); - } - template <class T, int C, bool B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void check_in_range(T, const std::integral_constant<int, C>&, const std::integral_constant<bool, B>&) noexcept {} - - template <class T> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void check_in_range(T val) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), boost::multiprecision::detail::is_signed<T>()))) - { - check_in_range(val, checked_type(), boost::multiprecision::detail::is_signed<T>()); - } - - public: - // - // Direct construction: - // -#ifdef __MSVC_RUNTIME_CHECKS - template <class SI> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i & limb_mask)) & limb_mask : static_cast<local_limb_type>(i & limb_mask)) - {} - template <class SI> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) - : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i & limb_mask) : static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); } - template <class UI> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(static_cast<local_limb_type>(i& limb_mask)) {} - template <class UI> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) - : m_data(static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); } -#else - template <class SI> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i)) & limb_mask : static_cast<local_limb_type>(i) & limb_mask) - {} - template <class SI> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(SI i, typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) - : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) { check_in_range(i); } - template <class UI> - BOOST_MP_FORCEINLINE constexpr cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == unchecked)>::type const* = nullptr) noexcept - : m_data(static_cast<local_limb_type>(i) & limb_mask) {} - template <class UI> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(UI i, typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (Checked == checked)>::type const* = nullptr) noexcept(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) - : m_data(static_cast<local_limb_type>(i)) { check_in_range(i); } -#endif - template <class F> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_base(F i, typename std::enable_if<std::is_floating_point<F>::value >::type const* = nullptr) noexcept((Checked == unchecked)) - : m_data(static_cast<local_limb_type>(i < 0 ? -i : i) & limb_mask) - { - check_in_range(i); - if (i < 0) - negate(); - } - constexpr cpp_int_base(literals::detail::value_pack<>) noexcept - : m_data(static_cast<local_limb_type>(0u)) - {} - template <limb_type a> - constexpr cpp_int_base(literals::detail::value_pack<a>) noexcept - : m_data(static_cast<local_limb_type>(a)) {} - template <limb_type a, limb_type b> - constexpr cpp_int_base(literals::detail::value_pack<a, b>) noexcept - : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)) {} - // - // These are deprecated in C++20 unless we make them explicit: - // - BOOST_MP_CXX14_CONSTEXPR cpp_int_base& operator=(const cpp_int_base&) = default; - - explicit constexpr cpp_int_base(scoped_shared_storage&, std::size_t) noexcept : m_data(0) - {} - // - // Helper functions for getting at our internal data, and manipulating storage: - // - BOOST_MP_FORCEINLINE constexpr std::size_t size() const noexcept { return 1; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_pointer limbs() noexcept { return &m_data; } - BOOST_MP_FORCEINLINE constexpr const_limb_pointer limbs() const noexcept { return &m_data; } - BOOST_MP_FORCEINLINE constexpr bool sign() const noexcept { return false; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void sign(bool b) noexcept((Checked == unchecked)) - { - if (b) - negate(); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void resize(unsigned, std::size_t min_size) - { - detail::verify_new_size(2, min_size, checked_type()); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void normalize() noexcept((Checked == unchecked)) - { - detail::verify_limb_mask(true, m_data, limb_mask, checked_type()); - m_data &= limb_mask; - } - - BOOST_MP_FORCEINLINE constexpr cpp_int_base() noexcept : m_data(0) {} - BOOST_MP_FORCEINLINE constexpr cpp_int_base(const cpp_int_base& o) noexcept - : m_data(o.m_data) {} - //~cpp_int_base() noexcept {} - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void assign(const cpp_int_base& o) noexcept - { - m_data = o.m_data; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate() - #if !defined(BOOST_NO_CXX17_IF_CONSTEXPR) - noexcept((Checked == unchecked)) - #endif - { - BOOST_IF_CONSTEXPR(Checked == checked) - { - BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned type.")); - } - m_data = ~m_data; - ++m_data; - } - BOOST_MP_FORCEINLINE constexpr bool isneg() const noexcept - { - return false; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void do_swap(cpp_int_base& o) noexcept - { - std_constexpr::swap(m_data, o.m_data); - } -}; -// -// Traits class, lets us know whether type T can be directly converted to the base type, -// used to enable/disable constructors etc: -// -template <class Arg, class Base> -struct is_allowed_cpp_int_base_conversion : public std::conditional< - std::is_same<Arg, limb_type>::value || std::is_same<Arg, signed_limb_type>::value -#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE) - || std::is_same<Arg, double_limb_type>::value || std::is_same<Arg, signed_double_limb_type>::value -#endif - || literals::detail::is_value_pack<Arg>::value || (is_trivial_cpp_int<Base>::value && boost::multiprecision::detail::is_arithmetic<Arg>::value), - std::integral_constant<bool, true>, - std::integral_constant<bool, false>>::type -{}; -// -// Now the actual backend, normalising parameters passed to the base class: -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct cpp_int_backend - : public cpp_int_base< - min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, - max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, - SignType, - Checked, - Allocator, - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value> -{ - using self_type = cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>; - using base_type = cpp_int_base< - min_precision<self_type>::value, - max_precision<self_type>::value, - SignType, - Checked, - Allocator, - is_trivial_cpp_int<self_type>::value>; - using trivial_tag = std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>; - - public: - using signed_types = typename std::conditional< - is_trivial_cpp_int<self_type>::value, - std::tuple< - signed char, short, int, long, - long long, signed_double_limb_type>, - std::tuple<signed_limb_type, signed_double_limb_type> >::type; - using unsigned_types = typename std::conditional< - is_trivial_cpp_int<self_type>::value, - std::tuple<unsigned char, unsigned short, unsigned, - unsigned long, unsigned long long, double_limb_type>, - std::tuple<limb_type, double_limb_type> >::type; - using float_types = typename std::conditional< - is_trivial_cpp_int<self_type>::value, - std::tuple<float, double, long double>, - std::tuple<long double> >::type; - using checked_type = std::integral_constant<int, Checked> ; - - BOOST_MP_FORCEINLINE constexpr cpp_int_backend() noexcept {} - BOOST_MP_FORCEINLINE constexpr cpp_int_backend(const cpp_int_backend& o) noexcept(std::is_void<Allocator>::value) : base_type(o) {} - // rvalue copy: - BOOST_MP_FORCEINLINE constexpr cpp_int_backend(cpp_int_backend&& o) noexcept - : base_type(static_cast<base_type&&>(o)) - {} - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2> - BOOST_MP_FORCEINLINE BOOST_CXX14_CONSTEXPR cpp_int_backend(cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>&& o, typename std::enable_if<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>, self_type>::value>::type* = nullptr) noexcept - { - *this = static_cast<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>&&>(o); - } - // - // Direct construction from arithmetic type: - // - template <class Arg> - BOOST_MP_FORCEINLINE constexpr cpp_int_backend(Arg i, typename std::enable_if<is_allowed_cpp_int_base_conversion<Arg, base_type>::value>::type const* = nullptr) noexcept(noexcept(base_type(std::declval<Arg>()))) - : base_type(i) {} - // - // Aliasing constructor: the result will alias the memory referenced, unless - // we have fixed precision and storage, in which case we copy the memory: - // - explicit constexpr cpp_int_backend(limb_type* data, std::size_t offset, std::size_t len) noexcept - : base_type(data, offset, len) {} - explicit cpp_int_backend(const limb_type* data, std::size_t offset, std::size_t len) noexcept - : base_type(data, offset, len) { this->normalize(); } - explicit constexpr cpp_int_backend(typename base_type::scoped_shared_storage& data, std::size_t len) noexcept - : base_type(data, len) {} - - private: - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::true_type const&, std::true_type const&) - { - // Assigning trivial type to trivial type: - this->check_in_range(*other.limbs()); - *this->limbs() = static_cast<typename self_type::local_limb_type>(*other.limbs()); - this->sign(other.sign()); - this->normalize(); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::true_type const&, std::false_type const&) - { - // non-trivial to trivial narrowing conversion: - double_limb_type v = *other.limbs(); - if (other.size() > 1) - { - v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb; - BOOST_IF_CONSTEXPR(Checked == checked) - { - if (other.size() > 2) - { - BOOST_MP_THROW_EXCEPTION(std::range_error("Assignment of a cpp_int that is out of range for the target type.")); - } - } - } - *this = v; - this->sign(other.sign()); - this->normalize(); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::false_type const&, std::true_type const&) - { - // trivial to non-trivial, treat the trivial argument as if it were an unsigned arithmetic type, then set the sign afterwards: - *this = static_cast< - typename boost::multiprecision::detail::canonical< - typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type, - cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::type>(*other.limbs()); - this->sign(other.sign()); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, std::false_type const&, std::false_type const&) - { - // regular non-trivial to non-trivial assign: - this->resize(other.size(), other.size()); - -#if !defined(BOOST_MP_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR) - std::size_t count = (std::min)(other.size(), this->size()); - for (std::size_t i = 0; i < count; ++i) - this->limbs()[i] = other.limbs()[i]; -#else -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(other.size())) - { - std::size_t count = (std::min)(other.size(), this->size()); - for (std::size_t i = 0; i < count; ++i) - this->limbs()[i] = other.limbs()[i]; - } - else -#endif - { - static_assert(sizeof(other.limbs()[0]) == sizeof(this->limbs()[0]), "This method requires equal limb sizes"); - std::memcpy(this->limbs(), other.limbs(), (std::min)(other.size() * sizeof(other.limbs()[0]), this->size() * sizeof(this->limbs()[0]))); - } -#endif - this->sign(other.sign()); - this->normalize(); - } - - public: - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR cpp_int_backend( - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, - typename std::enable_if<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value>::type* = nullptr) - : base_type() - { - do_assign( - other, - std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>(), - std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>()); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - explicit BOOST_MP_CXX14_CONSTEXPR cpp_int_backend( - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, - typename std::enable_if< !(is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value)>::type* = nullptr) - : base_type() - { - do_assign( - other, - std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>(), - std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>()); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR cpp_int_backend& operator=( - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other) - { - do_assign( - other, - std::integral_constant<bool, is_trivial_cpp_int<self_type>::value>(), - std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>()); - return *this; - } - constexpr cpp_int_backend(const cpp_int_backend& a, const literals::detail::negate_tag& tag) - : base_type(static_cast<const base_type&>(a), tag) - {} - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_backend& operator=(const cpp_int_backend& o) noexcept(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>()))) - { - this->assign(o); - return *this; - } - // rvalue copy: - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR cpp_int_backend& operator=(cpp_int_backend&& o) noexcept(noexcept(std::declval<base_type&>() = std::declval<base_type>())) - { - *static_cast<base_type*>(this) = static_cast<base_type&&>(o); - return *this; - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<((MaxBits2 <= MaxBits) || (MaxBits == 0)) && !std::is_void<Allocator>::value, cpp_int_backend&>::type operator=(cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator>&& o) noexcept - { - *static_cast<base_type*>(this) = static_cast<typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2>::base_type&&>(o); - return *this; - } - - template <class A> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<A>::value - && trivial_tag::value, cpp_int_backend&>::type - operator=(const A& val) - noexcept(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>()))) - { - this->check_in_range(val); - *this->limbs() = static_cast<typename self_type::local_limb_type>(val); - this->sign(false); - this->normalize(); - return *this; - } - template <class A> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !(boost::multiprecision::detail::is_unsigned<A>::value || !boost::multiprecision::detail::is_integral<A>::value) - && trivial_tag::value, cpp_int_backend&>::type - operator=(const A& val) - noexcept(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true))) - { - this->check_in_range(val); - *this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::unsigned_abs(val)) : static_cast<typename self_type::local_limb_type>(val); - this->sign(val < 0); - this->normalize(); - return *this; - } - template <class A> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_convertible<A, limb_type>::value - && !boost::multiprecision::detail::is_integral<A>::value - && trivial_tag::value, cpp_int_backend&>::type - operator=(const A& val) - { - this->check_in_range(val); - *this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::abs(val)) : static_cast<typename self_type::local_limb_type>(val); - this->sign(val < 0); - this->normalize(); - return *this; - } - template <class A> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<A, limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type - operator=(A i) noexcept - { - this->resize(1, 1); - *this->limbs() = i; - this->sign(false); - return *this; - } - template <class A> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if < - std::is_same<A, signed_limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type - operator=(A i) noexcept(noexcept(std::declval<cpp_int_backend>().sign(true))) - { - this->resize(1, 1); - *this->limbs() = static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i)); - this->sign(i < 0); - return *this; - } - template <class A> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if < - std::is_same<A, double_limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type - operator=(A i) noexcept - { - static_assert(sizeof(i) == 2 * sizeof(limb_type), "Failed integer size check"); - static_assert(base_type::internal_limb_count >= 2, "Failed internal limb count"); - typename base_type::limb_pointer p = this->limbs(); -#ifdef __MSVC_RUNTIME_CHECKS - *p = static_cast<limb_type>(i & ~static_cast<limb_type>(0)); -#else - *p = static_cast<limb_type>(i); -#endif - p[1] = static_cast<limb_type>(i >> base_type::limb_bits); - this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1); - this->sign(false); - return *this; - } - template <class A> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if < - std::is_same<A, signed_double_limb_type>::value && !trivial_tag::value, cpp_int_backend&>::type - operator=(A i) noexcept(noexcept(std::declval<cpp_int_backend>().sign(true))) - { - static_assert(sizeof(i) == 2 * sizeof(limb_type), "double limb type size check failed"); - static_assert(base_type::internal_limb_count >= 2, "Failed internal limb count check"); - bool s = false; - if (i < 0) - s = true; - double_limb_type ui = static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)); - typename base_type::limb_pointer p = this->limbs(); -#ifdef __MSVC_RUNTIME_CHECKS - *p = static_cast<limb_type>(ui & ~static_cast<limb_type>(0)); -#else - *p = static_cast<limb_type>(ui); -#endif - p[1] = static_cast<limb_type>(ui >> base_type::limb_bits); - this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1); - this->sign(s); - return *this; - } -private: - template <class F> - BOOST_MP_CXX14_CONSTEXPR void do_assign_float(F a) - { - using default_ops::eval_add; - using default_ops::eval_subtract; - BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp; - - if (a < 0) - { - do_assign_float(-a); - this->sign(true); - return; - } - - if (a == 0) - { - *this = static_cast<limb_type>(0u); - } - - if (a == 1) - { - *this = static_cast<limb_type>(1u); - } - - if (!BOOST_MP_ISFINITE(a)) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Cannot convert a non-finite number to an integer.")); - } - - int e = 0; - F f(0), term(0); - *this = static_cast<limb_type>(0u); - - f = frexp(a, &e); - -#if !(defined(__clang__) && (__clang_major__ <= 7)) - constexpr limb_type shift = std::numeric_limits<limb_type>::digits; -#else - // clang 7 has an issue converting long double to unsigned long long in - // release mode (bits get dropped, conversion appears to go via float) - // Never extract more than double bits at a time: - constexpr limb_type shift = std::numeric_limits<limb_type>::digits > std::numeric_limits<double>::digits - ? std::numeric_limits<double>::digits : std::numeric_limits<limb_type>::digits; -#endif - - while (f != static_cast<F>(0.0f)) - { - // extract int sized bits from f: - f = ldexp(f, shift); - term = floor(f); - e = e - static_cast<int>(shift); - eval_left_shift(*this, shift); -#if !(defined(__clang__) && (__clang_major__ <= 7)) - if (term > 0) - eval_add(*this, static_cast<limb_type>(term)); - else - eval_subtract(*this, static_cast<limb_type>(-term)); -#else - // clang 7 requires extra cast to double to avoid buggy code generation: - if (term > 0) - eval_add(*this, static_cast<limb_type>(static_cast<double>(term))); - else - eval_subtract(*this, static_cast<limb_type>(static_cast<double>(-term))); -#endif - f -= term; - } - if (e > 0) - eval_left_shift(*this, static_cast<unsigned int>(e)); - else if (e < 0) - eval_right_shift(*this, static_cast<unsigned int>(-e)); - } -public: - template <class A> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if < - std::is_floating_point<A>::value && !trivial_tag::value, cpp_int_backend&>::type - operator=(A a) - { - do_assign_float(a); - return *this; - } - - private: - void do_assign_string(const char* s, const std::integral_constant<bool, true>&) - { - std::size_t n = s ? std::strlen(s) : 0; - *this = 0; - unsigned radix = 10; - bool isneg = false; - if (n && (*s == '-')) - { - --n; - ++s; - isneg = true; - } - if (n && (*s == '0')) - { - if ((n > 1) && ((s[1] == 'x') || (s[1] == 'X'))) - { - radix = 16; - s += 2; - n -= 2; - } - else - { - radix = 8; - n -= 1; - } - } - if (n) - { - unsigned val; - while (*s) - { - if (*s >= '0' && *s <= '9') - val = static_cast<unsigned>(*s - '0'); - else if (*s >= 'a' && *s <= 'f') - val = 10u + static_cast<unsigned>(*s - 'a'); - else if (*s >= 'A' && *s <= 'F') - val = 10u + static_cast<unsigned>(*s - 'A'); - else - val = radix + 1u; - if (val >= radix) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string.")); - } - *this->limbs() = detail::checked_multiply(*this->limbs(), static_cast<typename base_type::local_limb_type>(radix), checked_type()); - *this->limbs() = detail::checked_add(*this->limbs(), static_cast<typename base_type::local_limb_type>(val), checked_type()); - ++s; - } - } - if (isneg) - this->negate(); - } - void do_assign_string(const char* s, const std::integral_constant<bool, false>&) - { - using default_ops::eval_add; - using default_ops::eval_multiply; - std::size_t n = s ? std::strlen(s) : 0; - *this = static_cast<limb_type>(0u); - unsigned radix = 10; - bool isneg = false; - if (n && (*s == '-')) - { - --n; - ++s; - isneg = true; - } - if (n && (*s == '0')) - { - if ((n > 1) && ((s[1] == 'x') || (s[1] == 'X'))) - { - radix = 16; - s += 2; - n -= 2; - } - else - { - radix = 8; - n -= 1; - } - } - // - // Exception guarantee: create the result in stack variable "result" - // then do a swap at the end. In the event of a throw, *this will - // be left unchanged. - // - cpp_int_backend result; - if (n) - { - if (radix == 16) - { - while (*s == '0') - ++s; - std::size_t bitcount = 4 * std::strlen(s); - limb_type val; - std::size_t limb, shift; - if (bitcount > 4) - bitcount -= 4; - else - bitcount = 0; - std::size_t newsize = bitcount / (sizeof(limb_type) * CHAR_BIT) + 1; - result.resize(static_cast<unsigned>(newsize), static_cast<unsigned>(newsize)); // will throw if this is a checked integer that cannot be resized - std::memset(result.limbs(), 0, result.size() * sizeof(limb_type)); - while (*s) - { - if (*s >= '0' && *s <= '9') - val = static_cast<unsigned>(*s - '0'); - else if (*s >= 'a' && *s <= 'f') - val = 10u + static_cast<unsigned>(*s - 'a'); - else if (*s >= 'A' && *s <= 'F') - val = 10u + static_cast<unsigned>(*s - 'A'); - else - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string.")); - } - limb = bitcount / (sizeof(limb_type) * CHAR_BIT); - shift = bitcount % (sizeof(limb_type) * CHAR_BIT); - val <<= shift; - if (result.size() > limb) - { - result.limbs()[limb] |= val; - } - ++s; - bitcount -= 4; - } - result.normalize(); - } - else if (radix == 8) - { - while (*s == '0') - ++s; - std::size_t bitcount = 3 * std::strlen(s); - limb_type val; - std::size_t limb, shift; - if (bitcount > 3) - bitcount -= 3; - else - bitcount = 0; - std::size_t newsize = bitcount / (sizeof(limb_type) * CHAR_BIT) + 1; - result.resize(static_cast<unsigned>(newsize), static_cast<unsigned>(newsize)); // will throw if this is a checked integer that cannot be resized - std::memset(result.limbs(), 0, result.size() * sizeof(limb_type)); - while (*s) - { - if (*s >= '0' && *s <= '7') - val = static_cast<unsigned>(*s - '0'); - else - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string.")); - } - limb = bitcount / (sizeof(limb_type) * CHAR_BIT); - shift = bitcount % (sizeof(limb_type) * CHAR_BIT); - if (result.size() > limb) - { - result.limbs()[limb] |= (val << shift); - if (shift > sizeof(limb_type) * CHAR_BIT - 3) - { - // Deal with the bits in val that overflow into the next limb: - val >>= (sizeof(limb_type) * CHAR_BIT - shift); - if (val) - { - // If this is the most-significant-limb, we may need to allocate an extra one for the overflow: - if (limb + 1 == newsize) - result.resize(static_cast<unsigned>(newsize + 1), static_cast<unsigned>(newsize + 1)); - if (result.size() > limb + 1) - { - result.limbs()[limb + 1] |= val; - } - } - } - } - ++s; - bitcount -= 3; - } - result.normalize(); - } - else - { - // Base 10, we extract blocks of size 10^9 at a time, that way - // the number of multiplications is kept to a minimum: - limb_type block_mult = max_block_10; - while (*s) - { - limb_type block = 0; - for (unsigned i = 0; i < digits_per_block_10; ++i) - { - limb_type val; - if (*s >= '0' && *s <= '9') - val = static_cast<limb_type>(*s - '0'); - else - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unexpected character encountered in input.")); - block *= 10; - block += val; - if (!*++s) - { - block_mult = block_multiplier(i); - break; - } - } - eval_multiply(result, block_mult); - eval_add(result, block); - } - } - } - if (isneg) - result.negate(); - result.swap(*this); - } - - public: - cpp_int_backend& operator=(const char* s) - { - do_assign_string(s, trivial_tag()); - return *this; - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void swap(cpp_int_backend& o) noexcept - { - this->do_swap(o); - } - - private: - std::string do_get_trivial_string(std::ios_base::fmtflags f, const std::integral_constant<bool, false>&) const - { - using io_type = typename std::conditional<sizeof(typename base_type::local_limb_type) == 1, unsigned, typename base_type::local_limb_type>::type; - if (this->sign() && (((f & std::ios_base::hex) == std::ios_base::hex) || ((f & std::ios_base::oct) == std::ios_base::oct))) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported.")); - std::stringstream ss; - ss.flags(f & ~std::ios_base::showpos); - ss << static_cast<io_type>(*this->limbs()); - std::string result; - if (this->sign()) - result += '-'; - else if (f & std::ios_base::showpos) - result += '+'; - result += ss.str(); - return result; - } - std::string do_get_trivial_string(std::ios_base::fmtflags f, const std::integral_constant<bool, true>&) const - { - // Even though we have only one limb, we can't do IO on it :-( - int base = 10; - if ((f & std::ios_base::oct) == std::ios_base::oct) - base = 8; - else if ((f & std::ios_base::hex) == std::ios_base::hex) - base = 16; - std::string result; - - std::size_t Bits = sizeof(typename base_type::local_limb_type) * CHAR_BIT; - - if (base == 8 || base == 16) - { - if (this->sign()) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported.")); - limb_type shift = base == 8 ? 3 : 4; - limb_type mask = static_cast<limb_type>((1u << shift) - 1); - typename base_type::local_limb_type v = *this->limbs(); - result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0'); - std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u); - char letter_a = f & std::ios_base::uppercase ? 'A' : 'a'; - for (std::size_t i = 0; i < Bits / shift; ++i) - { - char c = static_cast<char>('0' + static_cast<char>(v & mask)); - if (c > '9') - c = static_cast<char>(c + letter_a - '9' - 1); - result[static_cast<std::size_t>(pos)] = c; - --pos; - v >>= shift; - } - if (Bits % shift) - { - mask = static_cast<limb_type>((1u << (Bits % shift)) - 1); - char c = static_cast<char>('0' + static_cast<char>(v & mask)); - if (c > '9') - c = static_cast<char>(c + letter_a - '9'); - result[static_cast<std::size_t>(pos)] = c; - } - // - // Get rid of leading zeros: - // - std::string::size_type n = result.find_first_not_of('0'); - if (!result.empty() && (n == std::string::npos)) - n = result.size() - 1; - result.erase(0, n); - if (f & std::ios_base::showbase) - { - const char* pp = base == 8 ? "0" : (f & std::ios_base::uppercase) ? "0X" : "0x"; - result.insert(static_cast<std::string::size_type>(0), pp); - } - } - else - { - result.assign(Bits / 3 + 1, '0'); - std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u); - typename base_type::local_limb_type v(*this->limbs()); - bool neg = false; - if (this->sign()) - { - neg = true; - } - while (v) - { - result[static_cast<std::string::size_type>(pos)] = static_cast<char>(static_cast<char>(v % 10) + '0'); - --pos; - v /= 10; - } - std::string::size_type n = result.find_first_not_of('0'); - result.erase(0, n); - if (result.empty()) - result = "0"; - if (neg) - result.insert(static_cast<std::string::size_type>(0), 1, '-'); - else if (f & std::ios_base::showpos) - result.insert(static_cast<std::string::size_type>(0), 1, '+'); - } - return result; - } - std::string do_get_string(std::ios_base::fmtflags f, const std::integral_constant<bool, true>&) const - { -#ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO - return do_get_trivial_string(f, std::integral_constant<bool, std::is_same<typename base_type::local_limb_type, double_limb_type>::value>()); -#else - return do_get_trivial_string(f, std::integral_constant<bool, false>()); -#endif - } - std::string do_get_string(std::ios_base::fmtflags f, const std::integral_constant<bool, false>&) const - { - using default_ops::eval_get_sign; - int base = 10; - if ((f & std::ios_base::oct) == std::ios_base::oct) - base = 8; - else if ((f & std::ios_base::hex) == std::ios_base::hex) - base = 16; - std::string result; - - std::size_t Bits = this->size() * base_type::limb_bits; - - if (base == 8 || base == 16) - { - if (this->sign()) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported.")); - limb_type shift = base == 8 ? 3 : 4; - limb_type mask = static_cast<limb_type>((1u << shift) - 1); - cpp_int_backend t(*this); - result.assign(Bits / shift + ((Bits % shift) ? 1 : 0), '0'); - std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u); - char letter_a = f & std::ios_base::uppercase ? 'A' : 'a'; - for (std::size_t i = 0; i < Bits / shift; ++i) - { - char c = static_cast<char>('0' + static_cast<char>(t.limbs()[0] & mask)); - if (c > '9') - c = static_cast<char>(c + letter_a - '9' - 1); - result[static_cast<std::size_t>(pos)] = c; - --pos; - eval_right_shift(t, shift); - } - if (Bits % shift) - { - mask = static_cast<limb_type>((1u << (Bits % shift)) - 1); - char c = static_cast<char>('0' + static_cast<char>(t.limbs()[0] & mask)); - if (c > '9') - c = static_cast<char>(c + letter_a - '9'); - result[static_cast<std::size_t>(pos)] = c; - } - // - // Get rid of leading zeros: - // - std::string::size_type n = result.find_first_not_of('0'); - if (!result.empty() && (n == std::string::npos)) - n = result.size() - 1; - result.erase(0, n); - if (f & std::ios_base::showbase) - { - const char* pp = base == 8 ? "0" : (f & std::ios_base::uppercase) ? "0X" : "0x"; - result.insert(static_cast<std::string::size_type>(0), pp); - } - } - else - { - result.assign(Bits / 3 + 1, '0'); - std::string::difference_type pos = static_cast<std::string::difference_type>(result.size() - 1u); - cpp_int_backend t(*this); - cpp_int_backend r; - bool neg = false; - if (t.sign()) - { - t.negate(); - neg = true; - } - if (this->size() == 1) - { - result = std::to_string(t.limbs()[0]); - } - else - { - cpp_int_backend block10; - block10 = max_block_10; - while (eval_get_sign(t) != 0) - { - cpp_int_backend t2; - divide_unsigned_helper(&t2, t, block10, r); - t = t2; - limb_type v = r.limbs()[0]; - for (std::size_t i = 0; i < digits_per_block_10; ++i) - { - char c = static_cast<char>('0' + static_cast<char>(v % 10)); - v /= 10; - result[static_cast<std::size_t>(pos)] = c; - if (pos-- == 0u) - break; - } - } - } - std::string::size_type n = result.find_first_not_of('0'); - result.erase(0, n); - if (result.empty()) - result = std::string(static_cast<std::size_t>(1u), '0'); - if (neg) - result.insert(static_cast<std::string::size_type>(0), 1, '-'); - else if (f & std::ios_base::showpos) - result.insert(static_cast<std::string::size_type>(0), 1, '+'); - } - return result; - } - - public: - std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f) const - { - return do_get_string(f, trivial_tag()); - } - - private: - template <class Container> - void construct_from_container(const Container& c, const std::integral_constant<bool, false>&) - { - // - // We assume that c is a sequence of (unsigned) bytes with the most significant byte first: - // - std::size_t newsize = static_cast<unsigned>(c.size() / sizeof(limb_type)); - if (c.size() % sizeof(limb_type)) - { - ++newsize; - } - if (newsize) - { - this->resize(newsize, newsize); // May throw - std::memset(this->limbs(), 0, this->size()); - typename Container::const_iterator i(c.begin()), j(c.end()); - std::size_t byte_location = static_cast<unsigned>(c.size() - 1); - while (i != j) - { - std::size_t limb = byte_location / sizeof(limb_type); - std::size_t shift = (byte_location % sizeof(limb_type)) * CHAR_BIT; - if (this->size() > limb) - this->limbs()[limb] |= static_cast<limb_type>(static_cast<unsigned char>(*i)) << shift; - ++i; - --byte_location; - } - } - } - template <class Container> - BOOST_MP_CXX14_CONSTEXPR void construct_from_container(const Container& c, const std::integral_constant<bool, true>&) - { - // - // We assume that c is a sequence of (unsigned) bytes with the most significant byte first: - // - using local_limb_type = typename base_type::local_limb_type; - *this->limbs() = 0; - if (c.size()) - { - typename Container::const_iterator i(c.begin()), j(c.end()); - std::size_t byte_location = static_cast<unsigned>(c.size() - 1); - while (i != j) - { - std::size_t limb = byte_location / sizeof(local_limb_type); - std::size_t shift = (byte_location % sizeof(local_limb_type)) * CHAR_BIT; - if (limb == 0) - this->limbs()[0] |= static_cast<limb_type>(static_cast<unsigned char>(*i)) << shift; - ++i; - --byte_location; - } - } - } - - public: - template <class Container> - BOOST_MP_CXX14_CONSTEXPR cpp_int_backend(const Container& c, typename std::enable_if<boost::multiprecision::detail::is_byte_container<Container>::value>::type const* = nullptr) - { - // - // We assume that c is a sequence of (unsigned) bytes with the most significant byte first: - // - construct_from_container(c, trivial_tag()); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) const noexcept - { - if (this->sign() != o.sign()) - return this->sign() ? -1 : 1; - - // Only do the compare if the same sign: - int result = compare_unsigned(o); - - if (this->sign()) - result = -result; - return result; - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&) const - { - cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> t(*this); - return t.compare(o); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) const - { - cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> t(o); - return compare(t); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR int compare_imp(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&) const noexcept - { - if (this->sign()) - { - if (o.sign()) - { - return *this->limbs() < *o.limbs() ? 1 : (*this->limbs() > *o.limbs() ? -1 : 0); - } - else - return -1; - } - else - { - if (o.sign()) - return 1; - return *this->limbs() < *o.limbs() ? -1 : (*this->limbs() > *o.limbs() ? 1 : 0); - } - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR int compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) const noexcept - { - using t1 = std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value> ; - using t2 = std::integral_constant<bool, is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>; - return compare_imp(o, t1(), t2()); - } - template <std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> - BOOST_MP_CXX14_CONSTEXPR int compare_unsigned(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) const noexcept - { - if (this->size() != o.size()) - { - return this->size() > o.size() ? 1 : -1; - } - typename base_type::const_limb_pointer pa = this->limbs(); - typename base_type::const_limb_pointer pb = o.limbs(); - for (std::ptrdiff_t i = static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(this->size()) - 1); i >= 0; --i) - { - if (pa[i] != pb[i]) - return pa[i] > pb[i] ? 1 : -1; - } - return 0; - } - template <class Arithmetic> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<Arithmetic>::value, int>::type compare(Arithmetic i) const - { - // braindead version: - cpp_int_backend t; - t = i; - return compare(t); - } -}; - -} // namespace backends - -namespace default_ops { - -template <class Backend> -struct double_precision_type; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct double_precision_type<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > -{ - using type = typename std::conditional< - backends::is_fixed_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, - backends::cpp_int_backend< - (std::is_void<Allocator>::value ? 2 * backends::max_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value - : MinBits), - 2 * backends::max_precision<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, - SignType, - Checked, - Allocator>, - backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::type; -}; - -} // namespace default_ops - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -struct is_equivalent_number_type<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, backends::cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > - : public std::integral_constant<bool, std::numeric_limits<number<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, et_on> >::digits == std::numeric_limits<number<backends::cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, et_on> >::digits>{}; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked> -struct expression_template_default<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, void> > -{ - static constexpr expression_template_option value = et_off; -}; - -using boost::multiprecision::backends::cpp_int_backend; - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -struct number_category<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public std::integral_constant<int, number_kind_integer> -{}; - -using cpp_int = number<cpp_int_backend<> > ; -using cpp_rational_backend = rational_adaptor<cpp_int_backend<> >; -using cpp_rational = number<cpp_rational_backend> ; - -// Fixed precision unsigned types: -using uint128_t = number<cpp_int_backend<128, 128, unsigned_magnitude, unchecked, void> > ; -using uint256_t = number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void> > ; -using uint512_t = number<cpp_int_backend<512, 512, unsigned_magnitude, unchecked, void> > ; -using uint1024_t = number<cpp_int_backend<1024, 1024, unsigned_magnitude, unchecked, void> >; - -// Fixed precision signed types: -using int128_t = number<cpp_int_backend<128, 128, signed_magnitude, unchecked, void> > ; -using int256_t = number<cpp_int_backend<256, 256, signed_magnitude, unchecked, void> > ; -using int512_t = number<cpp_int_backend<512, 512, signed_magnitude, unchecked, void> > ; -using int1024_t = number<cpp_int_backend<1024, 1024, signed_magnitude, unchecked, void> >; - -// Over again, but with checking enabled this time: -using checked_cpp_int = number<cpp_int_backend<0, 0, signed_magnitude, checked> > ; -using checked_cpp_rational_backend = rational_adaptor<cpp_int_backend<0, 0, signed_magnitude, checked> >; -using checked_cpp_rational = number<checked_cpp_rational_backend> ; -// Fixed precision unsigned types: -using checked_uint128_t = number<cpp_int_backend<128, 128, unsigned_magnitude, checked, void> > ; -using checked_uint256_t = number<cpp_int_backend<256, 256, unsigned_magnitude, checked, void> > ; -using checked_uint512_t = number<cpp_int_backend<512, 512, unsigned_magnitude, checked, void> > ; -using checked_uint1024_t = number<cpp_int_backend<1024, 1024, unsigned_magnitude, checked, void> >; - -// Fixed precision signed types: -using checked_int128_t = number<cpp_int_backend<128, 128, signed_magnitude, checked, void> > ; -using checked_int256_t = number<cpp_int_backend<256, 256, signed_magnitude, checked, void> > ; -using checked_int512_t = number<cpp_int_backend<512, 512, signed_magnitude, checked, void> > ; -using checked_int1024_t = number<cpp_int_backend<1024, 1024, signed_magnitude, checked, void> >; - -#if defined(__GNUC__) && !defined(__clang__) -// see https://github.com/boostorg/multiprecision/issues/413 -// and https://github.com/boostorg/multiprecision/issues/431 -#pragma GCC diagnostic pop -#endif -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -}} // namespace boost::multiprecision - -// -// Last of all we include the implementations of all the eval_* non member functions: -// -#include <boost/multiprecision/cpp_int/limits.hpp> -#include <boost/multiprecision/cpp_int/comparison.hpp> -#include <boost/multiprecision/cpp_int/add.hpp> -#include <boost/multiprecision/cpp_int/multiply.hpp> -#include <boost/multiprecision/cpp_int/divide.hpp> -#include <boost/multiprecision/cpp_int/bitwise.hpp> -#include <boost/multiprecision/cpp_int/misc.hpp> -#include <boost/multiprecision/cpp_int/literals.hpp> -#include <boost/multiprecision/cpp_int/serialize.hpp> -#include <boost/multiprecision/cpp_int/import_export.hpp> - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add.hpp deleted file mode 100644 index 1b0f828534..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add.hpp +++ /dev/null @@ -1,368 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_ADD_HPP -#define BOOST_MP_CPP_INT_ADD_HPP - -#include <boost/multiprecision/detail/constexpr.hpp> -#include <boost/multiprecision/cpp_int/add_unsigned.hpp> - -namespace boost { namespace multiprecision { namespace backends { - -// -// As above, but for adding a single limb to a non-trivial cpp_int: -// -template <class CppInt1, class CppInt2> -inline BOOST_MP_CXX14_CONSTEXPR void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ - // Addition using modular arithmetic. - // Nothing fancy, just let uintmax_t take the strain: - if (&result != &a) - result.resize(a.size(), a.size()); - double_limb_type carry = o; - typename CppInt1::limb_pointer pr = result.limbs(); - typename CppInt2::const_limb_pointer pa = a.limbs(); - std::size_t i = 0; - // Addition with carry until we either run out of digits or carry is zero: - for (; carry && (i < result.size()); ++i) - { - carry += static_cast<double_limb_type>(pa[i]); -#ifdef __MSVC_RUNTIME_CHECKS - pr[i] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pr[i] = static_cast<limb_type>(carry); -#endif - carry >>= CppInt1::limb_bits; - } - // Just copy any remaining digits: - if (&a != &result) - { - std_constexpr::copy(pa + i, pa + a.size(), pr + i); - } - if (carry) - { - // We overflowed, need to add one more limb: - std::size_t x = result.size(); - result.resize(x + 1, x + 1); - if (result.size() > x) - result.limbs()[x] = static_cast<limb_type>(carry); - } - result.normalize(); - result.sign(a.sign()); -} -// -// And again to subtract a single limb: -// -template <class CppInt1, class CppInt2> -inline BOOST_MP_CXX14_CONSTEXPR void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ - // Subtract one limb. - // Nothing fancy, just let uintmax_t take the strain: - constexpr double_limb_type borrow = static_cast<double_limb_type>(CppInt1::max_limb_value) + 1; - result.resize(a.size(), a.size()); - typename CppInt1::limb_pointer pr = result.limbs(); - typename CppInt2::const_limb_pointer pa = a.limbs(); - if (*pa >= b) - { - *pr = *pa - b; - if (&result != &a) - { - std_constexpr::copy(pa + 1, pa + a.size(), pr + 1); - result.sign(a.sign()); - } - else if ((result.size() == 1) && (*pr == 0)) - { - result.sign(false); // zero is unsigned. - } - } - else if (result.size() == 1) - { - *pr = b - *pa; - result.sign(!a.sign()); - } - else - { - *pr = static_cast<limb_type>((borrow + *pa) - b); - std::size_t i = 1; - while (!pa[i]) - { - pr[i] = CppInt1::max_limb_value; - ++i; - } - pr[i] = pa[i] - 1; - if (&result != &a) - { - ++i; - std_constexpr::copy(pa + i, pa + a.size(), pr + i); - } - result.normalize(); - result.sign(a.sign()); - } -} - -// -// Now the actual functions called by the front end, all of which forward to one of the above: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_add( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_add(result, result, o); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -eval_add( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (a.sign() != b.sign()) - { - subtract_unsigned(result, a, b); - return; - } - add_unsigned(result, a, b); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (result.sign()) - { - subtract_unsigned(result, result, o); - } - else - add_unsigned(result, result, o); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_add( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (a.sign()) - { - subtract_unsigned(result, a, o); - } - else - add_unsigned(result, a, o); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_add( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (o < 0) - eval_subtract(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o))); - else if (o > 0) - eval_add(result, static_cast<limb_type>(o)); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_add( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (o < 0) - eval_subtract(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o))); - else if (o > 0) - eval_add(result, a, static_cast<limb_type>(o)); - else if (&result != &a) - result = a; -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (result.sign()) - { - add_unsigned(result, result, o); - } - else - subtract_unsigned(result, result, o); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (a.sign()) - { - add_unsigned(result, a, o); - } - else - { - subtract_unsigned(result, a, o); - } -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (o) - { - if (o < 0) - eval_add(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o))); - else - eval_subtract(result, static_cast<limb_type>(o)); - } -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (o) - { - if (o < 0) - eval_add(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o))); - else - eval_subtract(result, a, static_cast<limb_type>(o)); - } - else if (&result != &a) - result = a; -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - constexpr limb_type one = 1; - - if (!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)) - ++result.limbs()[0]; - else if (result.sign() && result.limbs()[0]) - { - --result.limbs()[0]; - if (!result.limbs()[0] && (result.size() == 1)) - result.sign(false); - } - else - eval_add(result, one); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - constexpr limb_type one = 1; - - if (!result.sign() && result.limbs()[0]) - --result.limbs()[0]; - else if (result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)) - ++result.limbs()[0]; - else - eval_subtract(result, one); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - eval_subtract(result, result, o); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (a.sign() != b.sign()) - { - add_unsigned(result, a, b); - return; - } - subtract_unsigned(result, a, b); -} - -// -// Simple addition and subtraction routine for trivial cpp_int's come last: -// -// One of the arguments is signed: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type -eval_add( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (result.sign() != o.sign()) - { - if (*o.limbs() > *result.limbs()) - { - *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.negate(); - } - else - *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - } - else - *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} -// Simple version for two unsigned arguments: -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -// signed subtraction: -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (result.sign() != o.sign()) - { - *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - } - else if (*result.limbs() < *o.limbs()) - { - *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.negate(); - } - else - *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_subtract( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -}}} // namespace boost::multiprecision::backends - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add_unsigned.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add_unsigned.hpp deleted file mode 100644 index 2149767e1e..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add_unsigned.hpp +++ /dev/null @@ -1,387 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2020 Madhur Chauhan. -// Copyright 2020 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_ADD_UNSIGNED_HPP -#define BOOST_MP_ADD_UNSIGNED_HPP - -#include <boost/multiprecision/cpp_int/intel_intrinsics.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -namespace boost { namespace multiprecision { namespace backends { - -template <class CppInt1, class CppInt2, class CppInt3> -inline BOOST_MP_CXX14_CONSTEXPR void add_unsigned_constexpr(CppInt1& result, const CppInt2& a, const CppInt3& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ - using ::boost::multiprecision::std_constexpr::swap; - // - // This is the generic, C++ only version of addition. - // It's also used for all constexpr branches, hence the name. - // Nothing fancy, just let uintmax_t take the strain: - // - double_limb_type carry = 0; - std::size_t m(0), x(0); - std::size_t as = a.size(); - std::size_t bs = b.size(); - minmax(as, bs, m, x); - if (x == 1) - { - bool s = a.sign(); - result = static_cast<double_limb_type>(*a.limbs()) + static_cast<double_limb_type>(*b.limbs()); - result.sign(s); - return; - } - result.resize(x, x); - typename CppInt2::const_limb_pointer pa = a.limbs(); - typename CppInt3::const_limb_pointer pb = b.limbs(); - typename CppInt1::limb_pointer pr = result.limbs(); - typename CppInt1::limb_pointer pr_end = pr + m; - - if (as < bs) - swap(pa, pb); - - // First where a and b overlap: - while (pr != pr_end) - { - carry += static_cast<double_limb_type>(*pa) + static_cast<double_limb_type>(*pb); -#ifdef __MSVC_RUNTIME_CHECKS - *pr = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - *pr = static_cast<limb_type>(carry); -#endif - carry >>= CppInt1::limb_bits; - ++pr, ++pa, ++pb; - } - pr_end += x - m; - // Now where only a has digits: - while (pr != pr_end) - { - if (!carry) - { - if (pa != pr) - std_constexpr::copy(pa, pa + (pr_end - pr), pr); - break; - } - carry += static_cast<double_limb_type>(*pa); -#ifdef __MSVC_RUNTIME_CHECKS - *pr = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - *pr = static_cast<limb_type>(carry); -#endif - carry >>= CppInt1::limb_bits; - ++pr, ++pa; - } - if (carry) - { - // We overflowed, need to add one more limb: - result.resize(x + 1, x + 1); - if (result.size() > x) - result.limbs()[x] = static_cast<limb_type>(1u); - } - result.normalize(); - result.sign(a.sign()); -} -// -// Core subtraction routine for all non-trivial cpp_int's: -// -template <class CppInt1, class CppInt2, class CppInt3> -inline BOOST_MP_CXX14_CONSTEXPR void subtract_unsigned_constexpr(CppInt1& result, const CppInt2& a, const CppInt3& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ - using ::boost::multiprecision::std_constexpr::swap; - // - // This is the generic, C++ only version of subtraction. - // It's also used for all constexpr branches, hence the name. - // Nothing fancy, just let uintmax_t take the strain: - // - double_limb_type borrow = 0; - std::size_t m(0), x(0); - minmax(a.size(), b.size(), m, x); - // - // special cases for small limb counts: - // - if (x == 1) - { - bool s = a.sign(); - limb_type al = *a.limbs(); - limb_type bl = *b.limbs(); - if (bl > al) - { - ::boost::multiprecision::std_constexpr::swap(al, bl); - s = !s; - } - result = al - bl; - result.sign(s); - return; - } - // This isn't used till later, but comparison has to occur before we resize the result, - // as that may also resize a or b if this is an inplace operation: - int c = a.compare_unsigned(b); - // Set up the result vector: - result.resize(x, x); - // Now that a, b, and result are stable, get pointers to their limbs: - typename CppInt2::const_limb_pointer pa = a.limbs(); - typename CppInt3::const_limb_pointer pb = b.limbs(); - typename CppInt1::limb_pointer pr = result.limbs(); - bool swapped = false; - if (c < 0) - { - swap(pa, pb); - swapped = true; - } - else if (c == 0) - { - result = static_cast<limb_type>(0); - return; - } - - std::size_t i = 0; - // First where a and b overlap: - while (i < m) - { - borrow = static_cast<double_limb_type>(pa[i]) - static_cast<double_limb_type>(pb[i]) - borrow; - pr[i] = static_cast<limb_type>(borrow); - borrow = (borrow >> CppInt1::limb_bits) & 1u; - ++i; - } - // Now where only a has digits, only as long as we've borrowed: - while (borrow && (i < x)) - { - borrow = static_cast<double_limb_type>(pa[i]) - borrow; - pr[i] = static_cast<limb_type>(borrow); - borrow = (borrow >> CppInt1::limb_bits) & 1u; - ++i; - } - // Any remaining digits are the same as those in pa: - if ((x != i) && (pa != pr)) - std_constexpr::copy(pa + i, pa + x, pr + i); - BOOST_MP_ASSERT(0 == borrow); - - // - // We may have lost digits, if so update limb usage count: - // - result.normalize(); - result.sign(a.sign()); - if (swapped) - result.negate(); -} - - -#ifdef BOOST_MP_HAS_IMMINTRIN_H -// -// This is the key addition routine where all the argument types are non-trivial cpp_int's: -// -// -// This optimization is limited to: GCC, LLVM, ICC (Intel), MSVC for x86_64 and i386. -// If your architecture and compiler supports ADC intrinsic, please file a bug -// -// As of May, 2020 major compilers don't recognize carry chain though adc -// intrinsics are used to hint compilers to use ADC and still compilers don't -// unroll the loop efficiently (except LLVM) so manual unrolling is done. -// -// Also note that these intrinsics were only introduced by Intel as part of the -// ADX processor extensions, even though the addc instruction has been available -// for basically all x86 processors. That means gcc-9, clang-9, msvc-14.2 and up -// are required to support these intrinsics. -// -template <class CppInt1, class CppInt2, class CppInt3> -inline BOOST_MP_CXX14_CONSTEXPR void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(a.size())) - { - add_unsigned_constexpr(result, a, b); - } - else -#endif - { - using std::swap; - - // Nothing fancy, just let uintmax_t take the strain: - std::size_t m(0), x(0); - std::size_t as = a.size(); - std::size_t bs = b.size(); - minmax(as, bs, m, x); - if (x == 1) - { - bool s = a.sign(); - result = static_cast<double_limb_type>(*a.limbs()) + static_cast<double_limb_type>(*b.limbs()); - result.sign(s); - return; - } - result.resize(x, x); - typename CppInt2::const_limb_pointer pa = a.limbs(); - typename CppInt3::const_limb_pointer pb = b.limbs(); - typename CppInt1::limb_pointer pr = result.limbs(); - - if (as < bs) - swap(pa, pb); - // First where a and b overlap: - std::size_t i = 0; - unsigned char carry = 0; -#if defined(BOOST_MSVC) && !defined(BOOST_HAS_INT128) && defined(_M_X64) - // - // Special case for 32-bit limbs on 64-bit architecture - we can process - // 2 limbs with each instruction. - // - for (; i + 8 <= m; i += 8) - { - carry = _addcarry_u64(carry, *(unsigned long long*)(pa + i + 0), *(unsigned long long*)(pb + i + 0), (unsigned long long*)(pr + i)); - carry = _addcarry_u64(carry, *(unsigned long long*)(pa + i + 2), *(unsigned long long*)(pb + i + 2), (unsigned long long*)(pr + i + 2)); - carry = _addcarry_u64(carry, *(unsigned long long*)(pa + i + 4), *(unsigned long long*)(pb + i + 4), (unsigned long long*)(pr + i + 4)); - carry = _addcarry_u64(carry, *(unsigned long long*)(pa + i + 6), *(unsigned long long*)(pb + i + 6), (unsigned long long*)(pr + i + 6)); - } -#else - for (; i + 4 <= m; i += 4) - { - carry = ::boost::multiprecision::detail::addcarry_limb(carry, pa[i + 0], pb[i + 0], pr + i); - carry = ::boost::multiprecision::detail::addcarry_limb(carry, pa[i + 1], pb[i + 1], pr + i + 1); - carry = ::boost::multiprecision::detail::addcarry_limb(carry, pa[i + 2], pb[i + 2], pr + i + 2); - carry = ::boost::multiprecision::detail::addcarry_limb(carry, pa[i + 3], pb[i + 3], pr + i + 3); - } -#endif - for (; i < m; ++i) - carry = ::boost::multiprecision::detail::addcarry_limb(carry, pa[i], pb[i], pr + i); - for (; i < x && carry; ++i) - // We know carry is 1, so we just need to increment pa[i] (ie add a literal 1) and capture the carry: - carry = ::boost::multiprecision::detail::addcarry_limb(0, pa[i], 1, pr + i); - if (i == x && carry) - { - // We overflowed, need to add one more limb: - result.resize(x + 1, x + 1); - if (result.size() > x) - result.limbs()[x] = static_cast<limb_type>(1u); - } - else if ((x != i) && (pa != pr)) - // Copy remaining digits only if we need to: - std_constexpr::copy(pa + i, pa + x, pr + i); - result.normalize(); - result.sign(a.sign()); - } -} - -template <class CppInt1, class CppInt2, class CppInt3> -inline BOOST_MP_CXX14_CONSTEXPR void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(a.size())) - { - subtract_unsigned_constexpr(result, a, b); - } - else -#endif - { - using std::swap; - - // Nothing fancy, just let uintmax_t take the strain: - std::size_t m(0), x(0); - minmax(a.size(), b.size(), m, x); - // - // special cases for small limb counts: - // - if (x == 1) - { - bool s = a.sign(); - limb_type al = *a.limbs(); - limb_type bl = *b.limbs(); - if (bl > al) - { - ::boost::multiprecision::std_constexpr::swap(al, bl); - s = !s; - } - result = al - bl; - result.sign(s); - return; - } - // This isn't used till later, but comparison has to occur before we resize the result, - // as that may also resize a or b if this is an inplace operation: - int c = a.compare_unsigned(b); - // Set up the result vector: - result.resize(x, x); - // Now that a, b, and result are stable, get pointers to their limbs: - typename CppInt2::const_limb_pointer pa = a.limbs(); - typename CppInt3::const_limb_pointer pb = b.limbs(); - typename CppInt1::limb_pointer pr = result.limbs(); - bool swapped = false; - if (c < 0) - { - swap(pa, pb); - swapped = true; - } - else if (c == 0) - { - result = static_cast<limb_type>(0); - return; - } - - std::size_t i = 0; - unsigned char borrow = 0; - // First where a and b overlap: -#if defined(BOOST_MSVC) && !defined(BOOST_HAS_INT128) && defined(_M_X64) - // - // Special case for 32-bit limbs on 64-bit architecture - we can process - // 2 limbs with each instruction. - // - for (; i + 8 <= m; i += 8) - { - borrow = _subborrow_u64(borrow, *reinterpret_cast<const unsigned long long*>(pa + i), *reinterpret_cast<const unsigned long long*>(pb + i), reinterpret_cast<unsigned long long*>(pr + i)); - borrow = _subborrow_u64(borrow, *reinterpret_cast<const unsigned long long*>(pa + i + 2), *reinterpret_cast<const unsigned long long*>(pb + i + 2), reinterpret_cast<unsigned long long*>(pr + i + 2)); - borrow = _subborrow_u64(borrow, *reinterpret_cast<const unsigned long long*>(pa + i + 4), *reinterpret_cast<const unsigned long long*>(pb + i + 4), reinterpret_cast<unsigned long long*>(pr + i + 4)); - borrow = _subborrow_u64(borrow, *reinterpret_cast<const unsigned long long*>(pa + i + 6), *reinterpret_cast<const unsigned long long*>(pb + i + 6), reinterpret_cast<unsigned long long*>(pr + i + 6)); - } -#else - for(; i + 4 <= m; i += 4) - { - borrow = boost::multiprecision::detail::subborrow_limb(borrow, pa[i], pb[i], pr + i); - borrow = boost::multiprecision::detail::subborrow_limb(borrow, pa[i + 1], pb[i + 1], pr + i + 1); - borrow = boost::multiprecision::detail::subborrow_limb(borrow, pa[i + 2], pb[i + 2], pr + i + 2); - borrow = boost::multiprecision::detail::subborrow_limb(borrow, pa[i + 3], pb[i + 3], pr + i + 3); - } -#endif - for (; i < m; ++i) - borrow = boost::multiprecision::detail::subborrow_limb(borrow, pa[i], pb[i], pr + i); - - // Now where only a has digits, only as long as we've borrowed: - while (borrow && (i < x)) - { - borrow = boost::multiprecision::detail::subborrow_limb(borrow, pa[i], 0, pr + i); - ++i; - } - // Any remaining digits are the same as those in pa: - if ((x != i) && (pa != pr)) - std_constexpr::copy(pa + i, pa + x, pr + i); - BOOST_MP_ASSERT(0 == borrow); - - // - // We may have lost digits, if so update limb usage count: - // - result.normalize(); - result.sign(a.sign()); - if (swapped) - result.negate(); - } // constepxr. -} - -#else - -template <class CppInt1, class CppInt2, class CppInt3> -inline BOOST_MP_CXX14_CONSTEXPR void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ - add_unsigned_constexpr(result, a, b); -} - -template <class CppInt1, class CppInt2, class CppInt3> -inline BOOST_MP_CXX14_CONSTEXPR void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value) -{ - subtract_unsigned_constexpr(result, a, b); -} - -#endif - -} } } // namespaces - - -#endif - - diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/bitwise.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/bitwise.hpp deleted file mode 100644 index de23f52657..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/bitwise.hpp +++ /dev/null @@ -1,889 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_BITWISE_HPP -#define BOOST_MP_CPP_INT_BITWISE_HPP - -#include <stdexcept> -#include <type_traits> -#include <boost/multiprecision/detail/endian.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4319) -#endif - - -namespace boost { namespace multiprecision { namespace backends { - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_CXX14_CONSTEXPR void is_valid_bitwise_op( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const std::integral_constant<int, checked>&) -{ - if (result.sign() || o.sign()) - BOOST_MP_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior.")); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_CXX14_CONSTEXPR void is_valid_bitwise_op( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&, const std::integral_constant<int, unchecked>&) {} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_CXX14_CONSTEXPR void is_valid_bitwise_op( - const cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>& result, const std::integral_constant<int, checked>&) -{ - if (result.sign()) - BOOST_MP_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior.")); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_CXX14_CONSTEXPR void is_valid_bitwise_op( - const cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>&, const std::integral_constant<int, checked>&) {} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_CXX14_CONSTEXPR void is_valid_bitwise_op( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&, const std::integral_constant<int, unchecked>&) {} - -template <class CppInt1, class CppInt2, class Op> -BOOST_MP_CXX14_CONSTEXPR void bitwise_op( - CppInt1& result, - const CppInt2& o, - Op op, const std::integral_constant<bool, true>&) noexcept((is_non_throwing_cpp_int<CppInt1>::value)) -{ - // - // There are 4 cases: - // * Both positive. - // * result negative, o positive. - // * o negative, result positive. - // * Both negative. - // - // When one arg is negative we convert to 2's complement form "on the fly", - // and then convert back to signed-magnitude form at the end. - // - // Note however, that if the type is checked, then bitwise ops on negative values - // are not permitted and an exception will result. - // - is_valid_bitwise_op(result, o, typename CppInt1::checked_type()); - // - // First figure out how big the result needs to be and set up some data: - // - std::size_t rs = result.size(); - std::size_t os = o.size(); - std::size_t m(0), x(0); - minmax(rs, os, m, x); - result.resize(x, x); - typename CppInt1::limb_pointer pr = result.limbs(); - typename CppInt2::const_limb_pointer po = o.limbs(); - for (std::size_t i = rs; i < x; ++i) - pr[i] = 0; - - limb_type next_limb = 0; - - if (!result.sign()) - { - if (!o.sign()) - { - for (std::size_t i = 0; i < os; ++i) - pr[i] = op(pr[i], po[i]); - for (std::size_t i = os; i < x; ++i) - pr[i] = op(pr[i], limb_type(0)); - } - else - { - // "o" is negative: - double_limb_type carry = 1; - for (std::size_t i = 0; i < os; ++i) - { - carry += static_cast<double_limb_type>(~po[i]); - pr[i] = op(pr[i], static_cast<limb_type>(carry)); - carry >>= CppInt1::limb_bits; - } - for (std::size_t i = os; i < x; ++i) - { - carry += static_cast<double_limb_type>(~limb_type(0)); - pr[i] = op(pr[i], static_cast<limb_type>(carry)); - carry >>= CppInt1::limb_bits; - } - // Set the overflow into the "extra" limb: - carry += static_cast<double_limb_type>(~limb_type(0)); - next_limb = op(limb_type(0), static_cast<limb_type>(carry)); - } - } - else - { - if (!o.sign()) - { - // "result" is negative: - double_limb_type carry = 1; - for (std::size_t i = 0; i < os; ++i) - { - carry += static_cast<double_limb_type>(~pr[i]); - pr[i] = op(static_cast<limb_type>(carry), po[i]); - carry >>= CppInt1::limb_bits; - } - for (std::size_t i = os; i < x; ++i) - { - carry += static_cast<double_limb_type>(~pr[i]); - pr[i] = op(static_cast<limb_type>(carry), limb_type(0)); - carry >>= CppInt1::limb_bits; - } - // Set the overflow into the "extra" limb: - carry += static_cast<double_limb_type>(~limb_type(0)); - next_limb = op(static_cast<limb_type>(carry), limb_type(0)); - } - else - { - // both are negative: - double_limb_type r_carry = 1; - double_limb_type o_carry = 1; - for (std::size_t i = 0; i < os; ++i) - { - r_carry += static_cast<double_limb_type>(~pr[i]); - o_carry += static_cast<double_limb_type>(~po[i]); - pr[i] = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry)); - r_carry >>= CppInt1::limb_bits; - o_carry >>= CppInt1::limb_bits; - } - for (std::size_t i = os; i < x; ++i) - { - r_carry += static_cast<double_limb_type>(~pr[i]); - o_carry += static_cast<double_limb_type>(~limb_type(0)); - pr[i] = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry)); - r_carry >>= CppInt1::limb_bits; - o_carry >>= CppInt1::limb_bits; - } - // Set the overflow into the "extra" limb: - r_carry += static_cast<double_limb_type>(~limb_type(0)); - o_carry += static_cast<double_limb_type>(~limb_type(0)); - next_limb = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry)); - } - } - // - // See if the result is negative or not: - // - if (static_cast<signed_limb_type>(next_limb) < 0) - { - double_limb_type carry = 1; - for (std::size_t i = 0; i < x; ++i) - { - carry += static_cast<double_limb_type>(~pr[i]); - pr[i] = static_cast<limb_type>(carry); - carry >>= CppInt1::limb_bits; - } - if (carry) - { - result.resize(x + 1, x); - if (result.size() > x) - result.limbs()[x] = static_cast<limb_type>(carry); - } - result.sign(true); - } - else - result.sign(false); - - result.normalize(); -} - -template <class CppInt1, class CppInt2, class Op> -BOOST_MP_CXX14_CONSTEXPR void bitwise_op( - CppInt1& result, - const CppInt2& o, - Op op, const std::integral_constant<bool, false>&) noexcept((is_non_throwing_cpp_int<CppInt1>::value)) -{ - // - // Both arguments are unsigned types, very simple case handled as a special case. - // - // First figure out how big the result needs to be and set up some data: - // - std::size_t rs = result.size(); - std::size_t os = o.size(); - std::size_t m(0), x(0); - minmax(rs, os, m, x); - result.resize(x, x); - typename CppInt1::limb_pointer pr = result.limbs(); - typename CppInt2::const_limb_pointer po = o.limbs(); - for (std::size_t i = rs; i < x; ++i) - pr[i] = 0; - - for (std::size_t i = 0; i < os; ++i) - pr[i] = op(pr[i], po[i]); - for (std::size_t i = os; i < x; ++i) - pr[i] = op(pr[i], limb_type(0)); - - result.normalize(); -} - -struct bit_and -{ - BOOST_MP_CXX14_CONSTEXPR limb_type operator()(limb_type a, limb_type b) const noexcept { return a & b; } -}; -struct bit_or -{ - BOOST_MP_CXX14_CONSTEXPR limb_type operator()(limb_type a, limb_type b) const noexcept { return a | b; } -}; -struct bit_xor -{ - BOOST_MP_CXX14_CONSTEXPR limb_type operator()(limb_type a, limb_type b) const noexcept { return a ^ b; } -}; - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_bitwise_and( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - bitwise_op(result, o, bit_and(), - std::integral_constant<bool, std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed > ()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_bitwise_or( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - bitwise_op(result, o, bit_or(), - std::integral_constant<bool, std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed > ()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_bitwise_xor( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - bitwise_op(result, o, bit_xor(), - std::integral_constant<bool, std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed > ()); -} -// -// Again for operands which are single limbs: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1> >::value>::type -eval_bitwise_and( - cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>& result, - limb_type l) noexcept -{ - result.limbs()[0] &= l; - result.resize(1, 1); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1> >::value>::type -eval_bitwise_or( - cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>& result, - limb_type l) noexcept -{ - result.limbs()[0] |= l; -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1> >::value>::type -eval_bitwise_xor( - cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>& result, - limb_type l) noexcept -{ - result.limbs()[0] ^= l; -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_complement( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - static_assert(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior."); - // Increment and negate: - result = o; - eval_increment(result); - result.negate(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_complement( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - std::size_t os = o.size(); - result.resize(SIZE_MAX, os); - for (std::size_t i = 0; i < os; ++i) - result.limbs()[i] = ~o.limbs()[i]; - for (std::size_t i = os; i < result.size(); ++i) - result.limbs()[i] = ~static_cast<limb_type>(0); - result.normalize(); -} - -template <class Int> -inline void left_shift_byte(Int& result, double_limb_type s) -{ - limb_type offset = static_cast<limb_type>(s / Int::limb_bits); - limb_type shift = static_cast<limb_type>(s % Int::limb_bits); - std::size_t ors = result.size(); - if ((ors == 1) && (!*result.limbs())) - return; // shifting zero yields zero. - std::size_t rs = ors; - if (shift && (result.limbs()[ors - 1] >> (Int::limb_bits - shift))) - ++rs; // Most significant limb will overflow when shifted - rs += offset; - result.resize(rs, rs); - rs = result.size(); - - typename Int::limb_pointer pr = result.limbs(); - - if (rs != ors) - pr[rs - 1] = 0u; - std::size_t bytes = static_cast<std::size_t>(s / CHAR_BIT); - std::size_t len = (std::min)(ors * sizeof(limb_type), rs * sizeof(limb_type) - bytes); - if (bytes >= rs * sizeof(limb_type)) - result = static_cast<limb_type>(0u); - else - { - unsigned char* pc = reinterpret_cast<unsigned char*>(pr); - std::memmove(pc + bytes, pc, len); - std::memset(pc, 0, bytes); - } -} - -template <class Int> -inline BOOST_MP_CXX14_CONSTEXPR void left_shift_limb(Int& result, double_limb_type s) -{ - limb_type offset = static_cast<limb_type>(s / Int::limb_bits); - limb_type shift = static_cast<limb_type>(s % Int::limb_bits); - - std::size_t ors = result.size(); - if ((ors == 1) && (!*result.limbs())) - return; // shifting zero yields zero. - std::size_t rs = ors; - if (shift && (result.limbs()[ors - 1] >> (Int::limb_bits - shift))) - ++rs; // Most significant limb will overflow when shifted - rs += offset; - result.resize(rs, rs); - - typename Int::limb_pointer pr = result.limbs(); - - if (offset > rs) - { - // The result is shifted past the end of the result: - result = static_cast<limb_type>(0); - return; - } - - std::size_t i = rs - result.size(); - for (; i < ors; ++i) - pr[rs - 1 - i] = pr[ors - 1 - i]; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(s)) - { - for (; i < rs; ++i) - pr[rs - 1 - i] = 0; - } - else -#endif - { - std::memset(pr, 0, (rs - i) * sizeof(*pr)); - } -} - -template <class Int> -inline BOOST_MP_CXX14_CONSTEXPR void left_shift_generic(Int& result, double_limb_type s) -{ - limb_type offset = static_cast<limb_type>(s / Int::limb_bits); - limb_type shift = static_cast<limb_type>(s % Int::limb_bits); - - std::size_t ors = result.size(); - if ((ors == 1) && (!*result.limbs())) - return; // shifting zero yields zero. - std::size_t rs = ors; - if (shift && (result.limbs()[ors - 1] >> (Int::limb_bits - shift))) - ++rs; // Most significant limb will overflow when shifted - rs += offset; - result.resize(rs, rs); - bool truncated = result.size() != rs; - - typename Int::limb_pointer pr = result.limbs(); - - if (offset > rs) - { - // The result is shifted past the end of the result: - result = static_cast<limb_type>(0); - return; - } - - std::size_t i = rs - result.size(); - // This code only works when shift is non-zero, otherwise we invoke undefined behaviour! - BOOST_MP_ASSERT(shift); - if (!truncated) - { - if (rs > ors + offset) - { - pr[rs - 1 - i] = pr[ors - 1 - i] >> (Int::limb_bits - shift); - --rs; - } - else - { - pr[rs - 1 - i] = pr[ors - 1 - i] << shift; - if (ors > 1) - pr[rs - 1 - i] |= pr[ors - 2 - i] >> (Int::limb_bits - shift); - ++i; - } - } - for (; rs - i >= 2 + offset; ++i) - { - pr[rs - 1 - i] = pr[rs - 1 - i - offset] << shift; - pr[rs - 1 - i] |= pr[rs - 2 - i - offset] >> (Int::limb_bits - shift); - } - if (rs - i >= 1 + offset) - { - pr[rs - 1 - i] = pr[rs - 1 - i - offset] << shift; - ++i; - } -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(s)) - { - for (; i < rs; ++i) - pr[rs - 1 - i] = 0; - } - else -#endif - { - std::memset(pr, 0, (rs - i) * sizeof(*pr)); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_left_shift( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - double_limb_type s) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - if (!s) - return; - -#if BOOST_MP_ENDIAN_LITTLE_BYTE && defined(BOOST_MP_USE_LIMB_SHIFT) - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - 1; - constexpr limb_type byte_shift_mask = CHAR_BIT - 1; - - if ((s & limb_shift_mask) == 0) - { - left_shift_limb(result, s); - } -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - else if ((s & byte_shift_mask) == 0) -#else - else if (((s & byte_shift_mask) == 0) && !BOOST_MP_IS_CONST_EVALUATED(s)) -#endif - { - left_shift_byte(result, s); - } -#elif BOOST_MP_ENDIAN_LITTLE_BYTE - constexpr limb_type byte_shift_mask = CHAR_BIT - 1; - -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - if ((s & byte_shift_mask) == 0) -#else - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - 1; - if (BOOST_MP_IS_CONST_EVALUATED(s) && ((s & limb_shift_mask) == 0)) - left_shift_limb(result, s); - else if (((s & byte_shift_mask) == 0) && !BOOST_MP_IS_CONST_EVALUATED(s)) -#endif - { - left_shift_byte(result, s); - } -#else - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - 1; - - if ((s & limb_shift_mask) == 0) - { - left_shift_limb(result, s); - } -#endif - else - { - left_shift_generic(result, s); - } - // - // We may have shifted off the end and have leading zeros: - // - result.normalize(); -} - -template <class Int> -inline void right_shift_byte(Int& result, double_limb_type s) -{ - limb_type offset = static_cast<limb_type>(s / Int::limb_bits); - BOOST_MP_ASSERT((s % CHAR_BIT) == 0); - std::size_t ors = result.size(); - std::size_t rs = ors; - if (offset >= rs) - { - result = limb_type(0); - return; - } - rs -= offset; - typename Int::limb_pointer pr = result.limbs(); - unsigned char* pc = reinterpret_cast<unsigned char*>(pr); - limb_type shift = static_cast<limb_type>(s / CHAR_BIT); - std::memmove(pc, pc + shift, ors * sizeof(pr[0]) - shift); - shift = (sizeof(limb_type) - shift % sizeof(limb_type)) * CHAR_BIT; - if (shift < Int::limb_bits) - { - pr[ors - offset - 1] &= (static_cast<limb_type>(1u) << shift) - 1; - if (!pr[ors - offset - 1] && (rs > 1)) - --rs; - } - result.resize(rs, rs); -} - -template <class Int> -inline BOOST_MP_CXX14_CONSTEXPR void right_shift_limb(Int& result, double_limb_type s) -{ - limb_type offset = static_cast<limb_type>(s / Int::limb_bits); - BOOST_MP_ASSERT((s % Int::limb_bits) == 0); - std::size_t ors = result.size(); - std::size_t rs = ors; - if (offset >= rs) - { - result = limb_type(0); - return; - } - rs -= offset; - typename Int::limb_pointer pr = result.limbs(); - std::size_t i = 0; - for (; i < rs; ++i) - pr[i] = pr[i + offset]; - result.resize(rs, rs); -} - -template <class Int> -inline BOOST_MP_CXX14_CONSTEXPR void right_shift_generic(Int& result, double_limb_type s) -{ - limb_type offset = static_cast<limb_type>(s / Int::limb_bits); - limb_type shift = static_cast<limb_type>(s % Int::limb_bits); - std::size_t ors = result.size(); - std::size_t rs = ors; - if (offset >= rs) - { - result = limb_type(0); - return; - } - rs -= offset; - typename Int::limb_pointer pr = result.limbs(); - if ((pr[ors - 1] >> shift) == 0) - { - if (--rs == 0) - { - result = limb_type(0); - return; - } - } - std::size_t i = 0; - - // This code only works for non-zero shift, otherwise we invoke undefined behaviour! - BOOST_MP_ASSERT(shift); - for (; i + offset + 1 < ors; ++i) - { - pr[i] = pr[i + offset] >> shift; - pr[i] |= pr[i + offset + 1] << (Int::limb_bits - shift); - } - pr[i] = pr[i + offset] >> shift; - result.resize(rs, rs); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1> >::value>::type -eval_right_shift( - cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>& result, - double_limb_type s) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>::checked_type()); - if (!s) - return; - -#if BOOST_MP_ENDIAN_LITTLE_BYTE && defined(BOOST_MP_USE_LIMB_SHIFT) - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::limb_bits - 1; - constexpr limb_type byte_shift_mask = CHAR_BIT - 1; - - if ((s & limb_shift_mask) == 0) - right_shift_limb(result, s); -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - else if ((s & byte_shift_mask) == 0) -#else - else if (((s & byte_shift_mask) == 0) && !BOOST_MP_IS_CONST_EVALUATED(s)) -#endif - right_shift_byte(result, s); -#elif BOOST_MP_ENDIAN_LITTLE_BYTE - constexpr limb_type byte_shift_mask = CHAR_BIT - 1; - -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - if ((s & byte_shift_mask) == 0) -#else - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::limb_bits - 1; - if (BOOST_MP_IS_CONST_EVALUATED(s) && ((s & limb_shift_mask) == 0)) - right_shift_limb(result, s); - else if (((s & byte_shift_mask) == 0) && !BOOST_MP_IS_CONST_EVALUATED(s)) -#endif - right_shift_byte(result, s); -#else - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::limb_bits - 1; - - if ((s & limb_shift_mask) == 0) - right_shift_limb(result, s); -#endif - else - right_shift_generic(result, s); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1> >::value>::type -eval_right_shift( - cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>& result, - double_limb_type s) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::checked_type()); - if (!s) - return; - - bool is_neg = result.sign(); - if (is_neg) - eval_increment(result); - -#if BOOST_MP_ENDIAN_LITTLE_BYTE && defined(BOOST_MP_USE_LIMB_SHIFT) - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::limb_bits - 1; - constexpr limb_type byte_shift_mask = CHAR_BIT - 1; - - if ((s & limb_shift_mask) == 0) - right_shift_limb(result, s); -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - else if ((s & byte_shift_mask) == 0) -#else - else if (((s & byte_shift_mask) == 0) && !BOOST_MP_IS_CONST_EVALUATED(s)) -#endif - right_shift_byte(result, s); -#elif BOOST_MP_ENDIAN_LITTLE_BYTE - constexpr limb_type byte_shift_mask = CHAR_BIT - 1; - -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - if ((s & byte_shift_mask) == 0) -#else - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::limb_bits - 1; - if (BOOST_MP_IS_CONST_EVALUATED(s) && ((s & limb_shift_mask) == 0)) - right_shift_limb(result, s); - else if (((s & byte_shift_mask) == 0) && !BOOST_MP_IS_CONST_EVALUATED(s)) -#endif - right_shift_byte(result, s); -#else - constexpr limb_type limb_shift_mask = cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>::limb_bits - 1; - - if ((s & limb_shift_mask) == 0) - right_shift_limb(result, s); -#endif - else - right_shift_generic(result, s); - if (is_neg) - eval_decrement(result); -} - -// -// Over again for trivial cpp_int's: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type -eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - *result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type -eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - // Nothing to check here... just make sure we don't invoke undefined behavior: - is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - *result.limbs() = (static_cast<unsigned>(s) >= sizeof(*result.limbs()) * CHAR_BIT) ? 0 : (result.sign() ? ((--*result.limbs()) >> s) + 1 : *result.limbs() >> s); - if (result.sign() && (*result.limbs() == 0)) - result = static_cast<signed_limb_type>(-1); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)>::type -eval_complement( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - static_assert(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior."); - // - // If we're not checked then emulate 2's complement behavior: - // - if (o.sign()) - { - *result.limbs() = *o.limbs() - 1; - result.sign(false); - } - else - { - *result.limbs() = 1 + *o.limbs(); - result.sign(true); - } - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_complement( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = ~*o.limbs(); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_bitwise_and( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() &= *o.limbs(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)>::type -eval_bitwise_and( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - - using default_ops::eval_bit_test; - using default_ops::eval_increment; - - if (result.sign() || o.sign()) - { - constexpr std::size_t m = detail::static_unsigned_max<detail::static_unsigned_max<MinBits1, MinBits2>::value, detail::static_unsigned_max<MaxBits1, MaxBits2>::value>::value; - cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t1(result); - cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t2(o); - eval_bitwise_and(t1, t2); - bool s = eval_bit_test(t1, m + 1); - if (s) - { - eval_complement(t1, t1); - eval_increment(t1); - } - result = t1; - result.sign(s); - } - else - { - *result.limbs() &= *o.limbs(); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_bitwise_or( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() |= *o.limbs(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)>::type -eval_bitwise_or( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - - using default_ops::eval_bit_test; - using default_ops::eval_increment; - - if (result.sign() || o.sign()) - { - constexpr std::size_t m = detail::static_unsigned_max<detail::static_unsigned_max<MinBits1, MinBits2>::value, detail::static_unsigned_max<MaxBits1, MaxBits2>::value>::value; - cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t1(result); - cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t2(o); - eval_bitwise_or(t1, t2); - bool s = eval_bit_test(t1, m + 1); - if (s) - { - eval_complement(t1, t1); - eval_increment(t1); - } - result = t1; - result.sign(s); - } - else - { - *result.limbs() |= *o.limbs(); - result.normalize(); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_bitwise_xor( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() ^= *o.limbs(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)>::type -eval_bitwise_xor( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - - using default_ops::eval_bit_test; - using default_ops::eval_increment; - - if (result.sign() || o.sign()) - { - constexpr std::size_t m = detail::static_unsigned_max<detail::static_unsigned_max<MinBits1, MinBits2>::value, detail::static_unsigned_max<MaxBits1, MaxBits2>::value>::value; - cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t1(result); - cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t2(o); - eval_bitwise_xor(t1, t2); - bool s = eval_bit_test(t1, m + 1); - if (s) - { - eval_complement(t1, t1); - eval_increment(t1); - } - result = t1; - result.sign(s); - } - else - { - *result.limbs() ^= *o.limbs(); - } -} - -}}} // namespace boost::multiprecision::backends - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/checked.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/checked.hpp deleted file mode 100644 index 5d621403d0..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/checked.hpp +++ /dev/null @@ -1,178 +0,0 @@ - -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_CPP_INT_CHECKED_HPP -#define BOOST_MP_CPP_INT_CHECKED_HPP - -#include <climits> -#include <limits> -#include <type_traits> -#include <stdexcept> -#include <string> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> - -namespace boost { namespace multiprecision { namespace backends { namespace detail { - -// -// Simple routines for performing checked arithmetic with a builtin arithmetic type. -// Note that this is not a complete header, it must be included as part of boost/multiprecision/cpp_int.hpp. -// - -template <typename T> -inline constexpr T type_max() noexcept -{ - return - #ifdef BOOST_HAS_INT128 - std::is_same<T, boost::multiprecision::int128_type>::value ? INT128_MAX : - std::is_same<T, boost::multiprecision::uint128_type>::value ? UINT128_MAX : - #endif - (std::numeric_limits<T>::max)(); -} - -template <typename T> -inline constexpr T type_min() noexcept -{ - return - #ifdef BOOST_HAS_INT128 - std::is_same<T, boost::multiprecision::int128_type>::value ? INT128_MIN : - std::is_same<T, boost::multiprecision::uint128_type>::value ? T(0) : - #endif - (std::numeric_limits<T>::min)(); -} - -inline void raise_overflow(std::string op) -{ - BOOST_MP_THROW_EXCEPTION(std::overflow_error("overflow in " + op)); -} -inline void raise_add_overflow() -{ - raise_overflow("addition"); -} -inline void raise_subtract_overflow() -{ - BOOST_MP_THROW_EXCEPTION(std::range_error("Subtraction resulted in a negative value, but the type is unsigned")); -} -inline void raise_mul_overflow() -{ - raise_overflow("multiplication"); -} -inline void raise_div_overflow() -{ - raise_overflow("division"); -} - -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_add_imp(A a, A b, const std::integral_constant<bool, true>&) -{ - if (a > 0) - { - if ((b > 0) && ((type_max<A>() - b) < a)) - raise_add_overflow(); - } - else - { - if ((b < 0) && ((type_min<A>() - b) > a)) - raise_add_overflow(); - } - return a + b; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_add_imp(A a, A b, const std::integral_constant<bool, false>&) -{ - if ((type_max<A>() - b) < a) - raise_add_overflow(); - return a + b; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_add(A a, A b, const std::integral_constant<int, checked>&) -{ - return checked_add_imp(a, b, std::integral_constant<bool, boost::multiprecision::detail::is_signed<A>::value && boost::multiprecision::detail::is_integral<A>::value > ()); -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_add(A a, A b, const std::integral_constant<int, unchecked>&) -{ - return a + b; -} - -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_subtract_imp(A a, A b, const std::integral_constant<bool, true>&) -{ - if (a > 0) - { - if ((b < 0) && ((type_max<A>() + b) < a)) - raise_subtract_overflow(); - } - else - { - if ((b > 0) && ((type_min<A>() + b) > a)) - raise_subtract_overflow(); - } - return a - b; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_subtract_imp(A a, A b, const std::integral_constant<bool, false>&) -{ - if (a < b) - raise_subtract_overflow(); - return a - b; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_subtract(A a, A b, const std::integral_constant<int, checked>&) -{ - return checked_subtract_imp(a, b, std::integral_constant<bool, boost::multiprecision::detail::is_signed<A>::value && boost::multiprecision::detail::is_integral<A>::value>()); -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_subtract(A a, A b, const std::integral_constant<int, unchecked>&) -{ - return a - b; -} - -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_multiply(A a, A b, const std::integral_constant<int, checked>&) -{ - BOOST_MP_USING_ABS - if (a && (type_max<A>() / abs(a) < abs(b))) - raise_mul_overflow(); - return a * b; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_multiply(A a, A b, const std::integral_constant<int, unchecked>&) -{ - return a * b; -} - -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_divide(A a, A b, const std::integral_constant<int, checked>&) -{ - if (b == 0) - raise_div_overflow(); - return a / b; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_divide(A a, A b, const std::integral_constant<int, unchecked>&) -{ - return a / b; -} - -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_left_shift(A a, unsigned long long shift, const std::integral_constant<int, checked>&) -{ - if (a && shift) - { - if ((shift > sizeof(A) * CHAR_BIT) || (a >> (sizeof(A) * CHAR_BIT - shift))) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Shift out of range")); - } - return a << shift; -} -template <class A> -inline BOOST_MP_CXX14_CONSTEXPR A checked_left_shift(A a, unsigned long long shift, const std::integral_constant<int, unchecked>&) -{ - return (shift >= sizeof(A) * CHAR_BIT) ? 0 : a << shift; -} - -}}}} // namespace boost::multiprecision::backends::detail - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp deleted file mode 100644 index 9808889ff1..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp +++ /dev/null @@ -1,374 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_COMPARISON_HPP -#define BOOST_MP_CPP_INT_COMPARISON_HPP - -#include <boost/multiprecision/detail/constexpr.hpp> - -namespace boost { namespace multiprecision { namespace backends { - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4018 4389 4996) -#endif - -// -// Start with non-trivial cpp_int's: -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a, const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b) noexcept -{ - return (a.sign() == b.sign()) && (a.size() == b.size()) && std_constexpr::equal(a.limbs(), a.limbs() + a.size(), b.limbs()); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) noexcept -{ - return (a.sign() == b.sign()) && (a.size() == b.size()) && std_constexpr::equal(a.limbs(), a.limbs() + a.size(), b.limbs()); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) noexcept -{ - return (a.sign() == false) && (a.size() == 1) && (*a.limbs() == b); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) noexcept -{ - return (a.sign() == (b < 0)) && (a.size() == 1) && (*a.limbs() == boost::multiprecision::detail::unsigned_abs(b)); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) noexcept -{ - return (a.size() == 1) && (*a.limbs() == b); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) noexcept -{ - return (b < 0) ? eval_eq(a, cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>(b)) : eval_eq(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) noexcept -{ - if (a.sign()) - return true; - if (a.size() > 1) - return false; - return *a.limbs() < b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) noexcept -{ - if ((b == 0) || (a.sign() != (b < 0))) - return a.sign(); - if (a.sign()) - { - if (a.size() > 1) - return true; - return *a.limbs() > boost::multiprecision::detail::unsigned_abs(b); - } - else - { - if (a.size() > 1) - return false; - return *a.limbs() < boost::multiprecision::detail::unsigned_abs(b); - } -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) noexcept -{ - if (a.size() > 1) - return false; - return *a.limbs() < b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) noexcept -{ - return (b < 0) ? a.compare(b) < 0 : eval_lt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) noexcept -{ - if (a.sign()) - return false; - if (a.size() > 1) - return true; - return *a.limbs() > b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) noexcept -{ - if (b == 0) - return !a.sign() && ((a.size() > 1) || *a.limbs()); - if (a.sign() != (b < 0)) - return !a.sign(); - if (a.sign()) - { - if (a.size() > 1) - return false; - return *a.limbs() < boost::multiprecision::detail::unsigned_abs(b); - } - else - { - if (a.size() > 1) - return true; - return *a.limbs() > boost::multiprecision::detail::unsigned_abs(b); - } -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) noexcept -{ - if (a.size() > 1) - return true; - return *a.limbs() > b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) noexcept -{ - return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison. -} -// -// And again for trivial cpp_ints: -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::value -eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) noexcept -{ - return (a.sign() == b.sign()) && (*a.limbs() == *b.limbs()); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::value -eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) noexcept -{ - return *a.limbs() == *b.limbs(); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class U> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) noexcept -{ - return !a.sign() && (*a.limbs() == b); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class S> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) noexcept -{ - return (a.sign() == (b < 0)) && (*a.limbs() == boost::multiprecision::detail::unsigned_abs(b)); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class U> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) noexcept -{ - return *a.limbs() == b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class S> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) noexcept -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type; - if (b < 0) - { - cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b); - return *a.limbs() == *t.limbs(); - } - else - { - return *a.limbs() == static_cast<ui_type>(b); - } -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) noexcept -{ - if (a.sign() != b.sign()) - return a.sign(); - return a.sign() ? *a.limbs() > *b.limbs() : *a.limbs() < *b.limbs(); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) noexcept -{ - return *a.limbs() < *b.limbs(); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class U> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) noexcept -{ - if (a.sign()) - return true; - return *a.limbs() < b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class S> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) noexcept -{ - if (a.sign() != (b < 0)) - return a.sign(); - return a.sign() ? (*a.limbs() > boost::multiprecision::detail::unsigned_abs(b)) : (*a.limbs() < boost::multiprecision::detail::unsigned_abs(b)); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class U> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) noexcept -{ - return *a.limbs() < b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class S> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) noexcept -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type; - if (b < 0) - { - cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b); - return *a.limbs() < *t.limbs(); - } - else - { - return *a.limbs() < static_cast<ui_type>(b); - } -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) noexcept -{ - if (a.sign() != b.sign()) - return !a.sign(); - return a.sign() ? *a.limbs() < *b.limbs() : *a.limbs() > *b.limbs(); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) noexcept -{ - return *a.limbs() > *b.limbs(); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class U> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) noexcept -{ - if (a.sign()) - return false; - return *a.limbs() > b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class S> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) noexcept -{ - if (a.sign() != (b < 0)) - return !a.sign(); - return a.sign() ? (*a.limbs() < boost::multiprecision::detail::unsigned_abs(b)) : (*a.limbs() > boost::multiprecision::detail::unsigned_abs(b)); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class U> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) noexcept -{ - return *a.limbs() > b; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class S> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value, - bool>::type -eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) noexcept -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type; - if (b < 0) - { - cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b); - return *a.limbs() > *t.limbs(); - } - else - { - return *a.limbs() > static_cast<ui_type>(b); - } -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -}}} // namespace boost::multiprecision::backends - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/cpp_int_config.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/cpp_int_config.hpp deleted file mode 100644 index 1b7df4f1a9..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/cpp_int_config.hpp +++ /dev/null @@ -1,176 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 - 2021 John Maddock. -// Copyright 2021 Matt Borland. -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_CPP_INT_CONFIG_HPP -#define BOOST_MP_CPP_INT_CONFIG_HPP - -#include <cstdint> -#include <type_traits> -#include <limits> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/number_base.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -namespace boost { -namespace multiprecision { - -namespace detail { - -// -// These traits calculate the largest type in the list -// [unsigned] long long, long, int, which has the specified number -// of bits. Note that int_t and uint_t find the first -// member of the above list, not the last. We want the last in the -// list to ensure that mixed arithmetic operations are as efficient -// as possible. -// - -template <std::size_t Bits> -struct int_t -{ - using exact = typename std::conditional<Bits <= sizeof(signed char) * CHAR_BIT, signed char, - typename std::conditional<Bits <= sizeof(short) * CHAR_BIT, short, - typename std::conditional<Bits <= sizeof(int) * CHAR_BIT, int, - typename std::conditional<Bits <= sizeof(long) * CHAR_BIT, long, - typename std::conditional<Bits <= sizeof(long long) * CHAR_BIT, long long, void - >::type>::type>::type>::type>::type; - - using least = typename std::conditional<Bits-1 <= std::numeric_limits<signed char>::digits, signed char, - typename std::conditional<Bits-1 <= std::numeric_limits<short>::digits, short, - typename std::conditional<Bits-1 <= std::numeric_limits<int>::digits, int, - typename std::conditional<Bits-1 <= std::numeric_limits<long>::digits, long, - typename std::conditional<Bits-1 <= std::numeric_limits<long long>::digits, long long, void - >::type>::type>::type>::type>::type; - - static_assert(!std::is_same<void, exact>::value && !std::is_same<void, least>::value, "Number of bits does not match any standard data type. \ - Please file an issue at https://github.com/boostorg/multiprecision/ referencing this error from cpp_int_config.hpp"); -}; - -template <std::size_t Bits> -struct uint_t -{ - using exact = typename std::conditional<Bits <= sizeof(unsigned char) * CHAR_BIT, unsigned char, - typename std::conditional<Bits <= sizeof(unsigned short) * CHAR_BIT, unsigned short, - typename std::conditional<Bits <= sizeof(unsigned int) * CHAR_BIT, unsigned int, - typename std::conditional<Bits <= sizeof(unsigned long) * CHAR_BIT, unsigned long, - typename std::conditional<Bits <= sizeof(unsigned long long) * CHAR_BIT, unsigned long long, void - >::type>::type>::type>::type>::type; - - using least = typename std::conditional<Bits <= std::numeric_limits<unsigned char>::digits, unsigned char, - typename std::conditional<Bits <= std::numeric_limits<unsigned short>::digits, unsigned short, - typename std::conditional<Bits <= std::numeric_limits<unsigned int>::digits, unsigned int, - typename std::conditional<Bits <= std::numeric_limits<unsigned long>::digits, unsigned long, - typename std::conditional<Bits <= std::numeric_limits<unsigned long long>::digits, unsigned long long, void - >::type>::type>::type>::type>::type; - - static_assert(!std::is_same<void, exact>::value && !std::is_same<void, least>::value, "Number of bits does not match any standard data type. \ - Please file an issue at https://github.com/boostorg/multiprecision/ referencing this error from cpp_int_config.hpp"); -}; - -template <std::size_t N> -struct largest_signed_type -{ - using type = typename std::conditional< - 1 + std::numeric_limits<long long>::digits == N, - long long, - typename std::conditional< - 1 + std::numeric_limits<long>::digits == N, - long, - typename std::conditional< - 1 + std::numeric_limits<int>::digits == N, - int, - typename int_t<N>::exact>::type>::type>::type; -}; - -template <std::size_t N> -struct largest_unsigned_type -{ - using type = typename std::conditional< - std::numeric_limits<unsigned long long>::digits == N, - unsigned long long, - typename std::conditional< - std::numeric_limits<unsigned long>::digits == N, - unsigned long, - typename std::conditional< - std::numeric_limits<unsigned int>::digits == N, - unsigned int, - typename uint_t<N>::exact>::type>::type>::type; -}; - -} // namespace detail - -#if defined(BOOST_HAS_INT128) - -using limb_type = detail::largest_unsigned_type<64>::type; -using signed_limb_type = detail::largest_signed_type<64>::type; -using double_limb_type = boost::multiprecision::uint128_type; -using signed_double_limb_type = boost::multiprecision::int128_type; -constexpr limb_type max_block_10 = 1000000000000000000uLL; -constexpr limb_type digits_per_block_10 = 18; - -inline BOOST_MP_CXX14_CONSTEXPR limb_type block_multiplier(std::size_t count) -{ - constexpr limb_type values[digits_per_block_10] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000}; - BOOST_MP_ASSERT(count < digits_per_block_10); - return values[count]; -} - -// Can't do formatted IO on an __int128 -#define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO - -#else - -using limb_type = detail::largest_unsigned_type<32>::type; -using signed_limb_type = detail::largest_signed_type<32>::type ; -using double_limb_type = detail::largest_unsigned_type<64>::type; -using signed_double_limb_type = detail::largest_signed_type<64>::type ; -constexpr limb_type max_block_10 = 1000000000; -constexpr limb_type digits_per_block_10 = 9; - -inline limb_type block_multiplier(std::size_t count) -{ - constexpr limb_type values[digits_per_block_10] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; - BOOST_MP_ASSERT(count < digits_per_block_10); - return values[count]; -} - -#endif - -constexpr std::size_t bits_per_limb = sizeof(limb_type) * CHAR_BIT; - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void minmax(const T& a, const T& b, T& aa, T& bb) -{ - if (a < b) - { - aa = a; - bb = b; - } - else - { - aa = b; - bb = a; - } -} - -enum cpp_integer_type -{ - signed_magnitude = 1, - unsigned_magnitude = 0, - signed_packed = 3, - unsigned_packed = 2 -}; - -enum cpp_int_check_type -{ - checked = 1, - unchecked = 0 -}; - -} // namespace multiprecision -} // namespace boost - -#endif // BOOST_MP_CPP_INT_CONFIG_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/divide.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/divide.hpp deleted file mode 100644 index b1253fc368..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/divide.hpp +++ /dev/null @@ -1,655 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_DIVIDE_HPP -#define BOOST_MP_CPP_INT_DIVIDE_HPP - -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -namespace boost { namespace multiprecision { namespace backends { - -template <class CppInt1, class CppInt2, class CppInt3> -BOOST_MP_CXX14_CONSTEXPR void divide_unsigned_helper( - CppInt1* result, - const CppInt2& x, - const CppInt3& y, - CppInt1& r) -{ - if (((void*)result == (void*)&x) || ((void*)&r == (void*)&x)) - { - CppInt2 t(x); - divide_unsigned_helper(result, t, y, r); - return; - } - if (((void*)result == (void*)&y) || ((void*)&r == (void*)&y)) - { - CppInt3 t(y); - divide_unsigned_helper(result, x, t, r); - return; - } - - /* - Very simple, fairly braindead long division. - Start by setting the remainder equal to x, and the - result equal to 0. Then in each loop we calculate our - "best guess" for how many times y divides into r, - add our guess to the result, and subtract guess*y - from the remainder r. One wrinkle is that the remainder - may go negative, in which case we subtract the current guess - from the result rather than adding. The value of the guess - is determined by dividing the most-significant-limb of the - current remainder by the most-significant-limb of y. - - Note that there are more efficient algorithms than this - available, in particular see Knuth Vol 2. However for small - numbers of limbs this generally outperforms the alternatives - and avoids the normalisation step which would require extra storage. - */ - - using default_ops::eval_subtract; - - if (result == &r) - { - CppInt1 rem; - divide_unsigned_helper(result, x, y, rem); - r = rem; - return; - } - - // - // Find the most significant words of numerator and denominator. - // - std::size_t y_order = y.size() - 1; - - if (y_order == 0) - { - // - // Only a single non-zero limb in the denominator, in this case - // we can use a specialized divide-by-single-limb routine which is - // much faster. This also handles division by zero: - // - divide_unsigned_helper(result, x, y.limbs()[y_order], r); - return; - } - - typename CppInt2::const_limb_pointer px = x.limbs(); - typename CppInt3::const_limb_pointer py = y.limbs(); - - std::size_t r_order = x.size() - 1; - if ((r_order == 0) && (*px == 0)) - { - // x is zero, so is the result: - r = x; - if (result) - *result = x; - return; - } - - r = x; - r.sign(false); - if (result) - *result = static_cast<limb_type>(0u); - // - // Check if the remainder is already less than the divisor, if so - // we already have the result. Note we try and avoid a full compare - // if we can: - // - if (r_order <= y_order) - { - if ((r_order < y_order) || (r.compare_unsigned(y) < 0)) - { - return; - } - } - - CppInt1 t; - bool r_neg = false; - - // - // See if we can short-circuit long division, and use basic arithmetic instead: - // - if (r_order == 0) - { - if (result) - { - *result = px[0] / py[0]; - } - r = px[0] % py[0]; - return; - } - else if (r_order == 1) - { - double_limb_type a = (static_cast<double_limb_type>(px[1]) << CppInt1::limb_bits) | px[0]; - double_limb_type b = y_order ? (static_cast<double_limb_type>(py[1]) << CppInt1::limb_bits) | py[0] - : py[0]; - if (result) - { - *result = a / b; - } - r = a % b; - return; - } - // - // prepare result: - // - if (result) - result->resize(1 + r_order - y_order, 1 + r_order - y_order); - typename CppInt1::const_limb_pointer prem = r.limbs(); - // This is initialised just to keep the compiler from emitting useless warnings later on: - typename CppInt1::limb_pointer pr = typename CppInt1::limb_pointer(); - if (result) - { - pr = result->limbs(); - for (std::size_t i = 1; i < 1 + r_order - y_order; ++i) - pr[i] = 0; - } - bool first_pass = true; - - do - { - // - // Calculate our best guess for how many times y divides into r: - // - limb_type guess = 1; - if ((prem[r_order] <= py[y_order]) && (r_order > 0)) - { - double_limb_type a = (static_cast<double_limb_type>(prem[r_order]) << CppInt1::limb_bits) | prem[r_order - 1]; - double_limb_type b = py[y_order]; - double_limb_type v = a / b; - if (v <= CppInt1::max_limb_value) - { - guess = static_cast<limb_type>(v); - --r_order; - } - } - else if (r_order == 0) - { - guess = prem[0] / py[y_order]; - } - else - { - double_limb_type a = (static_cast<double_limb_type>(prem[r_order]) << CppInt1::limb_bits) | prem[r_order - 1]; - double_limb_type b = (y_order > 0) ? (static_cast<double_limb_type>(py[y_order]) << CppInt1::limb_bits) | py[y_order - 1] : (static_cast<double_limb_type>(py[y_order]) << CppInt1::limb_bits); - BOOST_MP_ASSERT(b); - double_limb_type v = a / b; - guess = static_cast<limb_type>(v); - } - BOOST_MP_ASSERT(guess); // If the guess ever gets to zero we go on forever.... - // - // Update result: - // - std::size_t shift = r_order - y_order; - if (result) - { - if (r_neg) - { - if (pr[shift] > guess) - pr[shift] -= guess; - else - { - t.resize(shift + 1, shift + 1); - t.limbs()[shift] = guess; - for (std::size_t i = 0; i < shift; ++i) - t.limbs()[i] = 0; - eval_subtract(*result, t); - } - } - else if (CppInt1::max_limb_value - pr[shift] > guess) - pr[shift] += guess; - else - { - t.resize(shift + 1, shift + 1); - t.limbs()[shift] = guess; - for (std::size_t i = 0; i < shift; ++i) - t.limbs()[i] = 0; - eval_add(*result, t); - } - } - // - // Calculate guess * y, we use a fused mutiply-shift O(N) for this - // rather than a full O(N^2) multiply: - // - double_limb_type carry = 0; - t.resize(y.size() + shift + 1, y.size() + shift); - bool truncated_t = (t.size() != y.size() + shift + 1); - typename CppInt1::limb_pointer pt = t.limbs(); - for (std::size_t i = 0; i < shift; ++i) - pt[i] = 0; - for (std::size_t i = 0; i < y.size(); ++i) - { - carry += static_cast<double_limb_type>(py[i]) * static_cast<double_limb_type>(guess); -#ifdef __MSVC_RUNTIME_CHECKS - pt[i + shift] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pt[i + shift] = static_cast<limb_type>(carry); -#endif - carry >>= CppInt1::limb_bits; - } - if (carry && !truncated_t) - { -#ifdef __MSVC_RUNTIME_CHECKS - pt[t.size() - 1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pt[t.size() - 1] = static_cast<limb_type>(carry); -#endif - } - else if (!truncated_t) - { - t.resize(t.size() - 1, t.size() - 1); - } - // - // Update r in a way that won't actually produce a negative result - // in case the argument types are unsigned: - // - if (truncated_t && carry) - { - // We need to calculate 2^n + t - r - // where n is the number of bits in this type. - // Simplest way is to get 2^n - r by complementing - // r, then add t to it. Note that we can't call eval_complement - // in case this is a signed checked type: - for (std::size_t i = 0; i <= r_order; ++i) - r.limbs()[i] = ~prem[i]; - r.normalize(); - eval_increment(r); - eval_add(r, t); - r_neg = !r_neg; - } - else if (r.compare(t) > 0) - { - eval_subtract(r, t); - } - else - { - r.swap(t); - eval_subtract(r, t); - prem = r.limbs(); - r_neg = !r_neg; - } - // - // First time through we need to strip any leading zero, otherwise - // the termination condition goes belly-up: - // - if (result && first_pass) - { - first_pass = false; - while (pr[result->size() - 1] == 0) - result->resize(result->size() - 1, result->size() - 1); - } - // - // Update r_order: - // - r_order = r.size() - 1; - if (r_order < y_order) - break; - } - // Termination condition is really just a check that r > y, but with a common - // short-circuit case handled first: - while ((r_order > y_order) || (r.compare_unsigned(y) >= 0)); - - // - // We now just have to normalise the result: - // - if (r_neg && eval_get_sign(r)) - { - // We have one too many in the result: - if (result) - eval_decrement(*result); - if (y.sign()) - { - r.negate(); - eval_subtract(r, y); - } - else - eval_subtract(r, y, r); - } - - BOOST_MP_ASSERT(r.compare_unsigned(y) < 0); // remainder must be less than the divisor or our code has failed -} - -template <class CppInt1, class CppInt2> -BOOST_MP_CXX14_CONSTEXPR void divide_unsigned_helper( - CppInt1* result, - const CppInt2& x, - limb_type y, - CppInt1& r) -{ - if (((void*)result == (void*)&x) || ((void*)&r == (void*)&x)) - { - CppInt2 t(x); - divide_unsigned_helper(result, t, y, r); - return; - } - - if (result == &r) - { - CppInt1 rem; - divide_unsigned_helper(result, x, y, rem); - r = rem; - return; - } - - // As above, but simplified for integer divisor: - - using default_ops::eval_subtract; - - if (y == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer Division by zero.")); - } - // - // Find the most significant word of numerator. - // - std::size_t r_order = x.size() - 1; - - // - // Set remainder and result to their initial values: - // - r = x; - r.sign(false); - typename CppInt1::limb_pointer pr = r.limbs(); - - // - // check for x < y, try to do this without actually having to - // do a full comparison: - // - if ((r_order == 0) && (*pr < y)) - { - if (result) - *result = static_cast<limb_type>(0u); - return; - } - - // - // See if we can short-circuit long division, and use basic arithmetic instead: - // - if (r_order == 0) - { - if (result) - { - *result = *pr / y; - result->sign(x.sign()); - } - *pr %= y; - r.sign(x.sign()); - return; - } - else if (r_order == 1) - { - double_limb_type a = (static_cast<double_limb_type>(pr[r_order]) << CppInt1::limb_bits) | pr[0]; - if (result) - { - *result = a / y; - result->sign(x.sign()); - } - r = a % y; - r.sign(x.sign()); - return; - } - - // This is initialised just to keep the compiler from emitting useless warnings later on: - typename CppInt1::limb_pointer pres = typename CppInt1::limb_pointer(); - if (result) - { - result->resize(r_order + 1, r_order + 1); - pres = result->limbs(); - if (result->size() > r_order) - pres[r_order] = 0; // just in case we don't set the most significant limb below. - } - - do - { - // - // Calculate our best guess for how many times y divides into r: - // - if ((pr[r_order] < y) && r_order) - { - double_limb_type a = (static_cast<double_limb_type>(pr[r_order]) << CppInt1::limb_bits) | pr[r_order - 1]; - double_limb_type b = a % y; - r.resize(r.size() - 1, r.size() - 1); - --r_order; - pr[r_order] = static_cast<limb_type>(b); - if (result) - pres[r_order] = static_cast<limb_type>(a / y); - if (r_order && pr[r_order] == 0) - { - --r_order; // No remainder, division was exact. - r.resize(r.size() - 1, r.size() - 1); - if (result) - pres[r_order] = static_cast<limb_type>(0u); - } - } - else - { - if (result) - pres[r_order] = pr[r_order] / y; - pr[r_order] %= y; - if (r_order && pr[r_order] == 0) - { - --r_order; // No remainder, division was exact. - r.resize(r.size() - 1, r.size() - 1); - if (result) - pres[r_order] = static_cast<limb_type>(0u); - } - } - } - // Termination condition is really just a check that r >= y, but with two common - // short-circuit cases handled first: - while (r_order || (pr[r_order] >= y)); - - if (result) - { - result->normalize(); - result->sign(x.sign()); - } - r.normalize(); - r.sign(x.sign()); - - BOOST_MP_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) -{ - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r; - bool s = a.sign() != b.sign(); - divide_unsigned_helper(&result, a, b, r); - result.sign(s); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - limb_type& b) -{ - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r; - bool s = a.sign(); - divide_unsigned_helper(&result, a, b, r); - result.sign(s); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - signed_limb_type& b) -{ - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r; - bool s = a.sign() != (b < 0); - divide_unsigned_helper(&result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(b)), r); - result.sign(s); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) -{ - // There is no in place divide: - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result); - eval_divide(result, a, b); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - limb_type b) -{ - // There is no in place divide: - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result); - eval_divide(result, a, b); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - signed_limb_type b) -{ - // There is no in place divide: - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result); - eval_divide(result, a, b); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) -{ - bool s = a.sign(); - if (b.size() == 1) - eval_modulus(result, a, *b.limbs()); - else - { - using cpp_int_backend1_type = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>; - - divide_unsigned_helper(static_cast<cpp_int_backend1_type*>(nullptr), a, b, result); - } - result.sign(s); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type mod) -{ - const std::ptrdiff_t n = static_cast<std::ptrdiff_t>(a.size()); - const double_limb_type two_n_mod = static_cast<limb_type>(1u) + (~static_cast<limb_type>(0u) - mod) % mod; - limb_type res = a.limbs()[n - 1] % mod; - - for (std::ptrdiff_t i = n - 2; i >= 0; --i) - res = static_cast<limb_type>(static_cast<double_limb_type>(static_cast<double_limb_type>(res * two_n_mod) + a.limbs()[i]) % mod); - // - // We must not modify result until here in case - // result and a are the same object: - // - result.resize(1, 1); - *result.limbs() = res; - result.sign(a.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - signed_limb_type b) -{ - const limb_type t = b < 0 ? static_cast<limb_type>(-b) : static_cast<limb_type>(b); - eval_modulus(result, a, t); - result.sign(a.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) -{ - // There is no in place divide: - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result); - eval_modulus(result, a, b); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - limb_type b) -{ - // Single limb modulus is in place: - eval_modulus(result, result, b); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - signed_limb_type b) -{ - // Single limb modulus is in place: - eval_modulus(result, result, b); -} - -// -// Over again for trivial cpp_int's: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) -{ - if (!*o.limbs()) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - *result.limbs() /= *o.limbs(); - result.sign(result.sign() != o.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_divide( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) -{ - if (!*o.limbs()) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - *result.limbs() /= *o.limbs(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_modulus( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) -{ - if (!*o.limbs()) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - *result.limbs() %= *o.limbs(); - result.sign(result.sign()); -} - -}}} // namespace boost::multiprecision::backends - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/import_export.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/import_export.hpp deleted file mode 100644 index e0c122213f..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/import_export.hpp +++ /dev/null @@ -1,248 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2015 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_CPP_INT_IMPORT_EXPORT_HPP -#define BOOST_MP_CPP_INT_IMPORT_EXPORT_HPP - -#include <climits> -#include <cstring> -#include <boost/multiprecision/detail/endian.hpp> - -namespace boost { -namespace multiprecision { - -namespace detail { - -template <class Backend, class Unsigned> -void assign_bits(Backend& val, Unsigned bits, std::size_t bit_location, std::size_t chunk_bits, const std::integral_constant<bool, false>& tag) -{ - std::size_t limb = bit_location / (sizeof(limb_type) * CHAR_BIT); - std::size_t shift = bit_location % (sizeof(limb_type) * CHAR_BIT); - - limb_type mask = chunk_bits >= sizeof(limb_type) * CHAR_BIT ? ~static_cast<limb_type>(0u) : (static_cast<limb_type>(1u) << chunk_bits) - 1; - - limb_type value = static_cast<limb_type>(bits & mask) << shift; - if (value) - { - if (val.size() == limb) - { - val.resize(limb + 1, limb + 1); - if (val.size() > limb) - val.limbs()[limb] = value; - } - else if (val.size() > limb) - val.limbs()[limb] |= value; - } - if (chunk_bits > sizeof(limb_type) * CHAR_BIT - shift) - { - shift = sizeof(limb_type) * CHAR_BIT - shift; - chunk_bits -= shift; - bit_location += shift; - bits >>= shift; - if (bits) - assign_bits(val, bits, bit_location, chunk_bits, tag); - } -} -template <class Backend, class Unsigned> -void assign_bits(Backend& val, Unsigned bits, std::size_t bit_location, std::size_t chunk_bits, const std::integral_constant<bool, true>&) -{ - using local_limb_type = typename Backend::local_limb_type; - // - // Check for possible overflow, this may trigger an exception, or have no effect - // depending on whether this is a checked integer or not: - // - if ((bit_location >= sizeof(local_limb_type) * CHAR_BIT) && bits) - val.resize(2, 2); - else - { - local_limb_type mask = chunk_bits >= sizeof(local_limb_type) * CHAR_BIT ? ~static_cast<local_limb_type>(0u) : (static_cast<local_limb_type>(1u) << chunk_bits) - 1; - local_limb_type value = (static_cast<local_limb_type>(bits) & mask) << bit_location; - *val.limbs() |= value; - // - // Check for overflow bits: - // - bit_location = sizeof(local_limb_type) * CHAR_BIT - bit_location; - if ((bit_location < sizeof(bits) * CHAR_BIT) && (bits >>= bit_location)) - val.resize(2, 2); // May throw! - } -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -inline void resize_to_bit_size(cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& newval, std::size_t bits, const std::integral_constant<bool, false>&) -{ - std::size_t limb_count = static_cast<unsigned>(bits / (sizeof(limb_type) * CHAR_BIT)); - if (bits % (sizeof(limb_type) * CHAR_BIT)) - ++limb_count; - constexpr std::size_t max_limbs = MaxBits ? MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0) : (std::numeric_limits<unsigned>::max)(); - if (limb_count > max_limbs) - limb_count = max_limbs; - newval.resize(limb_count, limb_count); - std::memset(newval.limbs(), 0, newval.size() * sizeof(limb_type)); -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -inline void resize_to_bit_size(cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& newval, unsigned, const std::integral_constant<bool, true>&) -{ - *newval.limbs() = 0; -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, expression_template_option ExpressionTemplates, class Iterator> -number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& -import_bits_generic( - number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val, Iterator i, Iterator j, std::size_t chunk_size = 0, bool msv_first = true) -{ - typename number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>::backend_type newval; - - using value_type = typename std::iterator_traits<Iterator>::value_type ; - using unsigned_value_type = typename boost::multiprecision::detail::make_unsigned<value_type>::type ; - using difference_type = typename std::iterator_traits<Iterator>::difference_type ; - using size_type = typename boost::multiprecision::detail::make_unsigned<difference_type>::type ; - using tag_type = typename cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::trivial_tag; - - if (!chunk_size) - chunk_size = std::numeric_limits<value_type>::digits; - - size_type limbs = std::distance(i, j); - size_type bits = limbs * chunk_size; - - detail::resize_to_bit_size(newval, static_cast<unsigned>(bits), tag_type()); - - difference_type bit_location = msv_first ? bits - chunk_size : 0; - difference_type bit_location_change = msv_first ? -static_cast<difference_type>(chunk_size) : chunk_size; - - while (i != j) - { - detail::assign_bits(newval, static_cast<unsigned_value_type>(*i), static_cast<std::size_t>(bit_location), chunk_size, tag_type()); - ++i; - bit_location += bit_location_change; - } - - newval.normalize(); - - val.backend().swap(newval); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, expression_template_option ExpressionTemplates, class T> -inline typename std::enable_if< !boost::multiprecision::backends::is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>&>::type -import_bits_fast( - number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val, T* i, T* j, std::size_t chunk_size = 0) -{ - std::size_t byte_len = (j - i) * (chunk_size ? chunk_size / CHAR_BIT : sizeof(*i)); - std::size_t limb_len = byte_len / sizeof(limb_type); - if (byte_len % sizeof(limb_type)) - ++limb_len; - cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& result = val.backend(); - result.resize(static_cast<unsigned>(limb_len), static_cast<unsigned>(limb_len)); // checked types may throw here if they're not large enough to hold the data! - result.limbs()[result.size() - 1] = 0u; - std::memcpy(result.limbs(), i, (std::min)(byte_len, result.size() * sizeof(limb_type))); - result.normalize(); // In case data has leading zeros. - return val; -} -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, expression_template_option ExpressionTemplates, class T> -inline typename std::enable_if<boost::multiprecision::backends::is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value, number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>&>::type -import_bits_fast( - number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val, T* i, T* j, std::size_t chunk_size = 0) -{ - cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& result = val.backend(); - std::size_t byte_len = (j - i) * (chunk_size ? chunk_size / CHAR_BIT : sizeof(*i)); - std::size_t limb_len = byte_len / sizeof(result.limbs()[0]); - if (byte_len % sizeof(result.limbs()[0])) - ++limb_len; - result.limbs()[0] = 0u; - result.resize(static_cast<unsigned>(limb_len), static_cast<unsigned>(limb_len)); // checked types may throw here if they're not large enough to hold the data! - std::memcpy(result.limbs(), i, (std::min)(byte_len, result.size() * sizeof(result.limbs()[0]))); - result.normalize(); // In case data has leading zeros. - return val; -} -} // namespace detail - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, expression_template_option ExpressionTemplates, class Iterator> -inline number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& -import_bits( - number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val, Iterator i, Iterator j, std::size_t chunk_size = 0, bool msv_first = true) -{ - return detail::import_bits_generic(val, i, j, chunk_size, msv_first); -} - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, expression_template_option ExpressionTemplates, class T> -inline number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& -import_bits( - number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val, T* i, T* j, std::size_t chunk_size = 0, bool msv_first = true) -{ -#if BOOST_MP_ENDIAN_LITTLE_BYTE - if (((chunk_size % CHAR_BIT) == 0) && !msv_first) - return detail::import_bits_fast(val, i, j, chunk_size); -#endif - return detail::import_bits_generic(val, i, j, chunk_size, msv_first); -} - -namespace detail { - -template <class Backend> -std::uintmax_t extract_bits(const Backend& val, std::size_t location, std::size_t count, const std::integral_constant<bool, false>& tag) -{ - std::size_t limb = location / (sizeof(limb_type) * CHAR_BIT); - std::size_t shift = location % (sizeof(limb_type) * CHAR_BIT); - std::uintmax_t result = 0; - std::uintmax_t mask = count == std::numeric_limits<std::uintmax_t>::digits ? ~static_cast<std::uintmax_t>(0) : (static_cast<std::uintmax_t>(1u) << count) - 1; - if (count > (sizeof(limb_type) * CHAR_BIT - shift)) - { - result = extract_bits(val, location + sizeof(limb_type) * CHAR_BIT - shift, count - sizeof(limb_type) * CHAR_BIT + shift, tag); - result <<= sizeof(limb_type) * CHAR_BIT - shift; - } - if (limb < val.size()) - result |= (val.limbs()[limb] >> shift) & mask; - return result; -} - -template <class Backend> -inline std::uintmax_t extract_bits(const Backend& val, std::size_t location, std::size_t count, const std::integral_constant<bool, true>&) -{ - typename Backend::local_limb_type result = *val.limbs(); - typename Backend::local_limb_type mask = count >= std::numeric_limits<typename Backend::local_limb_type>::digits ? ~static_cast<typename Backend::local_limb_type>(0) : (static_cast<typename Backend::local_limb_type>(1u) << count) - 1; - return (result >> location) & mask; -} - -} // namespace detail - -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, expression_template_option ExpressionTemplates, class OutputIterator> -OutputIterator export_bits( - const number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val, OutputIterator out, std::size_t chunk_size, bool msv_first = true) -{ -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4244) -#endif - using tag_type = typename cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::trivial_tag; - if (!val) - { - *out = 0; - ++out; - return out; - } - std::size_t bitcount = boost::multiprecision::backends::eval_msb_imp(val.backend()) + 1; - - std::ptrdiff_t bit_location = msv_first ? static_cast<std::ptrdiff_t>(bitcount - chunk_size) : 0; - const std::ptrdiff_t bit_step = msv_first ? static_cast<std::ptrdiff_t>(-static_cast<std::ptrdiff_t>(chunk_size)) : static_cast<std::ptrdiff_t>(chunk_size); - while (bit_location % bit_step) - ++bit_location; - - do - { - *out = detail::extract_bits(val.backend(), bit_location, chunk_size, tag_type()); - ++out; - bit_location += bit_step; - } while ((bit_location >= 0) && (bit_location < static_cast<int>(bitcount))); - - return out; -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -} - -} -} // namespace boost::multiprecision - -#endif // BOOST_MP_CPP_INT_IMPORT_EXPORT_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/intel_intrinsics.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/intel_intrinsics.hpp deleted file mode 100644 index 1dfe181dee..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/intel_intrinsics.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2020 Madhur Chauhan. -// Copyright 2020 John Maddock. -// Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_INTEL_INTRINSICS_HPP -#define BOOST_MP_INTEL_INTRINSICS_HPP -// -// Select which actual implementation header to use: -// -#ifdef __has_include -#if __has_include(<immintrin.h>) -#define BOOST_MP_HAS_IMMINTRIN_H -#endif -#endif -// -// If this is GCC/clang, then check that the actual intrinsic exists: -// -#if defined(__has_builtin) && defined(__GNUC__) -#if !__has_builtin(__builtin_ia32_addcarryx_u64) && defined(BOOST_MP_HAS_IMMINTRIN_H) \ - && !(defined(BOOST_GCC) && (__GNUC__ >= 9) \ - && (defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)\ - || defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_AMD64) \ - || defined(_M_X64) || defined(__amd64__) || defined(_M_X64))) -#undef BOOST_MP_HAS_IMMINTRIN_H -#endif -#elif defined(BOOST_MP_HAS_IMMINTRIN_H) && defined(__GNUC__) && !(defined(BOOST_GCC) && (__GNUC__ >= 9)) -#undef BOOST_MP_HAS_IMMINTRIN_H -#endif - -#if defined(__clang_major__) && (__clang_major__ < 9) -// We appear to crash the compiler if we try to use these intrinsics? -#undef BOOST_MP_HAS_IMMINTRIN_H -#endif - -#if defined(_WIN32) && (defined(_M_ARM64) || defined(_M_ARM)) -// -// When targeting platforms such as ARM, msvc (and also clang when emulating msvc) still has the -// Intel headers in its include path even though they're not usable. -// See https://github.com/boostorg/multiprecision/issues/321 -// Also https://github.com/boostorg/multiprecision/issues/475 -// -#undef BOOST_MP_HAS_IMMINTRIN_H -#endif - -#if defined(__APPLE_CC__) && defined(__clang_major__) && (__clang_major__ < 11) && defined(BOOST_MP_HAS_IMMINTRIN_H) -// Apple clang has it's own version numbers. -#undef BOOST_MP_HAS_IMMINTRIN_H -#endif - - -// -// If the compiler supports the intrinsics used by GCC internally -// inside <immintrin.h> then we'll use them directly. -// This is a bit of defensive programming, mostly for a modern clang -// sitting on top of an older GCC header install. -// -#if defined(__has_builtin) && !defined(BOOST_INTEL) - -# if __has_builtin(__builtin_ia32_addcarryx_u64) -# define BOOST_MP_ADDC __builtin_ia32_addcarryx_u -# endif - -# if __has_builtin(__builtin_ia32_subborrow_u64) -# define BOOST_MP_SUBB __builtin_ia32_subborrow_u -# elif __has_builtin(__builtin_ia32_sbb_u64) -# define BOOST_MP_SUBB __builtin_ia32_sbb_u -# endif - -#endif - -#ifndef BOOST_MP_ADDC -#define BOOST_MP_ADDC _addcarry_u -#endif -#ifndef BOOST_MP_SUBB -#define BOOST_MP_SUBB _subborrow_u -#endif - -#ifdef BOOST_MP_HAS_IMMINTRIN_H - -#ifdef BOOST_MSVC -// -// This is a subset of the full <immintrin.h> : -// -#include <intrin.h> -#else -#include <immintrin.h> -#endif - -#if defined(BOOST_HAS_INT128) - -namespace boost { namespace multiprecision { namespace detail { - -BOOST_MP_FORCEINLINE unsigned char addcarry_limb(unsigned char carry, limb_type a, limb_type b, limb_type* p_result) -{ -#ifdef BOOST_INTEL - using cast_type = unsigned __int64; -#else - using cast_type = unsigned long long; -#endif - return BOOST_JOIN(BOOST_MP_ADDC, 64)(carry, a, b, reinterpret_cast<cast_type*>(p_result)); -} - -BOOST_MP_FORCEINLINE unsigned char subborrow_limb(unsigned char carry, limb_type a, limb_type b, limb_type* p_result) -{ -#ifdef BOOST_INTEL - using cast_type = unsigned __int64; -#else - using cast_type = unsigned long long; -#endif - return BOOST_JOIN(BOOST_MP_SUBB, 64)(carry, a, b, reinterpret_cast<cast_type*>(p_result)); -} - -}}} // namespace boost::multiprecision::detail - -#else - -namespace boost { namespace multiprecision { namespace detail { - -BOOST_MP_FORCEINLINE unsigned char addcarry_limb(unsigned char carry, limb_type a, limb_type b, limb_type* p_result) -{ - return BOOST_JOIN(BOOST_MP_ADDC, 32)(carry, a, b, reinterpret_cast<unsigned int*>(p_result)); -} - -BOOST_MP_FORCEINLINE unsigned char subborrow_limb(unsigned char carry, limb_type a, limb_type b, limb_type* p_result) -{ - return BOOST_JOIN(BOOST_MP_SUBB, 32)(carry, a, b, reinterpret_cast<unsigned int*>(p_result)); -} - -}}} // namespace boost::multiprecision::detail - -#endif - -#endif - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/limits.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/limits.hpp deleted file mode 100644 index df80d02e7e..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/limits.hpp +++ /dev/null @@ -1,268 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_LIMITS_HPP -#define BOOST_MP_CPP_INT_LIMITS_HPP - -#include <boost/multiprecision/traits/max_digits10.hpp> - -namespace std { - -namespace detail { - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4307) -#endif - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_CXX14_CONSTEXPR_IF_DETECTION boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_min(const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&) -{ - // Bounded, signed, and no allocator. - using result_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> ; - using ui_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MaxBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked>, ExpressionTemplates>; -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - static -#else - constexpr -#endif - const result_type val = -result_type(~ui_type(0)); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_min(const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&) -{ - // Bounded, signed, and an allocator (can't be constexpr). - using result_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> ; - using ui_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MaxBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked>, ExpressionTemplates>; - static const result_type val = -result_type(~ui_type(0)); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_CXX14_CONSTEXPR_IF_DETECTION boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_min(const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) -{ - // Bounded, unsigned, no allocator (can be constexpr): -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - static -#else - constexpr -#endif - const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_min(const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) -{ - // Bounded and std::size_t with allocator (no constexpr): - static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates, bool has_allocator> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_min(const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&, const std::integral_constant<bool, has_allocator>&) -{ - // Unbounded and signed, never constexpr because there must be an allocator. - // There is no minimum value, just return 0: - static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates, bool has_allocator> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_min(const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&, const std::integral_constant<bool, has_allocator>&) -{ - // Unbound and unsigned, never constexpr because there must be an allocator. - static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_CXX14_CONSTEXPR_IF_DETECTION boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_max(const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&) -{ - // Bounded and signed, no allocator, can be constexpr. - using result_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> ; - using ui_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MaxBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked>, ExpressionTemplates>; -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - static -#else - constexpr -#endif - const result_type val = ~ui_type(0); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_max(const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&) -{ - // Bounded and signed, has an allocator, never constexpr. - using result_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> ; - using ui_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MaxBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked>, ExpressionTemplates>; - static const result_type val = ~ui_type(0); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_CXX14_CONSTEXPR_IF_DETECTION boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_max(const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) -{ - // Bound and unsigned, no allocator so can be constexpr: - using result_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> ; - using ui_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates>; -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION - static -#else - constexpr -#endif - const result_type val = ~ui_type(0); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_max(const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) -{ - // Bound and unsigned, has an allocator so can never be constexpr: - using result_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> ; - using ui_type = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates>; - static const result_type val = ~ui_type(0); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates, bool has_allocator> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_max(const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&, const std::integral_constant<bool, has_allocator>&) -{ - // Unbounded and signed. - // There is no maximum value, just return 0: - static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u); - return val; -} - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates, bool has_allocator> -inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> -get_max(const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&, const std::integral_constant<bool, has_allocator>&) -{ - // Unbound and unsigned: - static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u); - return val; -} - -} // namespace detail - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> > -{ - using backend_type = boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>; - using number_type = boost::multiprecision::number<backend_type, ExpressionTemplates> ; - - public: - static constexpr bool is_specialized = true; - // - // Largest and smallest numbers are bounded only by available memory, set - // to zero: - // - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type(min)() - { - return detail::get_min<MinBits, MaxBits, SignType, Checked, Allocator, ExpressionTemplates>(boost::multiprecision::backends::is_fixed_precision<backend_type>(), boost::multiprecision::is_signed_number<backend_type>(), std::integral_constant<bool, std::is_void<Allocator>::value>()); - } - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type(max)() - { - return detail::get_max<MinBits, MaxBits, SignType, Checked, Allocator, ExpressionTemplates>(boost::multiprecision::backends::is_fixed_precision<backend_type>(), boost::multiprecision::is_signed_number<backend_type>(), std::integral_constant<bool, std::is_void<Allocator>::value>()); - } - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type lowest() { return (min)(); } - static constexpr int digits = boost::multiprecision::backends::max_precision<backend_type>::value == SIZE_MAX ? INT_MAX : boost::multiprecision::backends::max_precision<backend_type>::value; - static constexpr int digits10 = static_cast<int>(boost::multiprecision::detail::calc_digits10_s<static_cast<std::size_t>(digits)>::value); - static constexpr int max_digits10 = static_cast<int>(boost::multiprecision::detail::calc_max_digits10_s<static_cast<std::size_t>(digits)>::value); - static constexpr bool is_signed = boost::multiprecision::is_signed_number<backend_type>::value; - static constexpr bool is_integer = true; - static constexpr bool is_exact = true; - static constexpr int radix = 2; - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type epsilon() { return 0; } - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type round_error() { return 0; } - static constexpr int min_exponent = 0; - static constexpr int min_exponent10 = 0; - static constexpr int max_exponent = 0; - static constexpr int max_exponent10 = 0; - static constexpr bool has_infinity = false; - static constexpr bool has_quiet_NaN = false; - static constexpr bool has_signaling_NaN = false; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type infinity() { return 0; } - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type quiet_NaN() { return 0; } - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type signaling_NaN() { return 0; } - static BOOST_CXX14_CONSTEXPR_IF_DETECTION number_type denorm_min() { return 0; } - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = boost::multiprecision::backends::is_fixed_precision<backend_type>::value; - static constexpr bool is_modulo = (boost::multiprecision::backends::is_fixed_precision<backend_type>::value && (Checked == boost::multiprecision::unchecked)); - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_toward_zero; -}; - -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::digits; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::digits10; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::max_digits10; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_signed; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_integer; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_exact; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::radix; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::min_exponent; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::min_exponent10; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::max_exponent; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::max_exponent10; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_infinity; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_quiet_NaN; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_signaling_NaN; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_denorm; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_denorm_loss; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_iec559; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_bounded; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_modulo; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::traps; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::tinyness_before; -template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates> -constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::round_style; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -} // namespace std - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp deleted file mode 100644 index 1401667860..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp +++ /dev/null @@ -1,293 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_CPP_INT_LITERALS_HPP -#define BOOST_MP_CPP_INT_LITERALS_HPP - -#include <boost/multiprecision/cpp_int/cpp_int_config.hpp> - -namespace boost { namespace multiprecision { - -namespace literals { -namespace detail { - -template <char> -struct hex_value; -template <> -struct hex_value<'0'> -{ - static constexpr limb_type value = 0; -}; -template <> -struct hex_value<'1'> -{ - static constexpr limb_type value = 1; -}; -template <> -struct hex_value<'2'> -{ - static constexpr limb_type value = 2; -}; -template <> -struct hex_value<'3'> -{ - static constexpr limb_type value = 3; -}; -template <> -struct hex_value<'4'> -{ - static constexpr limb_type value = 4; -}; -template <> -struct hex_value<'5'> -{ - static constexpr limb_type value = 5; -}; -template <> -struct hex_value<'6'> -{ - static constexpr limb_type value = 6; -}; -template <> -struct hex_value<'7'> -{ - static constexpr limb_type value = 7; -}; -template <> -struct hex_value<'8'> -{ - static constexpr limb_type value = 8; -}; -template <> -struct hex_value<'9'> -{ - static constexpr limb_type value = 9; -}; -template <> -struct hex_value<'a'> -{ - static constexpr limb_type value = 10; -}; -template <> -struct hex_value<'b'> -{ - static constexpr limb_type value = 11; -}; -template <> -struct hex_value<'c'> -{ - static constexpr limb_type value = 12; -}; -template <> -struct hex_value<'d'> -{ - static constexpr limb_type value = 13; -}; -template <> -struct hex_value<'e'> -{ - static constexpr limb_type value = 14; -}; -template <> -struct hex_value<'f'> -{ - static constexpr limb_type value = 15; -}; -template <> -struct hex_value<'A'> -{ - static constexpr limb_type value = 10; -}; -template <> -struct hex_value<'B'> -{ - static constexpr limb_type value = 11; -}; -template <> -struct hex_value<'C'> -{ - static constexpr limb_type value = 12; -}; -template <> -struct hex_value<'D'> -{ - static constexpr limb_type value = 13; -}; -template <> -struct hex_value<'E'> -{ - static constexpr limb_type value = 14; -}; -template <> -struct hex_value<'F'> -{ - static constexpr limb_type value = 15; -}; - -template <class Pack, limb_type value> -struct combine_value_to_pack; -template <limb_type first, limb_type... ARGS, limb_type value> -struct combine_value_to_pack<value_pack<first, ARGS...>, value> -{ - using type = value_pack<first | value, ARGS...>; -}; - -template <char NextChar, char... CHARS> -struct pack_values -{ - static constexpr std::size_t chars_per_limb = sizeof(limb_type) * CHAR_BIT / 4; - static constexpr std::size_t shift = ((sizeof...(CHARS)) % chars_per_limb) * 4; - static constexpr limb_type value_to_add = shift ? hex_value<NextChar>::value << shift : hex_value<NextChar>::value; - - using recursive_packed_type = typename pack_values<CHARS...>::type ; - using pack_type = typename std::conditional<shift == 0, - typename recursive_packed_type::next_type, - recursive_packed_type>::type; - using type = typename combine_value_to_pack<pack_type, value_to_add>::type; -}; -template <char NextChar> -struct pack_values<NextChar> -{ - static constexpr limb_type value_to_add = hex_value<NextChar>::value; - - using type = value_pack<value_to_add>; -}; - -template <class T> -struct strip_leading_zeros_from_pack; -template <limb_type... PACK> -struct strip_leading_zeros_from_pack<value_pack<PACK...> > -{ - using type = value_pack<PACK...>; -}; -template <limb_type... PACK> -struct strip_leading_zeros_from_pack<value_pack<0u, PACK...> > -{ - using type = typename strip_leading_zeros_from_pack<value_pack<PACK...> >::type; -}; - -template <limb_type v, class PACK> -struct append_value_to_pack; -template <limb_type v, limb_type... PACK> -struct append_value_to_pack<v, value_pack<PACK...> > -{ - using type = value_pack<PACK..., v>; -}; - -template <class T> -struct reverse_value_pack; -template <limb_type v, limb_type... VALUES> -struct reverse_value_pack<value_pack<v, VALUES...> > -{ - using lead_values = typename reverse_value_pack<value_pack<VALUES...> >::type; - using type = typename append_value_to_pack<v, lead_values>::type ; -}; -template <limb_type v> -struct reverse_value_pack<value_pack<v> > -{ - using type = value_pack<v>; -}; -template <> -struct reverse_value_pack<value_pack<> > -{ - using type = value_pack<>; -}; - -template <char l1, char l2, char... STR> -struct make_packed_value_from_str -{ - static_assert(l1 == '0', "Multi-precision integer literals must be in hexadecimal notation."); - static_assert((l2 == 'X') || (l2 == 'x'), "Multi-precision integer literals must be in hexadecimal notation."); - using packed_type = typename pack_values<STR...>::type ; - using stripped_type = typename strip_leading_zeros_from_pack<packed_type>::type; - using type = typename reverse_value_pack<stripped_type>::type ; -}; - -template <class Pack, class B> -struct make_backend_from_pack -{ - static constexpr Pack p = {}; - static constexpr B value = p; -}; - -template <class Pack, class B> -constexpr B make_backend_from_pack<Pack, B>::value; - -template <unsigned Digits> -struct signed_cpp_int_literal_result_type -{ - static constexpr unsigned bits = Digits * 4; - using backend_type = boost::multiprecision::backends::cpp_int_backend<bits, bits, signed_magnitude, unchecked, void>; - using number_type = number<backend_type, et_off> ; -}; - -template <unsigned Digits> -struct unsigned_cpp_int_literal_result_type -{ - static constexpr unsigned bits = Digits * 4; - using backend_type = boost::multiprecision::backends::cpp_int_backend<bits, bits, unsigned_magnitude, unchecked, void>; - using number_type = number<backend_type, et_off> ; -}; - -} // namespace detail - -template <char... STR> -constexpr typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::number_type operator"" _cppi() -{ - using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; - return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::backend_type>::value; -} - -template <char... STR> -constexpr typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::number_type operator"" _cppui() -{ - using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; - return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::backend_type>::value; -} - -#define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits) \ - template <char... STR> \ - constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > operator"" BOOST_JOIN(_cppi, Bits)() \ - { \ - using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; \ - return boost::multiprecision::literals::detail::make_backend_from_pack< \ - pt, \ - boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >::value; \ - } \ - template <char... STR> \ - constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > operator"" BOOST_JOIN(_cppui, Bits)() \ - { \ - using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; \ - return boost::multiprecision::literals::detail::make_backend_from_pack< \ - pt, \ - boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> >::value; \ - } - -BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(128) -BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(256) -BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(512) -BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(1024) - -} // namespace literals - -// -// Overload unary minus operator for constexpr use: -// -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off> -operator-(const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>& a) -{ - return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(a.backend(), boost::multiprecision::literals::detail::make_negate_tag()); -} -template <std::size_t MinBits, cpp_int_check_type Checked> -constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off> -operator-(number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&& a) -{ - return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(static_cast<const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&>(a).backend(), boost::multiprecision::literals::detail::make_negate_tag()); -} - -}} // namespace boost::multiprecision - -#endif // BOOST_MP_CPP_INT_CORE_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/misc.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/misc.hpp deleted file mode 100644 index 6103f55b8e..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/misc.hpp +++ /dev/null @@ -1,1445 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012-2020 John Maddock. -// Copyright 2020 Madhur Chauhan. -// Copyright 2021 Matt Borland. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// https://www.boost.org/LICENSE_1_0.txt) -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_MISC_HPP -#define BOOST_MP_CPP_INT_MISC_HPP - -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/number_base.hpp> -#include <boost/multiprecision/cpp_int/cpp_int_config.hpp> -#include <boost/multiprecision/detail/float128_functions.hpp> -#include <boost/multiprecision/detail/assert.hpp> -#include <boost/multiprecision/detail/constexpr.hpp> -#include <boost/multiprecision/detail/bitscan.hpp> // lsb etc -#include <boost/multiprecision/detail/hash.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <numeric> // std::gcd -#include <type_traits> -#include <stdexcept> -#include <cmath> - -#ifndef BOOST_MP_STANDALONE -#include <boost/integer/common_factor_rt.hpp> -#endif - -#ifdef BOOST_MP_MATH_AVAILABLE -#include <boost/math/special_functions/next.hpp> -#endif - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4702) -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4146) // unary minus operator applied to unsigned type, result still unsigned -#endif - -// Forward decleration of gcd and lcm functions -namespace boost { namespace multiprecision { namespace detail { - -template <typename T> -inline BOOST_CXX14_CONSTEXPR T constexpr_gcd(T a, T b) noexcept; - -template <typename T> -inline BOOST_CXX14_CONSTEXPR T constexpr_lcm(T a, T b) noexcept; - -}}} // namespace boost::multiprecision::detail - -namespace boost { namespace multiprecision { namespace backends { - -template <class T, bool has_limits = std::numeric_limits<T>::is_specialized> -struct numeric_limits_workaround : public std::numeric_limits<T> -{ -}; -template <class R> -struct numeric_limits_workaround<R, false> -{ - static constexpr unsigned digits = ~static_cast<R>(0) < 0 ? sizeof(R) * CHAR_BIT - 1 : sizeof(R) * CHAR_BIT; - static constexpr R (min)(){ return (static_cast<R>(-1) < 0) ? static_cast<R>(1) << digits : 0; } - static constexpr R (max)() { return (static_cast<R>(-1) < 0) ? ~(static_cast<R>(1) << digits) : ~static_cast<R>(0); } -}; - -template <class R, class CppInt> -BOOST_MP_CXX14_CONSTEXPR void check_in_range(const CppInt& val, const std::integral_constant<int, checked>&) -{ - using cast_type = typename boost::multiprecision::detail::canonical<R, CppInt>::type; - - if (val.sign()) - { - BOOST_IF_CONSTEXPR (boost::multiprecision::detail::is_signed<R>::value == false) - BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to assign a negative value to an unsigned type.")); - if (val.compare(static_cast<cast_type>((numeric_limits_workaround<R>::min)())) < 0) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Could not convert to the target type - -value is out of range.")); - } - else - { - if (val.compare(static_cast<cast_type>((numeric_limits_workaround<R>::max)())) > 0) - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Could not convert to the target type - -value is out of range.")); - } -} -template <class R, class CppInt> -inline BOOST_MP_CXX14_CONSTEXPR void check_in_range(const CppInt& /*val*/, const std::integral_constant<int, unchecked>&) noexcept {} - -inline BOOST_MP_CXX14_CONSTEXPR void check_is_negative(const std::integral_constant<bool, true>&) noexcept {} -inline void check_is_negative(const std::integral_constant<bool, false>&) -{ - BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to assign a negative value to an unsigned type.")); -} - -template <class Integer> -inline BOOST_MP_CXX14_CONSTEXPR Integer negate_integer(Integer i, const std::integral_constant<bool, true>&) noexcept -{ - return -i; -} -template <class Integer> -inline BOOST_MP_CXX14_CONSTEXPR Integer negate_integer(Integer i, const std::integral_constant<bool, false>&) noexcept -{ - return ~(i - 1); -} - -template <class R, std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type -eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) -{ - using checked_type = std::integral_constant<int, Checked1>; - check_in_range<R>(backend, checked_type()); - - BOOST_IF_CONSTEXPR(numeric_limits_workaround<R>::digits < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) - { - if ((backend.sign() && boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value) && (1 + static_cast<boost::multiprecision::limb_type>((std::numeric_limits<R>::max)()) <= backend.limbs()[0])) - { - *result = (numeric_limits_workaround<R>::min)(); - return; - } - else if (boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value && !backend.sign() && static_cast<boost::multiprecision::limb_type>((std::numeric_limits<R>::max)()) <= backend.limbs()[0]) - { - *result = (numeric_limits_workaround<R>::max)(); - return; - } - else - *result = static_cast<R>(backend.limbs()[0]); - } - else - *result = static_cast<R>(backend.limbs()[0]); - - BOOST_IF_CONSTEXPR(numeric_limits_workaround<R>::digits > cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) - { - std::size_t shift = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - std::size_t i = 1u; - - while ((i < backend.size()) && (shift < static_cast<unsigned>(numeric_limits_workaround<R>::digits - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits))) - { - *result += static_cast<R>(backend.limbs()[i]) << shift; - shift += cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - ++i; - } - // - // We have one more limb to extract, but may not need all the bits, so treat this as a special case: - // - if (i < backend.size()) - { - const limb_type mask = ((numeric_limits_workaround<R>::digits - shift) == cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) ? ~static_cast<limb_type>(0) : static_cast<limb_type>(static_cast<limb_type>(1u) << (numeric_limits_workaround<R>::digits - shift)) - 1u; - const limb_type limb_at_index_masked = static_cast<limb_type>(backend.limbs()[i] & mask); - - *result = static_cast<R>(*result + static_cast<R>(static_cast<R>(limb_at_index_masked) << shift)); - - if ((backend.limbs()[i] & static_cast<limb_type>(~mask)) || (i + 1 < backend.size())) - { - // Overflow: - if (backend.sign()) - { - check_is_negative(boost::multiprecision::detail::is_signed<R>()); - *result = (numeric_limits_workaround<R>::min)(); - } - else if (boost::multiprecision::detail::is_signed<R>::value) - *result = (numeric_limits_workaround<R>::max)(); - return; - } - } - } - else if (backend.size() > 1) - { - // Overflow: - if (backend.sign()) - { - check_is_negative(boost::multiprecision::detail::is_signed<R>()); - *result = (numeric_limits_workaround<R>::min)(); - } - else if (boost::multiprecision::detail::is_signed<R>::value) - *result = (numeric_limits_workaround<R>::max)(); - return; - } - if (backend.sign()) - { - check_is_negative(std::integral_constant<bool, boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value>()); - *result = negate_integer(*result, std::integral_constant<bool, boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value>()); - } -} - -template <class R, std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_floating_point<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type -eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) noexcept(boost::multiprecision::detail::is_arithmetic<R>::value) -{ - BOOST_MP_FLOAT128_USING using std::ldexp; - if (eval_is_zero(backend)) - { - *result = 0.0f; - return; - } - -#ifdef BOOST_HAS_FLOAT128 - std::ptrdiff_t bits_to_keep = static_cast<std::ptrdiff_t>(std::is_same<R, float128_type>::value ? 113 : std::numeric_limits<R>::digits); -#else - std::ptrdiff_t bits_to_keep = static_cast<std::ptrdiff_t>(std::numeric_limits<R>::digits); -#endif - std::ptrdiff_t bits = static_cast<std::ptrdiff_t>(eval_msb_imp(backend) + 1); - - if (bits > bits_to_keep) - { - // Extract the bits we need, and then manually round the result: - *result = 0.0f; - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::const_limb_pointer p = backend.limbs(); - limb_type mask = ~static_cast<limb_type>(0u); - std::size_t index = backend.size() - 1; - std::size_t shift = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits * index; - while (bits_to_keep > 0) - { - if (bits_to_keep < (std::ptrdiff_t)cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) - { - if(index != backend.size() - 1) - { - const std::ptrdiff_t left_shift_amount = static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) - bits_to_keep); - - mask <<= left_shift_amount; - } - else - { - std::ptrdiff_t bits_in_first_limb = static_cast<std::ptrdiff_t>(bits % static_cast<std::ptrdiff_t>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits)); - if (bits_in_first_limb == 0) - bits_in_first_limb = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - if (bits_in_first_limb > bits_to_keep) - mask <<= bits_in_first_limb - bits_to_keep; - } - } - *result += ldexp(static_cast<R>(p[index] & mask), static_cast<int>(shift)); - shift -= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - - const bool bits_has_non_zero_remainder = (bits % static_cast<std::ptrdiff_t>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) != 0); - - bits_to_keep -= ((index == backend.size() - 1) && bits_has_non_zero_remainder) - ? bits % static_cast<std::ptrdiff_t>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits) - : static_cast<std::ptrdiff_t>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits); - --index; - } - // Perform rounding: - bits -= 1 + std::numeric_limits<R>::digits; - if (eval_bit_test(backend, static_cast<unsigned>(bits))) - { - if ((eval_lsb_imp(backend) < static_cast<std::size_t>(bits)) || eval_bit_test(backend, static_cast<std::size_t>(bits + 1))) - { - #ifdef BOOST_MP_MATH_AVAILABLE - *result = boost::math::float_next(*result); - #else - *result = std::nextafter(*result, *result * 2); - #endif - } - } - } - else - { - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::const_limb_pointer p = backend.limbs(); - std::size_t shift = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - *result = static_cast<R>(*p); - for (std::size_t i = 1; i < backend.size(); ++i) - { - *result += static_cast<R>(ldexp(static_cast<long double>(p[i]), static_cast<int>(shift))); - shift += cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - } - } - if (backend.sign()) - *result = -*result; -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, bool>::type -eval_is_zero(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) noexcept -{ - return (val.size() == 1) && (val.limbs()[0] == 0); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, int>::type -eval_get_sign(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) noexcept -{ - return eval_is_zero(val) ? 0 : val.sign() ? -1 : 1; -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_abs(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - result = val; - result.sign(false); -} - -// -// Get the location of the least-significant-bit: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_lsb_imp(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - // - // Find the index of the least significant limb that is non-zero: - // - std::size_t index = 0; - while (!a.limbs()[index] && (index < a.size())) - ++index; - // - // Find the index of the least significant bit within that limb: - // - std::size_t result = boost::multiprecision::detail::find_lsb(a.limbs()[index]); - - return result + index * cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_lsb(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - using default_ops::eval_get_sign; - if (eval_get_sign(a) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - if (a.sign()) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return eval_lsb_imp(a); -} - -// -// Get the location of the most-significant-bit: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_msb_imp(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - // - // Find the index of the most significant bit that is non-zero: - // - return (a.size() - 1) * cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits + boost::multiprecision::detail::find_msb(a.limbs()[a.size() - 1]); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_msb(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - using default_ops::eval_get_sign; - if (eval_get_sign(a) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - if (a.sign()) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return eval_msb_imp(a); -} - -#ifdef BOOST_GCC -// -// We really shouldn't need to be disabling this warning, but it really does appear to be -// spurious. The warning appears only when in release mode, and asserts are on. -// -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, bool>::type -eval_bit_test(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, std::size_t index) noexcept -{ - std::size_t offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - std::size_t shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u); - if (offset >= val.size()) - return false; - return val.limbs()[offset] & mask ? true : false; -} - -#ifdef BOOST_GCC -#pragma GCC diagnostic pop -#endif - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_bit_set(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, std::size_t index) -{ - std::size_t offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - std::size_t shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u); - if (offset >= val.size()) - { - std::size_t os = val.size(); - val.resize(offset + 1, offset + 1); - if (offset >= val.size()) - return; // fixed precision overflow - for (std::size_t i = os; i <= offset; ++i) - val.limbs()[i] = 0; - } - val.limbs()[offset] |= mask; -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_bit_unset(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, std::size_t index) noexcept -{ - std::size_t offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - std::size_t shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u); - if (offset >= val.size()) - return; - val.limbs()[offset] &= ~mask; - val.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_bit_flip(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, std::size_t index) -{ - std::size_t offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - std::size_t shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u); - if (offset >= val.size()) - { - std::size_t os = val.size(); - val.resize(offset + 1, offset + 1); - if (offset >= val.size()) - return; // fixed precision overflow - for (std::size_t i = os; i <= offset; ++i) - val.limbs()[i] = 0; - } - val.limbs()[offset] ^= mask; - val.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_qr( - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& y, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - divide_unsigned_helper(&q, x, y, r); - q.sign(x.sign() != y.sign()); - r.sign(x.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_qr( - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, - limb_type y, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - divide_unsigned_helper(&q, x, y, r); - q.sign(x.sign()); - r.sign(x.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<U>::value>::type eval_qr( - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, - U y, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - using default_ops::eval_qr; - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - t = y; - eval_qr(x, t, q, r); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Integer> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, Integer>::type -eval_integer_modulus(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, Integer mod) -{ - BOOST_IF_CONSTEXPR (sizeof(Integer) <= sizeof(limb_type)) - { - if (mod <= (std::numeric_limits<limb_type>::max)()) - { - const std::ptrdiff_t n = a.size(); - const double_limb_type two_n_mod = static_cast<limb_type>(1u) + (~static_cast<limb_type>(0u) - mod) % mod; - limb_type res = a.limbs()[n - 1] % mod; - - for (std::ptrdiff_t i = n - 2; i >= 0; --i) - res = static_cast<limb_type>((res * two_n_mod + a.limbs()[i]) % mod); - return res; - } - else - return default_ops::eval_integer_modulus(a, mod); - } - else - { - return default_ops::eval_integer_modulus(a, mod); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Integer> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, Integer>::type -eval_integer_modulus(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, Integer val) -{ - return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); -} - -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_type eval_gcd(limb_type u, limb_type v) -{ - // boundary cases - if (!u || !v) - return u | v; -#if (defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L)) - return std::gcd(u, v); -#else - std::size_t shift = boost::multiprecision::detail::find_lsb(u | v); - u >>= boost::multiprecision::detail::find_lsb(u); - do - { - v >>= boost::multiprecision::detail::find_lsb(v); - if (u > v) - std_constexpr::swap(u, v); - v -= u; - } while (v); - return u << shift; -#endif -} - -inline BOOST_MP_CXX14_CONSTEXPR double_limb_type eval_gcd(double_limb_type u, double_limb_type v) -{ -#if (defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L)) && (!defined(BOOST_HAS_INT128) || !defined(__STRICT_ANSI__)) - return std::gcd(u, v); -#else - if (u == 0) - return v; - - std::size_t shift = boost::multiprecision::detail::find_lsb(u | v); - u >>= boost::multiprecision::detail::find_lsb(u); - do - { - v >>= boost::multiprecision::detail::find_lsb(v); - if (u > v) - std_constexpr::swap(u, v); - v -= u; - } while (v); - return u << shift; -#endif -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - limb_type b) -{ - int s = eval_get_sign(a); - if (!b || !s) - { - result = a; - *result.limbs() |= b; - } - else - { - eval_modulus(result, a, b); - limb_type& res = *result.limbs(); - res = eval_gcd(res, b); - } - result.sign(false); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - double_limb_type b) -{ - int s = eval_get_sign(a); - if (!b || !s) - { - if (!s) - result = b; - else - result = a; - return; - } - double_limb_type res = 0; - if(a.sign() == 0) - res = eval_integer_modulus(a, b); - else - { - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(a); - t.negate(); - res = eval_integer_modulus(t, b); - } - res = eval_gcd(res, b); - result = res; - result.sign(false); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - signed_double_limb_type v) -{ - eval_gcd(result, a, static_cast<double_limb_type>(v < 0 ? -v : v)); -} -// -// These 2 overloads take care of gcd against an (unsigned) short etc: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Integer> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && (sizeof(Integer) <= sizeof(limb_type)) && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const Integer& v) -{ - eval_gcd(result, a, static_cast<limb_type>(v)); -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Integer> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value && (sizeof(Integer) <= sizeof(limb_type)) && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const Integer& v) -{ - eval_gcd(result, a, static_cast<limb_type>(v < 0 ? -v : v)); -} -// -// What follows is Lehmer's GCD algorithm: -// Essentially this uses the leading digit(s) of U and V -// only to run a "simulated" Euclid algorithm. It stops -// when the calculated quotient differs from what would have been -// the true quotient. At that point the cosequences are used to -// calculate the new U and V. A nice lucid description appears -// in "An Analysis of Lehmer's Euclidean GCD Algorithm", -// by Jonathan Sorenson. https://www.researchgate.net/publication/2424634_An_Analysis_of_Lehmer%27s_Euclidean_GCD_Algorithm -// DOI: 10.1145/220346.220378. -// -// There are two versions of this algorithm here, and both are "double digit" -// variations: which is to say if there are k bits per limb, then they extract -// 2k bits into a double_limb_type and then run the algorithm on that. The first -// version is a straightforward version of the algorithm, and is designed for -// situations where double_limb_type is a native integer (for example where -// limb_type is a 32-bit integer on a 64-bit machine). For 32-bit limbs it -// reduces the size of U by about 30 bits per call. The second is a more complex -// version for situations where double_limb_type is a synthetic type: for example -// __int128. For 64 bit limbs it reduces the size of U by about 62 bits per call. -// -// The complexity of the algorithm given by Sorenson is roughly O(ln^2(N)) for -// two N bit numbers. -// -// The original double-digit version of the algorithm is described in: -// -// "A Double Digit Lehmer-Euclid Algorithm for Finding the GCD of Long Integers", -// Tudor Jebelean, J Symbolic Computation, 1995 (19), 145. -// -#ifndef BOOST_HAS_INT128 -// -// When double_limb_type is a native integer type then we should just use it and not worry about the consequences. -// This can eliminate approximately a full limb with each call. -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Storage> -void eval_gcd_lehmer(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& U, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& V, std::size_t lu, Storage& storage) -{ - // - // Extract the leading 2 * bits_per_limb bits from U and V: - // - std::size_t h = lu % bits_per_limb; - double_limb_type u = (static_cast<double_limb_type>((U.limbs()[U.size() - 1])) << bits_per_limb) | U.limbs()[U.size() - 2]; - double_limb_type v = (static_cast<double_limb_type>((V.size() < U.size() ? 0 : V.limbs()[V.size() - 1])) << bits_per_limb) | V.limbs()[U.size() - 2]; - if (h) - { - u <<= bits_per_limb - h; - u |= U.limbs()[U.size() - 3] >> h; - v <<= bits_per_limb - h; - v |= V.limbs()[U.size() - 3] >> h; - } - // - // Co-sequences x an y: we need only the last 3 values of these, - // the first 2 values are known correct, the third gets checked - // in each loop operation, and we terminate when they go wrong. - // - // x[i+0] is positive for even i. - // y[i+0] is positive for odd i. - // - // However we track only absolute values here: - // - double_limb_type x[3] = {1, 0}; - double_limb_type y[3] = {0, 1}; - std::size_t i = 0; - -#ifdef BOOST_MP_GCD_DEBUG - cpp_int UU, VV; - UU = U; - VV = V; -#endif - - while (true) - { - double_limb_type q = u / v; - x[2] = x[0] + q * x[1]; - y[2] = y[0] + q * y[1]; - double_limb_type tu = u; - u = v; - v = tu - q * v; - ++i; - // - // We must make sure that y[2] occupies a single limb otherwise - // the multiprecision multiplications below would be much more expensive. - // This can sometimes lose us one iteration, but is worth it for improved - // calculation efficiency. - // - if (y[2] >> bits_per_limb) - break; - // - // These are Jebelean's exact termination conditions: - // - if ((i & 1u) == 0) - { - BOOST_MP_ASSERT(u > v); - if ((v < x[2]) || ((u - v) < (y[2] + y[1]))) - break; - } - else - { - BOOST_MP_ASSERT(u > v); - if ((v < y[2]) || ((u - v) < (x[2] + x[1]))) - break; - } -#ifdef BOOST_MP_GCD_DEBUG - BOOST_MP_ASSERT(q == UU / VV); - UU %= VV; - UU.swap(VV); -#endif - x[0] = x[1]; - x[1] = x[2]; - y[0] = y[1]; - y[1] = y[2]; - } - if (i == 1) - { - // No change to U and V we've stalled! - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - eval_modulus(t, U, V); - U.swap(V); - V.swap(t); - return; - } - // - // Update U and V. - // We have: - // - // U = x[0]U + y[0]V and - // V = x[1]U + y[1]V. - // - // But since we track only absolute values of x and y - // we have to take account of the implied signs and perform - // the appropriate subtraction depending on the whether i is - // even or odd: - // - std::size_t ts = U.size() + 1; - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t1(storage, ts), t2(storage, ts), t3(storage, ts); - eval_multiply(t1, U, static_cast<limb_type>(x[0])); - eval_multiply(t2, V, static_cast<limb_type>(y[0])); - eval_multiply(t3, U, static_cast<limb_type>(x[1])); - if ((i & 1u) == 0) - { - if (x[0] == 0) - U = t2; - else - { - BOOST_MP_ASSERT(t2.compare(t1) >= 0); - eval_subtract(U, t2, t1); - BOOST_MP_ASSERT(U.sign() == false); - } - } - else - { - BOOST_MP_ASSERT(t1.compare(t2) >= 0); - eval_subtract(U, t1, t2); - BOOST_MP_ASSERT(U.sign() == false); - } - eval_multiply(t2, V, static_cast<limb_type>(y[1])); - if (i & 1u) - { - if (x[1] == 0) - V = t2; - else - { - BOOST_MP_ASSERT(t2.compare(t3) >= 0); - eval_subtract(V, t2, t3); - BOOST_MP_ASSERT(V.sign() == false); - } - } - else - { - BOOST_MP_ASSERT(t3.compare(t2) >= 0); - eval_subtract(V, t3, t2); - BOOST_MP_ASSERT(V.sign() == false); - } - BOOST_MP_ASSERT(U.compare(V) >= 0); - BOOST_MP_ASSERT(lu > eval_msb(U)); -#ifdef BOOST_MP_GCD_DEBUG - - BOOST_MP_ASSERT(UU == U); - BOOST_MP_ASSERT(VV == V); - - extern std::size_t total_lehmer_gcd_calls; - extern std::size_t total_lehmer_gcd_bits_saved; - extern std::size_t total_lehmer_gcd_cycles; - - ++total_lehmer_gcd_calls; - total_lehmer_gcd_bits_saved += lu - eval_msb(U); - total_lehmer_gcd_cycles += i; -#endif - if (lu < 2048) - { - // - // Since we have stripped all common powers of 2 from U and V at the start - // if either are even at this point, we can remove stray powers of 2 now. - // Note that it is not possible for *both* U and V to be even at this point. - // - // This has an adverse effect on performance for high bit counts, but has - // a significant positive effect for smaller counts. - // - if ((U.limbs()[0] & 1u) == 0) - { - eval_right_shift(U, eval_lsb(U)); - if (U.compare(V) < 0) - U.swap(V); - } - else if ((V.limbs()[0] & 1u) == 0) - { - eval_right_shift(V, eval_lsb(V)); - } - } - storage.deallocate(ts * 3); -} - -#else -// -// This branch is taken when double_limb_type is a synthetic type with no native hardware support. -// For example __int128. The assumption is that add/subtract/multiply of double_limb_type are efficient, -// but that division is very slow. -// -// We begin with a specialized routine for division. -// We know that most of the time this is called the result will be 1. -// For small limb counts, this almost doubles the performance of Lehmer's routine! -// -BOOST_FORCEINLINE void divide_subtract(double_limb_type& q, double_limb_type& u, const double_limb_type& v) -{ - BOOST_MP_ASSERT(q == 1); // precondition on entry. - u -= v; - while (u >= v) - { - u -= v; - if (++q > 30) - { - double_limb_type t = u / v; - u -= t * v; - q += t; - } - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Storage> -void eval_gcd_lehmer(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& U, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& V, std::size_t lu, Storage& storage) -{ - // - // Extract the leading 2*bits_per_limb bits from U and V: - // - std::size_t h = lu % bits_per_limb; - double_limb_type u, v; - if (h) - { - u = (static_cast<double_limb_type>((U.limbs()[U.size() - 1])) << bits_per_limb) | U.limbs()[U.size() - 2]; - v = (static_cast<double_limb_type>((V.size() < U.size() ? 0 : V.limbs()[V.size() - 1])) << bits_per_limb) | V.limbs()[U.size() - 2]; - u <<= bits_per_limb - h; - u |= U.limbs()[U.size() - 3] >> h; - v <<= bits_per_limb - h; - v |= V.limbs()[U.size() - 3] >> h; - } - else - { - u = (static_cast<double_limb_type>(U.limbs()[U.size() - 1]) << bits_per_limb) | U.limbs()[U.size() - 2]; - v = (static_cast<double_limb_type>(V.limbs()[U.size() - 1]) << bits_per_limb) | V.limbs()[U.size() - 2]; - } - // - // Cosequences are stored as limb_types, we take care not to overflow these: - // - // x[i+0] is positive for even i. - // y[i+0] is positive for odd i. - // - // However we track only absolute values here: - // - limb_type x[3] = { 1, 0 }; - limb_type y[3] = { 0, 1 }; - std::size_t i = 0; - -#ifdef BOOST_MP_GCD_DEBUG - cpp_int UU, VV; - UU = U; - VV = V; -#endif - // - // We begine by running a single digit version of Lehmer's algorithm, we still have - // to track u and v at double precision, but this adds only a tiny performance penalty. - // What we gain is fast division, and fast termination testing. - // When you see static_cast<limb_type>(u >> bits_per_limb) here, this is really just - // a direct access to the upper bits_per_limb of the double limb type. For __int128 - // this is simple a load of the upper 64 bits and the "shift" is optimised away. - // - double_limb_type old_u, old_v; - while (true) - { - limb_type q = static_cast<limb_type>(u >> bits_per_limb) / static_cast<limb_type>(v >> bits_per_limb); - x[2] = x[0] + q * x[1]; - y[2] = y[0] + q * y[1]; - double_limb_type tu = u; - old_u = u; - old_v = v; - u = v; - double_limb_type t = q * v; - if (tu < t) - { - ++i; - break; - } - v = tu - t; - ++i; - BOOST_MP_ASSERT((u <= v) || (t / q == old_v)); - if (u <= v) - { - // We've gone terribly wrong, probably numeric overflow: - break; - } - if ((i & 1u) == 0) - { - if ((static_cast<limb_type>(v >> bits_per_limb) < x[2]) || ((static_cast<limb_type>(u >> bits_per_limb) - static_cast<limb_type>(v >> bits_per_limb)) < (y[2] + y[1]))) - break; - } - else - { - if ((static_cast<limb_type>(v >> bits_per_limb) < y[2]) || ((static_cast<limb_type>(u >> bits_per_limb) - static_cast<limb_type>(v >> bits_per_limb)) < (x[2] + x[1]))) - break; - } -#ifdef BOOST_MP_GCD_DEBUG - BOOST_MP_ASSERT(q == UU / VV); - UU %= VV; - UU.swap(VV); -#endif - x[0] = x[1]; - x[1] = x[2]; - y[0] = y[1]; - y[1] = y[2]; - } - // - // We get here when the single digit algorithm has gone wrong, back up i, u and v: - // - --i; - u = old_u; - v = old_v; - // - // Now run the full double-digit algorithm: - // - while (true) - { - double_limb_type q = 1u; - double_limb_type tt = u; - divide_subtract(q, u, v); - std::swap(u, v); - tt = y[0] + q * static_cast<double_limb_type>(y[1]); - // - // If calculation of y[2] would overflow a single limb, then we *must* terminate. - // Note that x[2] < y[2] so there is no need to check that as well: - // - if (tt >> bits_per_limb) - { - ++i; - break; - } - x[2] = static_cast<limb_type>(x[0] + static_cast<double_limb_type>(q * x[1])); - y[2] = static_cast<limb_type>(tt); - ++i; - if ((i & 1u) == 0) - { - BOOST_MP_ASSERT(u > v); - if ((v < x[2]) || ((u - v) < (static_cast<double_limb_type>(y[2]) + y[1]))) - break; - } - else - { - BOOST_MP_ASSERT(u > v); - if ((v < y[2]) || ((u - v) < (static_cast<double_limb_type>(x[2]) + x[1]))) - break; - } -#ifdef BOOST_MP_GCD_DEBUG - BOOST_MP_ASSERT(q == UU / VV); - UU %= VV; - UU.swap(VV); -#endif - x[0] = x[1]; - x[1] = x[2]; - y[0] = y[1]; - y[1] = y[2]; - } - if (i == 1) - { - // No change to U and V we've stalled! - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - eval_modulus(t, U, V); - U.swap(V); - V.swap(t); - return; - } - // - // Update U and V. - // We have: - // - // U = x[0]U + y[0]V and - // V = x[1]U + y[1]V. - // - // But since we track only absolute values of x and y - // we have to take account of the implied signs and perform - // the appropriate subtraction depending on the whether i is - // even or odd: - // - std::size_t ts = U.size() + 1; - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t1(storage, ts), t2(storage, ts), t3(storage, ts); - eval_multiply(t1, U, x[0]); - eval_multiply(t2, V, y[0]); - eval_multiply(t3, U, x[1]); - if ((i & 1u) == 0) - { - if (x[0] == 0) - U = t2; - else - { - BOOST_MP_ASSERT(t2.compare(t1) >= 0); - eval_subtract(U, t2, t1); - BOOST_MP_ASSERT(U.sign() == false); - } - } - else - { - BOOST_MP_ASSERT(t1.compare(t2) >= 0); - eval_subtract(U, t1, t2); - BOOST_MP_ASSERT(U.sign() == false); - } - eval_multiply(t2, V, y[1]); - if (i & 1u) - { - if (x[1] == 0) - V = t2; - else - { - BOOST_MP_ASSERT(t2.compare(t3) >= 0); - eval_subtract(V, t2, t3); - BOOST_MP_ASSERT(V.sign() == false); - } - } - else - { - BOOST_MP_ASSERT(t3.compare(t2) >= 0); - eval_subtract(V, t3, t2); - BOOST_MP_ASSERT(V.sign() == false); - } - BOOST_MP_ASSERT(U.compare(V) >= 0); - BOOST_MP_ASSERT(lu > eval_msb(U)); -#ifdef BOOST_MP_GCD_DEBUG - - BOOST_MP_ASSERT(UU == U); - BOOST_MP_ASSERT(VV == V); - - extern std::size_t total_lehmer_gcd_calls; - extern std::size_t total_lehmer_gcd_bits_saved; - extern std::size_t total_lehmer_gcd_cycles; - - ++total_lehmer_gcd_calls; - total_lehmer_gcd_bits_saved += lu - eval_msb(U); - total_lehmer_gcd_cycles += i; -#endif - if (lu < 2048) - { - // - // Since we have stripped all common powers of 2 from U and V at the start - // if either are even at this point, we can remove stray powers of 2 now. - // Note that it is not possible for *both* U and V to be even at this point. - // - // This has an adverse effect on performance for high bit counts, but has - // a significant positive effect for smaller counts. - // - if ((U.limbs()[0] & 1u) == 0) - { - eval_right_shift(U, eval_lsb(U)); - if (U.compare(V) < 0) - U.swap(V); - } - else if ((V.limbs()[0] & 1u) == 0) - { - eval_right_shift(V, eval_lsb(V)); - } - } - storage.deallocate(ts * 3); -} - -#endif - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) -{ - using default_ops::eval_get_sign; - using default_ops::eval_is_zero; - using default_ops::eval_lsb; - - if (a.size() == 1) - { - eval_gcd(result, b, *a.limbs()); - return; - } - if (b.size() == 1) - { - eval_gcd(result, a, *b.limbs()); - return; - } - std::size_t temp_size = (std::max)(a.size(), b.size()) + 1; - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::scoped_shared_storage storage(a, temp_size * 6); - - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> U(storage, temp_size); - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> V(storage, temp_size); - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(storage, temp_size); - U = a; - V = b; - - int s = eval_get_sign(U); - - /* GCD(0,x) := x */ - if (s < 0) - { - U.negate(); - } - else if (s == 0) - { - result = V; - return; - } - s = eval_get_sign(V); - if (s < 0) - { - V.negate(); - } - else if (s == 0) - { - result = U; - return; - } - // - // Remove common factors of 2: - // - std::size_t us = eval_lsb(U); - std::size_t vs = eval_lsb(V); - std::size_t shift = (std::min)(us, vs); - if (us) - eval_right_shift(U, us); - if (vs) - eval_right_shift(V, vs); - - if (U.compare(V) < 0) - U.swap(V); - - while (!eval_is_zero(V)) - { - if (U.size() <= 2) - { - // - // Special case: if V has no more than 2 limbs - // then we can reduce U and V to a pair of integers and perform - // direct integer gcd: - // - if (U.size() == 1) - U = eval_gcd(*V.limbs(), *U.limbs()); - else - { - double_limb_type i = U.limbs()[0] | (static_cast<double_limb_type>(U.limbs()[1]) << sizeof(limb_type) * CHAR_BIT); - double_limb_type j = (V.size() == 1) ? *V.limbs() : V.limbs()[0] | (static_cast<double_limb_type>(V.limbs()[1]) << sizeof(limb_type) * CHAR_BIT); - U = eval_gcd(i, j); - } - break; - } - std::size_t lu = eval_msb(U) + 1; - std::size_t lv = eval_msb(V) + 1; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (!BOOST_MP_IS_CONST_EVALUATED(lu) && (lu - lv <= bits_per_limb / 2)) -#else - if (lu - lv <= bits_per_limb / 2) -#endif - { - eval_gcd_lehmer(U, V, lu, storage); - } - else - { - eval_modulus(t, U, V); - U.swap(V); - V.swap(t); - } - } - result = U; - if (shift) - eval_left_shift(result, shift); -} -// -// Now again for trivial backends: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_gcd(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) noexcept -{ - *result.limbs() = boost::multiprecision::detail::constexpr_gcd(*a.limbs(), *b.limbs()); - result.sign(false); -} -// This one is only enabled for unchecked cpp_int's, for checked int's we need the checking in the default version: -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (Checked1 == unchecked)>::type -eval_lcm(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = boost::multiprecision::detail::constexpr_lcm(*a.limbs(), *b.limbs()); - result.normalize(); // result may overflow the specified number of bits - result.sign(false); -} - -inline void conversion_overflow(const std::integral_constant<int, checked>&) -{ - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Overflow in conversion to narrower type")); -} -inline BOOST_MP_CXX14_CONSTEXPR void conversion_overflow(const std::integral_constant<int, unchecked>&) {} - -#if defined(__clang__) && defined(__MINGW32__) -// -// clang-11 on Mingw segfaults on conversion of __int128 -> float. -// See: https://bugs.llvm.org/show_bug.cgi?id=48941 -// These workarounds pass everything through an intermediate uint64_t. -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && std::is_same<typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type, double_limb_type>::value>::type -eval_convert_to(float* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) -{ - float f = static_cast<std::uint64_t>((*val.limbs()) >> 64); - *result = std::ldexp(f, 64); - *result += static_cast<std::uint64_t>((*val.limbs())); - if(val.sign()) - *result = -*result; -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && std::is_same<typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type, double_limb_type>::value>::type -eval_convert_to(double* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) -{ - float f = static_cast<std::uint64_t>((*val.limbs()) >> 64); - *result = std::ldexp(f, 64); - *result += static_cast<std::uint64_t>((*val.limbs())); - if(val.sign()) - *result = -*result; -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && std::is_same<typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type, double_limb_type>::value>::type -eval_convert_to(long double* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) -{ - float f = static_cast<std::uint64_t>((*val.limbs()) >> 64); - *result = std::ldexp(f, 64); - *result += static_cast<std::uint64_t>((*val.limbs())); - if(val.sign()) - *result = -*result; -} -#endif - -template <class R, std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && std::is_convertible<typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type, R>::value>::type -eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) -{ - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_specialized) - { - using common_type = typename std::common_type<R, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type>::type; - - if (static_cast<common_type>(*val.limbs()) > static_cast<common_type>((std::numeric_limits<R>::max)())) - { - if (val.isneg()) - { - check_is_negative(std::integral_constant < bool, (boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value) || (number_category<R>::value == number_kind_floating_point) > ()); - if (static_cast<common_type>(*val.limbs()) > -static_cast<common_type>((std::numeric_limits<R>::min)())) - conversion_overflow(typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - *result = (std::numeric_limits<R>::min)(); - } - else - { - conversion_overflow(typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - *result = boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value ? (std::numeric_limits<R>::max)() : static_cast<R>(*val.limbs()); - } - } - else - { - *result = static_cast<R>(*val.limbs()); - if (val.isneg()) - { - check_is_negative(std::integral_constant < bool, (boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value) || (number_category<R>::value == number_kind_floating_point) > ()); - *result = negate_integer(*result, std::integral_constant < bool, is_signed_number<R>::value || (number_category<R>::value == number_kind_floating_point) > ()); - } - } - } - else - { - *result = static_cast<R>(*val.limbs()); - if (val.isneg()) - { - check_is_negative(std::integral_constant<bool, (boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value) || (number_category<R>::value == number_kind_floating_point) > ()); - *result = negate_integer(*result, std::integral_constant<bool, is_signed_number<R>::value || (number_category<R>::value == number_kind_floating_point) > ()); - } - } -} - -template <class R, std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && std::is_convertible<typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type, R>::value>::type -eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) -{ - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_specialized) - { - using common_type = typename std::common_type<R, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type>::type; - - if(static_cast<common_type>(*val.limbs()) > static_cast<common_type>((std::numeric_limits<R>::max)())) - { - conversion_overflow(typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - *result = boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value ? (std::numeric_limits<R>::max)() : static_cast<R>(*val.limbs()); - } - else - *result = static_cast<R>(*val.limbs()); - } - else - *result = static_cast<R>(*val.limbs()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_lsb(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - using default_ops::eval_get_sign; - if (eval_get_sign(a) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - if (a.sign()) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - // - // Find the index of the least significant bit within that limb: - // - return boost::multiprecision::detail::find_lsb(*a.limbs()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_msb_imp(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - // - // Find the index of the least significant bit within that limb: - // - return boost::multiprecision::detail::find_msb(*a.limbs()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, std::size_t>::type -eval_msb(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) -{ - using default_ops::eval_get_sign; - if (eval_get_sign(a) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - if (a.sign()) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - return eval_msb_imp(a); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t hash_value(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) noexcept -{ - std::size_t result = 0; - for (std::size_t i = 0; i < val.size(); ++i) - { - boost::multiprecision::detail::hash_combine(result, val.limbs()[i]); - } - boost::multiprecision::detail::hash_combine(result, val.sign()); - return result; -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -} // Namespace backends - -namespace detail { - -#ifndef BOOST_MP_STANDALONE -template <typename T> -inline BOOST_CXX14_CONSTEXPR T constexpr_gcd(T a, T b) noexcept -{ - return boost::integer::gcd(a, b); -} - -template <typename T> -inline BOOST_CXX14_CONSTEXPR T constexpr_lcm(T a, T b) noexcept -{ - return boost::integer::lcm(a, b); -} - -#else - -template <typename T> -inline BOOST_CXX14_CONSTEXPR T constexpr_gcd(T a, T b) noexcept -{ - return boost::multiprecision::backends::eval_gcd(a, b); -} - -template <typename T> -inline BOOST_CXX14_CONSTEXPR T constexpr_lcm(T a, T b) noexcept -{ - const T ab_gcd = boost::multiprecision::detail::constexpr_gcd(a, b); - return (a * b) / ab_gcd; -} - -#endif // BOOST_MP_STANDALONE - -} - -}} // Namespace boost::multiprecision - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/multiply.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/multiply.hpp deleted file mode 100644 index b72297ab6d..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/multiply.hpp +++ /dev/null @@ -1,848 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012-20 John Maddock. -// Copyright 2019-20 Christopher Kormanyos. -// Copyright 2019-20 Madhur Chauhan. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_CPP_INT_MULTIPLY_HPP -#define BOOST_MP_CPP_INT_MULTIPLY_HPP - -#include <limits> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/endian.hpp> -#include <boost/multiprecision/detail/assert.hpp> -#include <boost/multiprecision/integer.hpp> - -namespace boost { namespace multiprecision { namespace backends { - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4127) // conditional expression is constant -#endif -// -// Multiplication by a single limb: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& val) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - if (!val) - { - result = static_cast<limb_type>(0); - return; - } - if ((void*)&a != (void*)&result) - result.resize(a.size(), a.size()); - double_limb_type carry = 0; - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer p = result.limbs(); - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pe = result.limbs() + result.size(); - typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs(); - while (p != pe) - { - carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val); -#ifdef __MSVC_RUNTIME_CHECKS - *p = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - *p = static_cast<limb_type>(carry); -#endif - carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - ++p, ++pa; - } - if (carry) - { - std::size_t i = result.size(); - result.resize(i + 1, i + 1); - if (result.size() > i) - result.limbs()[i] = static_cast<limb_type>(carry); - } - result.sign(a.sign()); - if (is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value) - result.normalize(); -} - -// -// resize_for_carry forces a resize of the underlying buffer only if a previous request -// for "required" elements could possibly have failed, *and* we have checking enabled. -// This will cause an overflow error inside resize(): -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& /*result*/, std::size_t /*required*/) {} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, class Allocator1> -inline BOOST_MP_CXX14_CONSTEXPR void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, Allocator1>& result, std::size_t required) -{ - if (result.size() < required) - result.resize(required, required); -} -// -// Minimum number of limbs required for Karatsuba to be worthwhile: -// -#ifdef BOOST_MP_KARATSUBA_CUTOFF -const size_t karatsuba_cutoff = BOOST_MP_KARATSUBA_CUTOFF; -#else -const size_t karatsuba_cutoff = 40; -#endif -// -// Core (recursive) Karatsuba multiplication, all the storage required is allocated upfront and -// passed down the stack in this routine. Note that all the cpp_int_backend's must be the same type -// and full variable precision. Karatsuba really doesn't play nice with fixed-size integers. If necessary -// fixed precision integers will get aliased as variable-precision types before this is called. -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_int_check_type Checked, class Allocator> -inline void multiply_karatsuba( - cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& result, - const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, - const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& b, - typename cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>::scoped_shared_storage& storage) -{ - using cpp_int_type = cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>; - - std::size_t as = a.size(); - std::size_t bs = b.size(); - // - // Termination condition: if either argument is smaller than karatsuba_cutoff - // then schoolboy multiplication will be faster: - // - if ((as < karatsuba_cutoff) || (bs < karatsuba_cutoff)) - { - eval_multiply(result, a, b); - return; - } - // - // Partitioning size: split the larger of a and b into 2 halves - // - std::size_t n = (as > bs ? as : bs) / 2 + 1; - // - // Partition a and b into high and low parts. - // ie write a, b as a = a_h * 2^n + a_l, b = b_h * 2^n + b_l - // - // We could copy the high and low parts into new variables, but we'll - // use aliasing to reference the internal limbs of a and b. There is one wart here: - // if a and b are mismatched in size, then n may be larger than the smaller - // of a and b. In that situation the high part is zero, and we have no limbs - // to alias, so instead alias a local variable. - // This raises 2 questions: - // * Is this the best way to partition a and b? - // * Since we have one high part zero, the arithmetic simplifies considerably, - // so should we have a special routine for this? - // - std::size_t sz = (std::min)(as, n); - const cpp_int_type a_l(a.limbs(), 0, sz); - - sz = (std::min)(bs, n); - const cpp_int_type b_l(b.limbs(), 0, sz); - - limb_type zero = 0; - const cpp_int_type a_h(as > n ? a.limbs() + n : &zero, 0, as > n ? as - n : 1); - const cpp_int_type b_h(bs > n ? b.limbs() + n : &zero, 0, bs > n ? bs - n : 1); - // - // The basis for the Karatsuba algorithm is as follows: - // - // let x = a_h * b_ h - // y = a_l * b_l - // z = (a_h + a_l)*(b_h + b_l) - x - y - // and therefore a * b = x * (2 ^ (2 * n))+ z * (2 ^ n) + y - // - // Begin by allocating our temporaries, these alias the memory already allocated in the shared storage: - // - cpp_int_type t1(storage, 2 * n + 2); - cpp_int_type t2(storage, n + 1); - cpp_int_type t3(storage, n + 1); - // - // Now we want: - // - // result = | a_h*b_h | a_l*b_l | - // (bits) <-- 2*n --> - // - // We create aliases for the low and high parts of result, and multiply directly into them: - // - cpp_int_type result_low(result.limbs(), 0, 2 * n); - cpp_int_type result_high(result.limbs(), 2 * n, result.size() - 2 * n); - // - // low part of result is a_l * b_l: - // - multiply_karatsuba(result_low, a_l, b_l, storage); - // - // We haven't zeroed out memory in result, so set to zero any unused limbs, - // if a_l and b_l have mostly random bits then nothing happens here, but if - // one is zero or nearly so, then a memset might be faster... it's not clear - // that it's worth the extra logic though (and is darn hard to measure - // what the "average" case is). - // - for (std::size_t i = result_low.size(); i < 2 * n; ++i) - result.limbs()[i] = 0; - // - // Set the high part of result to a_h * b_h: - // - multiply_karatsuba(result_high, a_h, b_h, storage); - for (std::size_t i = result_high.size() + 2 * n; i < result.size(); ++i) - result.limbs()[i] = 0; - // - // Now calculate (a_h+a_l)*(b_h+b_l): - // - add_unsigned(t2, a_l, a_h); - add_unsigned(t3, b_l, b_h); - multiply_karatsuba(t1, t2, t3, storage); // t1 = (a_h+a_l)*(b_h+b_l) - // - // There is now a slight deviation from Karatsuba, we want to subtract - // a_l*b_l + a_h*b_h from t1, but rather than use an addition and a subtraction - // plus one temporary, we'll use 2 subtractions. On the minus side, a subtraction - // is on average slightly slower than an addition, but we save a temporary (ie memory) - // and also hammer the same piece of memory over and over rather than 2 disparate - // memory regions. Overall it seems to be a slight win. - // - subtract_unsigned(t1, t1, result_high); - subtract_unsigned(t1, t1, result_low); - // - // The final step is to left shift t1 by n bits and add to the result. - // Rather than do an actual left shift, we can simply alias the result - // and add to the alias: - // - cpp_int_type result_alias(result.limbs(), n, result.size() - n); - add_unsigned(result_alias, result_alias, t1); - // - // Free up storage for use by sister branches to this one: - // - storage.deallocate(t1.capacity() + t2.capacity() + t3.capacity()); - - result.normalize(); -} - -inline std::size_t karatsuba_storage_size(std::size_t s) -{ - // - // This estimates how much memory we will need based on - // s-limb multiplication. In an ideal world the number of limbs - // would halve with each recursion, and our storage requirements - // would be 4s in the limit, and rather less in practice since - // we bail out long before we reach one limb. In the real world - // we don't quite halve s in each recursion, so this is an heuristic - // which over-estimates how much we need. We could compute an exact - // value, but it would be rather time consuming. - // - return 5 * s; -} -// -// There are 2 entry point routines for Karatsuba multiplication: -// one for variable precision types, and one for fixed precision types. -// These are responsible for allocating all the storage required for the recursive -// routines above, and are always at the outermost level. -// -// Normal variable precision case comes first: -// -template <std::size_t MinBits, std::size_t MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator> -inline typename std::enable_if<!is_fixed_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>::type -setup_karatsuba( - cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& result, - const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a, - const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b) -{ - std::size_t as = a.size(); - std::size_t bs = b.size(); - std::size_t s = as > bs ? as : bs; - std::size_t storage_size = karatsuba_storage_size(s); - if (storage_size < 300) - { - // - // Special case: if we don't need too much memory, we can use stack based storage - // and save a call to the allocator, this allows us to use Karatsuba multiply - // at lower limb counts than would otherwise be possible: - // - limb_type limbs[300]; - typename cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::scoped_shared_storage storage(limbs, storage_size); - multiply_karatsuba(result, a, b, storage); - } - else - { - typename cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::scoped_shared_storage storage(result.allocator(), storage_size); - multiply_karatsuba(result, a, b, storage); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -inline typename std::enable_if<is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_fixed_precision<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value || is_fixed_precision<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -setup_karatsuba( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) -{ - // - // Now comes the fixed precision case. - // In fact Karatsuba doesn't really work with fixed precision since the logic - // requires that we calculate all the bits of the result (especially in the - // temporaries used internally). So... we'll convert all the arguments - // to variable precision types by aliasing them, this also - // reduce the number of template instantations: - // - using variable_precision_type = cpp_int_backend<0, 0, signed_magnitude, unchecked, std::allocator<limb_type> >; - variable_precision_type a_t(a.limbs(), 0, a.size()), b_t(b.limbs(), 0, b.size()); - std::size_t as = a.size(); - std::size_t bs = b.size(); - std::size_t s = as > bs ? as : bs; - std::size_t sz = as + bs; - std::size_t storage_size = karatsuba_storage_size(s); - - if (!is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || (sz * sizeof(limb_type) * CHAR_BIT <= MaxBits1)) - { - // Result is large enough for all the bits of the result, so we can use aliasing: - result.resize(sz, sz); - variable_precision_type t(result.limbs(), 0, result.size()); - typename variable_precision_type::scoped_shared_storage storage(t.allocator(), storage_size); - multiply_karatsuba(t, a_t, b_t, storage); - result.resize(t.size(), t.size()); - } - else - { - // - // Not enough bit in result for the answer, so we must use a temporary - // and then truncate (ie modular arithmetic): - // - typename variable_precision_type::scoped_shared_storage storage(variable_precision_type::allocator_type(), sz + storage_size); - variable_precision_type t(storage, sz); - multiply_karatsuba(t, a_t, b_t, storage); - // - // If there is truncation, and result is a checked type then this will throw: - // - result = t; - } -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -inline typename std::enable_if<!is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_fixed_precision<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_fixed_precision<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -setup_karatsuba( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) -{ - // - // Variable precision, mixed arguments, just alias and forward: - // - using variable_precision_type = cpp_int_backend<0, 0, signed_magnitude, unchecked, std::allocator<limb_type> >; - variable_precision_type a_t(a.limbs(), 0, a.size()), b_t(b.limbs(), 0, b.size()); - std::size_t as = a.size(); - std::size_t bs = b.size(); - std::size_t s = as > bs ? as : bs; - std::size_t sz = as + bs; - std::size_t storage_size = karatsuba_storage_size(s); - - result.resize(sz, sz); - variable_precision_type t(result.limbs(), 0, result.size()); - typename variable_precision_type::scoped_shared_storage storage(t.allocator(), storage_size); - multiply_karatsuba(t, a_t, b_t, storage); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -inline BOOST_MP_CXX14_CONSTEXPR void -eval_multiply_comba( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - // - // see PR #182 - // Comba Multiplier - based on Paul Comba's - // Exponentiation cryptosystems on the IBM PC, 1990 - // - std::ptrdiff_t as = a.size(), - bs = b.size(), - rs = result.size(); - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs(); - - double_limb_type carry = 0, - temp = 0; - limb_type overflow = 0; - const std::size_t limb_bits = sizeof(limb_type) * CHAR_BIT; - const bool must_throw = rs < as + bs - 1; - for (std::ptrdiff_t r = 0, lim = (std::min)(rs, as + bs - 1); r < lim; ++r, overflow = 0) - { - std::ptrdiff_t i = r >= as ? as - 1 : r, - j = r - i, - k = i < bs - j ? i + 1 : bs - j; // min(i+1, bs-j); - - typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs() + i; - typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs() + j; - - temp = carry; - carry += static_cast<double_limb_type>(*(pa)) * (*(pb)); - overflow += carry < temp; - for (--k; k; k--) - { - temp = carry; - carry += static_cast<double_limb_type>(*(--pa)) * (*(++pb)); - overflow += carry < temp; - } - *(pr++) = static_cast<limb_type>(carry); - carry = (static_cast<double_limb_type>(overflow) << limb_bits) | (carry >> limb_bits); - } - if (carry || must_throw) - { - resize_for_carry(result, as + bs); - if (static_cast<int>(result.size()) >= as + bs) - *pr = static_cast<limb_type>(carry); - } -} -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) - noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value - && (karatsuba_cutoff * sizeof(limb_type) * CHAR_BIT > MaxBits1) - && (karatsuba_cutoff * sizeof(limb_type)* CHAR_BIT > MaxBits2) - && (karatsuba_cutoff * sizeof(limb_type)* CHAR_BIT > MaxBits3))) -{ - // Uses simple (O(n^2)) multiplication when the limbs are less - // otherwise switches to karatsuba algorithm based on experimental value (~40 limbs) - // - // Trivial cases first: - // - std::size_t as = a.size(); - std::size_t bs = b.size(); - typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs(); - typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs(); - if (as == 1) - { - bool s = b.sign() != a.sign(); - if (bs == 1) - { - result = static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(*pb); - } - else - { - limb_type l = *pa; - eval_multiply(result, b, l); - } - result.sign(s); - return; - } - if (bs == 1) - { - bool s = b.sign() != a.sign(); - limb_type l = *pb; - eval_multiply(result, a, l); - result.sign(s); - return; - } - - if ((void*)&result == (void*)&a) - { - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(a); - eval_multiply(result, t, b); - return; - } - if ((void*)&result == (void*)&b) - { - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(b); - eval_multiply(result, a, t); - return; - } - - constexpr double_limb_type limb_max = static_cast<double_limb_type>(~static_cast<limb_type>(0u)); - constexpr double_limb_type double_limb_max = static_cast<double_limb_type>(~static_cast<double_limb_type>(0u)); - - result.resize(as + bs, as + bs - 1); -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (!BOOST_MP_IS_CONST_EVALUATED(as) && (as >= karatsuba_cutoff && bs >= karatsuba_cutoff)) -#else - if (as >= karatsuba_cutoff && bs >= karatsuba_cutoff) -#endif - { - setup_karatsuba(result, a, b); - // - // Set the sign of the result: - // - result.sign(a.sign() != b.sign()); - return; - } - typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs(); - static_assert(double_limb_max - 2 * limb_max >= limb_max * limb_max, "failed limb size sanity check"); - -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(as)) - { - for (std::size_t i = 0; i < result.size(); ++i) - pr[i] = 0; - } - else -#endif - std::memset(pr, 0, result.size() * sizeof(limb_type)); - -#if defined(BOOST_MP_COMBA) - // - // Comba Multiplier might not be efficient because of less efficient assembly - // by the compiler as of 09/01/2020 (DD/MM/YY). See PR #182 - // Till then this will lay dormant :( - // - eval_multiply_comba(result, a, b); -#else - - double_limb_type carry = 0; - for (std::size_t i = 0; i < as; ++i) - { - BOOST_MP_ASSERT(result.size() > i); - std::size_t inner_limit = !is_fixed_precision<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value ? bs : (std::min)(result.size() - i, bs); - std::size_t j = 0; - for (; j < inner_limit; ++j) - { - BOOST_MP_ASSERT(i + j < result.size()); -#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100) - BOOST_MP_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry > - static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))); -#endif - carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]); - BOOST_MP_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i + j])); - carry += pr[i + j]; -#ifdef __MSVC_RUNTIME_CHECKS - pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pr[i + j] = static_cast<limb_type>(carry); -#endif - carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; - BOOST_MP_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)); - } - if (carry) - { - resize_for_carry(result, i + j + 1); // May throw if checking is enabled - if (i + j < result.size()) -#ifdef __MSVC_RUNTIME_CHECKS - pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); -#else - pr[i + j] = static_cast<limb_type>(carry); -#endif - } - carry = 0; - } -#endif // ifdef(BOOST_MP_COMBA) ends - - result.normalize(); - // - // Set the sign of the result: - // - result.sign(a.sign() != b.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) - noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>())))) -{ - eval_multiply(result, result, a); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) - noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const limb_type&>())))) -{ - eval_multiply(result, result, val); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const double_limb_type& val) - noexcept( - (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const limb_type&>()))) - && (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>()))) - ) -{ - if (val <= (std::numeric_limits<limb_type>::max)()) - { - eval_multiply(result, a, static_cast<limb_type>(val)); - } - else - { -#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE) - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val); -#else - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - t = val; -#endif - eval_multiply(result, a, t); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) - noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const double_limb_type&>())))) -{ - eval_multiply(result, result, val); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& val) - noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const limb_type&>())))) -{ - if (val > 0) - eval_multiply(result, a, static_cast<limb_type>(val)); - else - { - eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val))); - result.negate(); - } -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) - noexcept((noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const limb_type&>())))) -{ - eval_multiply(result, result, val); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_double_limb_type& val) - noexcept( - (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const limb_type&>()))) - && (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>()))) - ) -{ - if (val > 0) - { - if (val <= (std::numeric_limits<limb_type>::max)()) - { - eval_multiply(result, a, static_cast<limb_type>(val)); - return; - } - } - else if (val >= -static_cast<signed_double_limb_type>((std::numeric_limits<limb_type>::max)())) - { - eval_multiply(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(val))); - result.negate(); - return; - } -#if BOOST_MP_ENDIAN_LITTLE_BYTE && !defined(BOOST_MP_TEST_NO_LE) - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val); -#else - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t; - t = val; -#endif - eval_multiply(result, a, t); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) - noexcept( - (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const limb_type&>()))) - && (noexcept(eval_multiply(std::declval<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>(), std::declval<const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&>()))) - ) -{ - eval_multiply(result, result, val); -} - -// -// Now over again for trivial cpp_int's: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.sign(result.sign() != o.sign()); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.sign(a.sign() != b.sign()); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) -{ - *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); - result.normalize(); -} - -// -// Special routines for multiplying two integers to obtain a multiprecision result: -// -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - signed_double_limb_type a, signed_double_limb_type b) -{ - constexpr signed_double_limb_type mask = static_cast<signed_double_limb_type>(~static_cast<limb_type>(0)); - constexpr std::size_t limb_bits = static_cast<std::size_t>(sizeof(limb_type) * CHAR_BIT); - - bool s = false; - if (a < 0) - { - a = -a; - s = true; - } - if (b < 0) - { - b = -b; - s = !s; - } - double_limb_type w = a & mask; - double_limb_type x = static_cast<double_limb_type>(a >> limb_bits); - double_limb_type y = b & mask; - double_limb_type z = static_cast<double_limb_type>(b >> limb_bits); - - result.resize(4, 4); - limb_type* pr = result.limbs(); - - double_limb_type carry = w * y; -#ifdef __MSVC_RUNTIME_CHECKS - pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += w * z + x * y; - pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += x * z; - pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#else - pr[0] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += w * z + x * y; - pr[1] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += x * z; - pr[2] = static_cast<limb_type>(carry); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#endif - result.sign(s); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - double_limb_type a, double_limb_type b) -{ - constexpr signed_double_limb_type mask = static_cast<signed_double_limb_type>(~static_cast<limb_type>(0)); - constexpr std::size_t limb_bits = static_cast<std::size_t>(sizeof(limb_type) * CHAR_BIT); - - double_limb_type w = a & mask; - double_limb_type x = a >> limb_bits; - double_limb_type y = b & mask; - double_limb_type z = b >> limb_bits; - - result.resize(4, 4); - limb_type* pr = result.limbs(); - - double_limb_type carry = w * y; -#ifdef __MSVC_RUNTIME_CHECKS - pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += w * z; - pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry = x * y + pr[1]; - pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - carry >>= limb_bits; - carry += pr[2] + x * z; - pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0)); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#else - pr[0] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += w * z; - pr[1] = static_cast<limb_type>(carry); - carry >>= limb_bits; - pr[2] = static_cast<limb_type>(carry); - carry = x * y + pr[1]; - pr[1] = static_cast<limb_type>(carry); - carry >>= limb_bits; - carry += pr[2] + x * z; - pr[2] = static_cast<limb_type>(carry); - pr[3] = static_cast<limb_type>(carry >> limb_bits); -#endif - result.sign(false); - result.normalize(); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, - std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& a, - cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> const& b) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::type; - eval_multiply(result, static_cast<canonical_type>(*a.limbs()), static_cast<canonical_type>(*b.limbs())); - result.sign(a.sign() != b.sign()); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class SI> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_signed<SI>::value && boost::multiprecision::detail::is_integral<SI>::value && (sizeof(SI) <= sizeof(signed_double_limb_type) / 2)>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - SI a, SI b) -{ - result = static_cast<signed_double_limb_type>(a) * static_cast<signed_double_limb_type>(b); -} - -template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class UI> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_unsigned<UI>::value && (sizeof(UI) <= sizeof(signed_double_limb_type) / 2)>::type -eval_multiply( - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - UI a, UI b) -{ - result = static_cast<double_limb_type>(a) * static_cast<double_limb_type>(b); -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -}}} // namespace boost::multiprecision::backends - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/serialize.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/serialize.hpp deleted file mode 100644 index e419619460..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/serialize.hpp +++ /dev/null @@ -1,211 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_CPP_INT_SERIALIZE_HPP -#define BOOST_MP_CPP_INT_SERIALIZE_HPP - -#ifndef BOOST_MP_STANDALONE - -namespace boost { - -namespace archive { - -class binary_oarchive; -class binary_iarchive; - -} // namespace archive - -namespace serialization { - -namespace mp = boost::multiprecision; - -namespace cpp_int_detail { - -using namespace boost::multiprecision; -using namespace boost::multiprecision::backends; - -template <class T> -struct is_binary_archive : public std::integral_constant<bool, false> -{}; -template <> -struct is_binary_archive<boost::archive::binary_oarchive> : public std::integral_constant<bool, true> -{}; -template <> -struct is_binary_archive<boost::archive::binary_iarchive> : public std::integral_constant<bool, true> -{}; - -// -// We have 8 serialization methods to fill out (and test), they are all permutations of: -// Load vs Store. -// Trivial or non-trivial cpp_int type. -// Binary or not archive. -// -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&) -{ - // Load. - // Non-trivial. - // Non binary. - - using boost::make_nvp; - bool s; - ar& make_nvp("sign", s); - std::size_t limb_count; - std::size_t byte_count; - ar& make_nvp("byte-count", byte_count); - limb_count = byte_count / sizeof(limb_type) + ((byte_count % sizeof(limb_type)) ? 1 : 0); - val.resize(limb_count, limb_count); - limb_type* pl = val.limbs(); - for (std::size_t i = 0; i < limb_count; ++i) - { - pl[i] = 0; - for (std::size_t j = 0; (j < sizeof(limb_type)) && byte_count; ++j) - { - unsigned char byte; - ar& make_nvp("byte", byte); - pl[i] |= static_cast<limb_type>(byte) << (j * CHAR_BIT); - --byte_count; - } - } - if (s != val.sign()) - val.negate(); - val.normalize(); -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&) -{ - // Store. - // Non-trivial. - // Non binary. - - using boost::make_nvp; - bool s = val.sign(); - ar& make_nvp("sign", s); - limb_type* pl = val.limbs(); - std::size_t limb_count = val.size(); - std::size_t byte_count = limb_count * sizeof(limb_type); - ar& make_nvp("byte-count", byte_count); - - for (std::size_t i = 0; i < limb_count; ++i) - { - limb_type l = pl[i]; - for (std::size_t j = 0; j < sizeof(limb_type); ++j) - { - unsigned char byte = static_cast<unsigned char>((l >> (j * CHAR_BIT)) & ((1u << CHAR_BIT) - 1)); - ar& make_nvp("byte", byte); - } - } -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&) -{ - // Load. - // Trivial. - // Non binary. - using boost::make_nvp; - bool s; - typename Int::local_limb_type l = 0; - ar& make_nvp("sign", s); - std::size_t byte_count; - ar& make_nvp("byte-count", byte_count); - for (std::size_t i = 0; i < byte_count; ++i) - { - unsigned char b; - ar& make_nvp("byte", b); - l |= static_cast<typename Int::local_limb_type>(b) << (i * CHAR_BIT); - } - *val.limbs() = l; - if (s != val.sign()) - val.negate(); -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&) -{ - // Store. - // Trivial. - // Non binary. - using boost::make_nvp; - bool s = val.sign(); - typename Int::local_limb_type l = *val.limbs(); - ar& make_nvp("sign", s); - std::size_t limb_count = sizeof(l); - ar& make_nvp("byte-count", limb_count); - for (std::size_t i = 0; i < limb_count; ++i) - { - unsigned char b = static_cast<unsigned char>(static_cast<typename Int::local_limb_type>(l >> (i * CHAR_BIT)) & static_cast<typename Int::local_limb_type>((1u << CHAR_BIT) - 1)); - ar& make_nvp("byte", b); - } -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&) -{ - // Load. - // Non-trivial. - // Binary. - bool s; - std::size_t c; - ar& s; - ar& c; - val.resize(c, c); - ar.load_binary(val.limbs(), c * sizeof(limb_type)); - if (s != val.sign()) - val.negate(); - val.normalize(); -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&) -{ - // Store. - // Non-trivial. - // Binary. - bool s = val.sign(); - std::size_t c = val.size(); - ar& s; - ar& c; - ar.save_binary(val.limbs(), c * sizeof(limb_type)); -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&) -{ - // Load. - // Trivial. - // Binary. - bool s; - ar& s; - ar.load_binary(val.limbs(), sizeof(*val.limbs())); - if (s != val.sign()) - val.negate(); -} -template <class Archive, class Int> -void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&) -{ - // Store. - // Trivial. - // Binary. - bool s = val.sign(); - ar& s; - ar.save_binary(val.limbs(), sizeof(*val.limbs())); -} - -} // namespace cpp_int_detail - -template <class Archive, std::size_t MinBits, std::size_t MaxBits, mp::cpp_integer_type SignType, mp::cpp_int_check_type Checked, class Allocator> -void serialize(Archive& ar, mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& val, const unsigned int /*version*/) -{ - using archive_save_tag = typename Archive::is_saving ; - using save_tag = std::integral_constant<bool, archive_save_tag::value> ; - using trivial_tag = std::integral_constant<bool, mp::backends::is_trivial_cpp_int<mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>; - using binary_tag = typename cpp_int_detail::is_binary_archive<Archive>::type ; - - // Just dispatch to the correct method: - cpp_int_detail::do_serialize(ar, val, save_tag(), trivial_tag(), binary_tag()); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_MP_STANDALONE - -#endif // BOOST_MP_CPP_INT_SERIALIZE_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/value_pack.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/value_pack.hpp deleted file mode 100644 index bb3fe880d5..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/value_pack.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_CPP_INT_VP_HPP -#define BOOST_MP_CPP_INT_VP_HPP - -namespace boost { -namespace multiprecision { - -namespace literals { namespace detail { - -template <limb_type... VALUES> -struct value_pack -{ - constexpr value_pack() {} - - using next_type = value_pack<0, VALUES...>; -}; -template <class T> -struct is_value_pack -{ - static constexpr bool value = false; -}; -template <limb_type... VALUES> -struct is_value_pack<value_pack<VALUES...> > -{ - static constexpr bool value = true; -}; - -struct negate_tag -{}; - -constexpr negate_tag make_negate_tag() -{ - return negate_tag(); -} - -}}}} // namespace boost::multiprecision::literals::detail - -#endif // BOOST_MP_CPP_INT_CORE_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/assert.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/assert.hpp deleted file mode 100644 index 9e7c795c94..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/assert.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// (C) Copyright Matt Borland 2021. -// 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) -// -// We deliberately use assert in here: -// -// boost-no-inspect - -#ifndef BOOST_MP_DETAIL_ASSERT_HPP -#define BOOST_MP_DETAIL_ASSERT_HPP - -#include <boost/multiprecision/detail/standalone_config.hpp> - -#ifndef BOOST_MP_STANDALONE - -#include <boost/assert.hpp> -#define BOOST_MP_ASSERT(expr) BOOST_ASSERT(expr) -#define BOOST_MP_ASSERT_MSG(expr, msg) BOOST_ASSERT_MSG(expr, msg) - -#else // Standalone mode - use cassert - -#include <cassert> -#define BOOST_MP_ASSERT(expr) assert(expr) -#define BOOST_MP_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) - -#endif - -#endif // BOOST_MP_DETAIL_ASSERT_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/bitscan.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/bitscan.hpp deleted file mode 100644 index 2a696b83ee..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/bitscan.hpp +++ /dev/null @@ -1,317 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2013 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Comparison operators for cpp_int_backend: -// -#ifndef BOOST_MP_DETAIL_BITSCAN_HPP -#define BOOST_MP_DETAIL_BITSCAN_HPP - -#include <cstdint> -#include <climits> -#include <type_traits> -#include <boost/multiprecision/detail/endian.hpp> -#include <boost/multiprecision/detail/standalone_config.hpp> - -#if (defined(BOOST_MSVC) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) -#include <intrin.h> -#endif - -namespace boost { namespace multiprecision { namespace detail { - -template <class Unsigned> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t find_lsb_default(Unsigned mask) -{ - std::size_t result = 0; - while (!(mask & 1u)) - { - mask >>= 1; - ++result; - } - return result; -} - -template <class Unsigned> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t find_msb_default(Unsigned mask) -{ - std::size_t index = 0; - while (mask) - { - ++index; - mask >>= 1; - } - return --index; -} - -template <class Unsigned> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t find_lsb(Unsigned mask, const std::integral_constant<int, 0>&) -{ - return find_lsb_default(mask); -} - -template <class Unsigned> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t find_msb(Unsigned mask, const std::integral_constant<int, 0>&) -{ - return find_msb_default(mask); -} - -#if (defined(BOOST_MSVC) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) - -#pragma intrinsic(_BitScanForward, _BitScanReverse) - -BOOST_FORCEINLINE std::size_t find_lsb(unsigned long mask, const std::integral_constant<int, 1>&) -{ - unsigned long result; - _BitScanForward(&result, mask); - return result; -} - -BOOST_FORCEINLINE std::size_t find_msb(unsigned long mask, const std::integral_constant<int, 1>&) -{ - unsigned long result; - _BitScanReverse(&result, mask); - return result; -} -#ifdef _M_X64 - -#pragma intrinsic(_BitScanForward64, _BitScanReverse64) - -BOOST_FORCEINLINE std::size_t find_lsb(unsigned __int64 mask, const std::integral_constant<int, 2>&) -{ - unsigned long result; - _BitScanForward64(&result, mask); - return result; -} -template <class Unsigned> -BOOST_FORCEINLINE std::size_t find_msb(Unsigned mask, const std::integral_constant<int, 2>&) -{ - unsigned long result; - _BitScanReverse64(&result, mask); - return result; -} -#endif - -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_lsb(Unsigned mask) -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<Unsigned>::type; - using tag_type = typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned long), - std::integral_constant<int, 1>, -#ifdef _M_X64 - typename std::conditional< - sizeof(Unsigned) <= sizeof(__int64), - std::integral_constant<int, 2>, - std::integral_constant<int, 0> >::type -#else - std::integral_constant<int, 0> -#endif - >::type; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(mask)) - { - return find_lsb_default(mask); - } - else -#endif - return find_lsb(static_cast<ui_type>(mask), tag_type()); -} - -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_msb(Unsigned mask) -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<Unsigned>::type; - using tag_type = typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned long), - std::integral_constant<int, 1>, -#ifdef _M_X64 - typename std::conditional< - sizeof(Unsigned) <= sizeof(__int64), - std::integral_constant<int, 2>, - std::integral_constant<int, 0> >::type -#else - std::integral_constant<int, 0> -#endif - >::type; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(mask)) - { - return find_msb_default(mask); - } - else -#endif - return find_msb(static_cast<ui_type>(mask), tag_type()); -} - -#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__)) - -BOOST_FORCEINLINE std::size_t find_lsb(std::size_t mask, std::integral_constant<int, 1> const&) -{ - return static_cast<std::size_t>(__builtin_ctz(static_cast<unsigned int>(mask))); -} -BOOST_FORCEINLINE std::size_t find_lsb(unsigned long mask, std::integral_constant<int, 2> const&) -{ - return static_cast<std::size_t>(__builtin_ctzl(static_cast<unsigned long>(mask))); -} -BOOST_FORCEINLINE std::size_t find_lsb(unsigned long long mask, std::integral_constant<int, 3> const&) -{ - return static_cast<std::size_t>(__builtin_ctzll(static_cast<unsigned long long>(mask))); -} -BOOST_FORCEINLINE std::size_t find_msb(std::size_t mask, std::integral_constant<int, 1> const&) -{ - return static_cast<std::size_t>(static_cast<std::size_t>(sizeof(unsigned) * static_cast<std::size_t>(CHAR_BIT) - 1u) - static_cast<std::size_t>(__builtin_clz(static_cast<unsigned int>(mask)))); -} -BOOST_FORCEINLINE std::size_t find_msb(unsigned long mask, std::integral_constant<int, 2> const&) -{ - return static_cast<std::size_t>(static_cast<std::size_t>(sizeof(unsigned long) * static_cast<std::size_t>(CHAR_BIT) - 1u) - static_cast<std::size_t>(__builtin_clzl(static_cast<unsigned long>(mask)))); -} -BOOST_FORCEINLINE std::size_t find_msb(unsigned long long mask, std::integral_constant<int, 3> const&) -{ - return static_cast<std::size_t>(static_cast<std::size_t>(sizeof(unsigned long long) * static_cast<std::size_t>(CHAR_BIT) - 1u) - static_cast<std::size_t>(__builtin_clzll(static_cast<unsigned long long>(mask)))); -} -#ifdef BOOST_HAS_INT128 - -BOOST_FORCEINLINE std::size_t find_msb(uint128_type mask, std::integral_constant<int, 0> const&) -{ - union - { - uint128_type v; - std::uint64_t sv[2]; - } val; - val.v = mask; -#if BOOST_MP_ENDIAN_LITTLE_BYTE - if (val.sv[1]) - return find_msb(val.sv[1], std::integral_constant<int, 3>()) + 64; - return find_msb(val.sv[0], std::integral_constant<int, 3>()); -#else - if (val.sv[0]) - return find_msb(val.sv[0], std::integral_constant<int, 3>()) + 64; - return find_msb(val.sv[1], std::integral_constant<int, 3>()); -#endif -} -BOOST_FORCEINLINE std::size_t find_lsb(uint128_type mask, std::integral_constant<int, 0> const&) -{ - union - { - uint128_type v; - std::uint64_t sv[2]; - } val; - val.v = mask; -#if BOOST_MP_ENDIAN_LITTLE_BYTE - if (val.sv[0] == 0) - return find_lsb(val.sv[1], std::integral_constant<int, 3>()) + 64; - return find_lsb(val.sv[0], std::integral_constant<int, 3>()); -#else - if (val.sv[1] == 0) - return find_lsb(val.sv[0], std::integral_constant<int, 3>()) + 64; - return find_lsb(val.sv[1], std::integral_constant<int, 3>()); -#endif -} -#endif - -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_lsb(Unsigned mask) -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<Unsigned>::type; - using tag_type = typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned), - std::integral_constant<int, 1>, - typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned long), - std::integral_constant<int, 2>, - typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned long long), - std::integral_constant<int, 3>, - std::integral_constant<int, 0> >::type>::type>::type; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(mask)) - { - return find_lsb_default(mask); - } - else -#endif - return find_lsb(static_cast<ui_type>(mask), tag_type()); -} -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_msb(Unsigned mask) -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<Unsigned>::type; - using tag_type = typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned), - std::integral_constant<int, 1>, - typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned long), - std::integral_constant<int, 2>, - typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned long long), - std::integral_constant<int, 3>, - std::integral_constant<int, 0> >::type>::type>::type; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(mask)) - { - return find_msb_default(mask); - } - else -#endif - return find_msb(static_cast<ui_type>(mask), tag_type()); -} -#elif defined(BOOST_INTEL) -BOOST_FORCEINLINE std::size_t find_lsb(std::size_t mask, std::integral_constant<int, 1> const&) -{ - return _bit_scan_forward(mask); -} -BOOST_FORCEINLINE std::size_t find_msb(std::size_t mask, std::integral_constant<int, 1> const&) -{ - return _bit_scan_reverse(mask); -} -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_lsb(Unsigned mask) -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<Unsigned>::type; - using tag_type = typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned), - std::integral_constant<int, 1>, - std::integral_constant<int, 0> >::type; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(mask)) - { - return find_lsb_default(mask); - } - else -#endif - return find_lsb(static_cast<ui_type>(mask), tag_type()); -} -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_msb(Unsigned mask) -{ - using ui_type = typename boost::multiprecision::detail::make_unsigned<Unsigned>::type; - using tag_type = typename std::conditional< - sizeof(Unsigned) <= sizeof(unsigned), - std::integral_constant<int, 1>, - std::integral_constant<int, 0> >::type; -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(mask)) - { - return find_msb_default(mask); - } - else -#endif - return find_msb(static_cast<ui_type>(mask), tag_type()); -} -#else -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_lsb(Unsigned mask) -{ - return find_lsb(mask, std::integral_constant<int, 0>()); -} -template <class Unsigned> -BOOST_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR std::size_t find_msb(Unsigned mask) -{ - return find_msb(mask, std::integral_constant<int, 0>()); -} -#endif - -}}} // namespace boost::multiprecision::detail - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/check_cpp11_config.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/check_cpp11_config.hpp deleted file mode 100644 index f798ef64d2..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/check_cpp11_config.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 John Maddock. 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) - -#ifndef BOOST_MP_CHECK_CPP11_CONFIG_HPP -#define BOOST_MP_CHECK_CPP11_CONFIG_HPP - -// -// We now require C++11, if something we use is not supported, then error and say why: -// -#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_RVALUE_REFERENCES being set" -#endif -#ifdef BOOST_NO_CXX11_TEMPLATE_ALIASES -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_TEMPLATE_ALIASES being set" -#endif -#ifdef BOOST_NO_CXX11_HDR_ARRAY -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_HDR_ARRAY being set" -#endif -#ifdef BOOST_NO_CXX11_HDR_TYPE_TRAITS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_HDR_TYPE_TRAITS being set" -#endif -#ifdef BOOST_NO_CXX11_ALLOCATOR -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_ALLOCATOR being set" -#endif -#ifdef BOOST_NO_CXX11_CONSTEXPR -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_CONSTEXPR being set" -#endif -#ifdef BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_MP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS being set" -#endif -#ifdef BOOST_NO_CXX11_REF_QUALIFIERS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_REF_QUALIFIERS being set" -#endif -#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_HDR_FUNCTIONAL being set" -#endif -#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_VARIADIC_TEMPLATES being set" -#endif -#ifdef BOOST_NO_CXX11_USER_DEFINED_LITERALS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_USER_DEFINED_LITERALS being set" -#endif -#ifdef BOOST_NO_CXX11_DECLTYPE -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_DECLTYPE being set" -#endif -#ifdef BOOST_NO_CXX11_STATIC_ASSERT -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_STATIC_ASSERT being set" -#endif -#ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_DEFAULTED_FUNCTIONS being set" -#endif -#ifdef BOOST_NO_CXX11_NOEXCEPT -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_NOEXCEPT being set" -#endif -#ifdef BOOST_NO_CXX11_REF_QUALIFIERS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_REF_QUALIFIERS being set" -#endif -#ifdef BOOST_NO_CXX11_USER_DEFINED_LITERALS -#error "This library now requires a C++11 or later compiler - this message was generated as a result of BOOST_NO_CXX11_USER_DEFINED_LITERALS being set" -#endif - -#endif // BOOST_MP_CHECK_CPP11_CONFIG_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/constexpr.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/constexpr.hpp deleted file mode 100644 index 6b4d952889..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/constexpr.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2019 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_DETAIL_CONSTEXPR_HPP -#define BOOST_MP_DETAIL_CONSTEXPR_HPP - -#include <cstring> -#include <boost/multiprecision/detail/standalone_config.hpp> - -namespace boost { - -namespace multiprecision { - -namespace std_constexpr { - -template <class T> -inline BOOST_CXX14_CONSTEXPR void swap(T& a, T& b) -{ - T t(a); - a = b; - b = t; -} - -template <class InputIterator, class OutputIterator> -inline BOOST_CXX14_CONSTEXPR OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) -{ - // - // There are 3 branches here, only one of which is selected at compile time: - // -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(*first)) - { - // constexpr safe code, never generates runtime code: - while (first != last) - { - *result = *first; - ++first; - ++result; - } - return result; - } - else -#endif - { -#ifndef BOOST_NO_CXX17_IF_CONSTEXPR - if constexpr (std::is_pointer<InputIterator>::value && std::is_pointer<OutputIterator>::value && std::is_trivially_copyable<typename std::remove_reference<decltype(*first)>::type>::value) - { - // The normal runtime branch: - std::memcpy(result, first, static_cast<std::size_t>(static_cast<std::size_t>(last - first) * sizeof(*first))); - return result + (last - first); - } - else -#endif - { - // Alternate runtime branch: - while (first != last) - { - *result = *first; - ++first; - ++result; - } - return result; - } - } -} - -template <class I> -inline BOOST_CXX14_CONSTEXPR bool equal(const I* first, const I* last, const I* other) -{ - while (first != last) - { - if (*first != *other) - return false; - ++first; - ++other; - } - return true; -} - -} - -} - -} // namespace boost::multiprecision::std_constexpr - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/default_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/default_ops.hpp deleted file mode 100644 index d959f56faa..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/default_ops.hpp +++ /dev/null @@ -1,4006 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011-21 John Maddock. -// Copyright 2021 Iskandarov Lev. 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) - -#ifndef BOOST_MP_DEFAULT_OPS -#define BOOST_MP_DEFAULT_OPS - -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/number_base.hpp> -#include <boost/multiprecision/detail/assert.hpp> -#include <boost/multiprecision/traits/is_backend.hpp> -#include <boost/multiprecision/detail/fpclassify.hpp> -#include <cstdint> -#include <complex> -#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW -#include <string_view> -#endif - -#ifdef BOOST_MP_MATH_AVAILABLE -#include <boost/math/special_functions/fpclassify.hpp> -#include <boost/math/special_functions/next.hpp> -#include <boost/math/special_functions/hypot.hpp> -#include <boost/math/policies/error_handling.hpp> -#endif - -#ifndef INSTRUMENT_BACKEND -#ifndef BOOST_MP_INSTRUMENT -#define INSTRUMENT_BACKEND(x) -#else -#define INSTRUMENT_BACKEND(x) \ - std::cout << BOOST_STRINGIZE(x) << " = " << x.str(0, std::ios_base::scientific) << std::endl; -#endif -#endif - -namespace boost { -namespace multiprecision { - -namespace detail { - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_floating_point>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/); -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_integer>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/); -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_floating_point>& /*to_type*/, const std::integral_constant<int, number_kind_floating_point>& /*from_type*/); -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_rational>& /*to_type*/, const std::integral_constant<int, number_kind_rational>& /*from_type*/); -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_rational>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/); - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR Integer karatsuba_sqrt(const Integer& x, Integer& r, size_t bits); - -} // namespace detail - -namespace default_ops { - -template <class T> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_backend<T>::value, int>::type eval_signbit(const T& val); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!boost::multiprecision::detail::is_backend<T>::value, int>::type eval_signbit(const T& val) { return val < 0; } - -inline int eval_signbit(float val) { return (std::signbit)(val); } -inline int eval_signbit(double val) { return (std::signbit)(val); } -inline int eval_signbit(long double val) { return (std::signbit)(val); } -#ifdef BOOST_HAS_FLOAT128 -extern "C" int signbitq(float128_type) throw(); -inline int eval_signbit(float128_type val) { return signbitq(val); } -#endif - -template <class T> -BOOST_MP_CXX14_CONSTEXPR bool eval_is_zero(const T& val); - -#ifdef BOOST_MSVC -// warning C4127: conditional expression is constant -// warning C4146: unary minus operator applied to unsigned type, result still unsigned -#pragma warning(push) -#pragma warning(disable : 4127 4146) -#endif -// -// Default versions of mixed arithmetic, these just construct a temporary -// from the arithmetic value and then do the arithmetic on that, two versions -// of each depending on whether the backend can be directly constructed from type V. -// -// Note that we have to provide *all* the template parameters to class number when used in -// enable_if as MSVC-10 won't compile the code if we rely on a computed-default parameter. -// Since the result of the test doesn't depend on whether expression templates are on or off -// we just use et_on everywhere. We could use a BOOST_WORKAROUND but that just obfuscates the -// code even more.... -// -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !std::is_convertible<V, T>::value>::type -eval_add(T& result, V const& v) -{ - T t; - t = v; - eval_add(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, T>::value>::type -eval_add(T& result, V const& v) -{ - T t(v); - eval_add(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !std::is_convertible<V, T>::value>::type -eval_subtract(T& result, V const& v) -{ - T t; - t = v; - eval_subtract(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, T>::value>::type -eval_subtract(T& result, V const& v) -{ - T t(v); - eval_subtract(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !std::is_convertible<V, T>::value>::type -eval_multiply(T& result, V const& v) -{ - T t; - t = v; - eval_multiply(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, T>::value>::type -eval_multiply(T& result, V const& v) -{ - T t(v); - eval_multiply(result, t); -} - -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_multiply(T& t, const U& u, const V& v); - -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(!std::is_same<T, U>::value && std::is_same<T, V>::value)>::type eval_multiply_add(T& t, const U& u, const V& v) -{ - T z; - eval_multiply(z, u, v); - eval_add(t, z); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!std::is_same<T, U>::value && std::is_same<T, V>::value>::type eval_multiply_add(T& t, const U& u, const V& v) -{ - eval_multiply_add(t, v, u); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(!std::is_same<T, U>::value && std::is_same<T, V>::value)>::type eval_multiply_subtract(T& t, const U& u, const V& v) -{ - T z; - eval_multiply(z, u, v); - eval_subtract(t, z); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!std::is_same<T, U>::value && std::is_same<T, V>::value>::type eval_multiply_subtract(T& t, const U& u, const V& v) -{ - eval_multiply_subtract(t, v, u); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && !std::is_convertible<V, T>::value>::type -eval_divide(T& result, V const& v) -{ - T t; - t = v; - eval_divide(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && std::is_convertible<V, T>::value>::type -eval_divide(T& result, V const& v) -{ - T t(v); - eval_divide(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && !std::is_convertible<V, T>::value>::type -eval_modulus(T& result, V const& v) -{ - T t; - t = v; - eval_modulus(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && std::is_convertible<V, T>::value>::type -eval_modulus(T& result, V const& v) -{ - T t(v); - eval_modulus(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && !std::is_convertible<V, T>::value>::type -eval_bitwise_and(T& result, V const& v) -{ - T t; - t = v; - eval_bitwise_and(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && std::is_convertible<V, T>::value>::type -eval_bitwise_and(T& result, V const& v) -{ - T t(v); - eval_bitwise_and(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && !std::is_convertible<V, T>::value>::type -eval_bitwise_or(T& result, V const& v) -{ - T t; - t = v; - eval_bitwise_or(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && std::is_convertible<V, T>::value>::type -eval_bitwise_or(T& result, V const& v) -{ - T t(v); - eval_bitwise_or(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && !std::is_convertible<V, T>::value>::type -eval_bitwise_xor(T& result, V const& v) -{ - T t; - t = v; - eval_bitwise_xor(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && std::is_convertible<V, T>::value>::type -eval_bitwise_xor(T& result, V const& v) -{ - T t(v); - eval_bitwise_xor(result, t); -} - -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && !std::is_convertible<V, T>::value>::type -eval_complement(T& result, V const& v) -{ - T t; - t = v; - eval_complement(result, t); -} -template <class T, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, number<T, et_on> >::value && std::is_convertible<V, T>::value>::type -eval_complement(T& result, V const& v) -{ - T t(v); - eval_complement(result, t); -} - -// -// Default versions of 3-arg arithmetic functions, these mostly just forward to the 2 arg versions: -// -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_add(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_add_default(T& t, const T& u, const T& v) -{ - if (&t == &v) - { - eval_add(t, u); - } - else if (&t == &u) - { - eval_add(t, v); - } - else - { - t = u; - eval_add(t, v); - } -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_add_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_add(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_add_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_add(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value>::type eval_add_default(T& t, const U& u, const T& v) -{ - eval_add(t, v, u); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_add_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - eval_add(t, u); - } - else - { - t = u; - eval_add(t, v); - } - } - else - { - t = u; - eval_add(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_add(T& t, const U& u, const V& v) -{ - eval_add_default(t, u, v); -} - -template <class T, class U, class V> -void BOOST_MP_CXX14_CONSTEXPR eval_subtract(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract_default(T& t, const T& u, const T& v) -{ - if ((&t == &v) && is_signed_number<T>::value) - { - eval_subtract(t, u); - t.negate(); - } - else if (&t == &u) - { - eval_subtract(t, v); - } - else - { - t = u; - eval_subtract(t, v); - } -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_subtract_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_subtract(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_subtract_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_subtract(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && is_signed_number<T>::value && (number_category<T>::value != number_kind_complex)>::type eval_subtract_default(T& t, const U& u, const T& v) -{ - eval_subtract(t, v, u); - if(!eval_is_zero(t) || (eval_signbit(u) != eval_signbit(v))) - t.negate(); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && is_signed_number<T>::value && (number_category<T>::value == number_kind_complex)>::type eval_subtract_default(T& t, const U& u, const T& v) -{ - eval_subtract(t, v, u); - t.negate(); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value && is_unsigned_number<T>::value>::type eval_subtract_default(T& t, const U& u, const T& v) -{ - T temp; - temp = u; - eval_subtract(t, temp, v); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value && is_unsigned_number<T>::value>::type eval_subtract_default(T& t, const U& u, const T& v) -{ - T temp(u); - eval_subtract(t, temp, v); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - eval_subtract(t, u); - t.negate(); - } - else - { - t = u; - eval_subtract(t, v); - } - } - else - { - t = u; - eval_subtract(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(T& t, const U& u, const V& v) -{ - eval_subtract_default(t, u, v); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply_default(T& t, const T& u, const T& v) -{ - if (&t == &v) - { - eval_multiply(t, u); - } - else if (&t == &u) - { - eval_multiply(t, v); - } - else - { - t = u; - eval_multiply(t, v); - } -} -#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900) -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_multiply_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_multiply(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_multiply_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_multiply(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value>::type eval_multiply_default(T& t, const U& u, const T& v) -{ - eval_multiply(t, v, u); -} -#endif -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - eval_multiply(t, u); - } - else - { - t = number<T>::canonical_value(u); - eval_multiply(t, v); - } - } - else - { - t = number<T>::canonical_value(u); - eval_multiply(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(T& t, const U& u, const V& v) -{ - eval_multiply_default(t, u, v); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply_add(T& t, const T& u, const T& v, const T& x) -{ - if ((void*)&x == (void*)&t) - { - T z; - z = number<T>::canonical_value(x); - eval_multiply_add(t, u, v, z); - } - else - { - eval_multiply(t, u, v); - eval_add(t, x); - } -} - -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !std::is_same<T, U>::value, T>::type make_T(const U& u) -{ - T t; - t = number<T>::canonical_value(u); - return t; -} -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR const T& make_T(const T& t) -{ - return t; -} - -template <class T, class U, class V, class X> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(!std::is_same<T, U>::value && std::is_same<T, V>::value)>::type eval_multiply_add(T& t, const U& u, const V& v, const X& x) -{ - eval_multiply_add(t, make_T<T>(u), make_T<T>(v), make_T<T>(x)); -} -template <class T, class U, class V, class X> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!std::is_same<T, U>::value && std::is_same<T, V>::value>::type eval_multiply_add(T& t, const U& u, const V& v, const X& x) -{ - eval_multiply_add(t, v, u, x); -} -template <class T, class U, class V, class X> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(!std::is_same<T, U>::value && std::is_same<T, V>::value)>::type eval_multiply_subtract(T& t, const U& u, const V& v, const X& x) -{ - if ((void*)&x == (void*)&t) - { - T z; - z = x; - eval_multiply_subtract(t, u, v, z); - } - else - { - eval_multiply(t, u, v); - eval_subtract(t, x); - } -} -template <class T, class U, class V, class X> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!std::is_same<T, U>::value && std::is_same<T, V>::value>::type eval_multiply_subtract(T& t, const U& u, const V& v, const X& x) -{ - eval_multiply_subtract(t, v, u, x); -} - -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_divide(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_divide_default(T& t, const T& u, const T& v) -{ - if (&t == &u) - eval_divide(t, v); - else if (&t == &v) - { - T temp; - eval_divide(temp, u, v); - temp.swap(t); - } - else - { - t = u; - eval_divide(t, v); - } -} -#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900) -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_divide_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_divide(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_divide_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_divide(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_divide_default(T& t, const U& u, const T& v) -{ - T uu; - uu = u; - eval_divide(t, uu, v); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_divide_default(T& t, const U& u, const T& v) -{ - T uu(u); - eval_divide(t, uu, v); -} -#endif -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_divide_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - T temp; - temp = u; - eval_divide(temp, v); - t = temp; - } - else - { - t = u; - eval_divide(t, v); - } - } - else - { - t = u; - eval_divide(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(T& t, const U& u, const V& v) -{ - eval_divide_default(t, u, v); -} - -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_modulus(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_modulus_default(T& t, const T& u, const T& v) -{ - if (&t == &u) - eval_modulus(t, v); - else if (&t == &v) - { - T temp; - eval_modulus(temp, u, v); - temp.swap(t); - } - else - { - t = u; - eval_modulus(t, v); - } -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_modulus_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_modulus(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_modulus_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_modulus(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_modulus_default(T& t, const U& u, const T& v) -{ - T uu; - uu = u; - eval_modulus(t, uu, v); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_modulus_default(T& t, const U& u, const T& v) -{ - T uu(u); - eval_modulus(t, uu, v); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_modulus_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - T temp(u); - eval_modulus(temp, v); - t = temp; - } - else - { - t = u; - eval_modulus(t, v); - } - } - else - { - t = u; - eval_modulus(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_modulus(T& t, const U& u, const V& v) -{ - eval_modulus_default(t, u, v); -} - -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_and(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_and_default(T& t, const T& u, const T& v) -{ - if (&t == &v) - { - eval_bitwise_and(t, u); - } - else if (&t == &u) - { - eval_bitwise_and(t, v); - } - else - { - t = u; - eval_bitwise_and(t, v); - } -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !std::is_convertible<U, T>::value>::type eval_bitwise_and_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_bitwise_and(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, T>::value>::type eval_bitwise_and_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_bitwise_and(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value>::type eval_bitwise_and_default(T& t, const U& u, const T& v) -{ - eval_bitwise_and(t, v, u); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!std::is_same<T, U>::value || std::is_same<T, V>::value>::type eval_bitwise_and_default(T& t, const U& u, const V& v) -{ - t = u; - eval_bitwise_and(t, v); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_and(T& t, const U& u, const V& v) -{ - eval_bitwise_and_default(t, u, v); -} - -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_or(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_or_default(T& t, const T& u, const T& v) -{ - if (&t == &v) - { - eval_bitwise_or(t, u); - } - else if (&t == &u) - { - eval_bitwise_or(t, v); - } - else - { - t = u; - eval_bitwise_or(t, v); - } -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_bitwise_or_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_bitwise_or(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_bitwise_or_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_bitwise_or(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value>::type eval_bitwise_or_default(T& t, const U& u, const T& v) -{ - eval_bitwise_or(t, v, u); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_or_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - eval_bitwise_or(t, u); - } - else - { - t = u; - eval_bitwise_or(t, v); - } - } - else - { - t = u; - eval_bitwise_or(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_or(T& t, const U& u, const V& v) -{ - eval_bitwise_or_default(t, u, v); -} - -template <class T, class U, class V> -BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_xor(T& t, const U& u, const V& v); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_xor_default(T& t, const T& u, const T& v) -{ - if (&t == &v) - { - eval_bitwise_xor(t, u); - } - else if (&t == &u) - { - eval_bitwise_xor(t, v); - } - else - { - t = u; - eval_bitwise_xor(t, v); - } -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && !std::is_convertible<U, T>::value>::type eval_bitwise_xor_default(T& t, const T& u, const U& v) -{ - T vv; - vv = v; - eval_bitwise_xor(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value && std::is_convertible<U, T>::value>::type eval_bitwise_xor_default(T& t, const T& u, const U& v) -{ - T vv(v); - eval_bitwise_xor(t, u, vv); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<U, number<T, et_on> >::value>::type eval_bitwise_xor_default(T& t, const U& u, const T& v) -{ - eval_bitwise_xor(t, v, u); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_xor_default(T& t, const U& u, const V& v) -{ - BOOST_IF_CONSTEXPR(std::is_same<T, V>::value) - { - if ((void*)&t == (void*)&v) - { - eval_bitwise_xor(t, u); - } - else - { - t = u; - eval_bitwise_xor(t, v); - } - } - else - { - t = u; - eval_bitwise_xor(t, v); - } -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_xor(T& t, const U& u, const V& v) -{ - eval_bitwise_xor_default(t, u, v); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_increment(T& val) -{ - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - eval_add(val, static_cast<ui_type>(1u)); -} -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_decrement(T& val) -{ - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - eval_subtract(val, static_cast<ui_type>(1u)); -} - -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_left_shift(T& result, const U& arg, const V val) -{ - result = arg; - eval_left_shift(result, val); -} - -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_right_shift(T& result, const U& arg, const V val) -{ - result = arg; - eval_right_shift(result, val); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_is_zero(const T& val) -{ - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - return val.compare(static_cast<ui_type>(0)) == 0; -} -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR int eval_get_sign(const T& val) -{ - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - return val.compare(static_cast<ui_type>(0)); -} - -template <class T, class V, class U> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components_imp2(T& result, const V& v1, const U& v2, const std::false_type&, const std::false_type&) -{ - using component_number_type = typename component_type<number<T> >::type; - - boost::multiprecision::detail::scoped_precision_options<component_number_type> sp(result); - (void)sp; - - component_number_type x(v1), y(v2); - assign_components(result, x.backend(), y.backend()); -} -template <class T, class V, class U> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components_imp2(T& result, const V& v1, const U& v2, const std::true_type&, const std::false_type&) -{ - boost::multiprecision::detail::scoped_source_precision<number<V>> scope; - (void)scope; - assign_components_imp2(result, number<V>(v1), v2, std::false_type(), std::false_type()); -} -template <class T, class V, class U> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components_imp2(T& result, const V& v1, const U& v2, const std::true_type&, const std::true_type&) -{ - boost::multiprecision::detail::scoped_source_precision<number<V>> scope1; - boost::multiprecision::detail::scoped_source_precision<number<U>> scope2; - (void)scope1; - (void)scope2; - assign_components_imp2(result, number<V>(v1), number<U>(v2), std::false_type(), std::false_type()); -} -template <class T, class V, class U> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components_imp2(T& result, const V& v1, const U& v2, const std::false_type&, const std::true_type&) -{ - boost::multiprecision::detail::scoped_source_precision<number<U>> scope; - (void)scope; - assign_components_imp2(result, v1, number<U>(v2), std::false_type(), std::false_type()); -} - - -template <class T, class V, class U> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components_imp(T& result, const V& v1, const U& v2, const std::integral_constant<int, number_kind_rational>&) -{ - result = v1; - T t; - t = v2; - eval_divide(result, t); -} - -template <class T, class V, class U, int N> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components_imp(T& result, const V& v1, const U& v2, const std::integral_constant<int, N>&) -{ - assign_components_imp2(result, v1, v2, boost::multiprecision::detail::is_backend<V>(), boost::multiprecision::detail::is_backend<U>()); -} - -template <class T, class V, class U> -inline BOOST_MP_CXX14_CONSTEXPR void assign_components(T& result, const V& v1, const U& v2) -{ - return assign_components_imp(result, v1, v2, typename number_category<T>::type()); -} -#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW -template <class Result, class Traits> -inline void assign_from_string_view(Result& result, const std::basic_string_view<char, Traits>& view) -{ - // since most (all?) backends require a const char* to construct from, we just - // convert to that: - std::string s(view); - result = s.c_str(); -} -template <class Result, class Traits> -inline void assign_from_string_view(Result& result, const std::basic_string_view<char, Traits>& view_x, const std::basic_string_view<char, Traits>& view_y) -{ - // since most (all?) backends require a const char* to construct from, we just - // convert to that: - std::string x(view_x), y(view_y); - assign_components(result, x.c_str(), y.c_str()); -} -#endif -template <class R, int b> -struct has_enough_bits -{ - template <class T> - struct type : public std::integral_constant<bool, !std::is_same<R, T>::value && (std::numeric_limits<T>::digits >= b)> - {}; -}; - -template <class R> -struct terminal -{ - BOOST_MP_CXX14_CONSTEXPR terminal(const R& v) : value(v) {} - BOOST_MP_CXX14_CONSTEXPR terminal() {} - BOOST_MP_CXX14_CONSTEXPR terminal& operator=(R val) - { - value = val; - return *this; - } - R value; - BOOST_MP_CXX14_CONSTEXPR operator R() const { return value; } -}; - -template <class Tuple, int i, class T, bool = (i == std::tuple_size<Tuple>::value)> -struct find_index_of_type -{ - static constexpr int value = - std::is_same<T, typename std::tuple_element<static_cast<std::size_t>(i), Tuple>::type>::value - ? i - : find_index_of_type<Tuple, i + 1, T>::value; -}; -template <class Tuple, int i, class T> -struct find_index_of_type<Tuple, i, T, true> -{ - static constexpr int value = -1; -}; - - -template <class R, class B> -struct calculate_next_larger_type -{ - // Find which list we're looking through: - using list_type = typename std::conditional< - boost::multiprecision::detail::is_signed<R>::value && boost::multiprecision::detail::is_integral<R>::value, - typename B::signed_types, - typename std::conditional< - boost::multiprecision::detail::is_unsigned<R>::value, - typename B::unsigned_types, - typename B::float_types>::type>::type; - static constexpr int start = find_index_of_type<list_type, 0, R>::value; - static constexpr int index_of_type = boost::multiprecision::detail::find_index_of_large_enough_type<list_type, start == INT_MAX ? 0 : start + 1, boost::multiprecision::detail::bits_of<R>::value> ::value; - using type = typename boost::multiprecision::detail::dereference_tuple<index_of_type, list_type, terminal<R> >::type; -}; - -template <class R, class T> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<R>::value, bool>::type check_in_range(const T& t) -{ - // Can t fit in an R? - if ((t > 0) && std::numeric_limits<R>::is_specialized && std::numeric_limits<R>::is_bounded && (t > (std::numeric_limits<R>::max)())) - return true; - else - return false; -} - -template <class R, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<R>::value>::type eval_convert_to(R* result, const B& backend) -{ - using next_type = typename calculate_next_larger_type<R, B>::type; - next_type n = next_type(); - eval_convert_to(&n, backend); - BOOST_IF_CONSTEXPR(!boost::multiprecision::detail::is_unsigned<R>::value && std::numeric_limits<R>::is_specialized && std::numeric_limits<R>::is_bounded) - { - if(n > static_cast<next_type>((std::numeric_limits<R>::max)())) - { - *result = (std::numeric_limits<R>::max)(); - return; - } - } - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_specialized&& std::numeric_limits<R>::is_bounded) - { - if (n < static_cast<next_type>((std::numeric_limits<R>::min)())) - { - *result = (std::numeric_limits<R>::min)(); - return; - } - } - *result = static_cast<R>(n); -} - -template <class R, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< !boost::multiprecision::detail::is_integral<R>::value && !std::is_enum<R>::value>::type eval_convert_to(R* result, const B& backend) -{ - using next_type = typename calculate_next_larger_type<R, B>::type; - next_type n = next_type(); - eval_convert_to(&n, backend); - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_specialized && std::numeric_limits<R>::is_bounded) - { - if ((n > (next_type)(std::numeric_limits<R>::max)() || (n < (next_type) - (std::numeric_limits<R>::max)()))) - { - *result = n > 0 ? (std::numeric_limits<R>::max)() : -(std::numeric_limits<R>::max)(); - } - else - *result = static_cast<R>(n); - } - else - *result = static_cast<R>(n); -} - -template <class R, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_enum<R>::value>::type eval_convert_to(R* result, const B& backend) -{ - typename std::underlying_type<R>::type t{}; - eval_convert_to(&t, backend); - *result = static_cast<R>(t); -} - -#ifndef BOOST_MP_STANDALONE -template <class R, class B> -inline void last_chance_eval_convert_to(terminal<R>* result, const B& backend, const std::integral_constant<bool, false>&) -{ - // - // We ran out of types to try for the conversion, try - // a lexical_cast and hope for the best: - // - BOOST_IF_CONSTEXPR (std::numeric_limits<R>::is_integer && !std::numeric_limits<R>::is_signed) - if (eval_get_sign(backend) < 0) - BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to convert negative value to an unsigned integer results in undefined behaviour")); - BOOST_MP_TRY { - result->value = boost::lexical_cast<R>(backend.str(0, std::ios_base::fmtflags(0))); - } - BOOST_MP_CATCH (const bad_lexical_cast&) - { - if (eval_get_sign(backend) < 0) - { - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_integer && !std::numeric_limits<R>::is_signed) - *result = (std::numeric_limits<R>::max)(); // we should never get here, exception above will be raised. - else BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_integer) - *result = (std::numeric_limits<R>::min)(); - else - *result = -(std::numeric_limits<R>::max)(); - } - else - *result = (std::numeric_limits<R>::max)(); - } - BOOST_MP_CATCH_END -} - -template <class R, class B> -inline void last_chance_eval_convert_to(terminal<R>* result, const B& backend, const std::integral_constant<bool, true>&) -{ - // - // Last chance conversion to an unsigned integer. - // We ran out of types to try for the conversion, try - // a lexical_cast and hope for the best: - // - if (eval_get_sign(backend) < 0) - BOOST_MP_THROW_EXCEPTION(std::range_error("Attempt to convert negative value to an unsigned integer results in undefined behaviour")); - BOOST_MP_TRY { - B t(backend); - R mask = ~static_cast<R>(0u); - eval_bitwise_and(t, mask); - result->value = boost::lexical_cast<R>(t.str(0, std::ios_base::fmtflags(0))); - } - BOOST_MP_CATCH (const bad_lexical_cast&) - { - // We should never really get here... - *result = (std::numeric_limits<R>::max)(); - } - BOOST_MP_CATCH_END -} -#else // Using standalone mode - -template <class R, class B> -inline void last_chance_eval_convert_to(terminal<R>*, const B&, const std::integral_constant<bool, false>&) -{ - static_assert(sizeof(R) == 1, "This type can not be used in standalone mode. Please de-activate and file a bug at https://github.com/boostorg/multiprecision/"); -} - -template <class R, class B> -inline void last_chance_eval_convert_to(terminal<R>* result, const B& backend, const std::integral_constant<bool, true>&) -{ - static_cast<void>(result); - static_cast<void>(backend); - - static_assert(sizeof(R) == 1, "This type can not be used in standalone mode. Please de-activate and file a bug at https://github.com/boostorg/multiprecision/"); -} -#endif - -template <class R, class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(terminal<R>* result, const B& backend) -{ - using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_unsigned<R>::value && number_category<B>::value == number_kind_integer>; - last_chance_eval_convert_to(result, backend, tag_type()); -} - -template <class B1, class B2, expression_template_option et> -inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(terminal<number<B1, et> >* result, const B2& backend) -{ - // - // We ran out of types to try for the conversion, try - // a generic conversion and hope for the best: - // - boost::multiprecision::detail::generic_interconvert(result->value.backend(), backend, number_category<B1>(), number_category<B2>()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(std::string* result, const B& backend) -{ - *result = backend.str(0, std::ios_base::fmtflags(0)); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(std::complex<float>* result, const B& backend) -{ - using scalar_type = typename scalar_result_from_possible_complex<multiprecision::number<B> >::type; - scalar_type re, im; - eval_real(re.backend(), backend); - eval_imag(im.backend(), backend); - - *result = std::complex<float>(re.template convert_to<float>(), im.template convert_to<float>()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(std::complex<double>* result, const B& backend) -{ - using scalar_type = typename scalar_result_from_possible_complex<multiprecision::number<B> >::type; - scalar_type re, im; - eval_real(re.backend(), backend); - eval_imag(im.backend(), backend); - - *result = std::complex<double>(re.template convert_to<double>(), im.template convert_to<double>()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(std::complex<long double>* result, const B& backend) -{ - using scalar_type = typename scalar_result_from_possible_complex<multiprecision::number<B> >::type; - scalar_type re, im; - eval_real(re.backend(), backend); - eval_imag(im.backend(), backend); - - *result = std::complex<long double>(re.template convert_to<long double>(), im.template convert_to<long double>()); -} - -// -// Functions: -// -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR void eval_abs(T& result, const U& arg) -{ - using type_list = typename U::signed_types ; - using front = typename std::tuple_element<0, type_list>::type; - result = arg; - if (arg.compare(front(0)) < 0) - result.negate(); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR void eval_fabs(T& result, const U& arg) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The fabs function is only valid for floating point types."); - using type_list = typename U::signed_types ; - using front = typename std::tuple_element<0, type_list>::type; - result = arg; - if (arg.compare(front(0)) < 0) - result.negate(); -} - -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR int eval_fpclassify(const Backend& arg) -{ - static_assert(number_category<Backend>::value == number_kind_floating_point, "The fpclassify function is only valid for floating point types."); - return eval_is_zero(arg) ? FP_ZERO : FP_NORMAL; -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_fmod(T& result, const T& a, const T& b) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The fmod function is only valid for floating point types."); - if ((&result == &a) || (&result == &b)) - { - T temp; - eval_fmod(temp, a, b); - result = temp; - return; - } - switch (eval_fpclassify(a)) - { - case FP_ZERO: - result = a; - return; - case FP_INFINITE: - case FP_NAN: - result = std::numeric_limits<number<T> >::quiet_NaN().backend(); - errno = EDOM; - return; - } - switch (eval_fpclassify(b)) - { - case FP_ZERO: - case FP_NAN: - result = std::numeric_limits<number<T> >::quiet_NaN().backend(); - errno = EDOM; - return; - } - T n; - eval_divide(result, a, b); - if (eval_get_sign(result) < 0) - eval_ceil(n, result); - else - eval_floor(n, result); - eval_multiply(n, b); - eval_subtract(result, a, n); -} -template <class T, class A> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_fmod(T& result, const T& x, const A& a) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c; - c = a; - eval_fmod(result, x, c); -} - -template <class T, class A> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_fmod(T& result, const A& x, const T& a) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c; - c = x; - eval_fmod(result, c, a); -} - -template <class T> -BOOST_MP_CXX14_CONSTEXPR void eval_round(T& result, const T& a); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_remquo(T& result, const T& a, const T& b, int* pi) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The remquo function is only valid for floating point types."); - if ((&result == &a) || (&result == &b)) - { - T temp; - eval_remquo(temp, a, b, pi); - result = temp; - return; - } - T n; - eval_divide(result, a, b); - eval_round(n, result); - eval_convert_to(pi, n); - eval_multiply(n, b); - eval_subtract(result, a, n); - if (eval_is_zero(result)) - { - if (eval_signbit(a)) - result.negate(); - } -} -template <class T, class A> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_remquo(T& result, const T& x, const A& a, int* pi) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c = cast_type(); - c = a; - eval_remquo(result, x, c, pi); -} -template <class T, class A> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_remquo(T& result, const A& x, const T& a, int* pi) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c = cast_type(); - c = x; - eval_remquo(result, c, a, pi); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_remainder(T& result, const U& a, const V& b) -{ - int i(0); - eval_remquo(result, a, b, &i); -} - -template <class B> -BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const B& a, const B& b); -template <class T, class U> -BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const T& a, const U& b); -template <class B> -BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const B& a, const B& b); -template <class T, class U> -BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const T& a, const U& b); - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_fdim(T& result, const T& a, const T& b) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - const ui_type zero = 0u; - switch (eval_fpclassify(b)) - { - case FP_NAN: - case FP_INFINITE: - result = zero; - return; - } - switch (eval_fpclassify(a)) - { - case FP_NAN: - result = zero; - return; - case FP_INFINITE: - result = a; - return; - } - if (eval_gt(a, b)) - { - eval_subtract(result, a, b); - } - else - result = zero; -} - -template <class T, class A> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value>::type eval_fdim(T& result, const T& a, const A& b) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - using arithmetic_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - const ui_type zero = 0u; - arithmetic_type canonical_b = b; - switch (BOOST_MP_FPCLASSIFY(b)) - { - case FP_NAN: - case FP_INFINITE: - result = zero; - return; - } - switch (eval_fpclassify(a)) - { - case FP_NAN: - result = zero; - return; - case FP_INFINITE: - result = a; - return; - } - if (eval_gt(a, canonical_b)) - { - eval_subtract(result, a, canonical_b); - } - else - result = zero; -} - -template <class T, class A> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value>::type eval_fdim(T& result, const A& a, const T& b) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - using arithmetic_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - const ui_type zero = 0u; - arithmetic_type canonical_a = a; - switch (eval_fpclassify(b)) - { - case FP_NAN: - case FP_INFINITE: - result = zero; - return; - } - switch (BOOST_MP_FPCLASSIFY(a)) - { - case FP_NAN: - result = zero; - return; - case FP_INFINITE: - result = std::numeric_limits<number<T> >::infinity().backend(); - return; - } - if (eval_gt(canonical_a, b)) - { - eval_subtract(result, canonical_a, b); - } - else - result = zero; -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_trunc(T& result, const T& a) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The trunc function is only valid for floating point types."); - switch (eval_fpclassify(a)) - { - case FP_NAN: - errno = EDOM; - // fallthrough... - case FP_ZERO: - case FP_INFINITE: - result = a; - return; - } - if (eval_get_sign(a) < 0) - eval_ceil(result, a); - else - eval_floor(result, a); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_modf(T& result, T const& arg, T* pipart) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - int c = eval_fpclassify(arg); - if (c == static_cast<int>(FP_NAN)) - { - if (pipart) - *pipart = arg; - result = arg; - return; - } - else if (c == static_cast<int>(FP_INFINITE)) - { - if (pipart) - *pipart = arg; - result = ui_type(0u); - return; - } - if (pipart) - { - eval_trunc(*pipart, arg); - eval_subtract(result, arg, *pipart); - } - else - { - T ipart; - eval_trunc(ipart, arg); - eval_subtract(result, arg, ipart); - } -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_round(T& result, const T& a) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The round function is only valid for floating point types."); - using fp_type = typename boost::multiprecision::detail::canonical<float, T>::type; - int c = eval_fpclassify(a); - if (c == static_cast<int>(FP_NAN)) - { - result = a; - errno = EDOM; - return; - } - if ((c == FP_ZERO) || (c == static_cast<int>(FP_INFINITE))) - { - result = a; - } - else if (eval_get_sign(a) < 0) - { - eval_subtract(result, a, fp_type(0.5f)); - eval_ceil(result, result); - } - else - { - eval_add(result, a, fp_type(0.5f)); - eval_floor(result, result); - } -} - -template <class B> -BOOST_MP_CXX14_CONSTEXPR void eval_lcm(B& result, const B& a, const B& b); -template <class B> -BOOST_MP_CXX14_CONSTEXPR void eval_gcd(B& result, const B& a, const B& b); - -template <class T, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Arithmetic>::value >::type eval_gcd(T& result, const T& a, const Arithmetic& b) -{ - using si_type = typename boost::multiprecision::detail::canonical<Arithmetic, T>::type; - using default_ops::eval_gcd; - T t; - t = static_cast<si_type>(b); - eval_gcd(result, a, t); -} -template <class T, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Arithmetic>::value >::type eval_gcd(T& result, const Arithmetic& a, const T& b) -{ - eval_gcd(result, b, a); -} -template <class T, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Arithmetic>::value >::type eval_lcm(T& result, const T& a, const Arithmetic& b) -{ - using si_type = typename boost::multiprecision::detail::canonical<Arithmetic, T>::type; - using default_ops::eval_lcm; - T t; - t = static_cast<si_type>(b); - eval_lcm(result, a, t); -} -template <class T, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Arithmetic>::value >::type eval_lcm(T& result, const Arithmetic& a, const T& b) -{ - eval_lcm(result, b, a); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t eval_lsb(const T& val) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - int c = eval_get_sign(val); - if (c == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - if (c < 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - std::size_t result = 0; - T mask, t; - mask = ui_type(1); - do - { - eval_bitwise_and(t, mask, val); - ++result; - eval_left_shift(mask, 1); - } while (eval_is_zero(t)); - - return --result; -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR std::ptrdiff_t eval_msb(const T& val) -{ - int c = eval_get_sign(val); - if (c == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - if (c < 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - // - // This implementation is really really rubbish - it does - // a linear scan for the most-significant-bit. We should really - // do a binary search, but as none of our backends actually needs - // this implementation, we'll leave it for now. In fact for most - // backends it's likely that there will always be a more efficient - // native implementation possible. - // - std::size_t result = 0; - T t(val); - while (!eval_is_zero(t)) - { - eval_right_shift(t, 1); - ++result; - } - --result; - - return static_cast<std::ptrdiff_t>(result); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_bit_test(const T& val, std::size_t index) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - T mask, t; - mask = ui_type(1); - eval_left_shift(mask, index); - eval_bitwise_and(t, mask, val); - return !eval_is_zero(t); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bit_set(T& val, std::size_t index) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - T mask; - mask = ui_type(1); - eval_left_shift(mask, index); - eval_bitwise_or(val, mask); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bit_flip(T& val, std::size_t index) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - T mask; - mask = ui_type(1); - eval_left_shift(mask, index); - eval_bitwise_xor(val, mask); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_bit_unset(T& val, std::size_t index) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - T mask, t; - mask = ui_type(1); - eval_left_shift(mask, index); - eval_bitwise_and(t, mask, val); - if (!eval_is_zero(t)) - eval_bitwise_xor(val, mask); -} - -template <class Backend> -BOOST_MP_CXX14_CONSTEXPR void eval_qr(const Backend& x, const Backend& y, Backend& q, Backend& r); - -template <class Backend> -BOOST_MP_CXX14_CONSTEXPR void eval_karatsuba_sqrt(Backend& result, const Backend& x, Backend& r, Backend& t, size_t bits) -{ - using default_ops::eval_is_zero; - using default_ops::eval_subtract; - using default_ops::eval_right_shift; - using default_ops::eval_left_shift; - using default_ops::eval_bit_set; - using default_ops::eval_decrement; - using default_ops::eval_bitwise_and; - using default_ops::eval_add; - using default_ops::eval_qr; - - using small_uint = typename std::tuple_element<0, typename Backend::unsigned_types>::type; - - constexpr small_uint zero = 0u; - - // we can calculate it faster with std::sqrt -#ifdef BOOST_HAS_INT128 - if (bits <= 128) - { - uint128_type a{}, b{}, c{}; - eval_convert_to(&a, x); - c = boost::multiprecision::detail::karatsuba_sqrt(a, b, bits); - r = number<Backend>::canonical_value(b); - result = number<Backend>::canonical_value(c); - return; - } -#else - if (bits <= std::numeric_limits<std::uintmax_t>::digits) - { - std::uintmax_t a{ 0 }, b{ 0 }, c{ 0 }; - eval_convert_to(&a, x); - c = boost::multiprecision::detail::karatsuba_sqrt(a, b, bits); - r = number<Backend>::canonical_value(b); - result = number<Backend>::canonical_value(c); - return; - } -#endif - // https://hal.inria.fr/file/index/docid/72854/filename/RR-3805.pdf - std::size_t b = bits / 4; - Backend q(x); - eval_right_shift(q, b * 2); - Backend s; - eval_karatsuba_sqrt(s, q, r, t, bits - b * 2); - t = zero; - eval_bit_set(t, static_cast<unsigned>(b * 2)); - eval_left_shift(r, b); - eval_decrement(t); - eval_bitwise_and(t, x); - eval_right_shift(t, b); - eval_add(t, r); - eval_left_shift(s, 1u); - eval_qr(t, s, q, r); - eval_left_shift(r, b); - t = zero; - eval_bit_set(t, static_cast<unsigned>(b)); - eval_decrement(t); - eval_bitwise_and(t, x); - eval_add(r, t); - eval_left_shift(s, b - 1); - eval_add(s, q); - eval_multiply(q, q); - // we substract after, so it works for unsigned integers too - if (r.compare(q) < 0) - { - t = s; - eval_left_shift(t, 1u); - eval_decrement(t); - eval_add(r, t); - eval_decrement(s); - } - eval_subtract(r, q); - result = s; -} - -template <class B> -void BOOST_MP_CXX14_CONSTEXPR eval_integer_sqrt_bitwise(B& s, B& r, const B& x) -{ - // - // This is slow bit-by-bit integer square root, see for example - // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 - // There are better methods such as http://hal.inria.fr/docs/00/07/28/54/PDF/RR-3805.pdf - // and http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf which should be implemented - // at some point. - // - using ui_type = typename boost::multiprecision::detail::canonical<unsigned char, B>::type; - - s = ui_type(0u); - if (eval_get_sign(x) == 0) - { - r = ui_type(0u); - return; - } - std::ptrdiff_t g = static_cast<std::ptrdiff_t>(eval_msb(x)); - if (g <= 1) - { - s = ui_type(1); - eval_subtract(r, x, s); - return; - } - - B t; - r = x; - g /= 2; - std::ptrdiff_t org_g = g; - eval_bit_set(s, static_cast<std::size_t>(g)); - eval_bit_set(t, static_cast<std::size_t>(2 * g)); - eval_subtract(r, x, t); - --g; - if (eval_get_sign(r) == 0) - return; - std::ptrdiff_t msbr = static_cast<std::ptrdiff_t>(eval_msb(r)); - do - { - if (msbr >= org_g + g + 1) - { - t = s; - eval_left_shift(t, static_cast<std::size_t>(g + 1)); - eval_bit_set(t, static_cast<std::size_t>(2 * g)); - if (t.compare(r) <= 0) - { - BOOST_MP_ASSERT(g >= 0); - eval_bit_set(s, static_cast<std::size_t>(g)); - eval_subtract(r, t); - if (eval_get_sign(r) == 0) - return; - msbr = static_cast<std::ptrdiff_t>(eval_msb(r)); - } - } - --g; - } while (g >= 0); -} - -template <class Backend> -BOOST_MP_CXX14_CONSTEXPR void eval_integer_sqrt(Backend& result, Backend& r, const Backend& x) -{ -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - // recursive Karatsuba sqrt can cause issues in constexpr context: - if (BOOST_MP_IS_CONST_EVALUATED(result.size())) - return eval_integer_sqrt_bitwise(result, r, x); -#endif - using small_uint = typename std::tuple_element<0, typename Backend::unsigned_types>::type; - - constexpr small_uint zero = 0u; - - if (eval_is_zero(x)) - { - r = zero; - result = zero; - return; - } - Backend t; - eval_karatsuba_sqrt(result, x, r, t, eval_msb(x) + 1); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_conj(B& result, const B& val) -{ - result = val; // assume non-complex result. -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_proj(B& result, const B& val) -{ - result = val; // assume non-complex result. -} - -// -// These have to implemented by the backend, declared here so that our macro generated code compiles OK. -// -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_floor(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_ceil(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_trunc(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_sqrt(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_ldexp(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_frexp(); -// TODO implement default versions of these: -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_asinh(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_acosh(); -template <class T> -typename std::enable_if<sizeof(T) == 0>::type eval_atanh(); - -// -// eval_logb and eval_scalbn simply assume base 2 and forward to -// eval_ldexp and eval_frexp: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename B::exponent_type eval_ilogb(const B& val) -{ - static_assert(!std::numeric_limits<number<B> >::is_specialized || (std::numeric_limits<number<B> >::radix == 2), "The default implementation of ilogb requires a base 2 number type"); - typename B::exponent_type e(0); - switch (eval_fpclassify(val)) - { - case FP_NAN: -#ifdef FP_ILOGBNAN - return FP_ILOGBNAN > 0 ? (std::numeric_limits<typename B::exponent_type>::max)() : (std::numeric_limits<typename B::exponent_type>::min)(); -#else - return (std::numeric_limits<typename B::exponent_type>::max)(); -#endif - case FP_INFINITE: - return (std::numeric_limits<typename B::exponent_type>::max)(); - case FP_ZERO: - return (std::numeric_limits<typename B::exponent_type>::min)(); - } - B result; - eval_frexp(result, val, &e); - return e - 1; -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_logb(B& result, const B& val) -{ - switch (eval_fpclassify(val)) - { - case FP_NAN: - result = val; - errno = EDOM; - return; - case FP_ZERO: - result = std::numeric_limits<number<B> >::infinity().backend(); - result.negate(); - errno = ERANGE; - return; - case FP_INFINITE: - result = val; - if (eval_signbit(val)) - result.negate(); - return; - } - using max_t = typename std::conditional<std::is_same<std::intmax_t, long>::value, long long, std::intmax_t>::type; - result = static_cast<max_t>(eval_ilogb(val)); -} -template <class B, class A> -inline BOOST_MP_CXX14_CONSTEXPR void eval_scalbn(B& result, const B& val, A e) -{ - static_assert(!std::numeric_limits<number<B> >::is_specialized || (std::numeric_limits<number<B> >::radix == 2), "The default implementation of scalbn requires a base 2 number type"); - eval_ldexp(result, val, static_cast<typename B::exponent_type>(e)); -} -template <class B, class A> -inline BOOST_MP_CXX14_CONSTEXPR void eval_scalbln(B& result, const B& val, A e) -{ - eval_scalbn(result, val, e); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR bool is_arg_nan(const T& val, std::integral_constant<bool, true> const&, const std::integral_constant<bool, false>&) -{ - return eval_fpclassify(val) == FP_NAN; -} -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR bool is_arg_nan(const T& val, std::integral_constant<bool, false> const&, const std::integral_constant<bool, true>&) -{ - return BOOST_MP_ISNAN(val); -} -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR bool is_arg_nan(const T&, std::integral_constant<bool, false> const&, const std::integral_constant<bool, false>&) -{ - return false; -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR bool is_arg_nan(const T& val) -{ - return is_arg_nan(val, std::integral_constant<bool, boost::multiprecision::detail::is_backend<T>::value>(), std::is_floating_point<T>()); -} - -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_fmax(T& result, const U& a, const V& b) -{ - if (is_arg_nan(a)) - result = number<T>::canonical_value(b); - else if (is_arg_nan(b)) - result = number<T>::canonical_value(a); - else if (eval_lt(number<T>::canonical_value(a), number<T>::canonical_value(b))) - result = number<T>::canonical_value(b); - else - result = number<T>::canonical_value(a); -} -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR void eval_fmin(T& result, const U& a, const V& b) -{ - if (is_arg_nan(a)) - result = number<T>::canonical_value(b); - else if (is_arg_nan(b)) - result = number<T>::canonical_value(a); - else if (eval_lt(number<T>::canonical_value(a), number<T>::canonical_value(b))) - result = number<T>::canonical_value(a); - else - result = number<T>::canonical_value(b); -} - -template <class R, class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR void eval_hypot(R& result, const T& a, const U& b) -{ - // - // Normalize x and y, so that both are positive and x >= y: - // - R x, y; - x = number<R>::canonical_value(a); - y = number<R>::canonical_value(b); - if (eval_get_sign(x) < 0) - x.negate(); - if (eval_get_sign(y) < 0) - y.negate(); - - // Special case, see C99 Annex F. - // The order of the if's is important: do not change! - int c1 = eval_fpclassify(x); - int c2 = eval_fpclassify(y); - - if (c1 == FP_ZERO) - { - result = y; - return; - } - if (c2 == FP_ZERO) - { - result = x; - return; - } - if (c1 == FP_INFINITE) - { - result = x; - return; - } - if ((c2 == FP_INFINITE) || (c2 == FP_NAN)) - { - result = y; - return; - } - if (c1 == FP_NAN) - { - result = x; - return; - } - - if (eval_gt(y, x)) - x.swap(y); - - eval_multiply(result, x, std::numeric_limits<number<R> >::epsilon().backend()); - - if (eval_gt(result, y)) - { - result = x; - return; - } - - R rat; - eval_divide(rat, y, x); - eval_multiply(result, rat, rat); - eval_increment(result); - eval_sqrt(rat, result); - eval_multiply(result, rat, x); -} - -template <class R, class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_nearbyint(R& result, const T& a) -{ - eval_round(result, a); -} -template <class R, class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_rint(R& result, const T& a) -{ - eval_nearbyint(result, a); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_backend<T>::value, int>::type eval_signbit(const T& val) -{ - return eval_get_sign(val) < 0 ? 1 : 0; -} - -// -// Real and imaginary parts: -// -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR void eval_real(To& to, const From& from) -{ - to = from; -} -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR void eval_imag(To& to, const From&) -{ - using ui_type = typename std::tuple_element<0, typename To::unsigned_types>::type; - to = ui_type(0); -} - -} // namespace default_ops -namespace default_ops_adl { - -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real_imp(To& to, const From& from) -{ - using to_component_type = typename component_type<number<To> >::type; - typename to_component_type::backend_type to_component; - to_component = from; - eval_set_real(to, to_component); -} -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag_imp(To& to, const From& from) -{ - using to_component_type = typename component_type<number<To> >::type; - typename to_component_type::backend_type to_component; - to_component = from; - eval_set_imag(to, to_component); -} - -} // namespace default_ops_adl -namespace default_ops { - -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<To>::value == number_kind_complex>::type eval_set_real(To& to, const From& from) -{ - default_ops_adl::eval_set_real_imp(to, from); -} -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<To>::value != number_kind_complex>::type eval_set_real(To& to, const From& from) -{ - to = from; -} - -template <class To, class From> -inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(To& to, const From& from) -{ - default_ops_adl::eval_set_imag_imp(to, from); -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(T& to, const T& from) -{ - to = from; -} -template <class T> -void BOOST_MP_CXX14_CONSTEXPR eval_set_imag(T&, const T&) -{ - static_assert(sizeof(T) == INT_MAX, "eval_set_imag needs to be specialised for each specific backend"); -} - -// -// These functions are implemented in separate files, but expanded inline here, -// DO NOT CHANGE THE ORDER OF THESE INCLUDES: -// -#include <boost/multiprecision/detail/functions/constants.hpp> -#include <boost/multiprecision/detail/functions/pow.hpp> -#include <boost/multiprecision/detail/functions/trig.hpp> - -} // namespace default_ops - -// -// Default versions of floating point classification routines: -// -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - using multiprecision::default_ops::eval_fpclassify; - return eval_fpclassify(arg.backend()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - int v = fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(arg); - return (v != static_cast<int>(FP_INFINITE)) && (v != static_cast<int>(FP_NAN)); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(arg) == static_cast<int>(FP_NAN); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return isnan BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(arg) == static_cast<int>(FP_INFINITE); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return isinf BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(arg) == static_cast<int>(FP_NORMAL); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} - -// Default versions of sign manipulation functions, if individual backends can do better than this -// (for example with signed zero), then they should overload these functions further: - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR int sign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return arg.sign(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR int sign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return sign BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - using default_ops::eval_signbit; - return static_cast<bool>(eval_signbit(arg.backend())); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return static_cast<bool>(signbit BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg))); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> changesign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return -arg; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type changesign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return changesign BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& a, const multiprecision::number<Backend, ExpressionTemplates>& b) -{ - return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? (boost::multiprecision::changesign)(a) : a; -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& a, const multiprecision::detail::expression<tag, A1, A2, A3, A4>& b) -{ - return copysign BOOST_PREVENT_MACRO_SUBSTITUTION(a, multiprecision::number<Backend, ExpressionTemplates>(b)); -} -template <class tag, class A1, class A2, class A3, class A4, class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& a, const multiprecision::number<Backend, ExpressionTemplates>& b) -{ - return copysign BOOST_PREVENT_MACRO_SUBSTITUTION(multiprecision::number<Backend, ExpressionTemplates>(a), b); -} -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& a, const multiprecision::detail::expression<tagb, A1b, A2b, A3b, A4b>& b) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return copysign BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(a), value_type(b)); -} -// -// real and imag: -// -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type -real(const multiprecision::number<Backend, ExpressionTemplates>& a) -{ - using default_ops::eval_real; - using result_type = typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type; - boost::multiprecision::detail::scoped_default_precision<result_type> precision_guard(a); - result_type result; - eval_real(result.backend(), a.backend()); - return result; -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type -imag(const multiprecision::number<Backend, ExpressionTemplates>& a) -{ - using default_ops::eval_imag; - using result_type = typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type; - boost::multiprecision::detail::scoped_default_precision<result_type> precision_guard(a); - result_type result; - eval_imag(result.backend(), a.backend()); - return result; -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type -real(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return real(value_type(arg)); -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type -imag(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return imag(value_type(arg)); -} - -// -// Complex number functions, these are overloaded at the Backend level, we just provide the -// expression template versions here, plus overloads for non-complex types: -// -#ifdef BOOST_MP_MATH_AVAILABLE -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_complex, component_type<number<T, ExpressionTemplates>>>::type::type -abs(const number<T, ExpressionTemplates>& v) -{ - return std::move(boost::math::hypot(real(v), imag(v))); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_complex, component_type<typename detail::expression<tag, A1, A2, A3, A4>::result_type>>::type::type -abs(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(abs(static_cast<number_type>(v))); -} - -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_complex, typename scalar_result_from_possible_complex<number<T, ExpressionTemplates> >::type>::type -arg(const number<T, ExpressionTemplates>& v) -{ - return std::move(atan2(imag(v), real(v))); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, typename scalar_result_from_possible_complex<number<T, ExpressionTemplates> >::type>::type -arg(const number<T, ExpressionTemplates>&) -{ - return 0; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_complex || number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename scalar_result_from_possible_complex<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type>::type -arg(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(arg(static_cast<number_type>(v))); -} -#endif // BOOST_MP_MATH_AVAILABLE - -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_complex, component_type<number<T, ExpressionTemplates>>>::type::type -norm(const number<T, ExpressionTemplates>& v) -{ - typename component_type<number<T, ExpressionTemplates> >::type a(real(v)), b(imag(v)); - return std::move(a * a + b * b); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value != number_kind_complex, typename scalar_result_from_possible_complex<number<T, ExpressionTemplates> >::type>::type -norm(const number<T, ExpressionTemplates>& v) -{ - return v * v; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -norm(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(norm(static_cast<number_type>(v))); -} - -template <class Backend, expression_template_option ExpressionTemplates> -BOOST_MP_CXX14_CONSTEXPR typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type polar(number<Backend, ExpressionTemplates> const& r, number<Backend, ExpressionTemplates> const& theta) -{ - return typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type(number<Backend, ExpressionTemplates>(r * cos(theta)), number<Backend, ExpressionTemplates>(r * sin(theta))); -} - -template <class tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_same<typename detail::expression<tag, A1, A2, A3, A4>::result_type, number<Backend, ExpressionTemplates> >::value, - typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type>::type -polar(detail::expression<tag, A1, A2, A3, A4> const& r, number<Backend, ExpressionTemplates> const& theta) -{ - return typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type(number<Backend, ExpressionTemplates>(r * cos(theta)), number<Backend, ExpressionTemplates>(r * sin(theta))); -} - -template <class Backend, expression_template_option ExpressionTemplates, class tag, class A1, class A2, class A3, class A4> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_same<typename detail::expression<tag, A1, A2, A3, A4>::result_type, number<Backend, ExpressionTemplates> >::value, - typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type>::type -polar(number<Backend, ExpressionTemplates> const& r, detail::expression<tag, A1, A2, A3, A4> const& theta) -{ - return typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type(number<Backend, ExpressionTemplates>(r * cos(theta)), number<Backend, ExpressionTemplates>(r * sin(theta))); -} - -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_same<typename detail::expression<tag, A1, A2, A3, A4>::result_type, typename detail::expression<tagb, A1b, A2b, A3b, A4b>::result_type>::value, - typename complex_result_from_scalar<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type>::type -polar(detail::expression<tag, A1, A2, A3, A4> const& r, detail::expression<tagb, A1b, A2b, A3b, A4b> const& theta) -{ - using scalar_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return typename complex_result_from_scalar<scalar_type>::type(scalar_type(r * cos(theta)), scalar_type(r * sin(theta))); -} -// -// We also allow the first argument to polar to be an arithmetic type (probably a literal): -// -template <class Scalar, class Backend, expression_template_option ExpressionTemplates> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<Scalar>::value, typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type>::type -polar(Scalar const& r, number<Backend, ExpressionTemplates> const& theta) -{ - return typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type(number<Backend, ExpressionTemplates>(r * cos(theta)), number<Backend, ExpressionTemplates>(r * sin(theta))); -} - -template <class tag, class A1, class A2, class A3, class A4, class Scalar> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<Scalar>::value, - typename complex_result_from_scalar<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type>::type -polar(Scalar const& r, detail::expression<tag, A1, A2, A3, A4> const& theta) -{ - using scalar_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return typename complex_result_from_scalar<scalar_type>::type(scalar_type(r * cos(theta)), scalar_type(r * sin(theta))); -} -// -// Single argument overloads: -// -template <class Backend, expression_template_option ExpressionTemplates> -BOOST_MP_CXX14_CONSTEXPR typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type polar(number<Backend, ExpressionTemplates> const& r) -{ - return typename complex_result_from_scalar<number<Backend, ExpressionTemplates> >::type(r); -} - -template <class tag, class A1, class A2, class A3, class A4> -BOOST_MP_CXX14_CONSTEXPR typename complex_result_from_scalar<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -polar(detail::expression<tag, A1, A2, A3, A4> const& r) -{ - return typename complex_result_from_scalar<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type(r); -} - -} // namespace multiprecision - -namespace math { - -// -// Import Math functions here, so they can be found by Boost.Math: -// -using boost::multiprecision::changesign; -using boost::multiprecision::copysign; -using boost::multiprecision::fpclassify; -using boost::multiprecision::isfinite; -using boost::multiprecision::isinf; -using boost::multiprecision::isnan; -using boost::multiprecision::isnormal; -using boost::multiprecision::sign; -using boost::multiprecision::signbit; - -#ifndef BOOST_MP_MATH_AVAILABLE -namespace policies { - -template <typename... Args> -class policy {}; - -template <typename T1, typename T2, typename T3, typename T4, typename T5> -void raise_rounding_error(T1, T2, T3, T4, T5) -{ - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Rounding error")); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5> -void raise_overflow_error(T1, T2, T3, T4, T5) -{ - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Overflow error")); -} - -template <typename T1, typename T2, typename T3, typename T4, typename T5> -void raise_evaluation_error(T1, T2, T3, T4, T5) -{ - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Evaluation error")); -} - -template <typename T, typename... Args> -struct is_policy -{ - static constexpr bool value = false; -}; - -template <typename... Args> -struct is_policy<policy<Args...>> -{ - static constexpr bool value = true; -}; - -} // namespace policies -#endif - -} // namespace math - -namespace multiprecision { -#ifdef BOOST_MP_MATH_AVAILABLE -using c99_error_policy = ::boost::math::policies::policy< - ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>, - ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>, - ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>, - ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>, - ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error> >; - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value != number_kind_complex, multiprecision::number<Backend, ExpressionTemplates> >::type - asinh - BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::asinh(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex, typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type - asinh - BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return asinh(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value != number_kind_complex, multiprecision::number<Backend, ExpressionTemplates> >::type - acosh - BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::acosh(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex, typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type - acosh - BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return acosh(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value != number_kind_complex, multiprecision::number<Backend, ExpressionTemplates> >::type - atanh - BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::atanh(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex, typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type - atanh - BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return atanh(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::cbrt(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return cbrt(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::erf(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type erf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return erf(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::erfc(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return erfc(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::expm1(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return expm1(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - multiprecision::number<Backend, ExpressionTemplates> result; - result = boost::math::lgamma(arg, c99_error_policy()); - if ((boost::multiprecision::isnan)(result) && !(boost::multiprecision::isnan)(arg)) - { - result = std::numeric_limits<multiprecision::number<Backend, ExpressionTemplates> >::infinity(); - errno = ERANGE; - } - return result; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return lgamma(value_type(arg)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - if ((arg == 0) && std::numeric_limits<multiprecision::number<Backend, ExpressionTemplates> >::has_infinity) - { - errno = ERANGE; - return 1 / arg; - } - return boost::math::tgamma(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return tgamma(value_type(arg)); -} - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR long lrint BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return lround(arg); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR long lrint BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - return lround(arg); -} -#ifndef BOOST_NO_LONG_LONG -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR long long llrint BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - return llround(arg); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR long long llrint BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - return llround(arg); -} -#endif -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(arg); - return boost::math::log1p(arg, c99_error_policy()); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(arg); - return log1p(value_type(arg)); -} - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& a, const multiprecision::number<Backend, ExpressionTemplates>& b) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(a, b); - return boost::math::nextafter(a, b, c99_error_policy()); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& a, const multiprecision::detail::expression<tag, A1, A2, A3, A4>& b) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(a, b); - return nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(a, multiprecision::number<Backend, ExpressionTemplates>(b)); -} -template <class tag, class A1, class A2, class A3, class A4, class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& a, const multiprecision::number<Backend, ExpressionTemplates>& b) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(a, b); - return nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(multiprecision::number<Backend, ExpressionTemplates>(a), b); -} -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& a, const multiprecision::detail::expression<tagb, A1b, A2b, A3b, A4b>& b) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(a, b); - return nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(a), value_type(b)); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& a, const multiprecision::number<Backend, ExpressionTemplates>& b) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(a, b); - return boost::math::nextafter(a, b, c99_error_policy()); -} -template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& a, const multiprecision::detail::expression<tag, A1, A2, A3, A4>& b) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(a, b); - return nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(a, multiprecision::number<Backend, ExpressionTemplates>(b)); -} -template <class tag, class A1, class A2, class A3, class A4, class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<Backend, ExpressionTemplates> nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& a, const multiprecision::number<Backend, ExpressionTemplates>& b) -{ - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(a, b); - return nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(multiprecision::number<Backend, ExpressionTemplates>(a), b); -} -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& a, const multiprecision::detail::expression<tagb, A1b, A2b, A3b, A4b>& b) -{ - using value_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<value_type> precision_guard(a, b); - return nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(a), value_type(b)); -} -#endif // BOOST_MP_MATH_AVAILABLE - -template <class B1, class B2, class B3, expression_template_option ET1, expression_template_option ET2, expression_template_option ET3> -inline BOOST_MP_CXX14_CONSTEXPR number<B1, ET1>& add(number<B1, ET1>& result, const number<B2, ET2>& a, const number<B3, ET3>& b) -{ - static_assert((std::is_convertible<B2, B1>::value), "No conversion to the target of a mixed precision addition exists"); - static_assert((std::is_convertible<B3, B1>::value), "No conversion to the target of a mixed precision addition exists"); - using default_ops::eval_add; - eval_add(result.backend(), a.backend(), b.backend()); - return result; -} - -template <class B1, class B2, class B3, expression_template_option ET1, expression_template_option ET2, expression_template_option ET3> -inline BOOST_MP_CXX14_CONSTEXPR number<B1, ET1>& subtract(number<B1, ET1>& result, const number<B2, ET2>& a, const number<B3, ET3>& b) -{ - static_assert((std::is_convertible<B2, B1>::value), "No conversion to the target of a mixed precision addition exists"); - static_assert((std::is_convertible<B3, B1>::value), "No conversion to the target of a mixed precision addition exists"); - using default_ops::eval_subtract; - eval_subtract(result.backend(), a.backend(), b.backend()); - return result; -} - -template <class B1, class B2, class B3, expression_template_option ET1, expression_template_option ET2, expression_template_option ET3> -inline BOOST_MP_CXX14_CONSTEXPR number<B1, ET1>& multiply(number<B1, ET1>& result, const number<B2, ET2>& a, const number<B3, ET3>& b) -{ - static_assert((std::is_convertible<B2, B1>::value), "No conversion to the target of a mixed precision addition exists"); - static_assert((std::is_convertible<B3, B1>::value), "No conversion to the target of a mixed precision addition exists"); - using default_ops::eval_multiply; - eval_multiply(result.backend(), a.backend(), b.backend()); - return result; -} - -template <class B, expression_template_option ET, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value, number<B, ET>&>::type -add(number<B, ET>& result, const I& a, const I& b) -{ - using default_ops::eval_add; - using canonical_type = typename detail::canonical<I, B>::type; - eval_add(result.backend(), static_cast<canonical_type>(a), static_cast<canonical_type>(b)); - return result; -} - -template <class B, expression_template_option ET, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value, number<B, ET>&>::type -subtract(number<B, ET>& result, const I& a, const I& b) -{ - using default_ops::eval_subtract; - using canonical_type = typename detail::canonical<I, B>::type; - eval_subtract(result.backend(), static_cast<canonical_type>(a), static_cast<canonical_type>(b)); - return result; -} - -template <class B, expression_template_option ET, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value, number<B, ET>&>::type -multiply(number<B, ET>& result, const I& a, const I& b) -{ - using default_ops::eval_multiply; - using canonical_type = typename detail::canonical<I, B>::type; - eval_multiply(result.backend(), static_cast<canonical_type>(a), static_cast<canonical_type>(b)); - return result; -} - -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<tag, A1, A2, A3, A4>::result_type trunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(trunc(number_type(v), pol)); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR number<Backend, ExpressionTemplates> trunc(const number<Backend, ExpressionTemplates>& v, const Policy&) -{ - using default_ops::eval_trunc; - detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(v); - number<Backend, ExpressionTemplates> result; - eval_trunc(result.backend(), v.backend()); - return result; -} - -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR int itrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type r(trunc(v, pol)); - if ((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, number_type(v), 0, pol); - return r.template convert_to<int>(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR int itrunc(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - return itrunc(v, boost::math::policies::policy<>()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR int itrunc(const number<Backend, ExpressionTemplates>& v, const Policy& pol) -{ - number<Backend, ExpressionTemplates> r(trunc(v, pol)); - if ((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, v, 0, pol); - return r.template convert_to<int>(); -} -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR int itrunc(const number<Backend, ExpressionTemplates>& v) -{ - return itrunc(v, boost::math::policies::policy<>()); -} -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long ltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type r(trunc(v, pol)); - if ((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, number_type(v), 0L, pol); - return r.template convert_to<long>(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR long ltrunc(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - return ltrunc(v, boost::math::policies::policy<>()); -} -template <class T, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long ltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol) -{ - number<T, ExpressionTemplates> r(trunc(v, pol)); - if ((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, v, 0L, pol); - return r.template convert_to<long>(); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR long ltrunc(const number<T, ExpressionTemplates>& v) -{ - return ltrunc(v, boost::math::policies::policy<>()); -} -#ifndef BOOST_NO_LONG_LONG -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type r(trunc(v, pol)); - if ((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol); - return r.template convert_to<long long>(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - return lltrunc(v, boost::math::policies::policy<>()); -} -template <class T, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long long lltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol) -{ - number<T, ExpressionTemplates> r(trunc(v, pol)); - if ((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol); - return r.template convert_to<long long>(); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR long long lltrunc(const number<T, ExpressionTemplates>& v) -{ - return lltrunc(v, boost::math::policies::policy<>()); -} -#endif -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<tag, A1, A2, A3, A4>::result_type round(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(round(static_cast<number_type>(v), pol)); -} -template <class T, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR number<T, ExpressionTemplates> round(const number<T, ExpressionTemplates>& v, const Policy&) -{ - using default_ops::eval_round; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result; - eval_round(result.backend(), v.backend()); - return result; -} - -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR int iround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type r(round(v, pol)); - if ((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0, pol); - return r.template convert_to<int>(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR int iround(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - return iround(v, boost::math::policies::policy<>()); -} -template <class T, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR int iround(const number<T, ExpressionTemplates>& v, const Policy& pol) -{ - number<T, ExpressionTemplates> r(round(v, pol)); - if ((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0, pol); - return r.template convert_to<int>(); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR int iround(const number<T, ExpressionTemplates>& v) -{ - return iround(v, boost::math::policies::policy<>()); -} -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long lround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type r(round(v, pol)); - if ((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, number_type(v), 0L, pol); - return r.template convert_to<long>(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR long lround(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - return lround(v, boost::math::policies::policy<>()); -} -template <class T, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long lround(const number<T, ExpressionTemplates>& v, const Policy& pol) -{ - number<T, ExpressionTemplates> r(round(v, pol)); - if ((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, v, 0L, pol); - return r.template convert_to<long>(); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR long lround(const number<T, ExpressionTemplates>& v) -{ - return lround(v, boost::math::policies::policy<>()); -} -#ifndef BOOST_NO_LONG_LONG -template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long long llround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type r(round(v, pol)); - if ((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol); - return r.template convert_to<long long>(); -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR long long llround(const detail::expression<tag, A1, A2, A3, A4>& v) -{ - return llround(v, boost::math::policies::policy<>()); -} -template <class T, expression_template_option ExpressionTemplates, class Policy> -inline BOOST_MP_CXX14_CONSTEXPR long long llround(const number<T, ExpressionTemplates>& v, const Policy& pol) -{ - number<T, ExpressionTemplates> r(round(v, pol)); - if ((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !BOOST_MP_ISFINITE(v)) - return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol); - return r.template convert_to<long long>(); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR long long llround(const number<T, ExpressionTemplates>& v) -{ - return llround(v, boost::math::policies::policy<>()); -} -#endif -// -// frexp does not return an expression template since we require the -// integer argument to be evaluated even if the returned value is -// not assigned to anything... -// -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, short* pint) -{ - using default_ops::eval_frexp; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result; - eval_frexp(result.backend(), v.backend(), pint); - return result; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -frexp(const detail::expression<tag, A1, A2, A3, A4>& v, short* pint) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(frexp(static_cast<number_type>(v), pint)); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, int* pint) -{ - using default_ops::eval_frexp; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result; - eval_frexp(result.backend(), v.backend(), pint); - return result; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -frexp(const detail::expression<tag, A1, A2, A3, A4>& v, int* pint) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(frexp(static_cast<number_type>(v), pint)); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long* pint) -{ - using default_ops::eval_frexp; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result; - eval_frexp(result.backend(), v.backend(), pint); - return result; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long* pint) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(frexp(static_cast<number_type>(v), pint)); -} -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long long* pint) -{ - using default_ops::eval_frexp; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result; - eval_frexp(result.backend(), v.backend(), pint); - return result; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long long* pint) -{ - using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - return std::move(frexp(static_cast<number_type>(v), pint)); -} -// -// modf does not return an expression template since we require the -// second argument to be evaluated even if the returned value is -// not assigned to anything... -// -template <class T, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type modf(const number<T, ExpressionTemplates>& v, number<T, ExpressionTemplates>* pipart) -{ - using default_ops::eval_modf; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result; - eval_modf(result.backend(), v.backend(), pipart ? &pipart->backend() : 0); - return result; -} -template <class T, expression_template_option ExpressionTemplates, class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type modf(const detail::expression<tag, A1, A2, A3, A4>& v, number<T, ExpressionTemplates>* pipart) -{ - using default_ops::eval_modf; - detail::scoped_default_precision<multiprecision::number<T, ExpressionTemplates> > precision_guard(v); - number<T, ExpressionTemplates> result, arg(v); - eval_modf(result.backend(), arg.backend(), pipart ? &pipart->backend() : 0); - return result; -} - -// -// Integer square root: -// -template <class B, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type -sqrt(const number<B, ExpressionTemplates>& x) -{ - using default_ops::eval_integer_sqrt; - number<B, ExpressionTemplates> s, r; - eval_integer_sqrt(s.backend(), r.backend(), x.backend()); - return s; -} -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type - sqrt(const detail::expression<tag, A1, A2, A3, A4>& arg) -{ - using default_ops::eval_integer_sqrt; - using result_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type; - detail::scoped_default_precision<result_type> precision_guard(arg); - result_type result, v(arg), r; - eval_integer_sqrt(result.backend(), r.backend(), v.backend()); - return result; -} - -// -// fma: -// - -namespace default_ops { - -struct fma_func -{ - template <class B, class T, class U, class V> - BOOST_MP_CXX14_CONSTEXPR void operator()(B& result, const T& a, const U& b, const V& c) const - { - eval_multiply_add(result, a, b, c); - } -}; - -} // namespace default_ops - -template <class Backend, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_on> >::value == number_kind_floating_point) && - (is_number<U>::value || is_number_expression<U>::value || boost::multiprecision::detail::is_arithmetic<U>::value) && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_arithmetic<V>::value), - detail::expression<detail::function, default_ops::fma_func, number<Backend, et_on>, U, V> >::type -fma(const number<Backend, et_on>& a, const U& b, const V& c) -{ - return detail::expression<detail::function, default_ops::fma_func, number<Backend, et_on>, U, V>( - default_ops::fma_func(), a, b, c); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_floating_point) && - (is_number<U>::value || is_number_expression<U>::value || boost::multiprecision::detail::is_arithmetic<U>::value) && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_arithmetic<V>::value), - detail::expression<detail::function, default_ops::fma_func, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, U, V> >::type -fma(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const U& b, const V& c) -{ - return detail::expression<detail::function, default_ops::fma_func, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, U, V>( - default_ops::fma_func(), a, b, c); -} - -template <class Backend, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_off> >::value == number_kind_floating_point) && - (is_number<U>::value || is_number_expression<U>::value || boost::multiprecision::detail::is_arithmetic<U>::value) && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_arithmetic<V>::value), - number<Backend, et_off> >::type -fma(const number<Backend, et_off>& a, const U& b, const V& c) -{ - using default_ops::eval_multiply_add; - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(a, b, c); - number<Backend, et_off> result; - eval_multiply_add(result.backend(), number<Backend, et_off>::canonical_value(a), number<Backend, et_off>::canonical_value(b), number<Backend, et_off>::canonical_value(c)); - return result; -} - -template <class U, class Backend, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_on> >::value == number_kind_floating_point) && - boost::multiprecision::detail::is_arithmetic<U>::value && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_arithmetic<V>::value), - detail::expression<detail::function, default_ops::fma_func, U, number<Backend, et_on>, V> >::type -fma(const U& a, const number<Backend, et_on>& b, const V& c) -{ - return detail::expression<detail::function, default_ops::fma_func, U, number<Backend, et_on>, V>( - default_ops::fma_func(), a, b, c); -} - -template <class U, class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_floating_point) && - boost::multiprecision::detail::is_arithmetic<U>::value && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_arithmetic<V>::value), - detail::expression<detail::function, default_ops::fma_func, U, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -fma(const U& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b, const V& c) -{ - return detail::expression<detail::function, default_ops::fma_func, U, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>( - default_ops::fma_func(), a, b, c); -} - -template <class U, class Backend, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_off> >::value == number_kind_floating_point) && - boost::multiprecision::detail::is_arithmetic<U>::value && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_arithmetic<V>::value), - number<Backend, et_off> >::type -fma(const U& a, const number<Backend, et_off>& b, const V& c) -{ - using default_ops::eval_multiply_add; - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(a, b, c); - number<Backend, et_off> result; - eval_multiply_add(result.backend(), number<Backend, et_off>::canonical_value(a), number<Backend, et_off>::canonical_value(b), number<Backend, et_off>::canonical_value(c)); - return result; -} - -template <class U, class V, class Backend> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_on> >::value == number_kind_floating_point) && - boost::multiprecision::detail::is_arithmetic<U>::value && - boost::multiprecision::detail::is_arithmetic<V>::value, - detail::expression<detail::function, default_ops::fma_func, U, V, number<Backend, et_on> > >::type -fma(const U& a, const V& b, const number<Backend, et_on>& c) -{ - return detail::expression<detail::function, default_ops::fma_func, U, V, number<Backend, et_on> >( - default_ops::fma_func(), a, b, c); -} - -template <class U, class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_floating_point) && - boost::multiprecision::detail::is_arithmetic<U>::value && - boost::multiprecision::detail::is_arithmetic<V>::value, - detail::expression<detail::function, default_ops::fma_func, U, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -fma(const U& a, const V& b, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& c) -{ - return detail::expression<detail::function, default_ops::fma_func, U, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >( - default_ops::fma_func(), a, b, c); -} - -template <class U, class V, class Backend> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_off> >::value == number_kind_floating_point) && - boost::multiprecision::detail::is_arithmetic<U>::value && - boost::multiprecision::detail::is_arithmetic<V>::value, - number<Backend, et_off> >::type -fma(const U& a, const V& b, const number<Backend, et_off>& c) -{ - using default_ops::eval_multiply_add; - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(a, b, c); - number<Backend, et_off> result; - eval_multiply_add(result.backend(), number<Backend, et_off>::canonical_value(a), number<Backend, et_off>::canonical_value(b), number<Backend, et_off>::canonical_value(c)); - return result; -} - -namespace default_ops { - -struct remquo_func -{ - template <class B, class T, class U> - BOOST_MP_CXX14_CONSTEXPR void operator()(B& result, const T& a, const U& b, int* pi) const - { - eval_remquo(result, a, b, pi); - } -}; - -} // namespace default_ops - -template <class Backend, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - number_category<number<Backend, et_on> >::value == number_kind_floating_point, - detail::expression<detail::function, default_ops::remquo_func, number<Backend, et_on>, U, int*> >::type -remquo(const number<Backend, et_on>& a, const U& b, int* pi) -{ - return detail::expression<detail::function, default_ops::remquo_func, number<Backend, et_on>, U, int*>( - default_ops::remquo_func(), a, b, pi); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_floating_point, - detail::expression<detail::function, default_ops::remquo_func, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, U, int*> >::type -remquo(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const U& b, int* pi) -{ - return detail::expression<detail::function, default_ops::remquo_func, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, U, int*>( - default_ops::remquo_func(), a, b, pi); -} - -template <class U, class Backend> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_on> >::value == number_kind_floating_point) && !is_number<U>::value && !is_number_expression<U>::value, - detail::expression<detail::function, default_ops::remquo_func, U, number<Backend, et_on>, int*> >::type -remquo(const U& a, const number<Backend, et_on>& b, int* pi) -{ - return detail::expression<detail::function, default_ops::remquo_func, U, number<Backend, et_on>, int*>( - default_ops::remquo_func(), a, b, pi); -} - -template <class U, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_floating_point) && !is_number<U>::value && !is_number_expression<U>::value, - detail::expression<detail::function, default_ops::remquo_func, U, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, int*> >::type -remquo(const U& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b, int* pi) -{ - return detail::expression<detail::function, default_ops::remquo_func, U, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, int*>( - default_ops::remquo_func(), a, b, pi); -} - -template <class Backend, class U> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - number_category<number<Backend, et_on> >::value == number_kind_floating_point, - number<Backend, et_off> >::type -remquo(const number<Backend, et_off>& a, const U& b, int* pi) -{ - using default_ops::eval_remquo; - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(a, b); - number<Backend, et_off> result; - eval_remquo(result.backend(), a.backend(), number<Backend, et_off>::canonical_value(b), pi); - return result; -} -template <class U, class Backend> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<number<Backend, et_on> >::value == number_kind_floating_point) && !is_number<U>::value && !is_number_expression<U>::value, - number<Backend, et_off> >::type -remquo(const U& a, const number<Backend, et_off>& b, int* pi) -{ - using default_ops::eval_remquo; - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(a, b); - number<Backend, et_off> result; - eval_remquo(result.backend(), number<Backend, et_off>::canonical_value(a), b.backend(), pi); - return result; -} - -template <class B, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type -sqrt(const number<B, ExpressionTemplates>& x, number<B, ExpressionTemplates>& r) -{ - using default_ops::eval_integer_sqrt; - detail::scoped_default_precision<multiprecision::number<B, ExpressionTemplates> > precision_guard(x, r); - number<B, ExpressionTemplates> s; - eval_integer_sqrt(s.backend(), r.backend(), x.backend()); - return s; -} -template <class B, expression_template_option ExpressionTemplates, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type -sqrt(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& arg, number<B, ExpressionTemplates>& r) -{ - using default_ops::eval_integer_sqrt; - detail::scoped_default_precision<multiprecision::number<B, ExpressionTemplates> > precision_guard(r); - number<B, ExpressionTemplates> s; - number<B, ExpressionTemplates> x(arg); - eval_integer_sqrt(s.backend(), r.backend(), x.backend()); - return s; -} - -// clang-format off -// -// Regrettably, when the argument to a function is an rvalue we must return by value, and not return an -// expression template, otherwise we can end up with dangling references. -// See https://github.com/boostorg/multiprecision/issues/175. -// -#define UNARY_OP_FUNCTOR_CXX11_RVALUE(func, category)\ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == category, number<Backend, et_on> > ::type \ - func(number<Backend, et_on>&& arg) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_on> > precision_guard(arg); \ - number<Backend, et_on> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func)(result.backend(), arg.backend()); \ - return result; \ - } \ - -#define BINARY_OP_FUNCTOR_CXX11_RVALUE(func, category)\ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == category, number<Backend, et_on> >::type func(number<Backend, et_on>&& arg, const number<Backend, et_on>& a) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_on> > precision_guard(arg, a); \ - number<Backend, et_on> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func)(result.backend(), arg.backend(), a.backend()); \ - return result; \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == category, number<Backend, et_on> >::type func(const number<Backend, et_on>& arg, number<Backend, et_on>&& a) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_on> > precision_guard(arg, a); \ - number<Backend, et_on> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func)(result.backend(), arg.backend(), a.backend()); \ - return result; \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == category, number<Backend, et_on> >::type func(number<Backend, et_on>&& arg, number<Backend, et_on>&& a) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_on> > precision_guard(arg, a); \ - number<Backend, et_on> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func)(result.backend(), arg.backend(), a.backend()); \ - return result; \ - } \ - template <class Backend, class tag, class A1, class A2, class A3, class A4> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value == category) && (std::is_convertible<typename detail::expression<tag, A1, A2, A3, A4>::result_type, number<Backend, et_on> >::value), \ - number<Backend, et_on> > ::type \ - func(number<Backend, et_on>&& arg, const detail::expression<tag, A1, A2, A3, A4>& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on>, detail::expression<tag, A1, A2, A3, A4> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class tag, class A1, class A2, class A3, class A4, class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value == category) && (std::is_convertible<typename detail::expression<tag, A1, A2, A3, A4>::result_type, number<Backend, et_on> >::value), \ - number<Backend, et_on> > ::type \ - func(const detail::expression<tag, A1, A2, A3, A4>& arg, number<Backend, et_on>&& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - detail::expression<tag, A1, A2, A3, A4>, number<Backend, et_on> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class Backend, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, number<Backend, et_on> >::value && (number_category<Backend>::value == category), \ - number<Backend, et_on> >::type \ - func(number<Backend, et_on>&& arg, const Arithmetic& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>, \ - number<Backend, et_on>, Arithmetic > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class Backend, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, number<Backend, et_on> >::value && (number_category<Backend>::value == category), \ - number<Backend, et_on> > ::type \ - func(const Arithmetic& arg, number<Backend, et_on>&& a) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - Arithmetic, number<Backend, et_on> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend > (), arg, a); \ - } \ - - -#define UNARY_OP_FUNCTOR(func, category) \ - namespace detail { \ - template <class Backend> \ - struct BOOST_JOIN(category, BOOST_JOIN(func, _funct)) \ - { \ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Backend& arg) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result, arg); \ - } \ - template <class U> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(U& result, const Backend& arg) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - Backend temp; \ - BOOST_JOIN(eval_, func) \ - (temp, arg); \ - result = std::move(temp); \ - } \ - }; \ - } \ - \ - template <class tag, class A1, class A2, class A3, class A4> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category, \ - detail::expression<detail::function, \ - detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4> > > ::type \ - func(const detail::expression<tag, A1, A2, A3, A4>& arg) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type > (), arg); \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == category, \ - detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, number<Backend, et_on> > > ::type \ - func(const number<Backend, et_on>& arg) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend > (), arg); \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - boost::multiprecision::number_category<Backend>::value == category, \ - number<Backend, et_off> >::type \ - func(const number<Backend, et_off>& arg) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg); \ - number<Backend, et_off> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func)(result.backend(), arg.backend()); \ - return result; \ - }\ - UNARY_OP_FUNCTOR_CXX11_RVALUE(func, category)\ - -#define BINARY_OP_FUNCTOR(func, category) \ - namespace detail { \ - template <class Backend> \ - struct BOOST_JOIN(category, BOOST_JOIN(func, _funct)) \ - { \ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Backend& arg, const Backend& a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result, arg, a); \ - } \ - template <class Arithmetic> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Backend& arg, const Arithmetic& a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result, arg, number<Backend>::canonical_value(a)); \ - } \ - template <class Arithmetic> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Arithmetic& arg, const Backend& a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result, number<Backend>::canonical_value(arg), a); \ - } \ - template <class U> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(U& result, const Backend& arg, const Backend& a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - Backend r; \ - BOOST_JOIN(eval_, func) \ - (r, arg, a); \ - result = std::move(r); \ - } \ - template <class U, class Arithmetic> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(U& result, const Backend& arg, const Arithmetic& a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - Backend r; \ - BOOST_JOIN(eval_, func) \ - (r, arg, number<Backend>::canonical_value(a)); \ - result = std::move(r); \ - } \ - template <class U, class Arithmetic> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(U& result, const Arithmetic& arg, const Backend& a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - Backend r; \ - BOOST_JOIN(eval_, func) \ - (r, number<Backend>::canonical_value(arg), a); \ - result = std::move(r); \ - } \ - }; \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == category, detail::expression<detail::function, \ - detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>, number<Backend, et_on>, number<Backend, et_on> > > ::type \ - func(const number<Backend, et_on>& arg, const number<Backend, et_on>& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on>, number<Backend, et_on> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class Backend, class tag, class A1, class A2, class A3, class A4> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value == category) && (std::is_convertible<typename detail::expression<tag, A1, A2, A3, A4>::result_type, number<Backend, et_on> >::value), \ - detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>, number<Backend, et_on>, detail::expression<tag, A1, A2, A3, A4> > > ::type \ - func(const number<Backend, et_on>& arg, const detail::expression<tag, A1, A2, A3, A4>& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on>, detail::expression<tag, A1, A2, A3, A4> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class tag, class A1, class A2, class A3, class A4, class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value == category) && (std::is_convertible<typename detail::expression<tag, A1, A2, A3, A4>::result_type, number<Backend, et_on> >::value), \ - detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>, detail::expression<tag, A1, A2, A3, A4>, number<Backend, et_on> > > ::type \ - func(const detail::expression<tag, A1, A2, A3, A4>& arg, const number<Backend, et_on>& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - detail::expression<tag, A1, A2, A3, A4>, number<Backend, et_on> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category) && (number_category<detail::expression<tagb, A1b, A2b, A3b, A4b> >::value == category), \ - detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4>, detail::expression<tagb, A1b, A2b, A3b, A4b> > > ::type \ - func(const detail::expression<tag, A1, A2, A3, A4>& arg, const detail::expression<tagb, A1b, A2b, A3b, A4b>& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4>, detail::expression<tagb, A1b, A2b, A3b, A4b> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>(), arg, a); \ - } \ - template <class Backend, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, number<Backend, et_on> >::value && (number_category<Backend>::value == category), \ - detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on>, Arithmetic> > ::type \ - func(const number<Backend, et_on>& arg, const Arithmetic& a) \ - { \ - return detail::expression<detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>, \ - number<Backend, et_on>, Arithmetic > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct))<Backend>(), arg, a); \ - } \ - template <class tag, class A1, class A2, class A3, class A4, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value && (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category), \ - detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4>, Arithmetic> > ::type \ - func(const detail::expression<tag, A1, A2, A3, A4>& arg, const Arithmetic& a) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4>, Arithmetic > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type > (), arg, a); \ - } \ - template <class Backend, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, number<Backend, et_on> >::value && (number_category<Backend>::value == category), \ - detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - Arithmetic, number<Backend, et_on> > > ::type \ - func(const Arithmetic& arg, const number<Backend, et_on>& a) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - Arithmetic, number<Backend, et_on> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend > (), arg, a); \ - } \ - template <class tag, class A1, class A2, class A3, class A4, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value && (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category), \ - detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - Arithmetic, detail::expression<tag, A1, A2, A3, A4> > > ::type \ - func(const Arithmetic& arg, const detail::expression<tag, A1, A2, A3, A4>& a) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - Arithmetic, detail::expression<tag, A1, A2, A3, A4> > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type > (), arg, a); \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value == category), number<Backend, et_off> >::type \ - func(const number<Backend, et_off>& arg, const number<Backend, et_off>& a) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg, a); \ - number<Backend, et_off> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func)(result.backend(), arg.backend(), a.backend()); \ - return result; \ - } \ - template <class Backend, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, number<Backend, et_off> >::value && (number_category<Backend>::value == category), \ - number<Backend, et_off> >::type \ - func(const number<Backend, et_off>& arg, const Arithmetic& a) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg); \ - number<Backend, et_off> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result.backend(), arg.backend(), number<Backend, et_off>::canonical_value(a)); \ - return result; \ - } \ - template <class Backend, class Arithmetic> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - is_compatible_arithmetic_type<Arithmetic, number<Backend, et_off> >::value && (number_category<Backend>::value == category), \ - number<Backend, et_off> >::type \ - func(const Arithmetic& a, const number<Backend, et_off>& arg) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg); \ - number<Backend, et_off> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result.backend(), number<Backend, et_off>::canonical_value(a), arg.backend()); \ - return result; \ - }\ - BINARY_OP_FUNCTOR_CXX11_RVALUE(func, category) - -#define HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category) \ - template <class tag, class A1, class A2, class A3, class A4> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category), \ - detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4>, Arg2> > ::type \ - func(const detail::expression<tag, A1, A2, A3, A4>& arg, Arg2 const& a) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, \ - detail::expression<tag, A1, A2, A3, A4>, Arg2 > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type > (), arg, a); \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - (number_category<Backend>::value == category), \ - detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on>, Arg2> > ::type \ - func(const number<Backend, et_on>& arg, Arg2 const& a) \ - { \ - return detail::expression< \ - detail::function, detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend>, \ - number<Backend, et_on>, Arg2 > (detail::BOOST_JOIN(category, BOOST_JOIN(func, _funct)) < Backend > (), arg, a); \ - } \ - template <class Backend> \ - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< \ - (number_category<Backend>::value == category), \ - number<Backend, et_off> >::type \ - func(const number<Backend, et_off>& arg, Arg2 const& a) \ - { \ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg, a); \ - number<Backend, et_off> result; \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result.backend(), arg.backend(), a); \ - return result; \ - } - -#define HETERO_BINARY_OP_FUNCTOR(func, Arg2, category) \ - namespace detail { \ - template <class Backend> \ - struct BOOST_JOIN(category, BOOST_JOIN(func, _funct)) \ - { \ - template <class Arg> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, Backend const& arg, Arg a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - BOOST_JOIN(eval_, func) \ - (result, arg, a); \ - } \ - template <class U, class Arg> \ - BOOST_MP_CXX14_CONSTEXPR void operator()(U& result, Backend const& arg, Arg a) const \ - { \ - using default_ops::BOOST_JOIN(eval_, func); \ - Backend temp; \ - BOOST_JOIN(eval_, func) \ - (temp, arg, a); \ - result = std::move(temp); \ - } \ - }; \ - } \ - \ - HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category) - -// clang-format on - -namespace detail { -template <class Backend> -struct abs_funct -{ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Backend& arg) const - { - using default_ops::eval_abs; - eval_abs(result, arg); - } -}; -template <class Backend> -struct conj_funct -{ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Backend& arg) const - { - using default_ops::eval_conj; - eval_conj(result, arg); - } -}; -template <class Backend> -struct proj_funct -{ - BOOST_MP_CXX14_CONSTEXPR void operator()(Backend& result, const Backend& arg) const - { - using default_ops::eval_proj; - eval_proj(result, arg); - } -}; - -} // namespace detail - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex, - detail::expression< - detail::function, detail::abs_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, detail::expression<tag, A1, A2, A3, A4> > >::type -abs(const detail::expression<tag, A1, A2, A3, A4>& arg) -{ - return detail::expression< - detail::function, detail::abs_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, detail::expression<tag, A1, A2, A3, A4> >( - detail::abs_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>(), arg); -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value != number_kind_complex, - detail::expression< - detail::function, detail::abs_funct<Backend>, number<Backend, et_on> > >::type -abs(const number<Backend, et_on>& arg) -{ - return detail::expression< - detail::function, detail::abs_funct<Backend>, number<Backend, et_on> >( - detail::abs_funct<Backend>(), arg); -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value != number_kind_complex, number<Backend, et_off> >::type -abs(const number<Backend, et_off>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg); - number<Backend, et_off> result; - using default_ops::eval_abs; - eval_abs(result.backend(), arg.backend()); - return result; -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression< - detail::function, detail::conj_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, detail::expression<tag, A1, A2, A3, A4> > -conj(const detail::expression<tag, A1, A2, A3, A4>& arg) -{ - return detail::expression< - detail::function, detail::conj_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, detail::expression<tag, A1, A2, A3, A4> >( - detail::conj_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>(), arg); -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression< - detail::function, detail::conj_funct<Backend>, number<Backend, et_on> > -conj(const number<Backend, et_on>& arg) -{ - return detail::expression< - detail::function, detail::conj_funct<Backend>, number<Backend, et_on> >( - detail::conj_funct<Backend>(), arg); -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR number<Backend, et_off> -conj(const number<Backend, et_off>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg); - number<Backend, et_off> result; - using default_ops::eval_conj; - eval_conj(result.backend(), arg.backend()); - return result; -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression< - detail::function, detail::proj_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, detail::expression<tag, A1, A2, A3, A4> > -proj(const detail::expression<tag, A1, A2, A3, A4>& arg) -{ - return detail::expression< - detail::function, detail::proj_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>, detail::expression<tag, A1, A2, A3, A4> >( - detail::proj_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>(), arg); -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression< - detail::function, detail::proj_funct<Backend>, number<Backend, et_on> > -proj(const number<Backend, et_on>& arg) -{ - return detail::expression< - detail::function, detail::proj_funct<Backend>, number<Backend, et_on> >( - detail::proj_funct<Backend>(), arg); -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR number<Backend, et_off> -proj(const number<Backend, et_off>& arg) -{ - detail::scoped_default_precision<multiprecision::number<Backend, et_off> > precision_guard(arg); - number<Backend, et_off> result; - using default_ops::eval_proj; - eval_proj(result.backend(), arg.backend()); - return result; -} - -UNARY_OP_FUNCTOR(fabs, number_kind_floating_point) -UNARY_OP_FUNCTOR(sqrt, number_kind_floating_point) -UNARY_OP_FUNCTOR(floor, number_kind_floating_point) -UNARY_OP_FUNCTOR(ceil, number_kind_floating_point) -UNARY_OP_FUNCTOR(trunc, number_kind_floating_point) -UNARY_OP_FUNCTOR(round, number_kind_floating_point) -UNARY_OP_FUNCTOR(exp, number_kind_floating_point) -UNARY_OP_FUNCTOR(exp2, number_kind_floating_point) -UNARY_OP_FUNCTOR(log, number_kind_floating_point) -UNARY_OP_FUNCTOR(log10, number_kind_floating_point) -UNARY_OP_FUNCTOR(cos, number_kind_floating_point) -UNARY_OP_FUNCTOR(sin, number_kind_floating_point) -UNARY_OP_FUNCTOR(tan, number_kind_floating_point) -UNARY_OP_FUNCTOR(asin, number_kind_floating_point) -UNARY_OP_FUNCTOR(acos, number_kind_floating_point) -UNARY_OP_FUNCTOR(atan, number_kind_floating_point) -UNARY_OP_FUNCTOR(cosh, number_kind_floating_point) -UNARY_OP_FUNCTOR(sinh, number_kind_floating_point) -UNARY_OP_FUNCTOR(tanh, number_kind_floating_point) -UNARY_OP_FUNCTOR(log2, number_kind_floating_point) -UNARY_OP_FUNCTOR(nearbyint, number_kind_floating_point) -UNARY_OP_FUNCTOR(rint, number_kind_floating_point) - -HETERO_BINARY_OP_FUNCTOR(ldexp, short, number_kind_floating_point) -//HETERO_BINARY_OP_FUNCTOR(frexp, short*, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(ldexp, int, number_kind_floating_point) -//HETERO_BINARY_OP_FUNCTOR_B(frexp, int*, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point) -//HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point) -//HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point) -BINARY_OP_FUNCTOR(pow, number_kind_floating_point) -BINARY_OP_FUNCTOR(fmod, number_kind_floating_point) -BINARY_OP_FUNCTOR(fmax, number_kind_floating_point) -BINARY_OP_FUNCTOR(fmin, number_kind_floating_point) -BINARY_OP_FUNCTOR(atan2, number_kind_floating_point) -BINARY_OP_FUNCTOR(fdim, number_kind_floating_point) -BINARY_OP_FUNCTOR(hypot, number_kind_floating_point) -BINARY_OP_FUNCTOR(remainder, number_kind_floating_point) - -UNARY_OP_FUNCTOR(logb, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR(scalbn, short, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR(scalbln, short, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbn, int, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbln, int, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbn, long, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbln, long, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbn, long long, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbln, long long, number_kind_floating_point) - -// -// Complex functions: -// -UNARY_OP_FUNCTOR(exp, number_kind_complex) -UNARY_OP_FUNCTOR(log, number_kind_complex) -UNARY_OP_FUNCTOR(log10, number_kind_complex) -BINARY_OP_FUNCTOR(pow, number_kind_complex) -UNARY_OP_FUNCTOR(sqrt, number_kind_complex) -UNARY_OP_FUNCTOR(sin, number_kind_complex) -UNARY_OP_FUNCTOR(cos, number_kind_complex) -UNARY_OP_FUNCTOR(tan, number_kind_complex) -UNARY_OP_FUNCTOR(asin, number_kind_complex) -UNARY_OP_FUNCTOR(acos, number_kind_complex) -UNARY_OP_FUNCTOR(atan, number_kind_complex) -UNARY_OP_FUNCTOR(sinh, number_kind_complex) -UNARY_OP_FUNCTOR(cosh, number_kind_complex) -UNARY_OP_FUNCTOR(tanh, number_kind_complex) -UNARY_OP_FUNCTOR(asinh, number_kind_complex) -UNARY_OP_FUNCTOR(acosh, number_kind_complex) -UNARY_OP_FUNCTOR(atanh, number_kind_complex) - -// -// Integer functions: -// -BINARY_OP_FUNCTOR(gcd, number_kind_integer) -BINARY_OP_FUNCTOR(lcm, number_kind_integer) -HETERO_BINARY_OP_FUNCTOR(pow, unsigned, number_kind_integer) - -#undef BINARY_OP_FUNCTOR -#undef UNARY_OP_FUNCTOR - -// -// ilogb: -// -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_floating_point, typename Backend::exponent_type>::type -ilogb(const multiprecision::number<Backend, ExpressionTemplates>& val) -{ - using default_ops::eval_ilogb; - return eval_ilogb(val.backend()); -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<detail::expression<tag, A1, A2, A3, A4> >::value == number_kind_floating_point, typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type::backend_type::exponent_type>::type -ilogb(const detail::expression<tag, A1, A2, A3, A4>& val) -{ - using default_ops::eval_ilogb; - typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type arg(val); - return eval_ilogb(arg.backend()); -} - -} //namespace multiprecision - -namespace math { -// -// Overload of Boost.Math functions that find the wrong overload when used with number: -// -namespace detail { -template <class T> -T sinc_pi_imp(T); -template <class T> -T sinhc_pi_imp(T); -} // namespace detail -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline multiprecision::number<Backend, ExpressionTemplates> sinc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x) -{ - boost::multiprecision::detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(x); - return std::move(detail::sinc_pi_imp(x)); -} - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class Policy> -inline multiprecision::number<Backend, ExpressionTemplates> sinc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x, const Policy&) -{ - boost::multiprecision::detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(x); - return std::move(detail::sinc_pi_imp(x)); -} - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline multiprecision::number<Backend, ExpressionTemplates> sinhc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x) -{ - boost::multiprecision::detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(x); - return std::move(detail::sinhc_pi_imp(x)); -} - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class Policy> -inline multiprecision::number<Backend, ExpressionTemplates> sinhc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x, const Policy&) -{ - boost::multiprecision::detail::scoped_default_precision<multiprecision::number<Backend, ExpressionTemplates> > precision_guard(x); - return std::move(boost::math::sinhc_pi(x)); -} - -using boost::multiprecision::gcd; -using boost::multiprecision::lcm; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -} // namespace math - -namespace integer { - -using boost::multiprecision::gcd; -using boost::multiprecision::lcm; - -} // namespace integer - -} // namespace boost - -// -// This has to come last of all: -// -#include <boost/multiprecision/detail/no_et_ops.hpp> -#include <boost/multiprecision/detail/et_ops.hpp> -// -// min/max overloads: -// -#include <boost/multiprecision/detail/min_max.hpp> - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/digits.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/digits.hpp deleted file mode 100644 index e942e081af..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/digits.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_DETAIL_DIGITS_HPP -#define BOOST_MP_DETAIL_DIGITS_HPP - -namespace boost { namespace multiprecision { namespace detail { - -inline constexpr unsigned long digits10_2_2(unsigned long d10) -{ - return (d10 * 1000uL) / 301uL + ((d10 * 1000uL) % 301 ? 2u : 1u); -} - -inline constexpr unsigned long digits2_2_10(unsigned long d2) -{ - return (d2 * 301uL) / 1000uL; -} - - -#if ULONG_MAX != SIZE_MAX - -inline constexpr std::size_t digits10_2_2(std::size_t d10) -{ - return (d10 * 1000uL) / 301uL + ((d10 * 1000uL) % 301 ? 2u : 1u); -} - -inline constexpr std::size_t digits2_2_10(std::size_t d2) -{ - return (d2 * 301uL) / 1000uL; -} - -template <class I> -inline constexpr typename std::enable_if<sizeof(I) <= sizeof(unsigned long), unsigned long>::type digits10_2_2(I d10) -{ - return digits10_2_2(static_cast<unsigned long>(d10)); -} - -template <class I> -inline constexpr typename std::enable_if<sizeof(I) <= sizeof(unsigned long), unsigned long>::type digits2_2_10(I d10) -{ - return digits2_2_10(static_cast<unsigned long>(d10)); -} -#endif - -}}} // namespace boost::multiprecision::detail - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/empty_value.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/empty_value.hpp deleted file mode 100644 index 401e5eca83..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/empty_value.hpp +++ /dev/null @@ -1,87 +0,0 @@ -///////////////////////////////////////////////////////////////////// -// Copyright 2018 Glen Joseph Fernandes. -// Copyright 2021 Matt Borland. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_DETAIL_EMPTY_VALUE_HPP -#define BOOST_MP_DETAIL_EMPTY_VALUE_HPP - -#include <utility> -#include <boost/multiprecision/detail/standalone_config.hpp> - -#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700) -#define BOOST_DETAIL_EMPTY_VALUE_BASE -#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800) -#define BOOST_DETAIL_EMPTY_VALUE_BASE -#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800) -#define BOOST_DETAIL_EMPTY_VALUE_BASE -#elif defined(BOOST_CLANG) && !defined(__CUDACC__) -#if __has_feature(is_empty) && __has_feature(is_final) -#define BOOST_DETAIL_EMPTY_VALUE_BASE -#endif -#endif - -namespace boost { namespace multiprecision { namespace detail { - -template <typename T> -struct use_empty_value_base -{ -#if defined(BOOST_DETAIL_EMPTY_VALUE_BASE) - static constexpr bool value = __is_empty(T) && !__is_final(T); -#else - static constexpr bool value = false; -#endif -}; - -struct empty_init_t {}; - -namespace empty_impl { - -template <typename T, unsigned N = 0, - bool E = boost::multiprecision::detail::use_empty_value_base<T>::value> -class empty_value -{ -private: - T value_; - -public: - using type = T; - - empty_value() = default; - explicit empty_value(boost::multiprecision::detail::empty_init_t) : value_ {} {} - - template <typename U, typename... Args> - empty_value(boost::multiprecision::detail::empty_init_t, U&& value, Args&&... args) : - value_ {std::forward<U>(value), std::forward<Args>(args)...} {} - - const T& get() const noexcept { return value_; } - T& get() noexcept { return value_; } -}; - -template <typename T, unsigned N> -class empty_value<T, N, true> : T -{ -public: - using type = T; - - empty_value() = default; - explicit empty_value(boost::multiprecision::detail::empty_init_t) : T{} {} - - template <typename U, typename... Args> - empty_value(boost::multiprecision::detail::empty_init_t, U&& value, Args&&... args) : - T{std::forward<U>(value), std::forward<Args>(args)...} {} - - const T& get() const noexcept { return *this; } - T& get() noexcept { return *this; } -}; - -} // Namespace empty impl - -using empty_impl::empty_value; - -BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t(); - -}}} // Namespaces - -#endif // BOOST_MP_DETAIL_EMPTY_VALUE_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/endian.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/endian.hpp deleted file mode 100644 index 7732425682..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/endian.hpp +++ /dev/null @@ -1,35 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Copyright 2021 Matt Borland. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_DETAIL_ENDIAN_HPP -#define BOOST_MP_DETAIL_ENDIAN_HPP - -#include <boost/multiprecision/detail/standalone_config.hpp> - -#ifndef BOOST_MP_STANDALONE - -# include <boost/predef/other/endian.h> -# define BOOST_MP_ENDIAN_BIG_BYTE BOOST_ENDIAN_BIG_BYTE -# define BOOST_MP_ENDIAN_LITTLE_BYTE BOOST_ENDIAN_LITTLE_BYTE - -#elif defined(_WIN32) - -# define BOOST_MP_ENDIAN_BIG_BYTE 0 -# define BOOST_MP_ENDIAN_LITTLE_BYTE 1 - -#elif defined(__BYTE_ORDER__) - -# define BOOST_MP_ENDIAN_BIG_BYTE (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -# define BOOST_MP_ENDIAN_LITTLE_BYTE (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) - -#else -# error Could not determine endian type. Please disable standalone mode, and file an issue at https://github.com/boostorg/multiprecision -#endif // Determine endianness - -static_assert((BOOST_MP_ENDIAN_BIG_BYTE || BOOST_MP_ENDIAN_LITTLE_BYTE) - && !(BOOST_MP_ENDIAN_BIG_BYTE && BOOST_MP_ENDIAN_LITTLE_BYTE), - "Inconsistent endianness detected. Please disable standalone mode, and file an issue at https://github.com/boostorg/multiprecision"); - -#endif // BOOST_MP_DETAIL_ENDIAN_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/et_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/et_ops.hpp deleted file mode 100644 index 7511d9c145..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/et_ops.hpp +++ /dev/null @@ -1,1831 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 John Maddock. 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) - -#ifndef BOOST_MP_ET_OPS_HPP -#define BOOST_MP_ET_OPS_HPP - -namespace boost { namespace multiprecision { - -// -// Non-member operators for number which return expression templates. -// -// Note that operators taking rvalue-references DO NOT return expression templates -// as this can lead to dangling references, see https://github.com/boostorg/multiprecision/issues/175. -// -// Unary operators first. -// Note that these *must* return by value, even though that's somewhat against -// existing practice. The issue is that in C++11 land one could easily and legitimately -// write: -// auto x = +1234_my_user_defined_suffix; -// which would result in a dangling-reference-to-temporary if unary + returned a reference -// to it's argument. While return-by-value is obviously inefficient in other situations -// the reality is that no one ever uses unary operator+ anyway...! -// -template <class B, expression_template_option ExpressionTemplates> -inline constexpr const number<B, ExpressionTemplates> operator+(const number<B, ExpressionTemplates>& v) { return v; } -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline constexpr const detail::expression<tag, Arg1, Arg2, Arg3, Arg4> operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; } -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, number<B, et_on> > operator-(const number<B, et_on>& v) -{ - static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior."); - return detail::expression<detail::negate, number<B, et_on> >(v); -} -// rvalue ops: -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> operator-(number<B, et_on>&& v) -{ - static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior."); - v.backend().negate(); - return std::move(v); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) -{ - static_assert((is_signed_number<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value), "Negating an unsigned type results in ill-defined behavior."); - return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::complement_immediates, number<B, et_on> > >::type -operator~(const number<B, et_on>& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); } - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator~(number<B, et_on>&& v) -{ - using default_ops::eval_complement; - eval_complement(v.backend(), v.backend()); - return std::move(v); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, - detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator~(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::expression<detail::bitwise_complement, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); } -// -// Then addition: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > -operator+(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator+(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_add; - eval_add(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator+(const number<B, et_on>& a, number<B, et_on>&& b) -{ - using default_ops::eval_add; - eval_add(b.backend(), a.backend()); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator+(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_add; - eval_add(a.backend(), b.backend()); - return std::move(a); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::add_immediates, number<B, et_on>, V> >::type -operator+(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::add_immediates, number<B, et_on>, V>(a, b); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator+(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_add; - eval_add(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type -operator+(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator+(const V& a, number<B, et_on>&& b) -{ - using default_ops::eval_add; - eval_add(b.backend(), number<B, et_on>::canonical_value(a)); - return std::move(b); -} - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > -operator+(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET> >::value, - typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator+(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a += b; - return std::move(a); -} -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET> >::value, - typename detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator+(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::plus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > -operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type -operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - b += a; - return std::move(b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type -operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > -operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator+(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::plus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator+(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::plus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Fused multiply add: -// -template <class V, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value, - detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type -operator+(const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value, - detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type -operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(a.left(), a.right(), b); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > -operator+(const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a); -} - -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type>::type -operator+(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - a += b; - return std::move(a); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type>::type -operator+(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > -operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type>::type -operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - b += a; - return std::move(b); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type>::type -operator+(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b); -} - -// -// Fused multiply subtract: -// -template <class V, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value, - detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> > >::type -operator-(const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >(detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a)); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value, - detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type -operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(a.left(), a.right(), b); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > > -operator-(const number<B, ET>& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >(detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a)); -} - -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >::result_type, number<B, ET>>::value, - typename detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >::result_type>::type -operator-(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - a -= b; - return std::move(a); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >::result_type, number<B, ET>>::value, - typename detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >::result_type>::type -operator-(number<B, ET>&& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > >(detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(b.left(), b.right(), a)); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> > -operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >::result_type -operator-(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, number<B, ET> >(a.left(), a.right(), b); -} - -// -// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: -// -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, Arg1> -operator+(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref()); -} - -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type -operator+(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - a -= b.left_ref(); - return std::move(a); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type -operator+(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::minus, number<B, ET>, Arg1>(a, b.left_ref()); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, Arg1> -operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref()); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type -operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - b -= a.left_ref(); - return std::move(b); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, number<B, ET>, Arg1>::result_type>::type -operator+(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::minus, number<B, ET>, Arg1>(b, a.left_ref()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> > -operator+(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >::result_type -operator+(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - using default_ops::eval_subtract; - eval_subtract(a.backend(), b.left_ref().backend()); - return std::move(a); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> > -operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) -{ - return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >::result_type -operator+(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b) -{ - using default_ops::eval_subtract; - eval_subtract(b.backend(), a.left_ref().backend()); - return std::move(b); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type -operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) -{ - return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(b, a.left_ref()); -} -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type -operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) -{ - return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref()); -} - -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type -operator+(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b) -{ - return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(b, a.left_ref()); -} - -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> > >::type -operator+(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()); -} - -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type -operator+(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::subtract_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > > -operator+(const detail::expression<detail::negate, number<B, et_on> >& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b.left_ref())); -} -// -// Subtraction: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> > -operator-(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::subtract_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator-(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_subtract; - eval_subtract(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator-(const number<B, et_on>& a, number<B, et_on>&& b) -{ - using default_ops::eval_subtract; - eval_subtract(b.backend(), a.backend()); - b.backend().negate(); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator-(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_subtract; - eval_subtract(a.backend(), b.backend()); - return std::move(a); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, number<B, et_on>, V> >::type -operator-(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::subtract_immediates, number<B, et_on>, V>(a, b); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator-(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_subtract; - eval_subtract(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::subtract_immediates, V, number<B, et_on> > >::type -operator-(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::subtract_immediates, V, number<B, et_on> >(a, b); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator-(const V& a, number<B, et_on>&& b) -{ - using default_ops::eval_subtract; - eval_subtract(b.backend(), number<B, et_on>::canonical_value(a)); - b.backend().negate(); - return std::move(b); -} - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > -operator-(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator-(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a -= b; - return std::move(a); -} -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator-(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::minus, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > -operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type -operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - b -= a; - b.backend().negate(); - return std::move(b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type -operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > -operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator-(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::minus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator-(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::minus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: -// -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::plus, number<B, ET>, Arg1> -operator-(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref()); -} - -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value, - typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type>::type -operator-(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - a += b.left_ref(); - return std::move(a); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type, number<B, ET>>::value, - typename detail::expression<detail::plus, number<B, ET>, Arg1>::result_type>::type -operator-(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::plus, number<B, ET>, Arg1>(a, b.left_ref()); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> > -operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >( - detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref())); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type>::type -operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - b += a.left_ref(); - b.backend().negate(); - return std::move(b); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >::result_type>::type -operator-(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::plus, number<B, ET>, Arg1> >(detail::expression<detail::plus, number<B, ET>, Arg1>(b, a.left_ref())); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > -operator-(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >::result_type -operator-(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - using default_ops::eval_add; - eval_add(a.backend(), b.left_ref().backend()); - return std::move(a); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > > -operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref())); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value, - typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type -operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b) -{ - using default_ops::eval_add; - eval_add(b.backend(), a.left_ref().backend()); - b.backend().negate(); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value, - typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type -operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::add_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref())); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V> > >::type -operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) -{ - return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, V> >(detail::expression<detail::add_immediates, number<B, et_on>, V>(a.left_ref(), b)); -} -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > > >::type -operator-(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); -} - -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type -operator-(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> > >(detail::expression<detail::add_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::add_immediates, V, number<B, et_on> > >::type -operator-(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::add_immediates, V, number<B, et_on> >(a, b.left_ref()); -} -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> > >::type -operator-(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()); -} - -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >::result_type>::type -operator-(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::add_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref()); -} - -// -// Multiplication: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > -operator*(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator*(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_multiply; - eval_multiply(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator*(const number<B, et_on>& a, number<B, et_on>&& b) -{ - using default_ops::eval_multiply; - eval_multiply(b.backend(), a.backend()); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator*(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_multiply; - eval_multiply(a.backend(), b.backend()); - return std::move(a); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >::type -operator*(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a, b); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator*(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_multiply; - eval_multiply(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::multiply_immediates, V, number<B, et_on> > >::type -operator*(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::multiply_immediates, V, number<B, et_on> >(a, b); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator*(const V& a, number<B, et_on>&& b) -{ - using default_ops::eval_multiply; - eval_multiply(b.backend(), number<B, et_on>::canonical_value(a)); - return std::move(b); -} - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > -operator*(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator*(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a *= b; - return std::move(a); -} -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator*(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::multiplies, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > -operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type -operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - b *= a; - return std::move(b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type>::type -operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > -operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator*(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::multiplies, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator*(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::multiplies, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: -// -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> > -operator*(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >( - detail::expression<detail::multiplies, number<B, ET>, Arg1>(a, b.left_ref())); -} - -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >::result_type -operator*(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >( - detail::expression<detail::multiplies, number<B, ET>, Arg1>(a, b.left_ref())); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> > -operator*(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >( - detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref())); -} - -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >::result_type -operator*(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiplies, number<B, ET>, Arg1> >( - detail::expression<detail::multiplies, number<B, ET>, Arg1>(b, a.left_ref())); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > > -operator*(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref())); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value, - typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type -operator*(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - a *= b.left_ref(); - a.backend().negate(); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value, - typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type -operator*(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref())); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > > -operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref())); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value, - typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type -operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b) -{ - b *= a.left_ref(); - b.backend().negate(); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type, number<B, et_on>>::value, - typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >::result_type>::type -operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B, et_on> >(b, a.left_ref())); -} - -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> > >::type -operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >( - detail::expression<detail::multiply_immediates, number<B, et_on>, V>(a.left_ref(), b)); -} -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type -operator*(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); -} - -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type -operator*(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); -} - -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> > >::type -operator*(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, V> >( - detail::expression<detail::multiply_immediates, number<B, et_on>, V>(b.left_ref(), a)); -} -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > > >::type -operator*(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a)); -} - -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type -operator*(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> > >( - detail::expression<detail::multiply_immediates, number<B, et_on>, number<B2, ET> >(b.left_ref(), a)); -} - -// -// Division: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > -operator/(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator/(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_divide; - eval_divide(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator/(const number<B, et_on>& a, number<B, et_on>&& b) -{ - return detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR number<B, et_on> -operator/(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_divide; - eval_divide(a.backend(), b.backend()); - return std::move(a); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, detail::expression<detail::divide_immediates, number<B, et_on>, V> >::type -operator/(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::divide_immediates, number<B, et_on>, V>(a, b); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && !is_equivalent_number_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator/(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_divide; - eval_divide(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::divide_immediates, V, number<B, et_on> > >::type -operator/(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, number<B, et_on> >::type -operator/(const V& a, number<B, et_on>&& b) -{ - return detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b); -} -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > -operator/(const number<B, ET>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator/(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a /= b; - return std::move(a); -} -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator/(number<B, ET>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::divides, number<B, ET>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > -operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::result_type -operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > -operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator/(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::divides, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value, detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator/(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::divides, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries: -// -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> > -operator/(const number<B, ET>& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >( - detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref())); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline typename std::enable_if< - std::is_same<typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type>::type -operator/(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - a /= b.left_ref(); - a.backend().negate(); - return std::move(a); -} -template <class B, expression_template_option ET, class Arg1, class Arg2, class Arg3, class Arg4> -inline typename std::enable_if< - !std::is_same<typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type, number<B, ET>>::value, - typename detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >::result_type>::type -operator/(number<B, ET>&& a, const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divides, number<B, ET>, Arg1> >( - detail::expression<detail::divides, number<B, ET>, Arg1>(a, b.left_ref())); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > > -operator/(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const number<B, ET>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >( - detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b)); -} -template <class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >::result_type -operator/(const detail::expression<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, number<B, ET>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divides, Arg1, number<B, ET> > >( - detail::expression<detail::divides, Arg1, number<B, ET> >(a.left_ref(), b)); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > > -operator/(const number<B, et_on>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a, b.left_ref())); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >::result_type -operator/(number<B, et_on>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - a /= b.left_ref(); - a.backend().negate(); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > > -operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B, et_on>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b)); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >::result_type -operator/(const detail::expression<detail::negate, number<B, et_on> >& a, number<B, et_on>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> > >( - detail::expression<detail::divide_immediates, number<B, et_on>, number<B, et_on> >(a.left_ref(), b)); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V> > >::type -operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const V& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, V> >( - detail::expression<detail::divide_immediates, number<B, et_on>, V>(a.left_ref(), b)); -} -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > > >::type -operator/(const detail::expression<detail::negate, number<B, et_on> >& a, const number<B2, ET>& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >( - detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); -} -template <class B, class B2, expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >::result_type>::type -operator/(const detail::expression<detail::negate, number<B, et_on> >& a, number<B2, ET>&& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> > >( - detail::expression<detail::divide_immediates, number<B, et_on>, number<B2, ET> >(a.left_ref(), b)); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > > >::type -operator/(const V& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, V, number<B, et_on> > >( - detail::expression<detail::divide_immediates, V, number<B, et_on> >(a, b.left_ref())); -} -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, number<B, et_on> >::value, detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > > >::type -operator/(const number<B2, ET>& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >( - detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref())); -} -template <class B2, expression_template_option ET, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<number<B2, ET>, typename detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >::result_type>::value, number<B, et_on> >::type -operator/(number<B2, ET>&& a, const detail::expression<detail::negate, number<B, et_on> >& b) -{ - return detail::expression<detail::negate, detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> > >( - detail::expression<detail::divide_immediates, number<B2, ET>, number<B, et_on> >(a, b.left_ref())); -} -// -// Modulus: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> > >::type -operator%(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator%(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_modulus; - eval_modulus(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator%(const number<B, et_on>& a, number<B, et_on>&& b) -{ - return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator%(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_modulus; - eval_modulus(a.backend(), b.backend()); - return std::move(a); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, number<B, et_on> >::value, - detail::expression<detail::modulus_immediates, number<B, et_on>, V> >::type -operator%(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::modulus_immediates, number<B, et_on>, V>(a, b); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, number<B, et_on> >::value, - number<B, et_on> >::type -operator%(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_modulus; - eval_modulus(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::modulus_immediates, V, number<B, et_on> > >::type -operator%(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator%(const V& a, number<B, et_on>&& b) -{ - return detail::expression<detail::modulus_immediates, V, number<B, et_on> >(a, b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator%(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type -operator%(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a %= b; - return std::move(a); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type -operator%(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::modulus, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type -operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - typename detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type -operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, - detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type -operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator%(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator%(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Left shift: -// -template <class B, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), detail::expression<detail::shift_left, number<B, et_on>, I> >::type -operator<<(const number<B, et_on>& a, const I& b) -{ - return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b); -} -template <class B, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_on> >::type -operator<<(number<B, et_on>&& a, const I& b) -{ - using default_ops::eval_left_shift; - eval_left_shift(a.backend(), b); - return std::move(a); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type -operator<<(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b) -{ - return detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b); -} -// -// Right shift: -// -template <class B, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::shift_right, number<B, et_on>, I> >::type -operator>>(const number<B, et_on>& a, const I& b) -{ - return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b); -} -template <class B, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator>>(number<B, et_on>&& a, const I& b) -{ - using default_ops::eval_right_shift; - eval_right_shift(a.backend(), b); - return std::move(a); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type -operator>>(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b) -{ - return detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b); -} -// -// Bitwise AND: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> > >::type -operator&(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator&(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_bitwise_and; - eval_bitwise_and(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator&(const number<B, et_on>& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_and; - eval_bitwise_and(b.backend(), a.backend()); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator&(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_and; - eval_bitwise_and(a.backend(), b.backend()); - return std::move(a); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V> >::type -operator&(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V>(a, b); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator&(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_bitwise_and; - eval_bitwise_and(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> > >::type -operator&(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> >(a, b); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator&(const V& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_and; - eval_bitwise_and(b.backend(), number<B, et_on>::canonical_value(a)); - return std::move(b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator&(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type -operator&(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a &= b; - return std::move(a); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type >::type -operator&(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_and, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type -operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type -operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - b &= a; - return std::move(b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type >::type -operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, - detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type -operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator&(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator&(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Bitwise OR: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> > >::type -operator|(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator|(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_bitwise_or; - eval_bitwise_or(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator|(const number<B, et_on>& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_or; - eval_bitwise_or(b.backend(), a.backend()); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator|(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_or; - eval_bitwise_or(a.backend(), b.backend()); - return std::move(a); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V> >::type -operator|(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V>(a, b); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator|(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_bitwise_or; - eval_bitwise_or(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> > >::type -operator|(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> >(a, b); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator|(const V& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_or; - eval_bitwise_or(b.backend(), number<B, et_on>::canonical_value(a)); - return std::move(b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator|(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator|(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a |= b; - return std::move(a); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator|(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_or, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type -operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type -operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - b |= a; - return std::move(b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type -operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, - detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type -operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator|(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator|(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -// -// Bitwise XOR: -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> > >::type -operator^(const number<B, et_on>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, number<B, et_on> >(a, b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator^(number<B, et_on>&& a, const number<B, et_on>& b) -{ - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(a.backend(), b.backend()); - return std::move(a); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator^(const number<B, et_on>& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(b.backend(), a.backend()); - return std::move(b); -} -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - number<B, et_on> >::type -operator^(number<B, et_on>&& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(a.backend(), b.backend()); - return std::move(a); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V> >::type -operator^(const number<B, et_on>& a, const V& b) -{ - return detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V>(a, b); -} -template <class B, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator^(number<B, et_on>&& a, const V& b) -{ - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(a.backend(), number<B, et_on>::canonical_value(b)); - return std::move(a); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> > >::type -operator^(const V& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> >(a, b); -} -template <class V, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer), - number<B, et_on> >::type -operator^(const V& a, number<B, et_on>&& b) -{ - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(b.backend(), number<B, et_on>::canonical_value(a)); - return std::move(b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator^(const number<B, et_on>& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator^(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - a ^= b; - return std::move(a); -} -template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >::result_type>::type -operator^(number<B, et_on>&& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_xor, number<B, et_on>, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, - detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> > >::type -operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const number<B, et_on>& b) -{ - return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - std::is_same<typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type -operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - b ^= a; - return std::move(b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - !std::is_same<typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type, number<B, et_on>>::value - && number_category<B>::value == number_kind_integer, - typename detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >::result_type>::type -operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, number<B, et_on>&& b) -{ - return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, et_on> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer, - detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> > >::type -operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b) -{ - return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b); -} -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), - detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V> >::type -operator^(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b) -{ - return detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V>(a, b); -} -template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer), detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type -operator^(const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b) -{ - return detail::expression<detail::bitwise_xor, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(a, b); -} - -}} // namespace boost::multiprecision - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/float128_functions.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/float128_functions.hpp deleted file mode 100644 index cf0e9be1e6..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/float128_functions.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// (C) Copyright John Maddock 2021. -// 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) -// -// We deliberately use assert in here: -// - -#ifndef BOOST_MP_DETAIL_FLOAT128_FUNCTIONS_HPP -#define BOOST_MP_DETAIL_FLOAT128_FUNCTIONS_HPP - -#include <boost/multiprecision/detail/standalone_config.hpp> - -#ifndef BOOST_MP_STANDALONE -#include <boost/cstdfloat.hpp> -#if defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) -# define BOOST_MP_HAVE_CSTDFLOAT -#endif -#endif - -#if defined(BOOST_HAS_FLOAT128) - -namespace boost -{ -namespace multiprecision -{ -namespace float128_procs -{ -extern "C" __float128 ldexpq(__float128, int) throw(); -extern "C" __float128 frexpq(__float128, int*) throw(); -extern "C" __float128 floorq(__float128) throw(); -extern "C" __float128 nextafterq(__float128, __float128) throw(); -extern "C" int isinfq(__float128) throw(); -extern "C" int isnanq(__float128) throw(); -extern "C" __float128 strtoflt128(const char*, char**) throw(); - -#ifdef BOOST_MP_HAVE_CSTDFLOAT -using std::ldexp; -using std::frexp; -using std::floor; -#else -inline __float128 ldexp(__float128 f, int i) throw() { return ldexpq(f, i); } -inline __float128 frexp(__float128 f, int* p) throw() { return frexpq(f, p); } -inline __float128 floor(__float128 f) throw() { return floorq(f); } -#endif -} - -namespace detail { - -template <class T> -struct is_float128 : public std::is_same<__float128, T> -{}; - -} -} -} - -namespace boost { -namespace math { - - inline __float128 float_next(const __float128& f) - { - return boost::multiprecision::float128_procs::nextafterq(f, 2 * f); - } - inline int (isinf)(const __float128& f) - { - return boost::multiprecision::float128_procs::isinfq(f); - } - inline int (isnan)(const __float128& f) - { - return boost::multiprecision::float128_procs::isnanq(f); - } - -}} - -#define BOOST_MP_FLOAT128_USING using boost::multiprecision::float128_procs::ldexp; using boost::multiprecision::float128_procs::frexp; using boost::multiprecision::float128_procs::floor; using boost::math::isinf; using boost::math::isnan; - -#else -#define BOOST_MP_FLOAT128_USING - -namespace boost { -namespace multiprecision { -namespace detail { - -template <class T> -struct is_float128 : public std::false_type -{}; - -}}} // namespace boost::multiprecision::detail - -#endif - -#endif // BOOST_MP_DETAIL_FLOAT128_FUNCTIONS_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/fpclassify.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/fpclassify.hpp deleted file mode 100644 index 2ca9833e23..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/fpclassify.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2022 Matt Borland. 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) - -#ifndef BOOST_MP_DETAIL_FPCLASSIFY_HPP -#define BOOST_MP_DETAIL_FPCLASSIFY_HPP - -#include <cmath> -#include <limits> -#include <type_traits> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/float128_functions.hpp> - -#ifdef BOOST_MP_MATH_AVAILABLE -#include <boost/math/special_functions/fpclassify.hpp> - -#define BOOST_MP_ISNAN(x) (boost::math::isnan)(x) -#define BOOST_MP_ISINF(x) (boost::math::isinf)(x) -#define BOOST_MP_FPCLASSIFY(x) (boost::math::fpclassify)(x) -#define BOOST_MP_ISFINITE(x) (!(boost::math::isnan)(x) && !(boost::math::isinf)(x)) - -#else - -namespace boost { namespace multiprecision { namespace detail { - -template <typename T, typename std::enable_if<std::is_floating_point<T>::value - #ifdef BOOST_HAS_FLOAT128 - || std::is_same<T, float128_type>::value - #endif - , bool>::type = true> -inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const T x) -{ - BOOST_MP_FLOAT128_USING; - using std::isnan; - return static_cast<bool>((isnan)(x)); -} - -template <typename T, typename std::enable_if<!std::is_floating_point<T>::value - #ifdef BOOST_HAS_FLOAT128 - && !std::is_same<T, float128_type>::value - #endif - , bool>::type = true> -inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const T x) -{ - return x != x; -} - -template <typename T, typename std::enable_if<std::is_floating_point<T>::value - #ifdef BOOST_HAS_FLOAT128 - || std::is_same<T, float128_type>::value - #endif - , bool>::type = true> -inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const T x) -{ - BOOST_MP_FLOAT128_USING; - using std::isinf; - return static_cast<bool>((isinf)(x)); -} - -template <typename T, typename std::enable_if<!std::is_floating_point<T>::value - #ifdef BOOST_HAS_FLOAT128 - && !std::is_same<T, float128_type>::value - #endif - , bool>::type = true> -inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const T x) -{ - return x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity(); -} - -template <typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true> -inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const T x) -{ - using std::fpclassify; - return fpclassify(x); -} - -template <typename T, typename std::enable_if<!std::is_floating_point<T>::value, bool>::type = true> -inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const T x) -{ - BOOST_MP_FLOAT128_USING; - using std::isnan; - using std::isinf; - using std::abs; - - return (isnan)(x) ? FP_NAN : - (isinf)(x) ? FP_INFINITE : - abs(x) == T(0) ? FP_ZERO : - abs(x) > 0 && abs(x) < (std::numeric_limits<T>::min)() ? FP_SUBNORMAL : FP_NORMAL; -} - -}}} // Namespace boost::multiprecision::detail - -#define BOOST_MP_ISNAN(x) (boost::multiprecision::detail::isnan)(x) -#define BOOST_MP_ISINF(x) (boost::multiprecision::detail::isinf)(x) -#define BOOST_MP_FPCLASSIFY(x) (boost::multiprecision::detail::fpclassify)(x) -#define BOOST_MP_ISFINITE(x) (!(boost::multiprecision::detail::isnan)(x) && !(boost::multiprecision::detail::isinf)(x)) - -#endif - -#endif // BOOST_MP_DETAIL_FPCLASSIFY_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/constants.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/constants.hpp deleted file mode 100644 index 56aa069f38..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/constants.hpp +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright 2011 John Maddock. -// 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) -// -// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp -// - -template <class T> -void calc_log2(T& num, unsigned digits) -{ - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - using si_type = typename std::tuple_element<0, typename T::signed_types>::type ; - - // - // String value with 1100 digits: - // - static const char* string_val = "0." - "6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875" - "4200148102057068573368552023575813055703267075163507596193072757082837143519030703862389167347112335" - "0115364497955239120475172681574932065155524734139525882950453007095326366642654104239157814952043740" - "4303855008019441706416715186447128399681717845469570262716310645461502572074024816377733896385506952" - "6066834113727387372292895649354702576265209885969320196505855476470330679365443254763274495125040606" - "9438147104689946506220167720424524529612687946546193165174681392672504103802546259656869144192871608" - "2938031727143677826548775664850856740776484514644399404614226031930967354025744460703080960850474866" - "3852313818167675143866747664789088143714198549423151997354880375165861275352916610007105355824987941" - "4729509293113897155998205654392871700072180857610252368892132449713893203784393530887748259701715591" - "0708823683627589842589185353024363421436706118923678919237231467232172053401649256872747782344535347" - "6481149418642386776774406069562657379600867076257199184734022651462837904883062033061144630073719489"; - // - // Check if we can just construct from string: - // - if (digits < 3640) // 3640 binary digits ~ 1100 decimal digits - { - num = string_val; - return; - } - // - // We calculate log2 from using the formula: - // - // ln(2) = 3/4 SUM[n>=0] ((-1)^n * N!^2 / (2^n(2n+1)!)) - // - // Numerator and denominator are calculated separately and then - // divided at the end, we also precalculate the terms up to n = 5 - // since these fit in a 32-bit integer anyway. - // - // See Gourdon, X., and Sebah, P. The logarithmic constant: log 2, Jan. 2004. - // Also http://www.mpfr.org/algorithms.pdf. - // - num = static_cast<ui_type>(1180509120uL); - T denom, next_term, temp; - denom = static_cast<ui_type>(1277337600uL); - next_term = static_cast<ui_type>(120uL); - si_type sign = -1; - - ui_type limit = digits / 3 + 1; - - for (ui_type n = 6; n < limit; ++n) - { - temp = static_cast<ui_type>(2); - eval_multiply(temp, ui_type(2 * n)); - eval_multiply(temp, ui_type(2 * n + 1)); - eval_multiply(num, temp); - eval_multiply(denom, temp); - sign = -sign; - eval_multiply(next_term, n); - eval_multiply(temp, next_term, next_term); - if (sign < 0) - temp.negate(); - eval_add(num, temp); - } - eval_multiply(denom, ui_type(4)); - eval_multiply(num, ui_type(3)); - INSTRUMENT_BACKEND(denom); - INSTRUMENT_BACKEND(num); - eval_divide(num, denom); - INSTRUMENT_BACKEND(num); -} - -template <class T> -void calc_e(T& result, unsigned digits) -{ - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - // - // 1100 digits in string form: - // - const char* string_val = "2." - "7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274" - "2746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901" - "1573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069" - "5517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416" - "9283681902551510865746377211125238978442505695369677078544996996794686445490598793163688923009879312" - "7736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117" - "3012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509" - "9618188159304169035159888851934580727386673858942287922849989208680582574927961048419844436346324496" - "8487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016" - "7683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354" - "0212340784981933432106817012100562788023519303322474501585390473041995777709350366041699732972508869"; - // - // Check if we can just construct from string: - // - if (digits < 3640) // 3640 binary digits ~ 1100 decimal digits - { - result = string_val; - return; - } - - T lim; - lim = ui_type(1); - eval_ldexp(lim, lim, digits); - - // - // Standard evaluation from the definition of e: http://functions.wolfram.com/Constants/E/02/ - // - result = ui_type(2); - T denom; - denom = ui_type(1); - ui_type i = 2; - do - { - eval_multiply(denom, i); - eval_multiply(result, i); - eval_add(result, ui_type(1)); - ++i; - } while (denom.compare(lim) <= 0); - eval_divide(result, denom); -} - -template <class T> -void calc_pi(T& result, unsigned digits) -{ - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - using real_type = typename std::tuple_element<0, typename T::float_types>::type ; - // - // 1100 digits in string form: - // - const char* string_val = "3." - "1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679" - "8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196" - "4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273" - "7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094" - "3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912" - "9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132" - "0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235" - "4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859" - "5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303" - "5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989" - "3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913152"; - // - // Check if we can just construct from string: - // - if (digits < 3640) // 3640 binary digits ~ 1100 decimal digits - { - result = string_val; - return; - } - - T a; - a = ui_type(1); - T b; - T A(a); - T B; - B = real_type(0.5f); - T D; - D = real_type(0.25f); - - T lim; - lim = ui_type(1); - eval_ldexp(lim, lim, -static_cast<int>(digits)); - - // - // This algorithm is from: - // Schonhage, A., Grotefeld, A. F. W., and Vetter, E. Fast Algorithms: A Multitape Turing - // Machine Implementation. BI Wissenschaftverlag, 1994. - // Also described in MPFR's algorithm guide: http://www.mpfr.org/algorithms.pdf. - // - // Let: - // a[0] = A[0] = 1 - // B[0] = 1/2 - // D[0] = 1/4 - // Then: - // S[k+1] = (A[k]+B[k]) / 4 - // b[k] = sqrt(B[k]) - // a[k+1] = a[k]^2 - // B[k+1] = 2(A[k+1]-S[k+1]) - // D[k+1] = D[k] - 2^k(A[k+1]-B[k+1]) - // Stop when |A[k]-B[k]| <= 2^(k-p) - // and PI = B[k]/D[k] - - unsigned k = 1; - - do - { - eval_add(result, A, B); - eval_ldexp(result, result, -2); - eval_sqrt(b, B); - eval_add(a, b); - eval_ldexp(a, a, -1); - eval_multiply(A, a, a); - eval_subtract(B, A, result); - eval_ldexp(B, B, 1); - eval_subtract(result, A, B); - bool neg = eval_get_sign(result) < 0; - if (neg) - result.negate(); - if (result.compare(lim) <= 0) - break; - if (neg) - result.negate(); - eval_ldexp(result, result, k - 1); - eval_subtract(D, result); - ++k; - eval_ldexp(lim, lim, 1); - } while (true); - - eval_divide(result, B, D); -} - -template <class T> -const T& get_constant_ln2() -{ - static BOOST_MP_THREAD_LOCAL T result; - static BOOST_MP_THREAD_LOCAL long digits = 0; - if ((digits != boost::multiprecision::detail::digits2<number<T> >::value())) - { - boost::multiprecision::detail::maybe_promote_precision(&result); - calc_log2(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - digits = boost::multiprecision::detail::digits2<number<T> >::value(); - } - - return result; -} - -template <class T> -const T& get_constant_e() -{ - static BOOST_MP_THREAD_LOCAL T result; - static BOOST_MP_THREAD_LOCAL long digits = 0; - if ((digits != boost::multiprecision::detail::digits2<number<T> >::value())) - { - boost::multiprecision::detail::maybe_promote_precision(&result); - calc_e(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - digits = boost::multiprecision::detail::digits2<number<T> >::value(); - } - - return result; -} - -template <class T> -const T& get_constant_pi() -{ - static BOOST_MP_THREAD_LOCAL T result; - static BOOST_MP_THREAD_LOCAL long digits = 0; - if ((digits != boost::multiprecision::detail::digits2<number<T> >::value())) - { - boost::multiprecision::detail::maybe_promote_precision(&result); - calc_pi(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - digits = boost::multiprecision::detail::digits2<number<T> >::value(); - } - - return result; -} -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4127) // conditional expression is constant -#endif -template <class T> -const T& get_constant_one_over_epsilon() -{ - static BOOST_MP_THREAD_LOCAL T result; - static BOOST_MP_THREAD_LOCAL long digits = 0; - if ((digits != boost::multiprecision::detail::digits2<number<T> >::value())) - { - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - boost::multiprecision::detail::maybe_promote_precision(&result); - result = static_cast<ui_type>(1u); - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T> >::is_specialized) - eval_divide(result, std::numeric_limits<number<T> >::epsilon().backend()); - else - eval_ldexp(result, result, boost::multiprecision::detail::digits2<number<T> >::value() - 1); - digits = boost::multiprecision::detail::digits2<number<T> >::value(); - } - - return result; -} -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/pow.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/pow.hpp deleted file mode 100644 index 36ea0e4024..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/pow.hpp +++ /dev/null @@ -1,905 +0,0 @@ - -// Copyright Christopher Kormanyos 2002 - 2013. -// Copyright 2011 - 2013 John Maddock. -// 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) - -// This work is based on an earlier work: -// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", -// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 -// -// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp -// - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 6326) // comparison of two constants -#pragma warning(disable : 4127) // conditional expression is constant -#endif - -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -namespace detail { - -template <typename T, typename U> -inline void pow_imp(T& result, const T& t, const U& p, const std::integral_constant<bool, false>&) -{ - // Compute the pure power of typename T t^p. - // Use the S-and-X binary method, as described in - // D. E. Knuth, "The Art of Computer Programming", Vol. 2, - // Section 4.6.3 . The resulting computational complexity - // is order log2[abs(p)]. - - using int_type = typename boost::multiprecision::detail::canonical<U, T>::type; - - if (&result == &t) - { - T temp; - pow_imp(temp, t, p, std::integral_constant<bool, false>()); - result = temp; - return; - } - - // This will store the result. - if (U(p % U(2)) != U(0)) - { - result = t; - } - else - result = int_type(1); - - U p2(p); - - // The variable x stores the binary powers of t. - T x(t); - - while (U(p2 /= 2) != U(0)) - { - // Square x for each binary power. - eval_multiply(x, x); - - const bool has_binary_power = (U(p2 % U(2)) != U(0)); - - if (has_binary_power) - { - // Multiply the result with each binary power contained in the exponent. - eval_multiply(result, x); - } - } -} - -template <typename T, typename U> -inline void pow_imp(T& result, const T& t, const U& p, const std::integral_constant<bool, true>&) -{ - // Signed integer power, just take care of the sign then call the unsigned version: - using int_type = typename boost::multiprecision::detail::canonical<U, T>::type; - using ui_type = typename boost::multiprecision::detail::make_unsigned<U>::type ; - - if (p < 0) - { - T temp; - temp = static_cast<int_type>(1); - T denom; - pow_imp(denom, t, static_cast<ui_type>(-p), std::integral_constant<bool, false>()); - eval_divide(result, temp, denom); - return; - } - pow_imp(result, t, static_cast<ui_type>(p), std::integral_constant<bool, false>()); -} - -} // namespace detail - -template <typename T, typename U> -inline typename std::enable_if<boost::multiprecision::detail::is_integral<U>::value>::type eval_pow(T& result, const T& t, const U& p) -{ - detail::pow_imp(result, t, p, boost::multiprecision::detail::is_signed<U>()); -} - -template <class T> -void hyp0F0(T& H0F0, const T& x) -{ - // Compute the series representation of Hypergeometric0F0 taken from - // http://functions.wolfram.com/HypergeometricFunctions/Hypergeometric0F0/06/01/ - // There are no checks on input range or parameter boundaries. - - using ui_type = typename std::tuple_element<0, typename T::unsigned_types>::type; - - BOOST_MP_ASSERT(&H0F0 != &x); - long tol = boost::multiprecision::detail::digits2<number<T, et_on> >::value(); - T t; - - T x_pow_n_div_n_fact(x); - - eval_add(H0F0, x_pow_n_div_n_fact, ui_type(1)); - - T lim; - eval_ldexp(lim, H0F0, 1 - tol); - if (eval_get_sign(lim) < 0) - lim.negate(); - - ui_type n; - - const unsigned series_limit = - boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100 - ? 100 - : boost::multiprecision::detail::digits2<number<T, et_on> >::value(); - // Series expansion of hyperg_0f0(; ; x). - for (n = 2; n < series_limit; ++n) - { - eval_multiply(x_pow_n_div_n_fact, x); - eval_divide(x_pow_n_div_n_fact, n); - eval_add(H0F0, x_pow_n_div_n_fact); - bool neg = eval_get_sign(x_pow_n_div_n_fact) < 0; - if (neg) - x_pow_n_div_n_fact.negate(); - if (lim.compare(x_pow_n_div_n_fact) > 0) - break; - if (neg) - x_pow_n_div_n_fact.negate(); - } - if (n >= series_limit) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("H0F0 failed to converge")); -} - -template <class T> -void hyp1F0(T& H1F0, const T& a, const T& x) -{ - // Compute the series representation of Hypergeometric1F0 taken from - // http://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F0/06/01/01/ - // and also see the corresponding section for the power function (i.e. x^a). - // There are no checks on input range or parameter boundaries. - - using si_type = typename boost::multiprecision::detail::canonical<int, T>::type; - - BOOST_MP_ASSERT(&H1F0 != &x); - BOOST_MP_ASSERT(&H1F0 != &a); - - T x_pow_n_div_n_fact(x); - T pochham_a(a); - T ap(a); - - eval_multiply(H1F0, pochham_a, x_pow_n_div_n_fact); - eval_add(H1F0, si_type(1)); - T lim; - eval_ldexp(lim, H1F0, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - if (eval_get_sign(lim) < 0) - lim.negate(); - - si_type n; - T term, part; - - const si_type series_limit = - boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100 - ? 100 - : boost::multiprecision::detail::digits2<number<T, et_on> >::value(); - // Series expansion of hyperg_1f0(a; ; x). - for (n = 2; n < series_limit; n++) - { - eval_multiply(x_pow_n_div_n_fact, x); - eval_divide(x_pow_n_div_n_fact, n); - eval_increment(ap); - eval_multiply(pochham_a, ap); - eval_multiply(term, pochham_a, x_pow_n_div_n_fact); - eval_add(H1F0, term); - if (eval_get_sign(term) < 0) - term.negate(); - if (lim.compare(term) >= 0) - break; - } - if (n >= series_limit) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("H1F0 failed to converge")); -} - -template <class T> -void eval_exp(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The exp function is only valid for floating point types."); - if (&x == &result) - { - T temp; - eval_exp(temp, x); - result = temp; - return; - } - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - using si_type = typename boost::multiprecision::detail::canonical<int, T>::type ; - using exp_type = typename T::exponent_type ; - using canonical_exp_type = typename boost::multiprecision::detail::canonical<exp_type, T>::type; - - // Handle special arguments. - int type = eval_fpclassify(x); - bool isneg = eval_get_sign(x) < 0; - if (type == static_cast<int>(FP_NAN)) - { - result = x; - errno = EDOM; - return; - } - else if (type == static_cast<int>(FP_INFINITE)) - { - if (isneg) - result = ui_type(0u); - else - result = x; - return; - } - else if (type == static_cast<int>(FP_ZERO)) - { - result = ui_type(1); - return; - } - - // Get local copy of argument and force it to be positive. - T xx = x; - T exp_series; - if (isneg) - xx.negate(); - - // Check the range of the argument. - if (xx.compare(si_type(1)) <= 0) - { - // - // Use series for exp(x) - 1: - // - T lim; - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::is_specialized) - lim = std::numeric_limits<number<T, et_on> >::epsilon().backend(); - else - { - result = ui_type(1); - eval_ldexp(lim, result, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - } - unsigned k = 2; - exp_series = xx; - result = si_type(1); - if (isneg) - eval_subtract(result, exp_series); - else - eval_add(result, exp_series); - eval_multiply(exp_series, xx); - eval_divide(exp_series, ui_type(k)); - eval_add(result, exp_series); - while (exp_series.compare(lim) > 0) - { - ++k; - eval_multiply(exp_series, xx); - eval_divide(exp_series, ui_type(k)); - if (isneg && (k & 1)) - eval_subtract(result, exp_series); - else - eval_add(result, exp_series); - } - return; - } - - // Check for pure-integer arguments which can be either signed or unsigned. - typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type ll; - eval_trunc(exp_series, x); - eval_convert_to(&ll, exp_series); - if (x.compare(ll) == 0) - { - detail::pow_imp(result, get_constant_e<T>(), ll, std::integral_constant<bool, true>()); - return; - } - else if (exp_series.compare(x) == 0) - { - // We have a value that has no fractional part, but is too large to fit - // in a long long, in this situation the code below will fail, so - // we're just going to assume that this will overflow: - if (isneg) - result = ui_type(0); - else - result = std::numeric_limits<number<T> >::has_infinity ? std::numeric_limits<number<T> >::infinity().backend() : (std::numeric_limits<number<T> >::max)().backend(); - return; - } - - // The algorithm for exp has been taken from MPFUN. - // exp(t) = [ (1 + r + r^2/2! + r^3/3! + r^4/4! ...)^p2 ] * 2^n - // where p2 is a power of 2 such as 2048, r = t_prime / p2, and - // t_prime = t - n*ln2, with n chosen to minimize the absolute - // value of t_prime. In the resulting Taylor series, which is - // implemented as a hypergeometric function, |r| is bounded by - // ln2 / p2. For small arguments, no scaling is done. - - // Compute the exponential series of the (possibly) scaled argument. - - eval_divide(result, xx, get_constant_ln2<T>()); - exp_type n; - eval_convert_to(&n, result); - - if (n == (std::numeric_limits<exp_type>::max)()) - { - // Exponent is too large to fit in our exponent type: - if (isneg) - result = ui_type(0); - else - result = std::numeric_limits<number<T> >::has_infinity ? std::numeric_limits<number<T> >::infinity().backend() : (std::numeric_limits<number<T> >::max)().backend(); - return; - } - - // The scaling is 2^11 = 2048. - const si_type p2 = static_cast<si_type>(si_type(1) << 11); - - eval_multiply(exp_series, get_constant_ln2<T>(), static_cast<canonical_exp_type>(n)); - eval_subtract(exp_series, xx); - eval_divide(exp_series, p2); - exp_series.negate(); - hyp0F0(result, exp_series); - - detail::pow_imp(exp_series, result, p2, std::integral_constant<bool, true>()); - result = ui_type(1); - eval_ldexp(result, result, n); - eval_multiply(exp_series, result); - - if (isneg) - eval_divide(result, ui_type(1), exp_series); - else - result = exp_series; -} - -template <class T> -void eval_log(T& result, const T& arg) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The log function is only valid for floating point types."); - // - // We use a variation of http://dlmf.nist.gov/4.45#i - // using frexp to reduce the argument to x * 2^n, - // then let y = x - 1 and compute: - // log(x) = log(2) * n + log1p(1 + y) - // - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - using exp_type = typename T::exponent_type ; - using canonical_exp_type = typename boost::multiprecision::detail::canonical<exp_type, T>::type; - using fp_type = typename std::tuple_element<0, typename T::float_types>::type ; - int s = eval_signbit(arg); - switch (eval_fpclassify(arg)) - { - case FP_NAN: - result = arg; - errno = EDOM; - return; - case FP_INFINITE: - if (s) - break; - result = arg; - return; - case FP_ZERO: - result = std::numeric_limits<number<T> >::has_infinity ? std::numeric_limits<number<T> >::infinity().backend() : (std::numeric_limits<number<T> >::max)().backend(); - result.negate(); - errno = ERANGE; - return; - } - if (s) - { - result = std::numeric_limits<number<T> >::quiet_NaN().backend(); - errno = EDOM; - return; - } - - exp_type e; - T t; - eval_frexp(t, arg, &e); - bool alternate = false; - - if (t.compare(fp_type(2) / fp_type(3)) <= 0) - { - alternate = true; - eval_ldexp(t, t, 1); - --e; - } - - eval_multiply(result, get_constant_ln2<T>(), canonical_exp_type(e)); - INSTRUMENT_BACKEND(result); - eval_subtract(t, ui_type(1)); /* -0.3 <= t <= 0.3 */ - if (!alternate) - t.negate(); /* 0 <= t <= 0.33333 */ - T pow = t; - T lim; - T t2; - - if (alternate) - eval_add(result, t); - else - eval_subtract(result, t); - - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::is_specialized) - eval_multiply(lim, result, std::numeric_limits<number<T, et_on> >::epsilon().backend()); - else - eval_ldexp(lim, result, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - if (eval_get_sign(lim) < 0) - lim.negate(); - INSTRUMENT_BACKEND(lim); - - ui_type k = 1; - do - { - ++k; - eval_multiply(pow, t); - eval_divide(t2, pow, k); - INSTRUMENT_BACKEND(t2); - if (alternate && ((k & 1) != 0)) - eval_add(result, t2); - else - eval_subtract(result, t2); - INSTRUMENT_BACKEND(result); - } while (lim.compare(t2) < 0); -} - -template <class T> -const T& get_constant_log10() -{ - static BOOST_MP_THREAD_LOCAL T result; - static BOOST_MP_THREAD_LOCAL long digits = 0; - if ((digits != boost::multiprecision::detail::digits2<number<T> >::value())) - { - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - T ten; - ten = ui_type(10u); - eval_log(result, ten); - digits = boost::multiprecision::detail::digits2<number<T> >::value(); - } - - return result; -} - -template <class T> -void eval_log10(T& result, const T& arg) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The log10 function is only valid for floating point types."); - eval_log(result, arg); - eval_divide(result, get_constant_log10<T>()); -} - -template <class R, class T> -inline void eval_log2(R& result, const T& a) -{ - eval_log(result, a); - eval_divide(result, get_constant_ln2<R>()); -} - -template <typename T> -inline void eval_pow(T& result, const T& x, const T& a) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The pow function is only valid for floating point types."); - using si_type = typename boost::multiprecision::detail::canonical<int, T>::type; - using fp_type = typename std::tuple_element<0, typename T::float_types>::type ; - - if ((&result == &x) || (&result == &a)) - { - T t; - eval_pow(t, x, a); - result = t; - return; - } - - if ((a.compare(si_type(1)) == 0) || (x.compare(si_type(1)) == 0)) - { - result = x; - return; - } - if (a.compare(si_type(0)) == 0) - { - result = si_type(1); - return; - } - - int type = eval_fpclassify(x); - - switch (type) - { - case FP_ZERO: - switch (eval_fpclassify(a)) - { - case FP_ZERO: - result = si_type(1); - break; - case FP_NAN: - result = a; - break; - case FP_NORMAL: { - // Need to check for a an odd integer as a special case: - BOOST_MP_TRY - { - typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type i; - eval_convert_to(&i, a); - if (a.compare(i) == 0) - { - if (eval_signbit(a)) - { - if (i & 1) - { - result = std::numeric_limits<number<T> >::infinity().backend(); - if (eval_signbit(x)) - result.negate(); - errno = ERANGE; - } - else - { - result = std::numeric_limits<number<T> >::infinity().backend(); - errno = ERANGE; - } - } - else if (i & 1) - { - result = x; - } - else - result = si_type(0); - return; - } - } - BOOST_MP_CATCH(const std::exception&) - { - // fallthrough.. - } - BOOST_MP_CATCH_END - BOOST_FALLTHROUGH; - } - default: - if (eval_signbit(a)) - { - result = std::numeric_limits<number<T> >::infinity().backend(); - errno = ERANGE; - } - else - result = x; - break; - } - return; - case FP_NAN: - result = x; - errno = ERANGE; - return; - default:; - } - - int s = eval_get_sign(a); - if (s == 0) - { - result = si_type(1); - return; - } - - if (s < 0) - { - T t, da; - t = a; - t.negate(); - eval_pow(da, x, t); - eval_divide(result, si_type(1), da); - return; - } - - typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type an; - typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type max_an = - std::numeric_limits<typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type>::is_specialized ? (std::numeric_limits<typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type>::max)() : static_cast<typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type>(1) << (sizeof(typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type) * CHAR_BIT - 2); - typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type min_an = - std::numeric_limits<typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type>::is_specialized ? (std::numeric_limits<typename boost::multiprecision::detail::canonical<std::intmax_t, T>::type>::min)() : -min_an; - - T fa; - BOOST_MP_TRY - { - eval_convert_to(&an, a); - if (a.compare(an) == 0) - { - detail::pow_imp(result, x, an, std::integral_constant<bool, true>()); - return; - } - } - BOOST_MP_CATCH(const std::exception&) - { - // conversion failed, just fall through, value is not an integer. - an = (std::numeric_limits<std::intmax_t>::max)(); - } - BOOST_MP_CATCH_END - if ((eval_get_sign(x) < 0)) - { - typename boost::multiprecision::detail::canonical<std::uintmax_t, T>::type aun; - BOOST_MP_TRY - { - eval_convert_to(&aun, a); - if (a.compare(aun) == 0) - { - fa = x; - fa.negate(); - eval_pow(result, fa, a); - if (aun & 1u) - result.negate(); - return; - } - } - BOOST_MP_CATCH(const std::exception&) - { - // conversion failed, just fall through, value is not an integer. - } - BOOST_MP_CATCH_END - - eval_floor(result, a); - // -1^INF is a special case in C99: - if ((x.compare(si_type(-1)) == 0) && (eval_fpclassify(a) == FP_INFINITE)) - { - result = si_type(1); - } - else if (a.compare(result) == 0) - { - // exponent is so large we have no fractional part: - if (x.compare(si_type(-1)) < 0) - { - result = std::numeric_limits<number<T, et_on> >::infinity().backend(); - } - else - { - result = si_type(0); - } - } - else if (type == FP_INFINITE) - { - result = std::numeric_limits<number<T, et_on> >::infinity().backend(); - } - else BOOST_IF_CONSTEXPR (std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result of pow is undefined or non-real and there is no NaN for this number type.")); - } - return; - } - - T t, da; - - eval_subtract(da, a, an); - - if ((x.compare(fp_type(0.5)) >= 0) && (x.compare(fp_type(0.9)) < 0) && (an < max_an) && (an > min_an)) - { - if (a.compare(fp_type(1e-5f)) <= 0) - { - // Series expansion for small a. - eval_log(t, x); - eval_multiply(t, a); - hyp0F0(result, t); - return; - } - else - { - // Series expansion for moderately sized x. Note that for large power of a, - // the power of the integer part of a is calculated using the pown function. - if (an) - { - da.negate(); - t = si_type(1); - eval_subtract(t, x); - hyp1F0(result, da, t); - detail::pow_imp(t, x, an, std::integral_constant<bool, true>()); - eval_multiply(result, t); - } - else - { - da = a; - da.negate(); - t = si_type(1); - eval_subtract(t, x); - hyp1F0(result, da, t); - } - } - } - else - { - // Series expansion for pow(x, a). Note that for large power of a, the power - // of the integer part of a is calculated using the pown function. - if (an) - { - eval_log(t, x); - eval_multiply(t, da); - eval_exp(result, t); - detail::pow_imp(t, x, an, std::integral_constant<bool, true>()); - eval_multiply(result, t); - } - else - { - eval_log(t, x); - eval_multiply(t, a); - eval_exp(result, t); - } - } -} - -template <class T, class A> -#if BOOST_WORKAROUND(BOOST_MSVC, < 1800) -inline typename std::enable_if<!boost::multiprecision::detail::is_integral<A>::value, void>::type -#else -inline typename std::enable_if<is_compatible_arithmetic_type<A, number<T> >::value && !boost::multiprecision::detail::is_integral<A>::value, void>::type -#endif -eval_pow(T& result, const T& x, const A& a) -{ - // Note this one is restricted to float arguments since pow.hpp already has a version for - // integer powers.... - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c; - c = a; - eval_pow(result, x, c); -} - -template <class T, class A> -#if BOOST_WORKAROUND(BOOST_MSVC, < 1800) -inline void -#else -inline typename std::enable_if<is_compatible_arithmetic_type<A, number<T> >::value, void>::type -#endif -eval_pow(T& result, const A& x, const T& a) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c; - c = x; - eval_pow(result, c, a); -} - -template <class T> -void eval_exp2(T& result, const T& arg) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The log function is only valid for floating point types."); - - // Check for pure-integer arguments which can be either signed or unsigned. - typename boost::multiprecision::detail::canonical<typename T::exponent_type, T>::type i; - T temp; - BOOST_MP_TRY - { - eval_trunc(temp, arg); - eval_convert_to(&i, temp); - if (arg.compare(i) == 0) - { - temp = static_cast<typename std::tuple_element<0, typename T::unsigned_types>::type>(1u); - eval_ldexp(result, temp, i); - return; - } - } - #ifdef BOOST_MP_MATH_AVAILABLE - BOOST_MP_CATCH(const boost::math::rounding_error&) - { /* Fallthrough */ - } - #endif - BOOST_MP_CATCH(const std::runtime_error&) - { /* Fallthrough */ - } - BOOST_MP_CATCH_END - - temp = static_cast<typename std::tuple_element<0, typename T::unsigned_types>::type>(2u); - eval_pow(result, temp, arg); -} - -namespace detail { - -template <class T> -void small_sinh_series(T x, T& result) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - bool neg = eval_get_sign(x) < 0; - if (neg) - x.negate(); - T p(x); - T mult(x); - eval_multiply(mult, x); - result = x; - ui_type k = 1; - - T lim(x); - eval_ldexp(lim, lim, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - - do - { - eval_multiply(p, mult); - eval_divide(p, ++k); - eval_divide(p, ++k); - eval_add(result, p); - } while (p.compare(lim) >= 0); - if (neg) - result.negate(); -} - -template <class T> -void sinhcosh(const T& x, T* p_sinh, T* p_cosh) -{ - using ui_type = typename boost::multiprecision::detail::canonical<unsigned, T>::type; - using fp_type = typename std::tuple_element<0, typename T::float_types>::type ; - - switch (eval_fpclassify(x)) - { - case FP_NAN: - errno = EDOM; - // fallthrough... - case FP_INFINITE: - if (p_sinh) - *p_sinh = x; - if (p_cosh) - { - *p_cosh = x; - if (eval_get_sign(x) < 0) - p_cosh->negate(); - } - return; - case FP_ZERO: - if (p_sinh) - *p_sinh = x; - if (p_cosh) - *p_cosh = ui_type(1); - return; - default:; - } - - bool small_sinh = eval_get_sign(x) < 0 ? x.compare(fp_type(-0.5)) > 0 : x.compare(fp_type(0.5)) < 0; - - if (p_cosh || !small_sinh) - { - T e_px, e_mx; - eval_exp(e_px, x); - eval_divide(e_mx, ui_type(1), e_px); - if (eval_signbit(e_mx) != eval_signbit(e_px)) - e_mx.negate(); // Handles lack of signed zero in some types - - if (p_sinh) - { - if (small_sinh) - { - small_sinh_series(x, *p_sinh); - } - else - { - eval_subtract(*p_sinh, e_px, e_mx); - eval_ldexp(*p_sinh, *p_sinh, -1); - } - } - if (p_cosh) - { - eval_add(*p_cosh, e_px, e_mx); - eval_ldexp(*p_cosh, *p_cosh, -1); - } - } - else - { - small_sinh_series(x, *p_sinh); - } -} - -} // namespace detail - -template <class T> -inline void eval_sinh(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The sinh function is only valid for floating point types."); - detail::sinhcosh(x, &result, static_cast<T*>(0)); -} - -template <class T> -inline void eval_cosh(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The cosh function is only valid for floating point types."); - detail::sinhcosh(x, static_cast<T*>(0), &result); -} - -template <class T> -inline void eval_tanh(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The tanh function is only valid for floating point types."); - T c; - detail::sinhcosh(x, &result, &c); - if ((eval_fpclassify(result) == FP_INFINITE) && (eval_fpclassify(c) == FP_INFINITE)) - { - bool s = eval_signbit(result) != eval_signbit(c); - result = static_cast<typename std::tuple_element<0, typename T::unsigned_types>::type>(1u); - if (s) - result.negate(); - return; - } - eval_divide(result, c); -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trig.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trig.hpp deleted file mode 100644 index 56476c5517..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trig.hpp +++ /dev/null @@ -1,1058 +0,0 @@ - -// Copyright Christopher Kormanyos 2002 - 2011. -// Copyright 2011 John Maddock. -// 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) - -// This work is based on an earlier work: -// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", -// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 -// -// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp -// - -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 6326) // comparison of two constants -#pragma warning(disable : 4127) // conditional expression is constant -#endif - -template <class T> -void hyp0F1(T& result, const T& b, const T& x) -{ - using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - - // Compute the series representation of Hypergeometric0F1 taken from - // http://functions.wolfram.com/HypergeometricFunctions/Hypergeometric0F1/06/01/01/ - // There are no checks on input range or parameter boundaries. - - T x_pow_n_div_n_fact(x); - T pochham_b(b); - T bp(b); - - eval_divide(result, x_pow_n_div_n_fact, pochham_b); - eval_add(result, ui_type(1)); - - si_type n; - - T tol; - tol = ui_type(1); - eval_ldexp(tol, tol, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - eval_multiply(tol, result); - if (eval_get_sign(tol) < 0) - tol.negate(); - T term; - - const int series_limit = - boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100 - ? 100 - : boost::multiprecision::detail::digits2<number<T, et_on> >::value(); - // Series expansion of hyperg_0f1(; b; x). - for (n = 2; n < series_limit; ++n) - { - eval_multiply(x_pow_n_div_n_fact, x); - eval_divide(x_pow_n_div_n_fact, n); - eval_increment(bp); - eval_multiply(pochham_b, bp); - - eval_divide(term, x_pow_n_div_n_fact, pochham_b); - eval_add(result, term); - - bool neg_term = eval_get_sign(term) < 0; - if (neg_term) - term.negate(); - if (term.compare(tol) <= 0) - break; - } - - if (n >= series_limit) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("H0F1 Failed to Converge")); -} - -template <class T, unsigned N, bool b = boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<T> >::value> -struct scoped_N_precision -{ - template <class U> - scoped_N_precision(U const&) {} - template <class U> - void reduce(U&) {} -}; - -template <class T, unsigned N> -struct scoped_N_precision<T, N, true> -{ - unsigned old_precision, old_arg_precision; - scoped_N_precision(T& arg) - { - old_precision = T::thread_default_precision(); - old_arg_precision = arg.precision(); - T::thread_default_precision(old_arg_precision * N); - arg.precision(old_arg_precision * N); - } - ~scoped_N_precision() - { - T::thread_default_precision(old_precision); - } - void reduce(T& arg) - { - arg.precision(old_arg_precision); - } -}; - -template <class T> -void reduce_n_half_pi(T& arg, const T& n, bool go_down) -{ - // - // We need to perform argument reduction at 3 times the precision of arg - // in order to ensure a correct result up to arg = 1/epsilon. Beyond that - // the value of n will have been incorrectly calculated anyway since it will - // have a value greater than 1/epsilon and no longer be an exact integer value. - // - // More information in ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng. - // - // There are two mutually exclusive ways to achieve this, both of which are - // supported here: - // 1) To define a fixed precision type with 3 times the precision for the calculation. - // 2) To dynamically increase the precision of the variables. - // - using reduction_type = typename boost::multiprecision::detail::transcendental_reduction_type<T>::type; - // - // Make a copy of the arg at higher precision: - // - reduction_type big_arg(arg); - // - // Dynamically increase precision when supported, this increases the default - // and ups the precision of big_arg to match: - // - scoped_N_precision<T, 3> scoped_precision(big_arg); - // - // High precision PI: - // - reduction_type reduction = get_constant_pi<reduction_type>(); - eval_ldexp(reduction, reduction, -1); // divide by 2 - eval_multiply(reduction, n); - - BOOST_MATH_INSTRUMENT_CODE(big_arg.str(10, std::ios_base::scientific)); - BOOST_MATH_INSTRUMENT_CODE(reduction.str(10, std::ios_base::scientific)); - - if (go_down) - eval_subtract(big_arg, reduction, big_arg); - else - eval_subtract(big_arg, reduction); - arg = T(big_arg); - // - // If arg is a variable precision type, then we have just copied the - // precision of big_arg s well it's value. Reduce the precision now: - // - scoped_precision.reduce(arg); - BOOST_MATH_INSTRUMENT_CODE(big_arg.str(10, std::ios_base::scientific)); - BOOST_MATH_INSTRUMENT_CODE(arg.str(10, std::ios_base::scientific)); -} - -template <class T> -void eval_sin(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The sin function is only valid for floating point types."); - BOOST_MATH_INSTRUMENT_CODE(x.str(0, std::ios_base::scientific)); - if (&result == &x) - { - T temp; - eval_sin(temp, x); - result = temp; - return; - } - - using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - using fp_type = typename std::tuple_element<0, typename T::float_types>::type ; - - switch (eval_fpclassify(x)) - { - case FP_INFINITE: - case FP_NAN: - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type.")); - return; - case FP_ZERO: - result = x; - return; - default:; - } - - // Local copy of the argument - T xx = x; - - // Analyze and prepare the phase of the argument. - // Make a local, positive copy of the argument, xx. - // The argument xx will be reduced to 0 <= xx <= pi/2. - bool b_negate_sin = false; - - if (eval_get_sign(x) < 0) - { - xx.negate(); - b_negate_sin = !b_negate_sin; - } - - T n_pi, t; - T half_pi = get_constant_pi<T>(); - eval_ldexp(half_pi, half_pi, -1); // divide by 2 - // Remove multiples of pi/2. - if (xx.compare(half_pi) > 0) - { - eval_divide(n_pi, xx, half_pi); - eval_trunc(n_pi, n_pi); - t = ui_type(4); - eval_fmod(t, n_pi, t); - bool b_go_down = false; - if (t.compare(ui_type(1)) == 0) - { - b_go_down = true; - } - else if (t.compare(ui_type(2)) == 0) - { - b_negate_sin = !b_negate_sin; - } - else if (t.compare(ui_type(3)) == 0) - { - b_negate_sin = !b_negate_sin; - b_go_down = true; - } - - if (b_go_down) - eval_increment(n_pi); - // - // If n_pi is > 1/epsilon, then it is no longer an exact integer value - // but an approximation. As a result we can no longer reliably reduce - // xx to 0 <= xx < pi/2, nor can we tell the sign of the result as we need - // n_pi % 4 for that, but that will always be zero in this situation. - // We could use a higher precision type for n_pi, along with division at - // higher precision, but that's rather expensive. So for now we do not support - // this, and will see if anyone complains and has a legitimate use case. - // - if (n_pi.compare(get_constant_one_over_epsilon<T>()) > 0) - { - result = ui_type(0); - return; - } - - reduce_n_half_pi(xx, n_pi, b_go_down); - // - // Post reduction we may be a few ulp below zero or above pi/2 - // given that n_pi was calculated at working precision and not - // at the higher precision used for reduction. Correct that now: - // - if (eval_get_sign(xx) < 0) - { - xx.negate(); - b_negate_sin = !b_negate_sin; - } - if (xx.compare(half_pi) > 0) - { - eval_ldexp(half_pi, half_pi, 1); - eval_subtract(xx, half_pi, xx); - eval_ldexp(half_pi, half_pi, -1); - b_go_down = !b_go_down; - } - - BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific)); - BOOST_MATH_INSTRUMENT_CODE(n_pi.str(0, std::ios_base::scientific)); - BOOST_MP_ASSERT(xx.compare(half_pi) <= 0); - BOOST_MP_ASSERT(xx.compare(ui_type(0)) >= 0); - } - - t = half_pi; - eval_subtract(t, xx); - - const bool b_zero = eval_get_sign(xx) == 0; - const bool b_pi_half = eval_get_sign(t) == 0; - - BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific)); - BOOST_MATH_INSTRUMENT_CODE(t.str(0, std::ios_base::scientific)); - - // Check if the reduced argument is very close to 0 or pi/2. - const bool b_near_zero = xx.compare(fp_type(1e-1)) < 0; - const bool b_near_pi_half = t.compare(fp_type(1e-1)) < 0; - - if (b_zero) - { - result = ui_type(0); - } - else if (b_pi_half) - { - result = ui_type(1); - } - else if (b_near_zero) - { - eval_multiply(t, xx, xx); - eval_divide(t, si_type(-4)); - T t2; - t2 = fp_type(1.5); - hyp0F1(result, t2, t); - BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific)); - eval_multiply(result, xx); - } - else if (b_near_pi_half) - { - eval_multiply(t, t); - eval_divide(t, si_type(-4)); - T t2; - t2 = fp_type(0.5); - hyp0F1(result, t2, t); - BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific)); - } - else - { - // Scale to a small argument for an efficient Taylor series, - // implemented as a hypergeometric function. Use a standard - // divide by three identity a certain number of times. - // Here we use division by 3^9 --> (19683 = 3^9). - - constexpr si_type n_scale = 9; - constexpr si_type n_three_pow_scale = static_cast<si_type>(19683L); - - eval_divide(xx, n_three_pow_scale); - - // Now with small arguments, we are ready for a series expansion. - eval_multiply(t, xx, xx); - eval_divide(t, si_type(-4)); - T t2; - t2 = fp_type(1.5); - hyp0F1(result, t2, t); - BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific)); - eval_multiply(result, xx); - - // Convert back using multiple angle identity. - for (std::int32_t k = static_cast<std::int32_t>(0); k < n_scale; k++) - { - // Rescale the cosine value using the multiple angle identity. - eval_multiply(t2, result, ui_type(3)); - eval_multiply(t, result, result); - eval_multiply(t, result); - eval_multiply(t, ui_type(4)); - eval_subtract(result, t2, t); - } - } - - if (b_negate_sin) - result.negate(); - BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific)); -} - -template <class T> -void eval_cos(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The cos function is only valid for floating point types."); - if (&result == &x) - { - T temp; - eval_cos(temp, x); - result = temp; - return; - } - - using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - - switch (eval_fpclassify(x)) - { - case FP_INFINITE: - case FP_NAN: - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type.")); - return; - case FP_ZERO: - result = ui_type(1); - return; - default:; - } - - // Local copy of the argument - T xx = x; - - // Analyze and prepare the phase of the argument. - // Make a local, positive copy of the argument, xx. - // The argument xx will be reduced to 0 <= xx <= pi/2. - bool b_negate_cos = false; - - if (eval_get_sign(x) < 0) - { - xx.negate(); - } - BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific)); - - T n_pi, t; - T half_pi = get_constant_pi<T>(); - eval_ldexp(half_pi, half_pi, -1); // divide by 2 - // Remove even multiples of pi. - if (xx.compare(half_pi) > 0) - { - eval_divide(t, xx, half_pi); - eval_trunc(n_pi, t); - // - // If n_pi is > 1/epsilon, then it is no longer an exact integer value - // but an approximation. As a result we can no longer reliably reduce - // xx to 0 <= xx < pi/2, nor can we tell the sign of the result as we need - // n_pi % 4 for that, but that will always be zero in this situation. - // We could use a higher precision type for n_pi, along with division at - // higher precision, but that's rather expensive. So for now we do not support - // this, and will see if anyone complains and has a legitimate use case. - // - if (n_pi.compare(get_constant_one_over_epsilon<T>()) > 0) - { - result = ui_type(1); - return; - } - BOOST_MATH_INSTRUMENT_CODE(n_pi.str(0, std::ios_base::scientific)); - t = ui_type(4); - eval_fmod(t, n_pi, t); - - bool b_go_down = false; - if (t.compare(ui_type(0)) == 0) - { - b_go_down = true; - } - else if (t.compare(ui_type(1)) == 0) - { - b_negate_cos = true; - } - else if (t.compare(ui_type(2)) == 0) - { - b_go_down = true; - b_negate_cos = true; - } - else - { - BOOST_MP_ASSERT(t.compare(ui_type(3)) == 0); - } - - if (b_go_down) - eval_increment(n_pi); - - reduce_n_half_pi(xx, n_pi, b_go_down); - // - // Post reduction we may be a few ulp below zero or above pi/2 - // given that n_pi was calculated at working precision and not - // at the higher precision used for reduction. Correct that now: - // - if (eval_get_sign(xx) < 0) - { - xx.negate(); - b_negate_cos = !b_negate_cos; - } - if (xx.compare(half_pi) > 0) - { - eval_ldexp(half_pi, half_pi, 1); - eval_subtract(xx, half_pi, xx); - eval_ldexp(half_pi, half_pi, -1); - } - BOOST_MP_ASSERT(xx.compare(half_pi) <= 0); - BOOST_MP_ASSERT(xx.compare(ui_type(0)) >= 0); - } - else - { - n_pi = ui_type(1); - reduce_n_half_pi(xx, n_pi, true); - } - - const bool b_zero = eval_get_sign(xx) == 0; - - if (b_zero) - { - result = si_type(0); - } - else - { - eval_sin(result, xx); - } - if (b_negate_cos) - result.negate(); - BOOST_MATH_INSTRUMENT_CODE(result.str(0, std::ios_base::scientific)); -} - -template <class T> -void eval_tan(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The tan function is only valid for floating point types."); - if (&result == &x) - { - T temp; - eval_tan(temp, x); - result = temp; - return; - } - T t; - eval_sin(result, x); - eval_cos(t, x); - eval_divide(result, t); -} - -template <class T> -void hyp2F1(T& result, const T& a, const T& b, const T& c, const T& x) -{ - // Compute the series representation of hyperg_2f1 taken from - // Abramowitz and Stegun 15.1.1. - // There are no checks on input range or parameter boundaries. - - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - - T x_pow_n_div_n_fact(x); - T pochham_a(a); - T pochham_b(b); - T pochham_c(c); - T ap(a); - T bp(b); - T cp(c); - - eval_multiply(result, pochham_a, pochham_b); - eval_divide(result, pochham_c); - eval_multiply(result, x_pow_n_div_n_fact); - eval_add(result, ui_type(1)); - - T lim; - eval_ldexp(lim, result, 1 - boost::multiprecision::detail::digits2<number<T, et_on> >::value()); - - if (eval_get_sign(lim) < 0) - lim.negate(); - - ui_type n; - T term; - - const unsigned series_limit = - boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100 - ? 100 - : boost::multiprecision::detail::digits2<number<T, et_on> >::value(); - // Series expansion of hyperg_2f1(a, b; c; x). - for (n = 2; n < series_limit; ++n) - { - eval_multiply(x_pow_n_div_n_fact, x); - eval_divide(x_pow_n_div_n_fact, n); - - eval_increment(ap); - eval_multiply(pochham_a, ap); - eval_increment(bp); - eval_multiply(pochham_b, bp); - eval_increment(cp); - eval_multiply(pochham_c, cp); - - eval_multiply(term, pochham_a, pochham_b); - eval_divide(term, pochham_c); - eval_multiply(term, x_pow_n_div_n_fact); - eval_add(result, term); - - if (eval_get_sign(term) < 0) - term.negate(); - if (lim.compare(term) >= 0) - break; - } - if (n > series_limit) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("H2F1 failed to converge.")); -} - -template <class T> -void eval_asin(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The asin function is only valid for floating point types."); - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - using fp_type = typename std::tuple_element<0, typename T::float_types>::type ; - - if (&result == &x) - { - T t(x); - eval_asin(result, t); - return; - } - - switch (eval_fpclassify(x)) - { - case FP_NAN: - case FP_INFINITE: - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type.")); - return; - case FP_ZERO: - result = x; - return; - default:; - } - - const bool b_neg = eval_get_sign(x) < 0; - - T xx(x); - if (b_neg) - xx.negate(); - - int c = xx.compare(ui_type(1)); - if (c > 0) - { - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type.")); - return; - } - else if (c == 0) - { - result = get_constant_pi<T>(); - eval_ldexp(result, result, -1); - if (b_neg) - result.negate(); - return; - } - - if (xx.compare(fp_type(1e-3)) < 0) - { - // http://functions.wolfram.com/ElementaryFunctions/ArcSin/26/01/01/ - eval_multiply(xx, xx); - T t1, t2; - t1 = fp_type(0.5f); - t2 = fp_type(1.5f); - hyp2F1(result, t1, t1, t2, xx); - eval_multiply(result, x); - return; - } - else if (xx.compare(fp_type(1 - 5e-2f)) > 0) - { - // http://functions.wolfram.com/ElementaryFunctions/ArcSin/26/01/01/ - // This branch is simlilar in complexity to Newton iterations down to - // the above limit. It is *much* more accurate. - T dx1; - T t1, t2; - eval_subtract(dx1, ui_type(1), xx); - t1 = fp_type(0.5f); - t2 = fp_type(1.5f); - eval_ldexp(dx1, dx1, -1); - hyp2F1(result, t1, t1, t2, dx1); - eval_ldexp(dx1, dx1, 2); - eval_sqrt(t1, dx1); - eval_multiply(result, t1); - eval_ldexp(t1, get_constant_pi<T>(), -1); - result.negate(); - eval_add(result, t1); - if (b_neg) - result.negate(); - return; - } -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - using guess_type = typename boost::multiprecision::detail::canonical<long double, T>::type; -#else - using guess_type = fp_type; -#endif - // Get initial estimate using standard math function asin. - guess_type dd; - eval_convert_to(&dd, xx); - - result = (guess_type)(std::asin(dd)); - - // Newton-Raphson iteration, we should double our precision with each iteration, - // in practice this seems to not quite work in all cases... so terminate when we - // have at least 2/3 of the digits correct on the assumption that the correction - // we've just added will finish the job... - - std::intmax_t current_precision = eval_ilogb(result); - std::intmax_t target_precision = std::numeric_limits<number<T> >::is_specialized ? - current_precision - 1 - (std::numeric_limits<number<T> >::digits * 2) / 3 - : current_precision - 1 - (boost::multiprecision::detail::digits2<number<T> >::value() * 2) / 3; - - // Newton-Raphson iteration - while (current_precision > target_precision) - { - T sine, cosine; - eval_sin(sine, result); - eval_cos(cosine, result); - eval_subtract(sine, xx); - eval_divide(sine, cosine); - eval_subtract(result, sine); - current_precision = eval_ilogb(sine); - if (current_precision <= (std::numeric_limits<typename T::exponent_type>::min)() + 1) - break; - } - if (b_neg) - result.negate(); -} - -template <class T> -inline void eval_acos(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The acos function is only valid for floating point types."); - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - - switch (eval_fpclassify(x)) - { - case FP_NAN: - case FP_INFINITE: - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type.")); - return; - case FP_ZERO: - result = get_constant_pi<T>(); - eval_ldexp(result, result, -1); // divide by two. - return; - } - - T xx; - eval_abs(xx, x); - int c = xx.compare(ui_type(1)); - - if (c > 0) - { - BOOST_IF_CONSTEXPR(std::numeric_limits<number<T, et_on> >::has_quiet_NaN) - { - result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend(); - errno = EDOM; - } - else - BOOST_MP_THROW_EXCEPTION(std::domain_error("Result is undefined or complex and there is no NaN for this number type.")); - return; - } - else if (c == 0) - { - if (eval_get_sign(x) < 0) - result = get_constant_pi<T>(); - else - result = ui_type(0); - return; - } - - using fp_type = typename std::tuple_element<0, typename T::float_types>::type; - - if (xx.compare(fp_type(1e-3)) < 0) - { - // https://functions.wolfram.com/ElementaryFunctions/ArcCos/26/01/01/ - eval_multiply(xx, xx); - T t1, t2; - t1 = fp_type(0.5f); - t2 = fp_type(1.5f); - hyp2F1(result, t1, t1, t2, xx); - eval_multiply(result, x); - eval_ldexp(t1, get_constant_pi<T>(), -1); - result.negate(); - eval_add(result, t1); - return; - } - if (eval_get_sign(x) < 0) - { - eval_acos(result, xx); - result.negate(); - eval_add(result, get_constant_pi<T>()); - return; - } - else if (xx.compare(fp_type(0.85)) > 0) - { - // https://functions.wolfram.com/ElementaryFunctions/ArcCos/26/01/01/ - // This branch is simlilar in complexity to Newton iterations down to - // the above limit. It is *much* more accurate. - T dx1; - T t1, t2; - eval_subtract(dx1, ui_type(1), xx); - t1 = fp_type(0.5f); - t2 = fp_type(1.5f); - eval_ldexp(dx1, dx1, -1); - hyp2F1(result, t1, t1, t2, dx1); - eval_ldexp(dx1, dx1, 2); - eval_sqrt(t1, dx1); - eval_multiply(result, t1); - return; - } - -#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS - using guess_type = typename boost::multiprecision::detail::canonical<long double, T>::type; -#else - using guess_type = fp_type; -#endif - // Get initial estimate using standard math function asin. - guess_type dd; - eval_convert_to(&dd, xx); - - result = (guess_type)(std::acos(dd)); - - // Newton-Raphson iteration, we should double our precision with each iteration, - // in practice this seems to not quite work in all cases... so terminate when we - // have at least 2/3 of the digits correct on the assumption that the correction - // we've just added will finish the job... - - std::intmax_t current_precision = eval_ilogb(result); - std::intmax_t target_precision = std::numeric_limits<number<T> >::is_specialized ? - current_precision - 1 - (std::numeric_limits<number<T> >::digits * 2) / 3 - : current_precision - 1 - (boost::multiprecision::detail::digits2<number<T> >::value() * 2) / 3; - - // Newton-Raphson iteration - while (current_precision > target_precision) - { - T sine, cosine; - eval_sin(sine, result); - eval_cos(cosine, result); - eval_subtract(cosine, xx); - cosine.negate(); - eval_divide(cosine, sine); - eval_subtract(result, cosine); - current_precision = eval_ilogb(cosine); - if (current_precision <= (std::numeric_limits<typename T::exponent_type>::min)() + 1) - break; - } -} - -template <class T> -void eval_atan(T& result, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The atan function is only valid for floating point types."); - using si_type = typename boost::multiprecision::detail::canonical<std::int32_t, T>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - using fp_type = typename std::tuple_element<0, typename T::float_types>::type ; - - switch (eval_fpclassify(x)) - { - case FP_NAN: - result = x; - errno = EDOM; - return; - case FP_ZERO: - result = x; - return; - case FP_INFINITE: - if (eval_get_sign(x) < 0) - { - eval_ldexp(result, get_constant_pi<T>(), -1); - result.negate(); - } - else - eval_ldexp(result, get_constant_pi<T>(), -1); - return; - default:; - } - - const bool b_neg = eval_get_sign(x) < 0; - - T xx(x); - if (b_neg) - xx.negate(); - - if (xx.compare(fp_type(0.1)) < 0) - { - T t1, t2, t3; - t1 = ui_type(1); - t2 = fp_type(0.5f); - t3 = fp_type(1.5f); - eval_multiply(xx, xx); - xx.negate(); - hyp2F1(result, t1, t2, t3, xx); - eval_multiply(result, x); - return; - } - - if (xx.compare(fp_type(10)) > 0) - { - T t1, t2, t3; - t1 = fp_type(0.5f); - t2 = ui_type(1u); - t3 = fp_type(1.5f); - eval_multiply(xx, xx); - eval_divide(xx, si_type(-1), xx); - hyp2F1(result, t1, t2, t3, xx); - eval_divide(result, x); - if (!b_neg) - result.negate(); - eval_ldexp(t1, get_constant_pi<T>(), -1); - eval_add(result, t1); - if (b_neg) - result.negate(); - return; - } - - // Get initial estimate using standard math function atan. - fp_type d; - eval_convert_to(&d, xx); - result = fp_type(std::atan(d)); - - // Newton-Raphson iteration, we should double our precision with each iteration, - // in practice this seems to not quite work in all cases... so terminate when we - // have at least 2/3 of the digits correct on the assumption that the correction - // we've just added will finish the job... - - std::intmax_t current_precision = eval_ilogb(result); - std::intmax_t target_precision = std::numeric_limits<number<T> >::is_specialized ? - current_precision - 1 - (std::numeric_limits<number<T> >::digits * 2) / 3 - : current_precision - 1 - (boost::multiprecision::detail::digits2<number<T> >::value() * 2) / 3; - - T s, c, t; - while (current_precision > target_precision) - { - eval_sin(s, result); - eval_cos(c, result); - eval_multiply(t, xx, c); - eval_subtract(t, s); - eval_multiply(s, t, c); - eval_add(result, s); - current_precision = eval_ilogb(s); - if (current_precision <= (std::numeric_limits<typename T::exponent_type>::min)() + 1) - break; - } - if (b_neg) - result.negate(); -} - -template <class T> -void eval_atan2(T& result, const T& y, const T& x) -{ - static_assert(number_category<T>::value == number_kind_floating_point, "The atan2 function is only valid for floating point types."); - if (&result == &y) - { - T temp(y); - eval_atan2(result, temp, x); - return; - } - else if (&result == &x) - { - T temp(x); - eval_atan2(result, y, temp); - return; - } - - using ui_type = typename boost::multiprecision::detail::canonical<std::uint32_t, T>::type; - - switch (eval_fpclassify(y)) - { - case FP_NAN: - result = y; - errno = EDOM; - return; - case FP_ZERO: - { - if (eval_signbit(x)) - { - result = get_constant_pi<T>(); - if (eval_signbit(y)) - result.negate(); - } - else - { - result = y; // Note we allow atan2(0,0) to be +-zero, even though it's mathematically undefined - } - return; - } - case FP_INFINITE: - { - if (eval_fpclassify(x) == FP_INFINITE) - { - if (eval_signbit(x)) - { - // 3Pi/4 - eval_ldexp(result, get_constant_pi<T>(), -2); - eval_subtract(result, get_constant_pi<T>()); - if (eval_get_sign(y) >= 0) - result.negate(); - } - else - { - // Pi/4 - eval_ldexp(result, get_constant_pi<T>(), -2); - if (eval_get_sign(y) < 0) - result.negate(); - } - } - else - { - eval_ldexp(result, get_constant_pi<T>(), -1); - if (eval_get_sign(y) < 0) - result.negate(); - } - return; - } - } - - switch (eval_fpclassify(x)) - { - case FP_NAN: - result = x; - errno = EDOM; - return; - case FP_ZERO: - { - eval_ldexp(result, get_constant_pi<T>(), -1); - if (eval_get_sign(y) < 0) - result.negate(); - return; - } - case FP_INFINITE: - if (eval_get_sign(x) > 0) - result = ui_type(0); - else - result = get_constant_pi<T>(); - if (eval_get_sign(y) < 0) - result.negate(); - return; - } - - T xx; - eval_divide(xx, y, x); - if (eval_get_sign(xx) < 0) - xx.negate(); - - eval_atan(result, xx); - - // Determine quadrant (sign) based on signs of x, y - const bool y_neg = eval_get_sign(y) < 0; - const bool x_neg = eval_get_sign(x) < 0; - - if (y_neg != x_neg) - result.negate(); - - if (x_neg) - { - if (y_neg) - eval_subtract(result, get_constant_pi<T>()); - else - eval_add(result, get_constant_pi<T>()); - } -} -template <class T, class A> -inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_atan2(T& result, const T& x, const A& a) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c; - c = a; - eval_atan2(result, x, c); -} - -template <class T, class A> -inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, void>::type eval_atan2(T& result, const A& x, const T& a) -{ - using canonical_type = typename boost::multiprecision::detail::canonical<A, T>::type ; - using cast_type = typename std::conditional<std::is_same<A, canonical_type>::value, T, canonical_type>::type; - cast_type c; - c = x; - eval_atan2(result, c, a); -} - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trunc.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trunc.hpp deleted file mode 100644 index ce440314fd..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trunc.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2022 Matt Borland. 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) - -#ifndef BOOST_MP_DETAIL_FUNCTIONS_TRUNC_HPP -#define BOOST_MP_DETAIL_FUNCTIONS_TRUNC_HPP - -#include <cmath> -#include <limits> -#include <stdexcept> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> - -#ifdef BOOST_MP_MATH_AVAILABLE -#include <boost/math/special_functions/trunc.hpp> -#endif - -namespace boost { namespace multiprecision { namespace detail { - -namespace impl { - -template <typename T> -inline T trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg) -{ - using std::floor; - using std::ceil; - - return (arg > 0) ? floor(arg) : ceil(arg); -} - -} // namespace impl - -#ifdef BOOST_MP_MATH_AVAILABLE - -template <typename T> -inline long long lltrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg) -{ - return boost::math::lltrunc(arg); -} - -template <typename T> -inline int itrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg) -{ - return boost::math::itrunc(arg); -} - -#else - -template <typename T> -inline long long lltrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg) -{ - if (arg > LLONG_MAX) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("arg cannot be converted into a long long")); - } - - return static_cast<long long>(boost::multiprecision::detail::impl::trunc(arg)); -} - -template <typename T> -inline int itrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg) -{ - if (arg > static_cast<T>(INT_MAX)) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("arg cannot be converted into an int")); - } - - return static_cast<int>(boost::multiprecision::detail::impl::trunc(arg)); -} - -#endif - -}}} // Namespaces - -#endif // BOOST_MP_DETAIL_FUNCTIONS_TRUNC_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/generic_interconvert.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/generic_interconvert.hpp deleted file mode 100644 index 61a9ffbda5..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/generic_interconvert.hpp +++ /dev/null @@ -1,687 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 John Maddock. 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) - -#ifndef BOOST_MP_GENERIC_INTERCONVERT_HPP -#define BOOST_MP_GENERIC_INTERCONVERT_HPP - -#include <cmath> -#include <limits> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/default_ops.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/assert.hpp> -#include <boost/multiprecision/detail/functions/trunc.hpp> - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4127 6326) -#endif - -namespace boost { namespace multiprecision { namespace detail { - -template <class To, class From> -inline To do_cast(const From& from) -{ - return static_cast<To>(from); -} -template <class To, class B, ::boost::multiprecision::expression_template_option et> -inline To do_cast(const number<B, et>& from) -{ - return from.template convert_to<To>(); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_floating_point>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/) -{ - using default_ops::eval_add; - using default_ops::eval_bitwise_and; - using default_ops::eval_convert_to; - using default_ops::eval_get_sign; - using default_ops::eval_is_zero; - using default_ops::eval_ldexp; - using default_ops::eval_right_shift; - // smallest unsigned type handled natively by "From" is likely to be it's limb_type: - using l_limb_type = typename canonical<unsigned char, From>::type; - // get the corresponding type that we can assign to "To": - using to_type = typename canonical<l_limb_type, To>::type; - From t(from); - bool is_neg = eval_get_sign(t) < 0; - if (is_neg) - t.negate(); - // Pick off the first limb: - l_limb_type limb; - l_limb_type mask = static_cast<l_limb_type>(~static_cast<l_limb_type>(0)); - From fl; - eval_bitwise_and(fl, t, mask); - eval_convert_to(&limb, fl); - to = static_cast<to_type>(limb); - eval_right_shift(t, std::numeric_limits<l_limb_type>::digits); - // - // Then keep picking off more limbs until "t" is zero: - // - To l; - unsigned shift = std::numeric_limits<l_limb_type>::digits; - while (!eval_is_zero(t)) - { - eval_bitwise_and(fl, t, mask); - eval_convert_to(&limb, fl); - l = static_cast<to_type>(limb); - eval_right_shift(t, std::numeric_limits<l_limb_type>::digits); - eval_ldexp(l, l, shift); - eval_add(to, l); - shift += std::numeric_limits<l_limb_type>::digits; - } - // - // Finish off by setting the sign: - // - if (is_neg) - to.negate(); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_integer>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/) -{ - using default_ops::eval_bitwise_and; - using default_ops::eval_bitwise_or; - using default_ops::eval_convert_to; - using default_ops::eval_get_sign; - using default_ops::eval_is_zero; - using default_ops::eval_left_shift; - using default_ops::eval_right_shift; - // smallest unsigned type handled natively by "From" is likely to be it's limb_type: - using limb_type = typename canonical<unsigned char, From>::type; - // get the corresponding type that we can assign to "To": - using to_type = typename canonical<limb_type, To>::type; - From t(from); - bool is_neg = eval_get_sign(t) < 0; - if (is_neg) - t.negate(); - // Pick off the first limb: - limb_type limb; - limb_type mask = static_cast<limb_type>(~static_cast<limb_type>(0)); - From fl; - eval_bitwise_and(fl, t, mask); - eval_convert_to(&limb, fl); - to = static_cast<to_type>(limb); - eval_right_shift(t, std::numeric_limits<limb_type>::digits); - // - // Then keep picking off more limbs until "t" is zero: - // - To l; - unsigned shift = std::numeric_limits<limb_type>::digits; - while (!eval_is_zero(t)) - { - eval_bitwise_and(fl, t, mask); - eval_convert_to(&limb, fl); - l = static_cast<to_type>(limb); - eval_right_shift(t, std::numeric_limits<limb_type>::digits); - eval_left_shift(l, shift); - eval_bitwise_or(to, l); - shift += std::numeric_limits<limb_type>::digits; - } - // - // Finish off by setting the sign: - // - if (is_neg) - to.negate(); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_floating_point>& /*to_type*/, const std::integral_constant<int, number_kind_floating_point>& /*from_type*/) -{ -#ifdef BOOST_MSVC -#pragma warning(push) -//#pragma warning(disable : 4127) -#endif - // - // The code here only works when the radix of "From" is 2, we could try shifting by other - // radixes but it would complicate things.... use a string conversion when the radix is other - // than 2: - // - BOOST_IF_CONSTEXPR(std::numeric_limits<number<From> >::radix != 2) - { - to = from.str(0, std::ios_base::fmtflags()).c_str(); - return; - } - else - { - using ui_type = typename canonical<unsigned char, To>::type; - - using default_ops::eval_add; - using default_ops::eval_convert_to; - using default_ops::eval_fpclassify; - using default_ops::eval_get_sign; - using default_ops::eval_is_zero; - using default_ops::eval_subtract; - - // - // First classify the input, then handle the special cases: - // - int c = eval_fpclassify(from); - - if (c == static_cast<int>(FP_ZERO)) - { - to = ui_type(0); - return; - } - else if (c == static_cast<int>(FP_NAN)) - { - to = static_cast<const char*>("nan"); - return; - } - else if (c == static_cast<int>(FP_INFINITE)) - { - to = static_cast<const char*>("inf"); - if (eval_get_sign(from) < 0) - to.negate(); - return; - } - - typename From::exponent_type e; - From f, term; - to = ui_type(0); - - eval_frexp(f, from, &e); - - constexpr int shift = std::numeric_limits<std::intmax_t>::digits - 1; - - while (!eval_is_zero(f)) - { - // extract int sized bits from f: - eval_ldexp(f, f, shift); - eval_floor(term, f); - e -= shift; - eval_ldexp(to, to, shift); - typename boost::multiprecision::detail::canonical<std::intmax_t, To>::type ll; - eval_convert_to(&ll, term); - eval_add(to, ll); - eval_subtract(f, term); - } - using to_exponent = typename To::exponent_type; - if (e > (std::numeric_limits<to_exponent>::max)()) - { - to = static_cast<const char*>("inf"); - if (eval_get_sign(from) < 0) - to.negate(); - return; - } - if (e < (std::numeric_limits<to_exponent>::min)()) - { - to = ui_type(0); - if (eval_get_sign(from) < 0) - to.negate(); - return; - } - eval_ldexp(to, to, static_cast<to_exponent>(e)); - } -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_rational>& /*to_type*/, const std::integral_constant<int, number_kind_rational>& /*from_type*/) -{ - using to_component_type = typename component_type<number<To> >::type; - - number<From> t(from); - to_component_type n(numerator(t)), d(denominator(t)); - using default_ops::assign_components; - assign_components(to, n.backend(), d.backend()); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_rational>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/) -{ - using to_component_type = typename component_type<number<To> >::type; - - number<From> t(from); - to_component_type n(t), d(1); - using default_ops::assign_components; - assign_components(to, n.backend(), d.backend()); -} - -template <class LargeInteger> -inline typename std::enable_if<is_signed_number<LargeInteger>::value>::type make_positive(LargeInteger& val) -{ - if (val.sign() < 0) - val = -val; -} -template <class LargeInteger> -inline typename std::enable_if<!is_signed_number<LargeInteger>::value>::type make_positive(LargeInteger&){} - -template <class R, class LargeInteger> -R safe_convert_to_float(const LargeInteger& i) -{ - if (!i) - return R(0); - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::is_specialized && std::numeric_limits<R>::max_exponent) - { - using std::ldexp; - - LargeInteger val(i); - make_positive(val); - std::size_t mb = msb(val); - if (mb >= std::numeric_limits<R>::max_exponent) - { - int scale_factor = static_cast<int>(mb) + 1 - std::numeric_limits<R>::max_exponent; - BOOST_MP_ASSERT(scale_factor >= 1); - val >>= scale_factor; - R result = val.template convert_to<R>(); - BOOST_IF_CONSTEXPR(std::numeric_limits<R>::digits == 0 || std::numeric_limits<R>::digits >= std::numeric_limits<R>::max_exponent) - { - // - // Calculate and add on the remainder, only if there are more - // digits in the mantissa that the size of the exponent, in - // other words if we are dropping digits in the conversion - // otherwise: - // - LargeInteger remainder(i); - remainder &= (LargeInteger(1) << scale_factor) - 1; - result += ldexp(safe_convert_to_float<R>(remainder), -scale_factor); - } - return i.sign() < 0 ? static_cast<R>(-result) : result; - } - } - return i.template convert_to<R>(); -} - -template <class To, class Integer> -inline typename std::enable_if<!(is_number<To>::value || std::is_floating_point<To>::value)>::type -generic_convert_rational_to_float_imp(To& result, const Integer& n, const Integer& d, const std::integral_constant<bool, true>&) -{ - // - // If we get here, then there's something about one type or the other - // that prevents an exactly rounded result from being calculated - // (or at least it's not clear how to implement such a thing). - // - using default_ops::eval_divide; - number<To> fn(safe_convert_to_float<number<To> >(n)), fd(safe_convert_to_float<number<To> >(d)); - eval_divide(result, fn.backend(), fd.backend()); -} -template <class To, class Integer> -inline typename std::enable_if<is_number<To>::value || std::is_floating_point<To>::value>::type -generic_convert_rational_to_float_imp(To& result, const Integer& n, const Integer& d, const std::integral_constant<bool, true>&) -{ - // - // If we get here, then there's something about one type or the other - // that prevents an exactly rounded result from being calculated - // (or at least it's not clear how to implement such a thing). - // - To fd(safe_convert_to_float<To>(d)); - result = safe_convert_to_float<To>(n); - result /= fd; -} - -template <class To, class Integer> -typename std::enable_if<is_number<To>::value || std::is_floating_point<To>::value>::type -generic_convert_rational_to_float_imp(To& result, Integer& num, Integer& denom, const std::integral_constant<bool, false>&) -{ - // - // If we get here, then the precision of type To is known, and the integer type is unbounded - // so we can use integer division plus manipulation of the remainder to get an exactly - // rounded result. - // - if (num == 0) - { - result = 0; - return; - } - bool s = false; - if (num < 0) - { - s = true; - num = -num; - } - std::ptrdiff_t denom_bits = msb(denom); - std::ptrdiff_t shift = std::numeric_limits<To>::digits + denom_bits - msb(num); - if (shift > 0) - num <<= shift; - else if (shift < 0) - denom <<= boost::multiprecision::detail::unsigned_abs(shift); - Integer q, r; - divide_qr(num, denom, q, r); - std::ptrdiff_t q_bits = msb(q); - if (q_bits == std::numeric_limits<To>::digits - 1) - { - // - // Round up if 2 * r > denom: - // - r <<= 1; - int c = r.compare(denom); - if (c > 0) - ++q; - else if ((c == 0) && (q & 1u)) - { - ++q; - } - } - else - { - BOOST_MP_ASSERT(q_bits == std::numeric_limits<To>::digits); - // - // We basically already have the rounding info: - // - if (q & 1u) - { - if (r || (q & 2u)) - ++q; - } - } - using std::ldexp; - result = do_cast<To>(q); - result = ldexp(result, static_cast<int>(-shift)); - if (s) - result = -result; -} -template <class To, class Integer> -inline typename std::enable_if<!(is_number<To>::value || std::is_floating_point<To>::value)>::type -generic_convert_rational_to_float_imp(To& result, Integer& num, Integer& denom, const std::integral_constant<bool, false>& tag) -{ - number<To> t; - generic_convert_rational_to_float_imp(t, num, denom, tag); - result = t.backend(); -} - -template <class To, class From> -inline void generic_convert_rational_to_float(To& result, const From& f) -{ - // - // Type From is always a Backend to number<>, or an - // instance of number<>, but we allow - // To to be either a Backend type, or a real number type, - // that way we can call this from generic conversions, and - // from specific conversions to built in types. - // - using actual_from_type = typename std::conditional<is_number<From>::value, From, number<From> >::type ; - using actual_to_type = typename std::conditional<is_number<To>::value || std::is_floating_point<To>::value, To, number<To> >::type ; - using integer_type = typename component_type<actual_from_type>::type ; - using dispatch_tag = std::integral_constant<bool, !std::numeric_limits<integer_type>::is_specialized || std::numeric_limits<integer_type>::is_bounded || !std::numeric_limits<actual_to_type>::is_specialized || !std::numeric_limits<actual_to_type>::is_bounded || (std::numeric_limits<actual_to_type>::radix != 2)>; - - integer_type n(numerator(static_cast<actual_from_type>(f))), d(denominator(static_cast<actual_from_type>(f))); - generic_convert_rational_to_float_imp(result, n, d, dispatch_tag()); -} - -template <class To, class From> -inline void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_floating_point>& /*to_type*/, const std::integral_constant<int, number_kind_rational>& /*from_type*/) -{ - generic_convert_rational_to_float(to, from); -} - -template <class To, class From> -void generic_interconvert_float2rational(To& to, const From& from, const std::integral_constant<int, 2>& /*radix*/) -{ - using std::ldexp; - using std::frexp; - using ui_type = typename std::tuple_element<0, typename To::unsigned_types>::type; - constexpr int shift = std::numeric_limits<long long>::digits; - typename From::exponent_type e; - typename component_type<number<To>>::type num, denom; - number<From> val(from); - val = frexp(val, &e); - while (val) - { - val = ldexp(val, shift); - e -= shift; - long long ll = boost::multiprecision::detail::lltrunc(val); - val -= ll; - num <<= shift; - num += ll; - } - denom = ui_type(1u); - if (e < 0) - denom <<= -e; - else if (e > 0) - num <<= e; - assign_components(to, num.backend(), denom.backend()); -} - -template <class To, class From, int Radix> -void generic_interconvert_float2rational(To& to, const From& from, const std::integral_constant<int, Radix>& /*radix*/) -{ - using std::ilogb; - using std::scalbn; - using std::pow; - using std::abs; - // - // This is almost the same as the binary case above, but we have to use - // scalbn and ilogb rather than ldexp and frexp, we also only extract - // one Radix digit at a time which is terribly inefficient! - // - using ui_type = typename std::tuple_element<0, typename To::unsigned_types>::type; - typename From::exponent_type e; - typename component_type<number<To>>::type num, denom; - number<From> val(from); - - if (!val) - { - to = ui_type(0u); - return; - } - - e = ilogb(val); - val = scalbn(val, -e); - while (val) - { - long long ll = boost::multiprecision::detail::lltrunc(val); - val -= ll; - val = scalbn(val, 1); - num *= Radix; - num += ll; - --e; - } - ++e; - denom = ui_type(Radix); - denom = pow(denom, abs(e)); - if (e > 0) - { - num *= denom; - denom = 1; - } - assign_components(to, num.backend(), denom.backend()); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_rational>& /*to_type*/, const std::integral_constant<int, number_kind_floating_point>& /*from_type*/) -{ - generic_interconvert_float2rational(to, from, std::integral_constant<int, std::numeric_limits<number<From> >::is_specialized ? std::numeric_limits<number<From> >::radix : 2>()); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_integer>& /*to_type*/, const std::integral_constant<int, number_kind_rational>& /*from_type*/) -{ - number<From> t(from); - number<To> result(numerator(t) / denominator(t)); - to = result.backend(); -} - -template <class To, class From> -void generic_interconvert_float2int(To& to, const From& from, const std::integral_constant<int, 2>& /*radix*/) -{ - using std::frexp; - using std::ldexp; - - using exponent_type = typename From::exponent_type; - constexpr exponent_type shift = std::numeric_limits<long long>::digits; - exponent_type e; - number<To> num(0u); - number<From> val(from); - val = frexp(val, &e); - bool neg = false; - if (val.sign() < 0) - { - val.backend().negate(); - neg = true; - } - while (e > 0) - { - exponent_type s = (std::min)(e, shift); - val = ldexp(val, s); - e -= s; - long long ll = boost::multiprecision::detail::lltrunc(val); - val -= ll; - num <<= s; - num += ll; - } - to = num.backend(); - if (neg) - to.negate(); -} - -template <class To, class From, int Radix> -void generic_interconvert_float2int(To& to, const From& from, const std::integral_constant<int, Radix>& /*radix*/) -{ - using std::ilogb; - using std::scalbn; - // - // This is almost the same as the binary case above, but we have to use - // scalbn and ilogb rather than ldexp and frexp, we also only extract - // one Radix digit at a time which is terribly inefficient! - // - typename From::exponent_type e; - number<To> num(0u); - number<From> val(from); - e = ilogb(val); - val = scalbn(val, -e); - while (e >= 0) - { - long long ll = boost::multiprecision::detail::lltrunc(val); - val -= ll; - val = scalbn(val, 1); - num *= Radix; - num += ll; - --e; - } - to = num.backend(); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_integer>& /*to_type*/, const std::integral_constant<int, number_kind_floating_point>& /*from_type*/) -{ - generic_interconvert_float2int(to, from, std::integral_constant<int, (std::numeric_limits<number<From> >::is_specialized ? std::numeric_limits<number<From> >::radix : 2)>()); -} - -template <class To, class From, class tag> -void generic_interconvert_complex_to_scalar(To& to, const From& from, const std::integral_constant<bool, true>&, const tag&) -{ - // We just want the real part, and "to" is the correct type already: - eval_real(to, from); - - To im; - eval_imag(im, from); - if (!eval_is_zero(im)) - BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); -} -template <class To, class From> -void generic_interconvert_complex_to_scalar(To& to, const From& from, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) -{ - using component_number = typename component_type<number<From> >::type; - using component_backend = typename component_number::backend_type ; - // - // Get the real part and copy-construct the result from it: - // - scoped_precision_options<component_number> scope(from); - component_backend r; - generic_interconvert_complex_to_scalar(r, from, std::integral_constant<bool, true>(), std::integral_constant<bool, true>()); - to = r; -} -template <class To, class From> -void generic_interconvert_complex_to_scalar(To& to, const From& from, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) -{ - using component_number = typename component_type<number<From> >::type; - using component_backend = typename component_number::backend_type; - // - // Get the real part and use a generic_interconvert to type To: - // - scoped_precision_options<component_number> scope(from); - component_backend r; - generic_interconvert_complex_to_scalar(r, from, std::integral_constant<bool, true>(), std::integral_constant<bool, true>()); - generic_interconvert(to, r, std::integral_constant<int, number_category<To>::value>(), std::integral_constant<int, number_category<component_backend>::value>()); -} - -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_floating_point>& /*to_type*/, const std::integral_constant<int, number_kind_complex>& /*from_type*/) -{ - using component_number = typename component_type<number<From> >::type; - using component_backend = typename component_number::backend_type ; - - generic_interconvert_complex_to_scalar(to, from, std::integral_constant<bool, std::is_same<component_backend, To>::value>(), std::integral_constant<bool, std::is_constructible<To, const component_backend&>::value>()); -} -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_integer>& /*to_type*/, const std::integral_constant<int, number_kind_complex>& /*from_type*/) -{ - using component_number = typename component_type<number<From> >::type; - using component_backend = typename component_number::backend_type ; - - generic_interconvert_complex_to_scalar(to, from, std::integral_constant<bool, std::is_same<component_backend, To>::value>(), std::integral_constant<bool, std::is_constructible<To, const component_backend&>::value>()); -} -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_rational>& /*to_type*/, const std::integral_constant<int, number_kind_complex>& /*from_type*/) -{ - using component_number = typename component_type<number<From> >::type; - using component_backend = typename component_number::backend_type ; - - generic_interconvert_complex_to_scalar(to, from, std::integral_constant<bool, std::is_same<component_backend, To>::value>(), std::integral_constant<bool, std::is_constructible<To, const component_backend&>::value>()); -} -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_complex>& /*to_type*/, const std::integral_constant<int, number_kind_integer>& /*from_type*/) -{ - using component_number = typename component_type<number<To> >::type; - - scoped_source_precision<number<From> > scope1; - scoped_precision_options<component_number> scope2(number<To>::thread_default_precision(), number<To>::thread_default_variable_precision_options()); - (void)scope1; - (void)scope2; - - number<From> f(from); - component_number scalar(f); - number<To> result(scalar); - to = result.backend(); -} -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_complex>& /*to_type*/, const std::integral_constant<int, number_kind_rational>& /*from_type*/) -{ - using component_number = typename component_type<number<To> >::type; - - scoped_source_precision<number<From> > scope1; - scoped_precision_options<component_number> scope2(number<To>::thread_default_precision(), number<To>::thread_default_variable_precision_options()); - (void)scope1; - (void)scope2; - - number<From> f(from); - component_number scalar(f); - number<To> result(scalar); - to = result.backend(); -} -template <class To, class From> -void generic_interconvert(To& to, const From& from, const std::integral_constant<int, number_kind_complex>& /*to_type*/, const std::integral_constant<int, number_kind_floating_point>& /*from_type*/) -{ - using component_number = typename component_type<number<To> >::type; - - scoped_source_precision<number<From> > scope1; - scoped_precision_options<component_number> scope2(number<To>::thread_default_precision(), number<To>::thread_default_variable_precision_options()); - (void)scope1; - (void)scope2; - - number<From> f(from); - component_number scalar(f); - number<To> result(scalar); - to = result.backend(); -} -template <class To, class From, int Tag1, int Tag2> -void generic_interconvert(To& /*to*/, const From& /*from*/, const std::integral_constant<int, Tag1>& /*to_type*/, const std::integral_constant<int, Tag2>& /*from_type*/) -{ - static_assert(sizeof(To) == 0, "Sorry, you asked for a conversion bewteen types that hasn't been implemented yet!!"); -} - -} -} -} // namespace boost::multiprecision::detail - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_MP_GENERIC_INTERCONVERT_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/hash.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/hash.hpp deleted file mode 100644 index 664680f80c..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/hash.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2021 Matt Borland. 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) - -#ifndef BOOST_MP_DETAIL_HASH_HPP -#define BOOST_MP_DETAIL_HASH_HPP - -#include <cstddef> -#include <functional> -#include <boost/multiprecision/detail/standalone_config.hpp> - -namespace boost { namespace multiprecision { namespace detail { - -template <typename T> -inline std::size_t hash_value(const T& v) -{ - std::hash<T> hasher; - return hasher(v); -} - -#if defined(BOOST_HAS_INT128) - -std::size_t hash_value(const uint128_type& val); - -inline std::size_t hash_value(const int128_type& val) -{ - return hash_value(static_cast<uint128_type>(val)); -} - -#endif - -inline void hash_combine(std::size_t&) {} - -template <typename T, typename... Args> -inline void hash_combine(std::size_t& seed, const T& v, Args... args) -{ - constexpr std::size_t adder = 0x9e3779b9; - seed = seed ^ (hash_value(v) + adder + (seed<<6) + (seed>>2)); - hash_combine(seed, args...); -} - -#if defined(BOOST_HAS_INT128) - -inline std::size_t hash_value(const uint128_type& val) -{ - std::size_t result = static_cast<std::size_t>(val); - hash_combine(result, static_cast<std::size_t>(val >> 64)); - return result; -} - -#endif - -}}} // Namespaces - -#endif // BOOST_MP_DETAIL_HASH_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/integer_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/integer_ops.hpp deleted file mode 100644 index 468e4d7596..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/integer_ops.hpp +++ /dev/null @@ -1,474 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_DETAIL_INTEGER_OPS_HPP -#define BOOST_MP_DETAIL_INTEGER_OPS_HPP - -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> - -namespace boost { namespace multiprecision { - -namespace default_ops { - -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR void eval_qr(const Backend& x, const Backend& y, Backend& q, Backend& r) -{ - eval_divide(q, x, y); - eval_modulus(r, x, y); -} - -template <class Backend, class Integer> -inline BOOST_MP_CXX14_CONSTEXPR Integer eval_integer_modulus(const Backend& x, Integer val) -{ - BOOST_MP_USING_ABS - using default_ops::eval_convert_to; - using default_ops::eval_modulus; - using int_type = typename boost::multiprecision::detail::canonical<Integer, Backend>::type; - Backend t; - eval_modulus(t, x, static_cast<int_type>(val)); - Integer result(0); - eval_convert_to(&result, t); - return abs(result); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_gcd(B& result, const B& a, const B& b) -{ - using default_ops::eval_get_sign; - using default_ops::eval_is_zero; - using default_ops::eval_lsb; - - std::ptrdiff_t shift(0); - - B u(a), v(b); - - int s = eval_get_sign(u); - - /* GCD(0,x) := x */ - if (s < 0) - { - u.negate(); - } - else if (s == 0) - { - result = v; - return; - } - s = eval_get_sign(v); - if (s < 0) - { - v.negate(); - } - else if (s == 0) - { - result = u; - return; - } - - /* Let shift := lg K, where K is the greatest power of 2 - dividing both u and v. */ - - std::size_t us = eval_lsb(u); - std::size_t vs = eval_lsb(v); - shift = static_cast<std::ptrdiff_t>((std::min)(us, vs)); - eval_right_shift(u, us); - eval_right_shift(v, vs); - - do - { - /* Now u and v are both odd, so diff(u, v) is even. - Let u = min(u, v), v = diff(u, v)/2. */ - s = u.compare(v); - if (s > 0) - u.swap(v); - if (s == 0) - break; - eval_subtract(v, u); - vs = eval_lsb(v); - eval_right_shift(v, vs); - } while (true); - - result = u; - eval_left_shift(result, shift); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR void eval_lcm(B& result, const B& a, const B& b) -{ - using ui_type = typename std::tuple_element<0, typename B::unsigned_types>::type; - B t; - eval_gcd(t, a, b); - - if (eval_is_zero(t)) - { - result = static_cast<ui_type>(0); - } - else - { - eval_divide(result, a, t); - eval_multiply(result, b); - } - if (eval_get_sign(result) < 0) - result.negate(); -} - -} // namespace default_ops - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer>::type -divide_qr(const number<Backend, ExpressionTemplates>& x, const number<Backend, ExpressionTemplates>& y, - number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r) -{ - using default_ops::eval_qr; - eval_qr(x.backend(), y.backend(), q.backend(), r.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates, class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer>::type -divide_qr(const number<Backend, ExpressionTemplates>& x, const multiprecision::detail::expression<tag, A1, A2, A3, A4>& y, - number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r) -{ - divide_qr(x, number<Backend, ExpressionTemplates>(y), q, r); -} - -template <class tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer>::type -divide_qr(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x, const number<Backend, ExpressionTemplates>& y, - number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r) -{ - divide_qr(number<Backend, ExpressionTemplates>(x), y, q, r); -} - -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer>::type -divide_qr(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x, const multiprecision::detail::expression<tagb, A1b, A2b, A3b, A4b>& y, - number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r) -{ - divide_qr(number<Backend, ExpressionTemplates>(x), number<Backend, ExpressionTemplates>(y), q, r); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Integer> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value && (number_category<Backend>::value == number_kind_integer), Integer>::type -integer_modulus(const number<Backend, ExpressionTemplates>& x, Integer val) -{ - using default_ops::eval_integer_modulus; - return eval_integer_modulus(x.backend(), val); -} - -template <class tag, class A1, class A2, class A3, class A4, class Integer> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value && (number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer), Integer>::type -integer_modulus(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x, Integer val) -{ - using result_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return integer_modulus(result_type(x), val); -} - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer, std::size_t>::type -lsb(const number<Backend, ExpressionTemplates>& x) -{ - using default_ops::eval_lsb; - return eval_lsb(x.backend()); -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer, std::size_t>::type -lsb(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x) -{ - using number_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type n(x); - using default_ops::eval_lsb; - return eval_lsb(n.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer, std::size_t>::type -msb(const number<Backend, ExpressionTemplates>& x) -{ - using default_ops::eval_msb; - return eval_msb(x.backend()); -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer, std::size_t>::type -msb(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x) -{ - using number_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type n(x); - using default_ops::eval_msb; - return eval_msb(n.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer, bool>::type -bit_test(const number<Backend, ExpressionTemplates>& x, std::size_t index) -{ - using default_ops::eval_bit_test; - return eval_bit_test(x.backend(), index); -} - -template <class tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer, bool>::type -bit_test(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& x, std::size_t index) -{ - using number_type = typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - number_type n(x); - using default_ops::eval_bit_test; - return eval_bit_test(n.backend(), index); -} - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer, number<Backend, ExpressionTemplates>&>::type -bit_set(number<Backend, ExpressionTemplates>& x, std::size_t index) -{ - using default_ops::eval_bit_set; - eval_bit_set(x.backend(), index); - return x; -} - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer, number<Backend, ExpressionTemplates>&>::type -bit_unset(number<Backend, ExpressionTemplates>& x, std::size_t index) -{ - using default_ops::eval_bit_unset; - eval_bit_unset(x.backend(), index); - return x; -} - -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<Backend>::value == number_kind_integer, number<Backend, ExpressionTemplates>&>::type -bit_flip(number<Backend, ExpressionTemplates>& x, std::size_t index) -{ - using default_ops::eval_bit_flip; - eval_bit_flip(x.backend(), index); - return x; -} - -namespace default_ops { - -// -// Within powm, we need a type with twice as many digits as the argument type, define -// a traits class to obtain that type: -// -template <class Backend> -struct double_precision_type -{ - using type = Backend; -}; - -// -// If the exponent is a signed integer type, then we need to -// check the value is positive: -// -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR void check_sign_of_backend(const Backend& v, const std::integral_constant<bool, true>) -{ - if (eval_get_sign(v) < 0) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } -} -template <class Backend> -inline BOOST_MP_CXX14_CONSTEXPR void check_sign_of_backend(const Backend&, const std::integral_constant<bool, false>) {} -// -// Calculate (a^p)%c: -// -template <class Backend> -BOOST_MP_CXX14_CONSTEXPR void eval_powm(Backend& result, const Backend& a, const Backend& p, const Backend& c) -{ - using default_ops::eval_bit_test; - using default_ops::eval_get_sign; - using default_ops::eval_modulus; - using default_ops::eval_multiply; - using default_ops::eval_right_shift; - - using double_type = typename double_precision_type<Backend>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<unsigned char, double_type>::type; - - check_sign_of_backend(p, std::integral_constant<bool, std::numeric_limits<number<Backend> >::is_signed>()); - - double_type x, y(a), b(p), t; - x = ui_type(1u); - - while (eval_get_sign(b) > 0) - { - if (eval_bit_test(b, 0)) - { - eval_multiply(t, x, y); - eval_modulus(x, t, c); - } - eval_multiply(t, y, y); - eval_modulus(y, t, c); - eval_right_shift(b, ui_type(1)); - } - Backend x2(x); - eval_modulus(result, x2, c); -} - -template <class Backend, class Integer> -BOOST_MP_CXX14_CONSTEXPR void eval_powm(Backend& result, const Backend& a, const Backend& p, Integer c) -{ - using double_type = typename double_precision_type<Backend>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<unsigned char, double_type>::type; - using i1_type = typename boost::multiprecision::detail::canonical<Integer, double_type>::type ; - using i2_type = typename boost::multiprecision::detail::canonical<Integer, Backend>::type ; - - using default_ops::eval_bit_test; - using default_ops::eval_get_sign; - using default_ops::eval_modulus; - using default_ops::eval_multiply; - using default_ops::eval_right_shift; - - check_sign_of_backend(p, std::integral_constant<bool, std::numeric_limits<number<Backend> >::is_signed>()); - - if (eval_get_sign(p) < 0) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - - double_type x, y(a), b(p), t; - x = ui_type(1u); - - while (eval_get_sign(b) > 0) - { - if (eval_bit_test(b, 0)) - { - eval_multiply(t, x, y); - eval_modulus(x, t, static_cast<i1_type>(c)); - } - eval_multiply(t, y, y); - eval_modulus(y, t, static_cast<i1_type>(c)); - eval_right_shift(b, ui_type(1)); - } - Backend x2(x); - eval_modulus(result, x2, static_cast<i2_type>(c)); -} - -template <class Backend, class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value >::type eval_powm(Backend& result, const Backend& a, Integer b, const Backend& c) -{ - using double_type = typename double_precision_type<Backend>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<unsigned char, double_type>::type; - - using default_ops::eval_bit_test; - using default_ops::eval_get_sign; - using default_ops::eval_modulus; - using default_ops::eval_multiply; - using default_ops::eval_right_shift; - - double_type x, y(a), t; - x = ui_type(1u); - - while (b > 0) - { - if (b & 1) - { - eval_multiply(t, x, y); - eval_modulus(x, t, c); - } - eval_multiply(t, y, y); - eval_modulus(y, t, c); - b >>= 1; - } - Backend x2(x); - eval_modulus(result, x2, c); -} - -template <class Backend, class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value>::type eval_powm(Backend& result, const Backend& a, Integer b, const Backend& c) -{ - if (b < 0) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - eval_powm(result, a, static_cast<typename boost::multiprecision::detail::make_unsigned<Integer>::type>(b), c); -} - -template <class Backend, class Integer1, class Integer2> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer1>::value >::type eval_powm(Backend& result, const Backend& a, Integer1 b, Integer2 c) -{ - using double_type = typename double_precision_type<Backend>::type ; - using ui_type = typename boost::multiprecision::detail::canonical<unsigned char, double_type>::type; - using i1_type = typename boost::multiprecision::detail::canonical<Integer1, double_type>::type ; - using i2_type = typename boost::multiprecision::detail::canonical<Integer2, Backend>::type ; - - using default_ops::eval_bit_test; - using default_ops::eval_get_sign; - using default_ops::eval_modulus; - using default_ops::eval_multiply; - using default_ops::eval_right_shift; - - double_type x, y(a), t; - x = ui_type(1u); - - while (b > 0) - { - if (b & 1) - { - eval_multiply(t, x, y); - eval_modulus(x, t, static_cast<i1_type>(c)); - } - eval_multiply(t, y, y); - eval_modulus(y, t, static_cast<i1_type>(c)); - b >>= 1; - } - Backend x2(x); - eval_modulus(result, x2, static_cast<i2_type>(c)); -} - -template <class Backend, class Integer1, class Integer2> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_signed<Integer1>::value && boost::multiprecision::detail::is_integral<Integer1>::value>::type eval_powm(Backend& result, const Backend& a, Integer1 b, Integer2 c) -{ - if (b < 0) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - eval_powm(result, a, static_cast<typename boost::multiprecision::detail::make_unsigned<Integer1>::type>(b), c); -} - -struct powm_func -{ - template <class T, class U, class V> - BOOST_MP_CXX14_CONSTEXPR void operator()(T& result, const T& b, const U& p, const V& m) const - { - eval_powm(result, b, p, m); - } - template <class R, class T, class U, class V> - BOOST_MP_CXX14_CONSTEXPR void operator()(R& result, const T& b, const U& p, const V& m) const - { - T temp; - eval_powm(temp, b, p, m); - result = std::move(temp); - } -}; - -} // namespace default_ops - -template <class T, class U, class V> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if< - (number_category<T>::value == number_kind_integer) && - (is_number<T>::value || is_number_expression<T>::value) && - (is_number<U>::value || is_number_expression<U>::value || boost::multiprecision::detail::is_integral<U>::value) && - (is_number<V>::value || is_number_expression<V>::value || boost::multiprecision::detail::is_integral<V>::value), - typename std::conditional< - is_no_et_number<T>::value, - T, - typename std::conditional< - is_no_et_number<U>::value, - U, - typename std::conditional< - is_no_et_number<V>::value, - V, - detail::expression<detail::function, default_ops::powm_func, T, U, V> >::type>::type>::type>::type -powm(const T& b, const U& p, const V& mod) -{ - return detail::expression<detail::function, default_ops::powm_func, T, U, V>( - default_ops::powm_func(), b, p, mod); -} - -}} // namespace boost::multiprecision - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/min_max.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/min_max.hpp deleted file mode 100644 index 8a78c612b0..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/min_max.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2016 John Maddock. 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) - -#ifndef BOOST_MP_MIN_MAX_HPP -#define BOOST_MP_MIN_MAX_HPP - -#include <boost/multiprecision/traits/is_backend.hpp> - -namespace boost { namespace multiprecision { - -// -// Expression template overloads for (min) and (max): -// -// Introduced in response to https://svn.boost.org/trac/boost/ticket/11149 -// note that these can not legally be injected into namespace std, and that doing so -// may break future enhancements to the standard. None the less adding -// namespace std{ using boost::multiprecision::(min); using boost::multiprecision::(max); } -// to your code may get some generic code working that wouldn't work otherwise. -// -// The use of enable_if on the return type is to avoid poisoning std::min/max, -// otherwise attempting to make an explicit call to min<long>(a, b) when these and std -// versions are in scope, will cause the compiler to try to instantiate the signatures -// for our versions as well as the std ones, which in turn instantiates number<long> -// which fails to compile as "long" is not a valid backend type. -// -template <class Backend> -inline typename std::enable_if<boost::multiprecision::detail::is_backend<Backend>::value, const number<Backend, et_on>&>::type(min)(const number<Backend, et_on>& a, const number<Backend, et_on>& b) -{ - return a < b ? a : b; -} -template <class Backend, class tag, class A1, class A2, class A3, class A4> -inline typename std::enable_if<boost::multiprecision::detail::is_backend<Backend>::value, const number<Backend, et_on> >::type(min)(const number<Backend, et_on>& a, const detail::expression<tag, A1, A2, A3, A4>& b) -{ - number<Backend, et_on> t(b); - if (a < t) - return a; - return std::move(t); -} -template <class tag, class A1, class A2, class A3, class A4, class Backend> -inline typename std::enable_if<boost::multiprecision::detail::is_backend<Backend>::value, const number<Backend, et_on> >::type(min)(const detail::expression<tag, A1, A2, A3, A4>& a, const number<Backend, et_on>& b) -{ - number<Backend, et_on> t(a); - if (t < b) - return std::move(t); - return b; -} -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> -inline typename detail::expression<tag, A1, A2, A3, A4>::result_type(min)(const detail::expression<tag, A1, A2, A3, A4>& a, const detail::expression<tagb, A1b, A2b, A3b, A4b>& b) -{ - typename detail::expression<tag, A1, A2, A3, A4>::result_type t1(a), t2(b); - if (t1 < t2) - return std::move(t1); - return std::move(t2); -} -template <class tag, class A1, class A2, class A3, class A4> -inline typename detail::expression<tag, A1, A2, A3, A4>::result_type(min)(const detail::expression<tag, A1, A2, A3, A4>& a, const detail::expression<tag, A1, A2, A3, A4>& b) -{ - typename detail::expression<tag, A1, A2, A3, A4>::result_type t1(a), t2(b); - if (t1 < t2) - return std::move(t1); - return std::move(t2); -} - -template <class Backend> -inline typename std::enable_if<boost::multiprecision::detail::is_backend<Backend>::value, const number<Backend, et_on>&>::type(max)(const number<Backend, et_on>& a, const number<Backend, et_on>& b) -{ - return a > b ? a : b; -} -template <class Backend, class tag, class A1, class A2, class A3, class A4> -inline typename std::enable_if<boost::multiprecision::detail::is_backend<Backend>::value, const number<Backend, et_on> >::type(max)(const number<Backend, et_on>& a, const detail::expression<tag, A1, A2, A3, A4>& b) -{ - number<Backend, et_on> t(b); - if (a > t) - return a; - return std::move(t); -} -template <class tag, class A1, class A2, class A3, class A4, class Backend> -inline typename std::enable_if<boost::multiprecision::detail::is_backend<Backend>::value, const number<Backend, et_on> >::type(max)(const detail::expression<tag, A1, A2, A3, A4>& a, const number<Backend, et_on>& b) -{ - number<Backend, et_on> t(a); - if (t > b) - return std::move(t); - return b; -} -template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> -inline typename detail::expression<tag, A1, A2, A3, A4>::result_type(max)(const detail::expression<tag, A1, A2, A3, A4>& a, const detail::expression<tagb, A1b, A2b, A3b, A4b>& b) -{ - typename detail::expression<tag, A1, A2, A3, A4>::result_type t1(a), t2(b); - if (t1 > t2) - return std::move(t1); - return std::move(t2); -} -template <class tag, class A1, class A2, class A3, class A4> -inline typename detail::expression<tag, A1, A2, A3, A4>::result_type(max)(const detail::expression<tag, A1, A2, A3, A4>& a, const detail::expression<tag, A1, A2, A3, A4>& b) -{ - typename detail::expression<tag, A1, A2, A3, A4>::result_type t1(a), t2(b); - if (t1 > t2) - return std::move(t1); - return std::move(t2); -} - -}} // namespace boost::multiprecision - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp deleted file mode 100644 index a702e85f56..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp +++ /dev/null @@ -1,661 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. 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) - -#ifndef BOOST_MP_NO_ET_OPS_HPP -#define BOOST_MP_NO_ET_OPS_HPP - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4714) -#endif - -namespace boost { - namespace multiprecision { - - // - // Operators for non-expression template enabled number. - // NOTE: this is not a complete header - really just a suffix to default_ops.hpp. - // NOTE: these operators have to be defined after the methods in default_ops.hpp. - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(const number<B, et_off>& v) - { - static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior."); - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(v); - number<B, et_off> result(v); - result.backend().negate(); - return result; - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator~(const number<B, et_off>& v) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(v); - number<B, et_off> result; - eval_complement(result.backend(), v.backend()); - return result; - } - // - // Addition: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(const number<B, et_off>& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_add; - eval_add(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator+(const number<B, et_off>& a, const V& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_add; - eval_add(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator+(const V& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a); - number<B, et_off> result; - using default_ops::eval_add; - eval_add(result.backend(), b.backend(), number<B, et_off>::canonical_value(a)); - return result; - } - // - // Subtraction: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(const number<B, et_off>& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_subtract; - eval_subtract(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator-(const number<B, et_off>& a, const V& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_subtract; - eval_subtract(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator-(const V& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a); - number<B, et_off> result; - using default_ops::eval_subtract; - eval_subtract(result.backend(), number<B, et_off>::canonical_value(a), b.backend()); - return result; - } - // - // Multiply: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(const number<B, et_off>& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_multiply; - eval_multiply(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator*(const number<B, et_off>& a, const V& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_multiply; - eval_multiply(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator*(const V& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a); - number<B, et_off> result; - using default_ops::eval_multiply; - eval_multiply(result.backend(), b.backend(), number<B, et_off>::canonical_value(a)); - return result; - } - // - // divide: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator/(const number<B, et_off>& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_divide; - eval_divide(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator/(const number<B, et_off>& a, const V& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_divide; - eval_divide(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator/(const V& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a); - number<B, et_off> result; - using default_ops::eval_divide; - eval_divide(result.backend(), number<B, et_off>::canonical_value(a), b.backend()); - return result; - } - // - // modulus: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator%(const number<B, et_off>& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - number<B, et_off> result; - using default_ops::eval_modulus; - eval_modulus(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator%(const number<B, et_off>& a, const V& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a); - number<B, et_off> result; - using default_ops::eval_modulus; - eval_modulus(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator%(const V& a, const number<B, et_off>& b) - { - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b); - number<B, et_off> result; - using default_ops::eval_modulus; - eval_modulus(result.backend(), number<B, et_off>::canonical_value(a), b.backend()); - return result; - } - // - // Bitwise or: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(const number<B, et_off>& a, const number<B, et_off>& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_or; - eval_bitwise_or(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator|(const number<B, et_off>& a, const V& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_or; - eval_bitwise_or(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator|(const V& a, const number<B, et_off>& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_or; - eval_bitwise_or(result.backend(), b.backend(), number<B, et_off>::canonical_value(a)); - return result; - } - // - // Bitwise xor: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(const number<B, et_off>& a, const number<B, et_off>& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator^(const number<B, et_off>& a, const V& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator^(const V& a, const number<B, et_off>& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(result.backend(), b.backend(), number<B, et_off>::canonical_value(a)); - return result; - } - // - // Bitwise and: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(const number<B, et_off>& a, const number<B, et_off>& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_and; - eval_bitwise_and(result.backend(), a.backend(), b.backend()); - return result; - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator&(const number<B, et_off>& a, const V& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_and; - eval_bitwise_and(result.backend(), a.backend(), number<B, et_off>::canonical_value(b)); - return result; - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator&(const V& a, const number<B, et_off>& b) - { - number<B, et_off> result; - using default_ops::eval_bitwise_and; - eval_bitwise_and(result.backend(), b.backend(), number<B, et_off>::canonical_value(a)); - return result; - } - // - // shifts: - // - template <class B, class I> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator<<(const number<B, et_off>& a, const I& b) - { - number<B, et_off> result(a); - using default_ops::eval_left_shift; - detail::check_shift_range(b, std::integral_constant<bool, (sizeof(I) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<I>::value>()); - eval_left_shift(result.backend(), b); - return result; - } - template <class B, class I> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator>>(const number<B, et_off>& a, const I& b) - { - number<B, et_off> result(a); - using default_ops::eval_right_shift; - detail::check_shift_range(b, std::integral_constant<bool, (sizeof(I) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<I>::value>()); - eval_right_shift(result.backend(), b); - return result; - } - - // - // If we have rvalue references go all over again with rvalue ref overloads and move semantics. - // Note that while it would be tempting to implement these so they return an rvalue reference - // (and indeed this would be optimally efficient), this is unsafe due to users propensity to - // write: - // - // const T& t = a * b; - // - // which would lead to a dangling reference if we didn't return by value. Of course move - // semantics help a great deal in return by value, so performance is still pretty good... - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& v) - { - static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior."); - v.backend().negate(); - return std::move(v); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator~(number<B, et_off>&& v) - { - eval_complement(v.backend(), v.backend()); - return std::move(v); - } - // - // Addition: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_add; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_add(a.backend(), b.backend()); - return std::move(a); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(const number<B, et_off>& a, number<B, et_off>&& b) - { - using default_ops::eval_add; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_add(b.backend(), a.backend()); - return std::move(b); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(number<B, et_off>&& a, number<B, et_off>&& b) - { - using default_ops::eval_add; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_add(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator+(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_add; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_add(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator+(const V& a, number<B, et_off>&& b) - { - using default_ops::eval_add; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_add(b.backend(), number<B, et_off>::canonical_value(a)); - return std::move(b); - } - // - // Subtraction: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_subtract; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_subtract(a.backend(), b.backend()); - return std::move(a); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_signed_number<B>::value, number<B, et_off> >::type operator-(const number<B, et_off>& a, number<B, et_off>&& b) - { - using default_ops::eval_subtract; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_subtract(b.backend(), a.backend()); - b.backend().negate(); - return std::move(b); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& a, number<B, et_off>&& b) - { - using default_ops::eval_subtract; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_subtract(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator-(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_subtract; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_subtract(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(is_compatible_arithmetic_type<V, number<B, et_off> >::value && is_signed_number<B>::value) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator-(const V& a, number<B, et_off>&& b) - { - using default_ops::eval_subtract; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_subtract(b.backend(), number<B, et_off>::canonical_value(a)); - b.backend().negate(); - return std::move(b); - } - // - // Multiply: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_multiply; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_multiply(a.backend(), b.backend()); - return std::move(a); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(const number<B, et_off>& a, number<B, et_off>&& b) - { - using default_ops::eval_multiply; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_multiply(b.backend(), a.backend()); - return std::move(b); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(number<B, et_off>&& a, number<B, et_off>&& b) - { - using default_ops::eval_multiply; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_multiply(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator*(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_multiply; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_multiply(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator*(const V& a, number<B, et_off>&& b) - { - using default_ops::eval_multiply; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_multiply(b.backend(), number<B, et_off>::canonical_value(a)); - return std::move(b); - } - // - // divide: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator/(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_divide; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_divide(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type - operator/(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_divide; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_divide(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - // - // modulus: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator%(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_modulus; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_modulus(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator%(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_modulus; - detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b); - eval_modulus(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - // - // Bitwise or: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_bitwise_or; - eval_bitwise_or(a.backend(), b.backend()); - return std::move(a); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(const number<B, et_off>& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_or; - eval_bitwise_or(b.backend(), a.backend()); - return std::move(b); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(number<B, et_off>&& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_or; - eval_bitwise_or(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator|(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_bitwise_or; - eval_bitwise_or(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator|(const V& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_or; - eval_bitwise_or(b.backend(), number<B, et_off>::canonical_value(a)); - return std::move(b); - } - // - // Bitwise xor: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(a.backend(), b.backend()); - return std::move(a); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(const number<B, et_off>& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(b.backend(), a.backend()); - return std::move(b); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(number<B, et_off>&& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator^(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator^(const V& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(b.backend(), number<B, et_off>::canonical_value(a)); - return std::move(b); - } - // - // Bitwise and: - // - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(number<B, et_off>&& a, const number<B, et_off>& b) - { - using default_ops::eval_bitwise_and; - eval_bitwise_and(a.backend(), b.backend()); - return std::move(a); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(const number<B, et_off>& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_and; - eval_bitwise_and(b.backend(), a.backend()); - return std::move(b); - } - template <class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(number<B, et_off>&& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_and; - eval_bitwise_and(a.backend(), b.backend()); - return std::move(a); - } - template <class B, class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator&(number<B, et_off>&& a, const V& b) - { - using default_ops::eval_bitwise_and; - eval_bitwise_and(a.backend(), number<B, et_off>::canonical_value(b)); - return std::move(a); - } - template <class V, class B> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type - operator&(const V& a, number<B, et_off>&& b) - { - using default_ops::eval_bitwise_and; - eval_bitwise_and(b.backend(), number<B, et_off>::canonical_value(a)); - return std::move(b); - } - // - // shifts: - // - template <class B, class I> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator<<(number<B, et_off>&& a, const I& b) - { - using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type; - - using default_ops::eval_left_shift; - eval_left_shift(a.backend(), static_cast<ui_type>(b)); - return std::move(a); - } - template <class B, class I> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type - operator>>(number<B, et_off>&& a, const I& b) - { - using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type; - - using default_ops::eval_right_shift; - eval_right_shift(a.backend(), static_cast<ui_type>(b)); - return std::move(a); - } - } -} // namespace boost::multiprecision - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_MP_NO_ET_OPS_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_exceptions_support.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_exceptions_support.hpp deleted file mode 100644 index c2133e2990..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_exceptions_support.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2004 - 2021 Pavel Vozenilek. -// Copyright 2021 Matt Borland. 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) - -#ifndef BOOST_MP_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP -#define BOOST_MP_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP - -#include <boost/multiprecision/detail/standalone_config.hpp> - -#ifdef BOOST_MP_STANDALONE - -#ifndef BOOST_NO_EXCEPTIONS -# define BOOST_MP_TRY { try -# define BOOST_MP_CATCH(x) catch(x) -# define BOOST_MP_RETHROW throw; -# define BOOST_MP_CATCH_END } -# define BOOST_MP_THROW_EXCEPTION(x) throw (x); -#else -# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 -# define BOOST_MP_TRY { if (true) -# define BOOST_MP_CATCH(x) else if (false) -# else - // warning C4127: conditional expression is constant -# define BOOST_MP_TRY { \ - __pragma(warning(push)) \ - __pragma(warning(disable: 4127)) \ - if (true) \ - __pragma(warning(pop)) -# define BOOST_MP_CATCH(x) else \ - __pragma(warning(push)) \ - __pragma(warning(disable: 4127)) \ - if (false) \ - __pragma(warning(pop)) -# endif -# define BOOST_MP_RETHROW -# define BOOST_MP_CATCH_END } -# define BOOST_MP_THROW_EXCEPTION(x) {static_cast<void>(x);} -#endif - -#else // Not standalone mode - -# include <boost/core/no_exceptions_support.hpp> -# include <boost/throw_exception.hpp> - -# define BOOST_MP_TRY BOOST_TRY -# define BOOST_MP_CATCH(x) BOOST_CATCH(x) -# define BOOST_MP_RETHROW BOOST_RETHROW -# define BOOST_MP_CATCH_END BOOST_CATCH_END -# define BOOST_MP_THROW_EXCEPTION(x) BOOST_THROW_EXCEPTION(x) - -#endif // BOOST_MP_STANDALONE - -#endif // BOOST_MP_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_base.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_base.hpp deleted file mode 100644 index ed395b8f00..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_base.hpp +++ /dev/null @@ -1,1699 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 John Maddock. 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) - -#ifndef BOOST_MP_NUMBER_BASE_HPP -#define BOOST_MP_NUMBER_BASE_HPP - -#include <climits> -#include <ios> -#include <string> -#include <limits> -#include <type_traits> -#include <stdexcept> -#include <tuple> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/traits/transcendental_reduction_type.hpp> -#include <boost/multiprecision/traits/std_integer_traits.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4307) -#pragma warning(pop) -#endif - -#ifndef BOOST_MP_STANDALONE -#include <boost/lexical_cast.hpp> -#include <boost/core/nvp.hpp> -#endif - -#ifdef BOOST_MP_MATH_AVAILABLE -#include <boost/math/tools/complex.hpp> -#endif - -// We now require C++11. -#include <boost/multiprecision/detail/check_cpp11_config.hpp> - -#if defined(NDEBUG) && !defined(_DEBUG) -#define BOOST_MP_FORCEINLINE BOOST_FORCEINLINE -#else -#define BOOST_MP_FORCEINLINE inline -#endif - -// -// Thread local storage: -// Note fails on Mingw, see https://sourceforge.net/p/mingw-w64/bugs/527/ -// -#if defined(BOOST_NO_CXX11_THREAD_LOCAL) -#define BOOST_MP_THREAD_LOCAL -#elif !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ < 9)) && !defined(__clang__)) -#define BOOST_MP_THREAD_LOCAL thread_local -#define BOOST_MP_USING_THREAD_LOCAL -#else -#pragma GCC warning "thread_local on mingw is broken, please use MSys mingw gcc-9 or later, see https://sourceforge.net/p/mingw-w64/bugs/527/" -#define BOOST_MP_THREAD_LOCAL -#endif - -#ifdef __has_include -# if __has_include(<version>) -# include <version> -# ifdef __cpp_lib_is_constant_evaluated -# include <type_traits> -# define BOOST_MP_HAS_IS_CONSTANT_EVALUATED -# endif -# endif -#endif - -#ifdef __has_builtin -#if __has_builtin(__builtin_is_constant_evaluated) && !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) -#define BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED -#endif -#endif -// -// MSVC also supports __builtin_is_constant_evaluated if it's recent enough: -// -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) -# define BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED -#endif -// -// As does GCC-9: -// -#if defined(BOOST_GCC) && !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9) && !defined(BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED) -# define BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED -#endif - -#if defined(BOOST_MP_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR) -# define BOOST_MP_IS_CONST_EVALUATED(x) std::is_constant_evaluated() -#elif defined(BOOST_MP_HAS_BUILTIN_IS_CONSTANT_EVALUATED) -# define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_is_constant_evaluated() -#elif !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_GCC) && (__GNUC__ >= 6) -# define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_constant_p(x) -#else -# define BOOST_MP_NO_CONSTEXPR_DETECTION -#endif - -#define BOOST_MP_CXX14_CONSTEXPR BOOST_CXX14_CONSTEXPR -// -// Early compiler versions trip over the constexpr code: -// -#if defined(__clang__) && (__clang_major__ < 5) -#undef BOOST_MP_CXX14_CONSTEXPR -#define BOOST_MP_CXX14_CONSTEXPR -#endif -#if defined(__apple_build_version__) && (__clang_major__ < 9) -#undef BOOST_MP_CXX14_CONSTEXPR -#define BOOST_MP_CXX14_CONSTEXPR -#endif -#if defined(BOOST_GCC) && (__GNUC__ < 6) -#undef BOOST_MP_CXX14_CONSTEXPR -#define BOOST_MP_CXX14_CONSTEXPR -#endif -#if defined(BOOST_INTEL) -#undef BOOST_MP_CXX14_CONSTEXPR -#define BOOST_MP_CXX14_CONSTEXPR -#define BOOST_MP_NO_CONSTEXPR_DETECTION -#endif - -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION -# define BOOST_CXX14_CONSTEXPR_IF_DETECTION -#else -# define BOOST_CXX14_CONSTEXPR_IF_DETECTION constexpr -#endif - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 6326) -#endif - -namespace boost { -namespace multiprecision { - -enum expression_template_option -{ - et_off = 0, - et_on = 1 -}; - -enum struct variable_precision_options : signed char -{ - assume_uniform_precision = -1, - preserve_target_precision = 0, - preserve_source_precision = 1, - preserve_component_precision = 2, - preserve_related_precision = 3, - preserve_all_precision = 4, -}; - -inline constexpr bool operator==(variable_precision_options a, variable_precision_options b) -{ - return static_cast<unsigned>(a) == static_cast<unsigned>(b); -} - -template <class Backend> -struct expression_template_default -{ - static constexpr expression_template_option value = et_on; -}; - -template <class Backend, expression_template_option ExpressionTemplates = expression_template_default<Backend>::value> -class number; - -template <class T> -struct is_number : public std::integral_constant<bool, false> -{}; - -template <class Backend, expression_template_option ExpressionTemplates> -struct is_number<number<Backend, ExpressionTemplates> > : public std::integral_constant<bool, true> -{}; - -template <class T> -struct is_et_number : public std::integral_constant<bool, false> -{}; - -template <class Backend> -struct is_et_number<number<Backend, et_on> > : public std::integral_constant<bool, true> -{}; - -template <class T> -struct is_no_et_number : public std::integral_constant<bool, false> -{}; - -template <class Backend> -struct is_no_et_number<number<Backend, et_off> > : public std::integral_constant<bool, true> -{}; - -namespace detail { - -// Forward-declare an expression wrapper -template <class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void, class Arg4 = void> -struct expression; - -} // namespace detail - -template <class T> -struct is_number_expression : public std::integral_constant<bool, false> -{}; - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -struct is_number_expression<detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > : public std::integral_constant<bool, true> -{}; - -template <class T, class Num> -struct is_compatible_arithmetic_type - : public std::integral_constant<bool, - std::is_convertible<T, Num>::value && !std::is_same<T, Num>::value && !is_number_expression<T>::value> -{}; - -namespace detail { -// -// Workaround for missing abs(long long) and abs(__int128) on some compilers: -// -template <class T> -constexpr typename std::enable_if<(boost::multiprecision::detail::is_signed<T>::value || std::is_floating_point<T>::value), T>::type abs(T t) noexcept -{ - // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. - // See https://svn.boost.org/trac/boost/ticket/9740. - return t < 0 ? T(1u) + T(-(t + 1)) : t; -} -template <class T> -constexpr typename std::enable_if<boost::multiprecision::detail::is_unsigned<T>::value, T>::type abs(T t) noexcept -{ - return t; -} - -#define BOOST_MP_USING_ABS using boost::multiprecision::detail::abs; - -template <class T> -constexpr typename std::enable_if<(boost::multiprecision::detail::is_signed<T>::value || std::is_floating_point<T>::value), typename boost::multiprecision::detail::make_unsigned<T>::type>::type unsigned_abs(T t) noexcept -{ - // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. - // See https://svn.boost.org/trac/boost/ticket/9740. - return t < 0 ? static_cast<typename boost::multiprecision::detail::make_unsigned<T>::type>(1u) + static_cast<typename boost::multiprecision::detail::make_unsigned<T>::type>(-(t + 1)) : static_cast<typename boost::multiprecision::detail::make_unsigned<T>::type>(t); -} -template <class T> -constexpr typename std::enable_if<boost::multiprecision::detail::is_unsigned<T>::value, T>::type unsigned_abs(T t) noexcept -{ - return t; -} - -template <class T> -struct bits_of -{ - static_assert(boost::multiprecision::detail::is_integral<T>::value || std::is_enum<T>::value || std::numeric_limits<T>::is_specialized, "Failed integer size check"); - static constexpr unsigned value = - std::numeric_limits<T>::is_specialized ? std::numeric_limits<T>::digits - : sizeof(T) * CHAR_BIT - (boost::multiprecision::detail::is_signed<T>::value ? 1 : 0); -}; - -#if defined(_GLIBCXX_USE_FLOAT128) && defined(BOOST_GCC) && !defined(__STRICT_ANSI__) -#define BOOST_MP_BITS_OF_FLOAT128_DEFINED -template <> -struct bits_of<float128_type> -{ - static constexpr unsigned value = 113; -}; -#endif - -template <int b> -struct has_enough_bits -{ - template <class T> - struct type : public std::integral_constant<bool, bits_of<T>::value >= b> - {}; -}; - -template <class Tuple, int i, int digits, bool = (i >= std::tuple_size<Tuple>::value)> -struct find_index_of_large_enough_type -{ - static constexpr int value = bits_of<typename std::tuple_element<static_cast<std::size_t>(i), Tuple>::type>::value >= digits ? i : find_index_of_large_enough_type<Tuple, i + 1, digits>::value; -}; -template <class Tuple, int i, int digits> -struct find_index_of_large_enough_type<Tuple, i, digits, true> -{ - static constexpr int value = INT_MAX; -}; - -template <int index, class Tuple, class Fallback, bool = (std::tuple_size<Tuple>::value <= index)> -struct dereference_tuple -{ - using type = typename std::tuple_element<static_cast<std::size_t>(index), Tuple>::type; -}; -template <int index, class Tuple, class Fallback> -struct dereference_tuple<index, Tuple, Fallback, true> -{ - using type = Fallback; -}; - -template <class Val, class Backend, class Tag> -struct canonical_imp -{ - using type = typename std::remove_cv<typename std::decay<const Val>::type>::type; -}; -template <class B, class Backend, class Tag> -struct canonical_imp<number<B, et_on>, Backend, Tag> -{ - using type = B; -}; -template <class B, class Backend, class Tag> -struct canonical_imp<number<B, et_off>, Backend, Tag> -{ - using type = B; -}; -#ifdef __SUNPRO_CC -template <class B, class Backend> -struct canonical_imp<number<B, et_on>, Backend, std::integral_constant<int, 3> > -{ - using type = B; -}; -template <class B, class Backend> -struct canonical_imp<number<B, et_off>, Backend, std::integral_constant<int, 3> > -{ - using type = B; -}; -#endif -template <class Val, class Backend> -struct canonical_imp<Val, Backend, std::integral_constant<int, 0> > -{ - static constexpr int index = find_index_of_large_enough_type<typename Backend::signed_types, 0, bits_of<Val>::value>::value; - using type = typename dereference_tuple<index, typename Backend::signed_types, Val>::type; -}; -template <class Val, class Backend> -struct canonical_imp<Val, Backend, std::integral_constant<int, 1> > -{ - static constexpr int index = find_index_of_large_enough_type<typename Backend::unsigned_types, 0, bits_of<Val>::value>::value; - using type = typename dereference_tuple<index, typename Backend::unsigned_types, Val>::type; -}; -template <class Val, class Backend> -struct canonical_imp<Val, Backend, std::integral_constant<int, 2> > -{ - static constexpr int index = find_index_of_large_enough_type<typename Backend::float_types, 0, bits_of<Val>::value>::value; - using type = typename dereference_tuple<index, typename Backend::float_types, Val>::type; -}; -template <class Val, class Backend> -struct canonical_imp<Val, Backend, std::integral_constant<int, 3> > -{ - using type = const char*; -}; -template <class Val, class Backend> -struct canonical_imp<Val, Backend, std::integral_constant<int, 4> > -{ - using underlying = typename std::underlying_type<Val>::type; - using tag = typename std::conditional<boost::multiprecision::detail::is_signed<Val>::value, std::integral_constant<int, 0>, std::integral_constant<int, 1>>::type; - using type = typename canonical_imp<underlying, Backend, tag>::type; -}; - -template <class Val, class Backend> -struct canonical -{ - using tag_type = typename std::conditional< - boost::multiprecision::detail::is_signed<Val>::value && boost::multiprecision::detail::is_integral<Val>::value, - std::integral_constant<int, 0>, - typename std::conditional< - boost::multiprecision::detail::is_unsigned<Val>::value, - std::integral_constant<int, 1>, - typename std::conditional< - std::is_floating_point<Val>::value, - std::integral_constant<int, 2>, - typename std::conditional< - (std::is_convertible<Val, const char*>::value || std::is_same<Val, std::string>::value), - std::integral_constant<int, 3>, - typename std::conditional< - std::is_enum<Val>::value, - std::integral_constant<int, 4>, - std::integral_constant<int, 5> >::type>::type>::type>::type>::type; - - using type = typename canonical_imp<Val, Backend, tag_type>::type; -}; - -struct terminal -{}; -struct negate -{}; -struct plus -{}; -struct minus -{}; -struct multiplies -{}; -struct divides -{}; -struct modulus -{}; -struct shift_left -{}; -struct shift_right -{}; -struct bitwise_and -{}; -struct bitwise_or -{}; -struct bitwise_xor -{}; -struct bitwise_complement -{}; -struct add_immediates -{}; -struct subtract_immediates -{}; -struct multiply_immediates -{}; -struct divide_immediates -{}; -struct modulus_immediates -{}; -struct bitwise_and_immediates -{}; -struct bitwise_or_immediates -{}; -struct bitwise_xor_immediates -{}; -struct complement_immediates -{}; -struct function -{}; -struct multiply_add -{}; -struct multiply_subtract -{}; - -template <class T> -struct backend_type; - -template <class T, expression_template_option ExpressionTemplates> -struct backend_type<number<T, ExpressionTemplates> > -{ - using type = T; -}; - -template <class tag, class A1, class A2, class A3, class A4> -struct backend_type<expression<tag, A1, A2, A3, A4> > -{ - using type = typename backend_type<typename expression<tag, A1, A2, A3, A4>::result_type>::type; -}; - -template <class T1, class T2> -struct combine_expression -{ - using type = decltype(T1() + T2()); -}; - -template <class T1, expression_template_option ExpressionTemplates, class T2> -struct combine_expression<number<T1, ExpressionTemplates>, T2> -{ - using type = number<T1, ExpressionTemplates>; -}; - -template <class T1, class T2, expression_template_option ExpressionTemplates> -struct combine_expression<T1, number<T2, ExpressionTemplates> > -{ - using type = number<T2, ExpressionTemplates>; -}; - -template <class T, expression_template_option ExpressionTemplates> -struct combine_expression<number<T, ExpressionTemplates>, number<T, ExpressionTemplates> > -{ - using type = number<T, ExpressionTemplates>; -}; - -template <class T1, expression_template_option ExpressionTemplates1, class T2, expression_template_option ExpressionTemplates2> -struct combine_expression<number<T1, ExpressionTemplates1>, number<T2, ExpressionTemplates2> > -{ - using type = typename std::conditional< - std::is_convertible<number<T2, ExpressionTemplates2>, number<T1, ExpressionTemplates2> >::value, - number<T1, ExpressionTemplates1>, - number<T2, ExpressionTemplates2> >::type; -}; - -template <class T> -struct arg_type -{ - using type = expression<terminal, T>; -}; - -template <class Tag, class Arg1, class Arg2, class Arg3, class Arg4> -struct arg_type<expression<Tag, Arg1, Arg2, Arg3, Arg4> > -{ - using type = expression<Tag, Arg1, Arg2, Arg3, Arg4>; -}; - -struct unmentionable -{ - unmentionable* proc() { return nullptr; } -}; - -typedef unmentionable* (unmentionable::*unmentionable_type)(); - -template <class T, bool b> -struct expression_storage_base -{ - using type = const T&; -}; - -template <class T> -struct expression_storage_base<T, true> -{ - using type = T; -}; - -template <class T> -struct expression_storage : public expression_storage_base<T, boost::multiprecision::detail::is_arithmetic<T>::value> -{}; - -template <class T> -struct expression_storage<T*> -{ - using type = T*; -}; - -template <class T> -struct expression_storage<const T*> -{ - using type = const T*; -}; - -template <class tag, class A1, class A2, class A3, class A4> -struct expression_storage<expression<tag, A1, A2, A3, A4> > -{ - using type = expression<tag, A1, A2, A3, A4>; -}; - -template <class tag, class Arg1> -struct expression<tag, Arg1, void, void, void> -{ - using arity = std::integral_constant<int, 1> ; - using left_type = typename arg_type<Arg1>::type ; - using left_result_type = typename left_type::result_type; - using result_type = typename left_type::result_type; - using tag_type = tag ; - - explicit BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a) : arg(a) {} - BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg(e.arg) {} - - // - // If we have static_assert we can give a more useful error message - // than if we simply have no operator defined at all: - // - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR left_type left() const - { - return left_type(arg); - } - - BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const noexcept { return arg; } - - static constexpr unsigned depth = left_type::depth + 1; - template <class T -#ifndef __SUNPRO_CC - , - typename std::enable_if<!is_number<T>::value && !std::is_convertible<result_type, T const&>::value && std::is_constructible<T, result_type>::value, int>::type = 0 -#endif - > - explicit BOOST_MP_CXX14_CONSTEXPR operator T() const - { - return static_cast<T>(static_cast<result_type>(*this)); - } - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const - { - result_type r(*this); - return static_cast<bool>(r); - } - - template <class T> - BOOST_MP_CXX14_CONSTEXPR T convert_to() - { - result_type r(*this); - return r.template convert_to<T>(); - } - - private: - typename expression_storage<Arg1>::type arg; - expression& operator=(const expression&); -}; - -template <class Arg1> -struct expression<terminal, Arg1, void, void, void> -{ - using arity = std::integral_constant<int, 0>; - using result_type = Arg1 ; - using tag_type = terminal ; - - explicit BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a) : arg(a) {} - BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg(e.arg) {} - - // - // If we have static_assert we can give a more useful error message - // than if we simply have no operator defined at all: - // - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR const Arg1& value() const noexcept - { - return arg; - } - - static constexpr unsigned depth = 0; - - template <class T -#ifndef __SUNPRO_CC - , - typename std::enable_if<!is_number<T>::value && !std::is_convertible<result_type, T const&>::value && std::is_constructible<T, result_type>::value, int>::type = 0 -#endif - > - explicit BOOST_MP_CXX14_CONSTEXPR operator T() const - { - return static_cast<T>(static_cast<result_type>(*this)); - } - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const - { - result_type r(*this); - return static_cast<bool>(r); - } - - template <class T> - BOOST_MP_CXX14_CONSTEXPR T convert_to() - { - result_type r(*this); - return r.template convert_to<T>(); - } - - private: - typename expression_storage<Arg1>::type arg; - expression& operator=(const expression&); -}; - -template <class tag, class Arg1, class Arg2> -struct expression<tag, Arg1, Arg2, void, void> -{ - using arity = std::integral_constant<int, 2> ; - using left_type = typename arg_type<Arg1>::type ; - using right_type = typename arg_type<Arg2>::type ; - using left_result_type = typename left_type::result_type ; - using right_result_type = typename right_type::result_type ; - using result_type = typename combine_expression<left_result_type, right_result_type>::type; - using tag_type = tag ; - - BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a1, const Arg2& a2) : arg1(a1), arg2(a2) {} - BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg1(e.arg1), arg2(e.arg2) {} - - // - // If we have static_assert we can give a more useful error message - // than if we simply have no operator defined at all: - // - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR left_type left() const - { - return left_type(arg1); - } - BOOST_MP_CXX14_CONSTEXPR right_type right() const { return right_type(arg2); } - BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const noexcept { return arg1; } - BOOST_MP_CXX14_CONSTEXPR const Arg2& right_ref() const noexcept { return arg2; } - - template <class T -#ifndef __SUNPRO_CC - , - typename std::enable_if<!is_number<T>::value && !std::is_convertible<result_type, T const&>::value && std::is_constructible<T, result_type>::value, int>::type = 0 -#endif - > - explicit BOOST_MP_CXX14_CONSTEXPR operator T() const - { - return static_cast<T>(static_cast<result_type>(*this)); - } - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const - { - result_type r(*this); - return static_cast<bool>(r); - } - template <class T> - BOOST_MP_CXX14_CONSTEXPR T convert_to() - { - result_type r(*this); - return r.template convert_to<T>(); - } - - static const constexpr unsigned left_depth = left_type::depth + 1; - static const constexpr unsigned right_depth = right_type::depth + 1; - static const constexpr unsigned depth = left_depth > right_depth ? left_depth : right_depth; - - private: - typename expression_storage<Arg1>::type arg1; - typename expression_storage<Arg2>::type arg2; - expression& operator=(const expression&); -}; - -template <class tag, class Arg1, class Arg2, class Arg3> -struct expression<tag, Arg1, Arg2, Arg3, void> -{ - using arity = std::integral_constant<int, 3> ; - using left_type = typename arg_type<Arg1>::type ; - using middle_type = typename arg_type<Arg2>::type ; - using right_type = typename arg_type<Arg3>::type ; - using left_result_type = typename left_type::result_type ; - using middle_result_type = typename middle_type::result_type; - using right_result_type = typename right_type::result_type ; - using result_type = typename combine_expression< - left_result_type, - typename combine_expression<right_result_type, middle_result_type>::type>::type; - using tag_type = tag ; - - BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a1, const Arg2& a2, const Arg3& a3) : arg1(a1), arg2(a2), arg3(a3) {} - BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg1(e.arg1), arg2(e.arg2), arg3(e.arg3) {} - - // - // If we have static_assert we can give a more useful error message - // than if we simply have no operator defined at all: - // - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR left_type left() const - { - return left_type(arg1); - } - BOOST_MP_CXX14_CONSTEXPR middle_type middle() const { return middle_type(arg2); } - BOOST_MP_CXX14_CONSTEXPR right_type right() const { return right_type(arg3); } - BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const noexcept { return arg1; } - BOOST_MP_CXX14_CONSTEXPR const Arg2& middle_ref() const noexcept { return arg2; } - BOOST_MP_CXX14_CONSTEXPR const Arg3& right_ref() const noexcept { return arg3; } - - template <class T -#ifndef __SUNPRO_CC - , - typename std::enable_if<!is_number<T>::value && !std::is_convertible<result_type, T const&>::value && std::is_constructible<T, result_type>::value, int>::type = 0 -#endif - > - explicit BOOST_MP_CXX14_CONSTEXPR operator T() const - { - return static_cast<T>(static_cast<result_type>(*this)); - } - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const - { - result_type r(*this); - return static_cast<bool>(r); - } - template <class T> - BOOST_MP_CXX14_CONSTEXPR T convert_to() - { - result_type r(*this); - return r.template convert_to<T>(); - } - - static constexpr unsigned left_depth = left_type::depth + 1; - static constexpr unsigned middle_depth = middle_type::depth + 1; - static constexpr unsigned right_depth = right_type::depth + 1; - static constexpr unsigned depth = left_depth > right_depth ? (left_depth > middle_depth ? left_depth : middle_depth) : (right_depth > middle_depth ? right_depth : middle_depth); - - private: - typename expression_storage<Arg1>::type arg1; - typename expression_storage<Arg2>::type arg2; - typename expression_storage<Arg3>::type arg3; - expression& operator=(const expression&); -}; - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -struct expression -{ - using arity = std::integral_constant<int, 4> ; - using left_type = typename arg_type<Arg1>::type ; - using left_middle_type = typename arg_type<Arg2>::type ; - using right_middle_type = typename arg_type<Arg3>::type ; - using right_type = typename arg_type<Arg4>::type ; - using left_result_type = typename left_type::result_type ; - using left_middle_result_type = typename left_middle_type::result_type ; - using right_middle_result_type = typename right_middle_type::result_type; - using right_result_type = typename right_type::result_type ; - using result_type = typename combine_expression< - left_result_type, - typename combine_expression< - left_middle_result_type, - typename combine_expression<right_middle_result_type, right_result_type>::type>::type>::type; - using tag_type = tag ; - - BOOST_MP_CXX14_CONSTEXPR expression(const Arg1& a1, const Arg2& a2, const Arg3& a3, const Arg4& a4) : arg1(a1), arg2(a2), arg3(a3), arg4(a4) {} - BOOST_MP_CXX14_CONSTEXPR expression(const expression& e) : arg1(e.arg1), arg2(e.arg2), arg3(e.arg3), arg4(e.arg4) {} - - // - // If we have static_assert we can give a more useful error message - // than if we simply have no operator defined at all: - // - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator++(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--() - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR expression& operator--(int) - { - // This should always fail: - static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator+=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator-=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator*=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator/=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator%=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator|=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator&=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator^=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator<<=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - template <class Other> - BOOST_MP_CXX14_CONSTEXPR expression& operator>>=(const Other&) - { - // This should always fail: - static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?"); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR left_type left() const - { - return left_type(arg1); - } - BOOST_MP_CXX14_CONSTEXPR left_middle_type left_middle() const { return left_middle_type(arg2); } - BOOST_MP_CXX14_CONSTEXPR right_middle_type right_middle() const { return right_middle_type(arg3); } - BOOST_MP_CXX14_CONSTEXPR right_type right() const { return right_type(arg4); } - BOOST_MP_CXX14_CONSTEXPR const Arg1& left_ref() const noexcept { return arg1; } - BOOST_MP_CXX14_CONSTEXPR const Arg2& left_middle_ref() const noexcept { return arg2; } - BOOST_MP_CXX14_CONSTEXPR const Arg3& right_middle_ref() const noexcept { return arg3; } - BOOST_MP_CXX14_CONSTEXPR const Arg4& right_ref() const noexcept { return arg4; } - - template <class T -#ifndef __SUNPRO_CC - , - typename std::enable_if<!is_number<T>::value && !std::is_convertible<result_type, T const&>::value && std::is_constructible<T, result_type>::value, int>::type = 0 -#endif - > - explicit BOOST_MP_CXX14_CONSTEXPR operator T() const - { - return static_cast<T>(static_cast<result_type>(*this)); - } - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const - { - result_type r(*this); - return static_cast<bool>(r); - } - template <class T> - BOOST_MP_CXX14_CONSTEXPR T convert_to() - { - result_type r(*this); - return r.template convert_to<T>(); - } - - static constexpr unsigned left_depth = left_type::depth + 1; - static constexpr unsigned left_middle_depth = left_middle_type::depth + 1; - static constexpr unsigned right_middle_depth = right_middle_type::depth + 1; - static constexpr unsigned right_depth = right_type::depth + 1; - - static constexpr unsigned left_max_depth = left_depth > left_middle_depth ? left_depth : left_middle_depth; - static constexpr unsigned right_max_depth = right_depth > right_middle_depth ? right_depth : right_middle_depth; - - static constexpr unsigned depth = left_max_depth > right_max_depth ? left_max_depth : right_max_depth; - - private: - typename expression_storage<Arg1>::type arg1; - typename expression_storage<Arg2>::type arg2; - typename expression_storage<Arg3>::type arg3; - typename expression_storage<Arg4>::type arg4; - expression& operator=(const expression&); -}; - -template <class T> -struct digits2 -{ - static_assert(std::numeric_limits<T>::is_specialized, "numeric_limits must be specialized here"); - static_assert((std::numeric_limits<T>::radix == 2) || (std::numeric_limits<T>::radix == 10), "Failed radix check"); - // If we really have so many digits that this fails, then we're probably going to hit other problems anyway: - static_assert(LONG_MAX / 1000 > (std::numeric_limits<T>::digits + 1), "Too many digits to cope with here"); - static constexpr long m_value = std::numeric_limits<T>::radix == 10 ? (((std::numeric_limits<T>::digits + 1) * 1000L) / 301L) : std::numeric_limits<T>::digits; - static inline constexpr long value() noexcept { return m_value; } -}; - -#ifndef BOOST_MP_MIN_EXPONENT_DIGITS -#ifdef _MSC_VER -#define BOOST_MP_MIN_EXPONENT_DIGITS 2 -#else -#define BOOST_MP_MIN_EXPONENT_DIGITS 2 -#endif -#endif - -template <class S> -void format_float_string(S& str, std::intmax_t my_exp, std::intmax_t digits, std::ios_base::fmtflags f, bool iszero) -{ - using size_type = typename S::size_type; - - bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; - bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; - bool showpoint = (f & std::ios_base::showpoint) == std::ios_base::showpoint; - bool showpos = (f & std::ios_base::showpos) == std::ios_base::showpos; - - bool neg = str.size() && (str[0] == '-'); - - if (neg) - str.erase(0, 1); - - if (digits == 0 && !fixed) - { - digits = static_cast<std::intmax_t>((std::max)(str.size(), size_type(16))); - } - - if (iszero || str.empty() || (str.find_first_not_of('0') == S::npos)) - { - // We will be printing zero, even though the value might not - // actually be zero (it just may have been rounded to zero). - str = "0"; - if (scientific || fixed) - { - if (showpoint || digits > 0) { - str.append(1, '.'); - if (digits > 0) - str.append(size_type(digits), '0'); - } - if (scientific) - str.append("e+00"); - } - else - { - if (showpoint) - { - str.append(1, '.'); - if (digits > 1) - str.append(size_type(digits - 1), '0'); - } - } - if (neg) - str.insert(static_cast<std::string::size_type>(0), 1, '-'); - else if (showpos) - str.insert(static_cast<std::string::size_type>(0), 1, '+'); - return; - } - - if (!fixed && !scientific && !showpoint) - { - // - // Suppress trailing zeros: - // - std::string::iterator pos = str.end(); - while (pos != str.begin() && *--pos == '0') - { - } - if (pos != str.end()) - ++pos; - str.erase(pos, str.end()); - if (str.empty()) - str = '0'; - } - else if (!fixed || (my_exp >= 0)) - { - // - // Pad out the end with zero's if we need to: - // - std::intmax_t chars = static_cast<std::intmax_t>(str.size()); - chars = digits - chars; - if (scientific) - ++chars; - if (chars > 0) - { - str.append(static_cast<std::string::size_type>(chars), '0'); - } - } - - if (fixed || (!scientific && (my_exp >= -4) && (my_exp < digits))) - { - if (1 + my_exp > static_cast<std::intmax_t>(str.size())) - { - // Just pad out the end with zeros: - str.append(static_cast<std::string::size_type>(1 + my_exp - static_cast<std::intmax_t>(str.size())), '0'); - if (showpoint || (fixed && digits > 0)) - str.append("."); - } - else if (my_exp + 1 < static_cast<std::intmax_t>(str.size())) - { - if (my_exp < 0) - { - str.insert(static_cast<std::string::size_type>(0), static_cast<std::string::size_type>(-1 - my_exp), '0'); - str.insert(static_cast<std::string::size_type>(0), "0."); - } - else - { - // Insert the decimal point: - str.insert(static_cast<std::string::size_type>(my_exp + 1), 1, '.'); - } - } - else if (showpoint || (fixed && digits > 0)) // we have exactly the digits we require to left of the point - str += "."; - - if (fixed) - { - // We may need to add trailing zeros: - auto pos = str.find('.'); - if (pos != str.npos) { // this test is probably redundant, but just to be safe and for clarity - std::intmax_t l = static_cast<std::intmax_t>(pos + 1); - l = static_cast<std::intmax_t>(digits - (static_cast<std::intmax_t>(str.size()) - l)); - if (l > 0) - str.append(size_type(l), '0'); - } - } - } - else - { - BOOST_MP_USING_ABS - // Scientific format: - if (showpoint || (str.size() > 1)) - str.insert(static_cast<std::string::size_type>(1u), 1, '.'); - str.append(static_cast<std::string::size_type>(1u), 'e'); - - S e; - - #ifndef BOOST_MP_STANDALONE - e = boost::lexical_cast<S>(abs(my_exp)); - #else - BOOST_IF_CONSTEXPR(std::is_same<S, std::string>::value) - { - e = std::to_string(abs(my_exp)); - } - else - { - const std::string str_local_exp = std::to_string(abs(my_exp)); - e = S(str_local_exp.cbegin(), str_local_exp.cend()); - } - #endif - - if (e.size() < BOOST_MP_MIN_EXPONENT_DIGITS) - e.insert(static_cast<std::string::size_type>(0), BOOST_MP_MIN_EXPONENT_DIGITS - e.size(), '0'); - if (my_exp < 0) - e.insert(static_cast<std::string::size_type>(0), 1, '-'); - else - e.insert(static_cast<std::string::size_type>(0), 1, '+'); - str.append(e); - } - if (neg) - str.insert(static_cast<std::string::size_type>(0), 1, '-'); - else if (showpos) - str.insert(static_cast<std::string::size_type>(0), 1, '+'); -} - -template <class V> -BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V val, const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&) -{ - if (val > (std::numeric_limits<std::size_t>::max)()) - BOOST_MP_THROW_EXCEPTION(std::out_of_range("Can not shift by a value greater than std::numeric_limits<std::size_t>::max().")); - if (val < 0) - BOOST_MP_THROW_EXCEPTION(std::out_of_range("Can not shift by a negative value.")); -} -template <class V> -BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V val, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) -{ - if (val < 0) - BOOST_MP_THROW_EXCEPTION(std::out_of_range("Can not shift by a negative value.")); -} -template <class V> -BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V val, const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&) -{ - if (val > (std::numeric_limits<std::size_t>::max)()) - BOOST_MP_THROW_EXCEPTION(std::out_of_range("Can not shift by a value greater than std::numeric_limits<std::size_t>::max().")); -} -template <class V> -BOOST_MP_CXX14_CONSTEXPR void check_shift_range(V, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) noexcept {} - -template <class T> -BOOST_MP_CXX14_CONSTEXPR const T& evaluate_if_expression(const T& val) { return val; } -template <class T> -BOOST_MP_CXX14_CONSTEXPR T&& evaluate_if_expression(T&& val) { return static_cast<T&&>(val); } -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -BOOST_MP_CXX14_CONSTEXPR typename expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type evaluate_if_expression(const expression<tag, Arg1, Arg2, Arg3, Arg4>& val) { return val; } -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> -BOOST_MP_CXX14_CONSTEXPR typename expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type evaluate_if_expression(expression<tag, Arg1, Arg2, Arg3, Arg4>&& val) { return val; } - -template <class T> -struct convertible_to -{ - operator T () const; -}; - -} // namespace detail - -// -// Traits class, lets us know what kind of number we have, defaults to a floating point type: -// -enum number_category_type -{ - number_kind_unknown = -1, - number_kind_integer = 0, - number_kind_floating_point = 1, - number_kind_rational = 2, - number_kind_fixed_point = 3, - number_kind_complex = 4 -}; - -template <class Num, bool, bool> -struct number_category_base : public std::integral_constant<int, number_kind_unknown> -{}; -template <class Num> -struct number_category_base<Num, true, false> : public std::integral_constant<int, std::numeric_limits<Num>::is_integer ? number_kind_integer : (std::numeric_limits<Num>::max_exponent ? number_kind_floating_point : number_kind_unknown)> -{}; -template <class Num> -struct number_category : public number_category_base<Num, std::is_class<Num>::value || boost::multiprecision::detail::is_arithmetic<Num>::value, std::is_abstract<Num>::value> -{}; -template <class Backend, expression_template_option ExpressionTemplates> -struct number_category<number<Backend, ExpressionTemplates> > : public number_category<Backend> -{}; -template <class tag, class A1, class A2, class A3, class A4> -struct number_category<detail::expression<tag, A1, A2, A3, A4> > : public number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type> -{}; -// -// Specializations for types which do not always have numberic_limits specializations: -// -#ifdef BOOST_HAS_INT128 -template <> -struct number_category<boost::multiprecision::int128_type> : public std::integral_constant<int, number_kind_integer> -{}; -template <> -struct number_category<boost::multiprecision::uint128_type> : public std::integral_constant<int, number_kind_integer> -{}; -#endif -#ifdef BOOST_HAS_FLOAT128 -template <> -struct number_category<boost::multiprecision::float128_type> : public std::integral_constant<int, number_kind_floating_point> -{}; -#endif - -template <class T> -struct component_type -{ - using type = T; -}; -template <class tag, class A1, class A2, class A3, class A4> -struct component_type<detail::expression<tag, A1, A2, A3, A4> > : public component_type<typename detail::expression<tag, A1, A2, A3, A4>::result_type> -{}; - -template <class T> -struct scalar_result_from_possible_complex -{ - using type = typename std::conditional<number_category<T>::value == number_kind_complex, typename component_type<T>::type, T>::type; -}; - -template <class T> -struct complex_result_from_scalar; // individual backends must specialize this trait. - -template <class T> -struct is_unsigned_number : public std::integral_constant<bool, false> -{}; -template <class Backend, expression_template_option ExpressionTemplates> -struct is_unsigned_number<number<Backend, ExpressionTemplates> > : public is_unsigned_number<Backend> -{}; -template <class T> -struct is_signed_number : public std::integral_constant<bool, !is_unsigned_number<T>::value> -{}; -template <class T> -struct is_interval_number : public std::integral_constant<bool, false> -{}; -template <class Backend, expression_template_option ExpressionTemplates> -struct is_interval_number<number<Backend, ExpressionTemplates> > : public is_interval_number<Backend> -{}; - -template <class T, class U> -struct is_equivalent_number_type : public std::is_same<T, U> -{}; - -template <class Backend, expression_template_option ExpressionTemplates, class T2> -struct is_equivalent_number_type<number<Backend, ExpressionTemplates>, T2> : public is_equivalent_number_type<Backend, T2> -{}; -template <class T1, class Backend, expression_template_option ExpressionTemplates> -struct is_equivalent_number_type<T1, number<Backend, ExpressionTemplates> > : public is_equivalent_number_type<Backend, T1> -{}; -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -struct is_equivalent_number_type<number<Backend, ExpressionTemplates>, number<Backend2, ExpressionTemplates2> > : public is_equivalent_number_type<Backend, Backend2> -{}; - -} -} // namespace boost - -#ifdef BOOST_MP_MATH_AVAILABLE -namespace boost { namespace math { - namespace tools { - - template <class T> - struct promote_arg; - - template <class tag, class A1, class A2, class A3, class A4> - struct promote_arg<boost::multiprecision::detail::expression<tag, A1, A2, A3, A4> > - { - using type = typename boost::multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - }; - - template <class R, class B, boost::multiprecision::expression_template_option ET> - inline R real_cast(const boost::multiprecision::number<B, ET>& val) - { - return val.template convert_to<R>(); - } - - template <class R, class tag, class A1, class A2, class A3, class A4> - inline R real_cast(const boost::multiprecision::detail::expression<tag, A1, A2, A3, A4>& val) - { - using val_type = typename boost::multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type; - return val_type(val).template convert_to<R>(); - } - - template <class B, boost::multiprecision::expression_template_option ET> - struct is_complex_type<boost::multiprecision::number<B, ET> > : public std::integral_constant<bool, boost::multiprecision::number_category<B>::value == boost::multiprecision::number_kind_complex> {}; - -} // namespace tools - -namespace constants { - -template <class T> -struct is_explicitly_convertible_from_string; - -template <class B, boost::multiprecision::expression_template_option ET> -struct is_explicitly_convertible_from_string<boost::multiprecision::number<B, ET> > -{ - static constexpr bool value = true; -}; - -} // namespace constants - -}} // namespace boost::math -#endif - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_MP_NUMBER_BASE_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_compare.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_compare.hpp deleted file mode 100644 index 41160308a9..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_compare.hpp +++ /dev/null @@ -1,848 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. 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) - -#ifndef BOOST_MP_NUMBER_COMPARE_HPP -#define BOOST_MP_NUMBER_COMPARE_HPP - -#include <boost/multiprecision/traits/is_backend.hpp> -#include <boost/multiprecision/detail/fpclassify.hpp> - -// -// Comparison operators for number. -// - -namespace boost { namespace multiprecision { - -namespace default_ops { - -// -// The dispatching mechanism used here to deal with differently typed arguments -// could be better replaced with enable_if overloads, but that breaks MSVC-12 -// under strange and hard to reproduce circumstances. -// -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq(const B& a, const B& b) -{ - return a.compare(b) == 0; -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq_imp(const T& a, const U& b, const std::integral_constant<bool, true>&) -{ - typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); - return eval_eq(a, t.backend()); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq_imp(const T& a, const U& b, const std::integral_constant<bool, false>&) -{ - typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); - return eval_eq(t.backend(), b); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq(const T& a, const U& b) -{ - using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_first_backend<T, U>::value>; - return eval_eq_imp(a, b, tag_type()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const B& a, const B& b) -{ - return a.compare(b) < 0; -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt_imp(const T& a, const U& b, const std::integral_constant<bool, true>&) -{ - typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); - return eval_lt(a, t.backend()); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt_imp(const T& a, const U& b, const std::integral_constant<bool, false>&) -{ - typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); - return eval_lt(t.backend(), b); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const T& a, const U& b) -{ - using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_first_backend<T, U>::value>; - return eval_lt_imp(a, b, tag_type()); -} - -template <class B> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const B& a, const B& b) -{ - return a.compare(b) > 0; -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt_imp(const T& a, const U& b, const std::integral_constant<bool, true>&) -{ - typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); - return eval_gt(a, t.backend()); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt_imp(const T& a, const U& b, const std::integral_constant<bool, false>&) -{ - typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); - return eval_gt(t.backend(), b); -} -template <class T, class U> -inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const T& a, const U& b) -{ - using tag_type = std::integral_constant<bool, boost::multiprecision::detail::is_first_backend<T, U>::value>; - return eval_gt_imp(a, b, tag_type()); -} - -} // namespace default_ops - -namespace detail { - -template <class Num, class Val> -struct is_valid_mixed_compare : public std::integral_constant<bool, false> -{}; - -template <class B, expression_template_option ET, class Val> -struct is_valid_mixed_compare<number<B, ET>, Val> : public std::is_convertible<Val, number<B, ET> > -{}; - -template <class B, expression_template_option ET> -struct is_valid_mixed_compare<number<B, ET>, number<B, ET> > : public std::integral_constant<bool, false> -{}; - -template <class B, expression_template_option ET, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -struct is_valid_mixed_compare<number<B, ET>, expression<tag, Arg1, Arg2, Arg3, Arg4> > - : public std::is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > -{}; - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, expression_template_option ET> -struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > - : public std::is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > -{}; - -template <class Backend, expression_template_option ExpressionTemplates> -inline constexpr typename std::enable_if<number_category<Backend>::value != number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>&) -{ - return false; -} -template <class Backend, expression_template_option ExpressionTemplates> -inline constexpr typename std::enable_if<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a) -{ - using default_ops::eval_fpclassify; - return eval_fpclassify(a.backend()) == FP_NAN; -} - -template <class Arithmetic> -inline constexpr typename std::enable_if<number_category<Arithmetic>::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&) -{ - return false; -} -template <class Arithmetic> -inline -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - BOOST_MP_CXX14_CONSTEXPR -#endif - typename std::enable_if < number_category < Arithmetic> ::value == number_kind_floating_point, bool> ::type - is_unordered_value(const Arithmetic& a) -{ -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - if (BOOST_MP_IS_CONST_EVALUATED(a)) - { - return a != a; - } - else -#endif - { - return BOOST_MP_ISNAN(a); - } -} - -template <class T, class U> -inline constexpr bool is_unordered_comparison(const T& a, const U& b) -{ - return is_unordered_value(a) || is_unordered_value(b); -} - -} // namespace detail - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool operator==(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - using default_ops::eval_eq; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_eq(a.backend(), b.backend()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type -operator==(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - using default_ops::eval_eq; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); -} -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type -operator==(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - using default_ops::eval_eq; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); -} -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type -operator==(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return false; - return eval_eq(t.backend(), result_type::canonical_value(a)); -} -template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool operator==(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return false; - return eval_eq(t.backend(), a.backend()); -} -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type -operator==(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return false; - return eval_eq(t.backend(), result_type::canonical_value(b)); -} -template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool operator==(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return false; - return eval_eq(t.backend(), b.backend()); -} -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type -operator==(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) -{ - using default_ops::eval_eq; - typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - if (detail::is_unordered_comparison(t, t2)) - return false; - return eval_eq(t.backend(), t2.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool operator!=(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - using default_ops::eval_eq; - if (detail::is_unordered_comparison(a, b)) - return true; - return !eval_eq(a.backend(), b.backend()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type -operator!=(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - using default_ops::eval_eq; - if (detail::is_unordered_comparison(a, b)) - return true; - return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b)); -} -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && !is_number_expression<Arithmetic>::value, bool>::type -operator!=(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - using default_ops::eval_eq; - if (detail::is_unordered_comparison(a, b)) - return true; - return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a)); -} -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type -operator!=(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return true; - return !eval_eq(t.backend(), result_type::canonical_value(a)); -} -template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool operator!=(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return true; - return !eval_eq(t.backend(), a.backend()); -} -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type -operator!=(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return true; - return !eval_eq(t.backend(), result_type::canonical_value(b)); -} -template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool operator!=(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_eq; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return true; - return !eval_eq(t.backend(), result_type::canonical_value(b)); -} -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type -operator!=(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) -{ - using default_ops::eval_eq; - typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - if (detail::is_unordered_comparison(t, t2)) - return true; - return !eval_eq(t.backend(), t2.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type -operator<(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - using default_ops::eval_lt; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_lt(a.backend(), b.backend()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator<(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - using default_ops::eval_lt; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); -} -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator<(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - using default_ops::eval_gt; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); -} -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator<(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return false; - return eval_gt(t.backend(), result_type::canonical_value(a)); -} -template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool operator<(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(b); - return a < t; -} -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator<(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return false; - return eval_lt(t.backend(), result_type::canonical_value(b)); -} -template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool operator<(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - result_type t(a); - return t < b; -} -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator<(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) -{ - using default_ops::eval_lt; - typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - if (detail::is_unordered_comparison(t, t2)) - return false; - return eval_lt(t.backend(), t2.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type -operator>(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - using default_ops::eval_gt; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_gt(a.backend(), b.backend()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator>(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - using default_ops::eval_gt; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); -} -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator>(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - using default_ops::eval_lt; - if (detail::is_unordered_comparison(a, b)) - return false; - return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); -} -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator>(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - result_type t(b); - return a > t; -} -template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool operator>(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - result_type t(b); - return a > t; -} -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator>(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(a); - return t > b; -} -template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool operator>(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(a); - return t > b; -} -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator>(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) -{ - using default_ops::eval_gt; - typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - return t > t2; -} - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type -operator<=(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - using default_ops::eval_gt; - if (detail::is_unordered_comparison(a, b)) - return false; - return !eval_gt(a.backend(), b.backend()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator<=(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - using default_ops::eval_gt; - if (detail::is_unordered_comparison(a, b)) - return false; - return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); -} -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator<=(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - using default_ops::eval_lt; - if (detail::is_unordered_comparison(a, b)) - return false; - return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); -} -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator<=(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - if (detail::is_unordered_value(a) || detail::is_unordered_value(b)) - return false; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return false; - return !eval_lt(t.backend(), result_type::canonical_value(a)); -} -template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool operator<=(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - if (detail::is_unordered_value(a) || detail::is_unordered_value(b)) - return false; - result_type t(b); - return a <= t; -} -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator<=(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return false; - return !eval_gt(t.backend(), result_type::canonical_value(b)); -} -template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool operator<=(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(a); - return t <= b; -} -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator<=(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) -{ - using default_ops::eval_gt; - typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - if (detail::is_unordered_comparison(t, t2)) - return false; - return !eval_gt(t.backend(), t2.backend()); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type -operator>=(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - using default_ops::eval_lt; - if (detail::is_unordered_comparison(a, b)) - return false; - return !eval_lt(a.backend(), b.backend()); -} -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator>=(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - using default_ops::eval_lt; - if (detail::is_unordered_comparison(a, b)) - return false; - return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); -} -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex) && !is_number_expression<Arithmetic>::value, bool>::type -operator>=(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - using default_ops::eval_gt; - if (detail::is_unordered_comparison(a, b)) - return false; - return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); -} -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator>=(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(b); - if (detail::is_unordered_comparison(a, t)) - return false; - return !eval_gt(t.backend(), result_type::canonical_value(a)); -} -template <class Backend, expression_template_option ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR bool operator>=(const number<Backend, ExpressionTemplates>& a, const detail::expression<Tag, A1, A2, A3, A4>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_gt; - result_type t(b); - return a >= t; -} -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator>=(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - result_type t(a); - if (detail::is_unordered_comparison(t, b)) - return false; - return !eval_lt(t.backend(), result_type::canonical_value(b)); -} -template <class Tag, class A1, class A2, class A3, class A4, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR bool operator>=(const detail::expression<Tag, A1, A2, A3, A4>& a, const number<Backend, ExpressionTemplates>& b) -{ - using result_type = typename detail::expression<Tag, A1, A2, A3, A4>::result_type; - using default_ops::eval_lt; - result_type t(a); - return t >= b; -} -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type -operator>=(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) -{ - using default_ops::eval_lt; - typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - if (detail::is_unordered_comparison(t, t2)) - return false; - return !eval_lt(t.backend(), t2.backend()); -} - -// -// C99 comparison macros as functions: -// -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a > b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a > b; } - -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a > b; } - -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a > b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a > b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type - isgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a > b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a >= b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isgreaterequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a >= b; } - -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isgreaterequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a >= b; } - -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isgreaterequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a >= b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isgreaterequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a >= b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type - isgreaterequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a >= b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a <= b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - islessequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a <= b; } - -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - islessequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a <= b; } - -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - islessequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a <= b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - islessequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a <= b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type - islessequal - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a <= b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return a < b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isless - BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return a < b; } - -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isless - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return a < b; } - -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isless - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b) { return a < b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isless - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b) { return a < b; } - -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type - isless - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b) { return a < b; } - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) -{ - if (detail::is_unordered_comparison(a, b)) - return false; - return a != b; -} - -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - islessgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) -{ - if (detail::is_unordered_comparison(a, b)) - return false; - return a != b; -} - -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - islessgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) -{ - if (detail::is_unordered_comparison(a, b)) - return false; - return a != b; -} - -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - islessgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& bb) -{ - typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb); - return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b); -} - -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - islessgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const Arithmetic& b) -{ - typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa); - return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b); -} - -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type - islessgreater - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& bb) -{ - typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type b(bb); - return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(a, b); -} - -template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> -inline BOOST_MP_CXX14_CONSTEXPR bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { return detail::is_unordered_comparison(a, b); } - -template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isunordered - BOOST_PREVENT_MACRO_SUBSTITUTION(const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { return detail::is_unordered_comparison(a, b); } - -template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type - isunordered - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { return detail::is_unordered_comparison(a, b); } - -template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isunordered - BOOST_PREVENT_MACRO_SUBSTITUTION(const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& bb) -{ - typename detail::expression<Tag, A1, A2, A3, A4>::result_type b(bb); - return detail::is_unordered_comparison(a, b); -} - -template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type - isunordered - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const Arithmetic& b) -{ - typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa); - return detail::is_unordered_comparison(a, b); -} - -template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_equivalent_number_type<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value, bool>::type - isunordered - BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::expression<Tag, A1, A2, A3, A4>& aa, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& bb) -{ - typename detail::expression<Tag, A1, A2, A3, A4>::result_type a(aa); - typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type b(bb); - return detail::is_unordered_comparison(a, b); -} - -}} // namespace boost::multiprecision - -#endif // BOOST_MP_NUMBER_COMPARE_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/precision.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/precision.hpp deleted file mode 100644 index df58144297..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/precision.hpp +++ /dev/null @@ -1,313 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2018 John Maddock. 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) - -#ifndef BOOST_MP_DETAIL_PRECISION_HPP -#define BOOST_MP_DETAIL_PRECISION_HPP - -#include <boost/multiprecision/traits/is_variable_precision.hpp> -#include <boost/multiprecision/detail/number_base.hpp> -#include <boost/multiprecision/detail/digits.hpp> -#include <boost/multiprecision/detail/assert.hpp> - -namespace boost { namespace multiprecision { namespace detail { - -template <class B, boost::multiprecision::expression_template_option ET> -inline constexpr unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>&, const std::integral_constant<int, 0>&) -{ - return std::numeric_limits<boost::multiprecision::number<B, ET> >::digits10; -} -template <class B, boost::multiprecision::expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>& val, const std::integral_constant<int, 1>&) -{ - // - // We have an arbitrary precision integer, take it's "precision" as the - // location of the most-significant-bit less the location of the - // least-significant-bit, ie the number of bits required to represent the - // the value assuming we will have an exponent to shift things by: - // - return static_cast<unsigned>(val.is_zero() ? 1 : 1 + digits2_2_10(msb(abs(val)) - lsb(abs(val)) + 1)); -} -template <class B, boost::multiprecision::expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>& val, const std::integral_constant<int, 2>&) -{ - // - // We have an arbitrary precision rational, take it's "precision" as the - // the larger of the "precision" of numerator and denominator: - // - return (std::max)(current_precision_of_last_chance_imp(numerator(val), std::integral_constant<int, 1>()), current_precision_of_last_chance_imp(denominator(val), std::integral_constant<int, 1>())); -} - -template <class B, boost::multiprecision::expression_template_option ET> -inline BOOST_MP_CXX14_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& n, const std::integral_constant<bool, true>&) -{ - return n.precision(); -} -template <class B, boost::multiprecision::expression_template_option ET> -inline constexpr unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& val, const std::integral_constant<bool, false>&) -{ - using tag = std::integral_constant<int, - std::numeric_limits<boost::multiprecision::number<B, ET> >::is_specialized && - std::numeric_limits<boost::multiprecision::number<B, ET> >::is_integer && - std::numeric_limits<boost::multiprecision::number<B, ET> >::is_exact && - !std::numeric_limits<boost::multiprecision::number<B, ET> >::is_modulo - ? 1 - : boost::multiprecision::number_category<boost::multiprecision::number<B, ET> >::value == boost::multiprecision::number_kind_rational ? 2 - : 0>; - return current_precision_of_last_chance_imp(val, tag()); -} - -template <class R, class Terminal> -inline constexpr unsigned current_precision_of_terminal(const Terminal&) -{ - return (R::thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) - ? (std::numeric_limits<Terminal>::min_exponent ? std::numeric_limits<Terminal>::digits10 : 1 + std::numeric_limits<Terminal>::digits10) : 0; -} -template <class R, class Terminal> -inline constexpr unsigned current_precision_of(const Terminal& r) -{ - return current_precision_of_terminal<R>(R::canonical_value(r)); -} -template <class R> -inline constexpr unsigned current_precision_of(const float&) -{ - using list = typename R::backend_type::float_types; - using first_float = typename std::tuple_element<0, list>::type; - - return (R::thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) ? std::numeric_limits<first_float>::digits10 : 0; -} - -template <class R, class Terminal, std::size_t N> -inline constexpr unsigned current_precision_of(const Terminal (&)[N]) -{ // For string literals: - return 0; -} - -template <class R, class B, boost::multiprecision::expression_template_option ET> -inline constexpr unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& n, const std::true_type&) -{ - return std::is_same<R, boost::multiprecision::number<B, ET> >::value - || (std::is_same<typename R::value_type, boost::multiprecision::number<B, ET> >::value && (R::thread_default_variable_precision_options() >= variable_precision_options::preserve_component_precision)) - || (R::thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) - ? current_precision_of_imp(n, boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<B, ET> >()) : 0; -} -template <class R, class B, boost::multiprecision::expression_template_option ET> -inline constexpr unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& n, const std::false_type&) -{ - return std::is_same<R, boost::multiprecision::number<B, ET> >::value - || std::is_same<typename R::value_type, boost::multiprecision::number<B, ET> >::value - ? current_precision_of_imp(n, boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<B, ET> >()) : 0; -} - -template <class R, class B, boost::multiprecision::expression_template_option ET> -inline constexpr unsigned current_precision_of(const boost::multiprecision::number<B, ET>& n) -{ - return current_precision_of_imp<R>(n, boost::multiprecision::detail::is_variable_precision<R>()); -} - -template <class R, class tag, class Arg1> -inline constexpr unsigned current_precision_of(const expression<tag, Arg1, void, void, void>& expr) -{ - return current_precision_of<R>(expr.left_ref()); -} - -template <class R, class Arg1> -inline constexpr unsigned current_precision_of(const expression<terminal, Arg1, void, void, void>& expr) -{ - return current_precision_of<R>(expr.value()); -} - -template <class R, class tag, class Arg1, class Arg2> -inline constexpr unsigned current_precision_of(const expression<tag, Arg1, Arg2, void, void>& expr) -{ - return (std::max)(current_precision_of<R>(expr.left_ref()), current_precision_of<R>(expr.right_ref())); -} - -template <class R, class tag, class Arg1, class Arg2, class Arg3> -inline constexpr unsigned current_precision_of(const expression<tag, Arg1, Arg2, Arg3, void>& expr) -{ - return (std::max)((std::max)(current_precision_of<R>(expr.left_ref()), current_precision_of<R>(expr.right_ref())), current_precision_of<R>(expr.middle_ref())); -} - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable : 4130) -#endif - -template <class R, bool = boost::multiprecision::detail::is_variable_precision<R>::value> -struct scoped_default_precision -{ - template <class T> - constexpr scoped_default_precision(const T&) {} - template <class T, class U> - constexpr scoped_default_precision(const T&, const U&) {} - template <class T, class U, class V> - constexpr scoped_default_precision(const T&, const U&, const V&) {} - - // - // This function is never called: in C++17 it won't be compiled either: - // - unsigned precision() const - { - BOOST_MP_ASSERT("This function should never be called!!" == nullptr); - return 0; - } -}; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -template <class R> -struct scoped_default_precision<R, true> -{ - template <class T> - BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a) - { - init(has_uniform_precision() ? R::thread_default_precision() : (std::max)(R::thread_default_precision(), current_precision_of<R>(a))); - } - template <class T, class U> - BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b) - { - init(has_uniform_precision() ? R::thread_default_precision() : (std::max)(R::thread_default_precision(), (std::max)(current_precision_of<R>(a), current_precision_of<R>(b)))); - } - template <class T, class U, class V> - BOOST_MP_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b, const V& c) - { - init(has_uniform_precision() ? R::thread_default_precision() : (std::max)((std::max)(current_precision_of<R>(a), current_precision_of<R>(b)), (std::max)(R::thread_default_precision(), current_precision_of<R>(c)))); - } - ~scoped_default_precision() - { - if(m_new_prec != m_old_prec) - R::thread_default_precision(m_old_prec); - } - BOOST_MP_CXX14_CONSTEXPR unsigned precision() const - { - return m_new_prec; - } - - static constexpr bool has_uniform_precision() - { - return R::thread_default_variable_precision_options() <= boost::multiprecision::variable_precision_options::assume_uniform_precision; - } - - private: - BOOST_MP_CXX14_CONSTEXPR void init(unsigned p) - { - m_old_prec = R::thread_default_precision(); - if (p && (p != m_old_prec)) - { - R::thread_default_precision(p); - m_new_prec = p; - } - else - m_new_prec = m_old_prec; - } - unsigned m_old_prec, m_new_prec; -}; - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T*, const std::integral_constant<bool, false>&) {} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj, const std::integral_constant<bool, true>&) -{ - if (obj->precision() != T::thread_default_precision()) - { - obj->precision(T::thread_default_precision()); - } -} - -template <class T> -inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj) -{ - maybe_promote_precision(obj, std::integral_constant<bool, boost::multiprecision::detail::is_variable_precision<T>::value>()); -} - -#ifndef BOOST_NO_CXX17_IF_CONSTEXPR -#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) \ - if \ - constexpr(boost::multiprecision::detail::is_variable_precision<T>::value) -#else -#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if (boost::multiprecision::detail::is_variable_precision<T>::value) -#endif - -template <class T, bool = boost::multiprecision::detail::is_variable_precision<T>::value> -struct scoped_target_precision -{ - variable_precision_options opts; - scoped_target_precision() : opts(T::thread_default_variable_precision_options()) - { - T::thread_default_variable_precision_options(variable_precision_options::preserve_target_precision); - } - ~scoped_target_precision() - { - T::thread_default_variable_precision_options(opts); - } -}; -template <class T> -struct scoped_target_precision<T, false> {}; - -template <class T, bool = boost::multiprecision::detail::is_variable_precision<T>::value> -struct scoped_source_precision -{ - variable_precision_options opts; - scoped_source_precision() : opts(T::thread_default_variable_precision_options()) - { - T::thread_default_variable_precision_options(variable_precision_options::preserve_source_precision); - } - ~scoped_source_precision() - { - T::thread_default_variable_precision_options(opts); - } -}; -template <class T> -struct scoped_source_precision<T, false> {}; - -template <class T, bool = boost::multiprecision::detail::is_variable_precision<T>::value> -struct scoped_precision_options -{ - unsigned saved_digits; - boost::multiprecision::variable_precision_options saved_options; - - scoped_precision_options(unsigned digits) - : saved_digits(T::thread_default_precision()), saved_options(T::thread_default_variable_precision_options()) - { - T::thread_default_precision(digits); - } - scoped_precision_options(unsigned digits, variable_precision_options opts) - : saved_digits(T::thread_default_precision()), saved_options(T::thread_default_variable_precision_options()) - { - T::thread_default_precision(digits); - T::thread_default_variable_precision_options(opts); - } - template <class U> - scoped_precision_options(const U& u) - : saved_digits(T::thread_default_precision()), saved_options(T::thread_default_variable_precision_options()) - { - T::thread_default_precision(u.precision()); - T::thread_default_variable_precision_options(U::thread_default_variable_precision_options()); - } - ~scoped_precision_options() - { - T::thread_default_variable_precision_options(saved_options); - T::thread_default_precision(saved_digits); - } -}; - -template <class T> -struct scoped_precision_options<T, false> -{ - scoped_precision_options(unsigned) {} - scoped_precision_options(unsigned, variable_precision_options) {} - template <class U> - scoped_precision_options(const U&) {} - ~scoped_precision_options() {} -}; - -} -} -} // namespace boost::multiprecision::detail - -#endif // BOOST_MP_DETAIL_PRECISION_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/rebind.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/rebind.hpp deleted file mode 100644 index 6c6bbda127..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/rebind.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. -// Copyright Christopher Kormanyos 2013. 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) -// - -#ifndef BOOST_MP_DETAIL_REBIND_HPP -#define BOOST_MP_DETAIL_REBIND_HPP - -namespace boost { namespace multiprecision { namespace backends { namespace detail { -template <class value_type, class my_allocator> -struct rebind -{ - using type = typename std::allocator_traits<my_allocator>::template rebind_alloc<value_type>; -}; -}}}} // namespace boost::multiprecision::backends::detail - -#endif // BOOST_MP_DETAIL_REBIND_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/standalone_config.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/standalone_config.hpp deleted file mode 100644 index 9c8ee9a5bc..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/standalone_config.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2010 - 2021 Douglas Gregor -// Copyright 2021 Matt Borland. -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -// -// Used to support configuration options depending on standalone context -// by providing either required support or disabling functionality - -#ifndef BOOST_MP_STANDALONE_CONFIG_HPP -#define BOOST_MP_STANDALONE_CONFIG_HPP - -#include <climits> -// Boost.Config is dependency free so it is considered a requirement to use Boost.Multiprecision in standalone mode -#include <boost/config.hpp> -#include <boost/config/workaround.hpp> - -// Minimum language standard transition - #ifdef _MSVC_LANG - # if _MSVC_LANG < 201402L - # pragma warning("The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)"); - # endif - #else - # if __cplusplus < 201402L - # warning "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)" - # endif - #endif - -// If any of the most frequently used boost headers are missing assume that standalone mode is supposed to be used -#ifdef __has_include -#if !__has_include(<boost/assert.hpp>) || !__has_include(<boost/lexical_cast.hpp>) || \ - !__has_include(<boost/throw_exception.hpp>) || !__has_include(<boost/predef/other/endian.h>) -# ifndef BOOST_MP_STANDALONE -# define BOOST_MP_STANDALONE -# endif -#endif -#endif - -#ifndef BOOST_MP_STANDALONE - -#include <boost/integer.hpp> -#include <boost/integer_traits.hpp> - -// Required typedefs for interoperability with standalone mode -#if defined(BOOST_HAS_INT128) && defined(__cplusplus) -namespace boost { namespace multiprecision { - using int128_type = boost::int128_type; - using uint128_type = boost::uint128_type; -}} -#endif -#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) -namespace boost { namespace multiprecision { - using float128_type = boost::float128_type; -}} -#endif - -// Boost.Math available by default -#define BOOST_MP_MATH_AVAILABLE - -#else // Standalone mode - -#ifdef BOOST_MATH_STANDALONE -# define BOOST_MP_MATH_AVAILABLE -#endif - -#ifndef BOOST_MP_MATH_AVAILABLE -# define BOOST_MATH_INSTRUMENT_CODE(x) -#endif - -// Prevent Macro sub -#ifndef BOOST_PREVENT_MACRO_SUBSTITUTION -# define BOOST_PREVENT_MACRO_SUBSTITUTION -#endif - -#if defined(BOOST_HAS_INT128) && defined(__cplusplus) -namespace boost { namespace multiprecision { -# ifdef __GNUC__ - __extension__ typedef __int128 int128_type; - __extension__ typedef unsigned __int128 uint128_type; -# else - typedef __int128 int128_type; - typedef unsigned __int128 uint128_type; -# endif -}} - -#endif -// same again for __float128: -#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) -namespace boost { namespace multiprecision { -# ifdef __GNUC__ - __extension__ typedef __float128 float128_type; -# else - typedef __float128 float128_type; -# endif -}} - -#endif - -#endif // BOOST_MP_STANDALONE - -// Workarounds for numeric limits on old compilers -#ifdef BOOST_HAS_INT128 -# ifndef INT128_MAX -# define INT128_MAX static_cast<boost::multiprecision::int128_type>((static_cast<boost::multiprecision::uint128_type>(1) << ((__SIZEOF_INT128__ * __CHAR_BIT__) - 1)) - 1) -# endif -# ifndef INT128_MIN -# define INT128_MIN (-INT128_MAX - 1) -# endif -# ifndef UINT128_MAX -# define UINT128_MAX ((2 * static_cast<boost::multiprecision::uint128_type>(INT128_MAX)) + 1) -# endif -#endif - -#endif // BOOST_MP_STANDALONE_CONFIG_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/ublas_interop.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/ublas_interop.hpp deleted file mode 100644 index ad3afa987f..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/ublas_interop.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2013 John Maddock. 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) - -#ifndef BOOST_MP_UBLAS_INTEROP_HPP -#define BOOST_MP_UBLAS_INTEROP_HPP - -namespace boost { namespace numeric { namespace ublas { - -template <class V> -class sparse_vector_element; - -template <class V, class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline bool operator==(const sparse_vector_element<V>& a, const ::boost::multiprecision::number<Backend, ExpressionTemplates>& b) -{ - using ref_type = typename sparse_vector_element<V>::const_reference; - return static_cast<ref_type>(a) == b; -} - -template <class X, class Y> -struct promote_traits; - -template <class Backend1, boost::multiprecision::expression_template_option ExpressionTemplates1, class Backend2, boost::multiprecision::expression_template_option ExpressionTemplates2> -struct promote_traits<boost::multiprecision::number<Backend1, ExpressionTemplates1>, boost::multiprecision::number<Backend2, ExpressionTemplates2> > -{ - using number1_t = boost::multiprecision::number<Backend1, ExpressionTemplates1>; - using number2_t = boost::multiprecision::number<Backend2, ExpressionTemplates2>; - using promote_type = typename std::conditional< - std::is_convertible<number1_t, number2_t>::value && !std::is_convertible<number2_t, number1_t>::value, - number2_t, number1_t>::type; -}; - -template <class Backend1, boost::multiprecision::expression_template_option ExpressionTemplates1, class Arithmetic> -struct promote_traits<boost::multiprecision::number<Backend1, ExpressionTemplates1>, Arithmetic> -{ - using promote_type = boost::multiprecision::number<Backend1, ExpressionTemplates1>; -}; - -template <class Arithmetic, class Backend1, boost::multiprecision::expression_template_option ExpressionTemplates1> -struct promote_traits<Arithmetic, boost::multiprecision::number<Backend1, ExpressionTemplates1> > -{ - using promote_type = boost::multiprecision::number<Backend1, ExpressionTemplates1>; -}; - -template <class Backend1, boost::multiprecision::expression_template_option ExpressionTemplates1, class tag, class Arg1, class Arg2, class Arg3, class Arg4> -struct promote_traits<boost::multiprecision::number<Backend1, ExpressionTemplates1>, boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > -{ - using number1_t = boost::multiprecision::number<Backend1, ExpressionTemplates1> ; - using expression_type = boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>; - using number2_t = typename expression_type::result_type ; - using promote_type = typename promote_traits<number1_t, number2_t>::promote_type ; -}; - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Backend1, boost::multiprecision::expression_template_option ExpressionTemplates1> -struct promote_traits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::number<Backend1, ExpressionTemplates1> > -{ - using number1_t = boost::multiprecision::number<Backend1, ExpressionTemplates1> ; - using expression_type = boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>; - using number2_t = typename expression_type::result_type ; - using promote_type = typename promote_traits<number1_t, number2_t>::promote_type ; -}; - -template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tagb, class Arg1b, class Arg2b, class Arg3b, class Arg4b> -struct promote_traits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::detail::expression<tagb, Arg1b, Arg2b, Arg3b, Arg4b> > -{ - using expression1_t = boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> ; - using number1_t = typename expression1_t::result_type ; - using expression2_t = boost::multiprecision::detail::expression<tagb, Arg1b, Arg2b, Arg3b, Arg4b>; - using number2_t = typename expression2_t::result_type ; -}; - -}}} // namespace boost::numeric::ublas - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/integer.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/integer.hpp deleted file mode 100644 index 2873b730a6..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/integer.hpp +++ /dev/null @@ -1,363 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012-21 John Maddock. -// Copyright 2021 Iskandarov Lev. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_INTEGER_HPP -#define BOOST_MP_INTEGER_HPP - -#include <type_traits> -#include <boost/multiprecision/cpp_int.hpp> -#include <boost/multiprecision/detail/bitscan.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> -#include <boost/multiprecision/detail/standalone_config.hpp> - -namespace boost { -namespace multiprecision { - -template <class Integer, class I2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value && boost::multiprecision::detail::is_integral<I2>::value, Integer&>::type -multiply(Integer& result, const I2& a, const I2& b) -{ - return result = static_cast<Integer>(a) * static_cast<Integer>(b); -} -template <class Integer, class I2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value && boost::multiprecision::detail::is_integral<I2>::value, Integer&>::type -add(Integer& result, const I2& a, const I2& b) -{ - return result = static_cast<Integer>(a) + static_cast<Integer>(b); -} -template <class Integer, class I2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value && boost::multiprecision::detail::is_integral<I2>::value, Integer&>::type -subtract(Integer& result, const I2& a, const I2& b) -{ - return result = static_cast<Integer>(a) - static_cast<Integer>(b); -} - -template <class Integer> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value>::type divide_qr(const Integer& x, const Integer& y, Integer& q, Integer& r) -{ - q = x / y; - r = x % y; -} - -template <class I1, class I2> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val) -{ - return static_cast<I2>(x % val); -} - -namespace detail { -// -// Figure out the kind of integer that has twice as many bits as some builtin -// integer type I. Use a native type if we can (including types which may not -// be recognised by boost::int_t because they're larger than long long), -// otherwise synthesize a cpp_int to do the job. -// -template <class I> -struct double_integer -{ - static constexpr const unsigned int_t_digits = - 2 * sizeof(I) <= sizeof(long long) ? std::numeric_limits<I>::digits * 2 : 1; - - using type = typename std::conditional< - 2 * sizeof(I) <= sizeof(long long), - typename std::conditional< - boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value, - typename boost::multiprecision::detail::int_t<int_t_digits>::least, - typename boost::multiprecision::detail::uint_t<int_t_digits>::least>::type, - typename std::conditional< - 2 * sizeof(I) <= sizeof(double_limb_type), - typename std::conditional< - boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value, - signed_double_limb_type, - double_limb_type>::type, - number<cpp_int_backend<sizeof(I) * CHAR_BIT * 2, sizeof(I) * CHAR_BIT * 2, (boost::multiprecision::detail::is_signed<I>::value ? signed_magnitude : unsigned_magnitude), unchecked, void> > >::type>::type; -}; - -} // namespace detail - -template <class I1, class I2, class I3> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_unsigned<I2>::value && boost::multiprecision::detail::is_integral<I3>::value, I1>::type -powm(const I1& a, I2 b, I3 c) -{ - using double_type = typename detail::double_integer<I1>::type; - - I1 x(1), y(a); - double_type result(0); - - while (b > 0) - { - if (b & 1) - { - multiply(result, x, y); - x = integer_modulus(result, c); - } - multiply(result, y, y); - y = integer_modulus(result, c); - b >>= 1; - } - return x % c; -} - -template <class I1, class I2, class I3> -inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I1>::value && boost::multiprecision::detail::is_signed<I2>::value && boost::multiprecision::detail::is_integral<I2>::value && boost::multiprecision::detail::is_integral<I3>::value, I1>::type -powm(const I1& a, I2 b, I3 c) -{ - if (b < 0) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent.")); - } - return powm(a, static_cast<typename boost::multiprecision::detail::make_unsigned<I2>::type>(b), c); -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, std::size_t>::type lsb(const Integer& val) -{ - if (val <= 0) - { - if (val == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - else - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - } - return detail::find_lsb(val); -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, std::size_t>::type msb(Integer val) -{ - if (val <= 0) - { - if (val == 0) - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand.")); - } - else - { - BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined.")); - } - } - return detail::find_msb(val); -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, bool>::type bit_test(const Integer& val, std::size_t index) -{ - Integer mask = 1; - if (index >= sizeof(Integer) * CHAR_BIT) - return 0; - if (index) - mask <<= index; - return val & mask ? true : false; -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, Integer&>::type bit_set(Integer& val, std::size_t index) -{ - Integer mask = 1; - if (index >= sizeof(Integer) * CHAR_BIT) - return val; - if (index) - mask <<= index; - val |= mask; - return val; -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, Integer&>::type bit_unset(Integer& val, std::size_t index) -{ - Integer mask = 1; - if (index >= sizeof(Integer) * CHAR_BIT) - return val; - if (index) - mask <<= index; - val &= ~mask; - return val; -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, Integer&>::type bit_flip(Integer& val, std::size_t index) -{ - Integer mask = 1; - if (index >= sizeof(Integer) * CHAR_BIT) - return val; - if (index) - mask <<= index; - val ^= mask; - return val; -} - -namespace detail { - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR Integer karatsuba_sqrt(const Integer& x, Integer& r, size_t bits) -{ - // - // Define the floating point type used for std::sqrt, in our tests, sqrt(double) and sqrt(long double) take - // about the same amount of time as long as long double is not an emulated 128-bit type (ie the same type - // as __float128 from libquadmath). So only use long double if it's an 80-bit type: - // -#ifndef __clang__ - typedef typename std::conditional<(std::numeric_limits<long double>::digits == 64), long double, double>::type real_cast_type; -#else - // clang has buggy __int128 -> long double conversion: - typedef double real_cast_type; -#endif - // - // As per the Karatsuba sqrt algorithm, the low order bits/4 bits pay no part in the result, only in the remainder, - // so define the number of bits our argument must have before passing to std::sqrt is safe, even if doing so - // looses a few bits: - // - constexpr std::size_t cutoff = (std::numeric_limits<real_cast_type>::digits * 4) / 3; - // - // Type which can hold at least "cutoff" bits: - // -#ifdef BOOST_HAS_INT128 - using cutoff_t = typename std::conditional<(cutoff > 64), uint128_type, std::uint64_t>::type; -#else - using cutoff_t = std::uint64_t; -#endif - // - // See if we can take the fast path: - // - if (bits <= cutoff) - { - constexpr cutoff_t half_bits = (cutoff_t(1u) << ((sizeof(cutoff_t) * CHAR_BIT) / 2)) - 1; - cutoff_t val = static_cast<cutoff_t>(x); - real_cast_type real_val = static_cast<real_cast_type>(val); - cutoff_t s64 = static_cast<cutoff_t>(std::sqrt(real_val)); - // converting to long double can loose some precision, and `sqrt` can give eps error, so we'll fix this - // this is needed - while ((s64 > half_bits) || (s64 * s64 > val)) - s64--; - // in my tests this never fired, but theoretically this might be needed - while ((s64 < half_bits) && ((s64 + 1) * (s64 + 1) <= val)) - s64++; - r = static_cast<Integer>(val - s64 * s64); - return static_cast<Integer>(s64); - } - // https://hal.inria.fr/file/index/docid/72854/filename/RR-3805.pdf - std::size_t b = bits / 4; - Integer q = x; - q >>= b * 2; - Integer s = karatsuba_sqrt(q, r, bits - b * 2); - Integer t = 0u; - bit_set(t, static_cast<unsigned>(b * 2)); - r <<= b; - t--; - t &= x; - t >>= b; - t += r; - s <<= 1; - divide_qr(t, s, q, r); - r <<= b; - t = 0u; - bit_set(t, static_cast<unsigned>(b)); - t--; - t &= x; - r += t; - s <<= (b - 1); // we already <<1 it before - s += q; - q *= q; - // we substract after, so it works for unsigned integers too - if (r < q) - { - t = s; - t <<= 1; - t--; - r += t; - s--; - } - r -= q; - return s; -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR Integer bitwise_sqrt(const Integer& x, Integer& r) -{ - // - // This is slow bit-by-bit integer square root, see for example - // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 - // There are better methods such as http://hal.inria.fr/docs/00/07/28/54/PDF/RR-3805.pdf - // and http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf which should be implemented - // at some point. - // - Integer s = 0; - switch (x) - { - case 0: - r = 0; - return s; - case 1: - r = 0; - return 1; - case 2: - r = 1; - return 1; - case 3: - r = 2; - return 1; - default: - break; - // fall through: - } - std::ptrdiff_t g = msb(x); - - Integer t = 0; - r = x; - g /= 2; - bit_set(s, g); - bit_set(t, 2 * g); - r = x - t; - --g; - do - { - t = s; - t <<= g + 1; - bit_set(t, 2 * g); - if (t <= r) - { - bit_set(s, g); - r -= t; - } - --g; - } while (g >= 0); - return s; -} - -} // namespace detail - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, Integer>::type sqrt(const Integer& x, Integer& r) -{ -#ifndef BOOST_MP_NO_CONSTEXPR_DETECTION - // recursive Karatsuba sqrt can cause issues in constexpr context: - if (BOOST_MP_IS_CONST_EVALUATED(x)) - { - return detail::bitwise_sqrt(x, r); - } -#endif - if (x == 0u) { - r = 0u; - return 0u; - } - - return detail::karatsuba_sqrt(x, r, msb(x) + 1); -} - -template <class Integer> -BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<Integer>::value, Integer>::type sqrt(const Integer& x) -{ - Integer r(0); - return sqrt(x, r); -} - -}} // namespace boost::multiprecision - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/number.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/number.hpp deleted file mode 100644 index c6e8167c2e..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/number.hpp +++ /dev/null @@ -1,2490 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2011 John Maddock. 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) - -#ifndef BOOST_MP_NUMBER_HPP -#define BOOST_MP_NUMBER_HPP - -#include <cstdint> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/precision.hpp> -#include <boost/multiprecision/detail/generic_interconvert.hpp> -#include <boost/multiprecision/detail/number_compare.hpp> -#include <boost/multiprecision/traits/is_restricted_conversion.hpp> -#include <boost/multiprecision/traits/is_complex.hpp> -#include <boost/multiprecision/traits/is_convertible_arithmetic.hpp> -#include <boost/multiprecision/detail/hash.hpp> -#include <boost/multiprecision/detail/number_base.hpp> -#include <istream> // stream operators -#include <cstdio> // EOF -#include <cctype> // isspace -#include <functional> // std::hash -#include <type_traits> -#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW -#include <string_view> -#endif - -#ifndef BOOST_MP_STANDALONE -#include <boost/core/nvp.hpp> -#endif - -namespace boost { -namespace multiprecision { - -#ifdef BOOST_MSVC -// warning C4127: conditional expression is constant -// warning C4714: function marked as __forceinline not inlined -#pragma warning(push) -#pragma warning(disable : 4127 4714 6326) -#endif - -template <class Backend, expression_template_option ExpressionTemplates> -class number -{ - using self_type = number<Backend, ExpressionTemplates>; - - public: - using backend_type = Backend ; - using value_type = typename component_type<self_type>::type; - - static constexpr expression_template_option et = ExpressionTemplates; - - BOOST_MP_FORCEINLINE constexpr number() noexcept(noexcept(Backend())) {} - BOOST_MP_FORCEINLINE constexpr number(const number& e) noexcept(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(e.m_backend) {} - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const V& v, - typename std::enable_if< - (boost::multiprecision::detail::is_convertible_arithmetic<V, Backend>::value - || std::is_same<std::string, V>::value - || std::is_convertible<V, const char*>::value) - && !std::is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value - && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value>::type* = nullptr) - { - m_backend = canonical_value(v); - } - template <class V> - BOOST_MP_FORCEINLINE constexpr number(const V& v, typename std::enable_if< - std::is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value>::type* = nullptr) -#ifndef BOOST_INTEL - noexcept(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>()))) -#endif - : m_backend(canonical_value(v)) - {} - template <class V, class U> - BOOST_MP_FORCEINLINE constexpr number(const V& v, U digits10, - typename std::enable_if< - (boost::multiprecision::detail::is_convertible_arithmetic<V, Backend>::value - || std::is_same<std::string, V>::value - || std::is_convertible<V, const char*>::value) - && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value - && (boost::multiprecision::number_category<Backend>::value != boost::multiprecision::number_kind_complex) - && (boost::multiprecision::number_category<Backend>::value != boost::multiprecision::number_kind_rational) - && std::is_same<self_type, value_type>::value - && std::is_integral<U>::value - && (std::numeric_limits<U>::digits <= std::numeric_limits<unsigned>::digits) - && std::is_constructible<Backend, typename detail::canonical<V, Backend>::type const&, unsigned>::value>::type* = nullptr) - : m_backend(canonical_value(v), static_cast<unsigned>(digits10)) - {} - // - // Conversions from unscoped enum's are implicit: - // - template <class V> - BOOST_MP_FORCEINLINE -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1900)) - constexpr -#endif - number(const V& v, typename std::enable_if< - std::is_enum<V>::value && std::is_convertible<V, int>::value && !std::is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value>::type* = nullptr) - : number(static_cast<typename std::underlying_type<V>::type>(v)) - {} - // - // Conversions from scoped enum's are explicit: - // - template <class V> - BOOST_MP_FORCEINLINE explicit -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1900)) - constexpr -#endif - number(const V& v, typename std::enable_if< - std::is_enum<V>::value && !std::is_convertible<V, int>::value && !std::is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value>::type* = nullptr) - : number(static_cast<typename std::underlying_type<V>::type>(v)) - {} - - template <class U> - BOOST_MP_FORCEINLINE constexpr number(const number& e, U digits10, typename std::enable_if<std::is_constructible<Backend, const Backend&, unsigned>::value && std::is_integral<U>::value && (std::numeric_limits<U>::digits <= std::numeric_limits<unsigned>::digits)>::type* = nullptr) - noexcept(noexcept(Backend(std::declval<Backend const&>(), std::declval<unsigned>()))) - : m_backend(e.m_backend, static_cast<unsigned>(digits10)) {} - template <class V> - explicit BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const V& v, typename std::enable_if< - (boost::multiprecision::detail::is_arithmetic<V>::value || std::is_same<std::string, V>::value || std::is_convertible<V, const char*>::value) && !detail::is_explicitly_convertible<typename detail::canonical<V, Backend>::type, Backend>::value && detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value>::type* = nullptr) - noexcept(noexcept(std::declval<Backend&>() = std::declval<typename detail::canonical<V, Backend>::type const&>())) - { - m_backend = canonical_value(v); - } - template <class V> - explicit BOOST_MP_FORCEINLINE constexpr number(const V& v, typename std::enable_if< - detail::is_explicitly_convertible<typename detail::canonical<V, Backend>::type, Backend>::value && (detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value || !std::is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value)>::type* = nullptr) - noexcept(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>()))) - : m_backend(canonical_value(v)) {} - template <class V> - explicit BOOST_MP_FORCEINLINE constexpr number(const V& v, unsigned digits10, typename std::enable_if<(boost::multiprecision::detail::is_arithmetic<V>::value || std::is_same<std::string, V>::value || std::is_convertible<V, const char*>::value) && detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value && (boost::multiprecision::number_category<Backend>::value != boost::multiprecision::number_kind_complex) && (boost::multiprecision::number_category<Backend>::value != boost::multiprecision::number_kind_rational)>::type* = nullptr) - : m_backend(canonical_value(v), digits10) {} - - template <expression_template_option ET> - BOOST_MP_FORCEINLINE constexpr number(const number<Backend, ET>& val) - noexcept(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(val.backend()) {} - - template <class Other, expression_template_option ET> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const number<Other, ET>& val, - typename std::enable_if<(std::is_convertible<Other, Backend>::value && !detail::is_restricted_conversion<Other, Backend>::value)>::type* = nullptr) - noexcept(noexcept(Backend(std::declval<Other const&>()))) - : m_backend(val.backend()) {} - - template <class Other, expression_template_option ET> - explicit BOOST_MP_CXX14_CONSTEXPR number(const number<Other, ET>& val, typename std::enable_if< - (!detail::is_explicitly_convertible<Other, Backend>::value)>::type* = nullptr) - { - // - // Attempt a generic interconvertion: - // - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard_1(val); - detail::scoped_default_precision<number<Other, ET> > precision_guard_2(val); - using detail::generic_interconvert; - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - { - if (precision_guard_1.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - self_type t; - generic_interconvert(t.backend(), val.backend(), number_category<Backend>(), number_category<Other>()); - *this = std::move(t); - return; - } - } - generic_interconvert(backend(), val.backend(), number_category<Backend>(), number_category<Other>()); - } - template <class Other, expression_template_option ET> - explicit BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const number<Other, ET>& val, typename std::enable_if< - (detail::is_explicitly_convertible<Other, Backend>::value && (detail::is_restricted_conversion<Other, Backend>::value || !std::is_convertible<Other, Backend>::value))>::type* = nullptr) noexcept(noexcept(Backend(std::declval<Other const&>()))) - : m_backend(val.backend()) {} - - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const V& v1, const U& v2, - typename std::enable_if< - (std::is_convertible<V, value_type>::value - && std::is_convertible<U, value_type>::value - && !std::is_same<value_type, self_type>::value - && std::is_constructible<Backend, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const V&>()))>::type>::type, Backend>::type const&, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const U&>()))>::type>::type, Backend>::type const&>::value - && !boost::multiprecision::detail::is_variable_precision<Backend>::value)>::type* = nullptr) - : m_backend(canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(v2))) - { - } - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(V&& v1, const U& v2, - typename std::enable_if< - (std::is_convertible<V, value_type>::value - && std::is_convertible<U, value_type>::value - && !std::is_same<value_type, self_type>::value - && std::is_constructible<Backend, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const V&>()))>::type>::type, Backend>::type const&, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const U&>()))>::type>::type, Backend>::type const&>::value - && !boost::multiprecision::detail::is_variable_precision<Backend>::value)>::type* = nullptr) - : m_backend(canonical_value(detail::evaluate_if_expression(static_cast<V&&>(v1))), canonical_value(detail::evaluate_if_expression(v2))) - { - } - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const V& v1, U&& v2, - typename std::enable_if< - (std::is_convertible<V, value_type>::value - && std::is_convertible<U, value_type>::value - && !std::is_same<value_type, self_type>::value - && std::is_constructible<Backend, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const V&>()))>::type>::type, Backend>::type const&, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const U&>()))>::type>::type, Backend>::type const&>::value - && !boost::multiprecision::detail::is_variable_precision<Backend>::value)>::type* = nullptr) - : m_backend(canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(static_cast<U&&>(v2)))) - { - } - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(V&& v1, U&& v2, - typename std::enable_if< - (std::is_convertible<V, value_type>::value - && std::is_convertible<U, value_type>::value - && !std::is_same<value_type, self_type>::value - && std::is_constructible<Backend, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const V&>()))>::type>::type, Backend>::type const&, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const U&>()))>::type>::type, Backend>::type const&>::value - && !boost::multiprecision::detail::is_variable_precision<Backend>::value)>::type* = nullptr) - : m_backend(canonical_value(detail::evaluate_if_expression(static_cast<V&&>(v1))), canonical_value(detail::evaluate_if_expression(static_cast<U&&>(v2)))) - { - } - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const V& v1, const U& v2, - typename std::enable_if< - (std::is_convertible<V, value_type>::value - && std::is_convertible<U, value_type>::value - && !std::is_same<value_type, self_type>::value - && (!std::is_constructible<Backend, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const V&>()))>::type>::type, Backend>::type const&, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const U&>()))>::type>::type, Backend>::type const&>::value - || boost::multiprecision::detail::is_variable_precision<Backend>::value))>::type* = nullptr) - { - using default_ops::assign_components; - // Copy precision options from this type to component_type: - boost::multiprecision::detail::scoped_precision_options<value_type> scoped_opts(*this); - // precision guards: - detail::scoped_default_precision<self_type> precision_guard(v1, v2, *this); - detail::scoped_default_precision<value_type> component_precision_guard(v1, v2, *this); - assign_components(m_backend, canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(v2))); - } - template <class V, class U> - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR number(const V& v1, const U& v2, - typename std::enable_if< - (std::is_constructible<value_type, V>::value || std::is_convertible<V, std::string>::value) && (std::is_constructible<value_type, U>::value || std::is_convertible<U, std::string>::value) && !std::is_same<value_type, self_type>::value && !std::is_same<V, self_type>::value && !(std::is_convertible<V, value_type>::value && std::is_convertible<U, value_type>::value)>::type* = nullptr) - { - using default_ops::assign_components; - // Copy precision options from this type to component_type: - boost::multiprecision::detail::scoped_precision_options<value_type> scoped_opts(*this); - // precision guards: - detail::scoped_default_precision<self_type> precision_guard(v1, v2, *this); - detail::scoped_default_precision<value_type> component_precision_guard(v1, v2, *this); - assign_components(m_backend, canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(v2))); - } -#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW - // - // Support for new types in C++17 - // - template <class Traits> - explicit inline BOOST_MP_CXX14_CONSTEXPR number(const std::basic_string_view<char, Traits>& view) - { - using default_ops::assign_from_string_view; - assign_from_string_view(this->backend(), view); - } - template <class Traits> - explicit inline BOOST_MP_CXX14_CONSTEXPR number(const std::basic_string_view<char, Traits>& view_x, const std::basic_string_view<char, Traits>& view_y) - { - using default_ops::assign_from_string_view; - assign_from_string_view(this->backend(), view_x, view_y); - } - template <class Traits> - explicit BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const std::basic_string_view<char, Traits>& v, unsigned digits10) - : m_backend(canonical_value(v), digits10) {} - template <class Traits> - BOOST_MP_CXX14_CONSTEXPR number& assign(const std::basic_string_view<char, Traits>& view) - { - using default_ops::assign_from_string_view; - assign_from_string_view(this->backend(), view); - return *this; - } -#endif - - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(const V& v1, const U& v2, unsigned digits10, - typename std::enable_if<(std::is_convertible<V, value_type>::value && std::is_convertible<U, value_type>::value && !std::is_same<value_type, self_type>::value)>::type* = nullptr) - : m_backend(canonical_value(detail::evaluate_if_expression(v1)), canonical_value(detail::evaluate_if_expression(v2)), digits10) - {} - template <class V, class U> - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR number(const V& v1, const U& v2, unsigned digits10, - typename std::enable_if<((std::is_constructible<value_type, V>::value || std::is_convertible<V, std::string>::value) && (std::is_constructible<value_type, U>::value || std::is_convertible<U, std::string>::value) && !std::is_same<value_type, self_type>::value) && !(std::is_convertible<V, value_type>::value && std::is_convertible<U, value_type>::value)>::type* = nullptr) - : m_backend(detail::evaluate_if_expression(v1), detail::evaluate_if_expression(v2), digits10) {} - - template <class Other, expression_template_option ET> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number( - const number<Other, ET>& v1, - const number<Other, ET>& v2, - typename std::enable_if< - std::is_convertible<Other, Backend>::value - && (!std::is_constructible<Backend, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const number<Other, ET>&>()))>::type>::type, Backend>::type const&, typename detail::canonical<typename std::remove_cv<typename std::remove_reference<decltype(detail::evaluate_if_expression(std::declval<const number<Other, ET>&>()))>::type>::type, Backend>::type const&>::value || boost::multiprecision::detail::is_variable_precision<Backend>::value) >::type* = nullptr) - { - using default_ops::assign_components; - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(v1, v2); - assign_components(m_backend, v1.backend(), v2.backend()); - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - using tag_type = std::integral_constant<bool, is_equivalent_number_type<number, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value>; - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(e); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_IF_CONSTEXPR (std::is_same<self_type, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value) - { - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(e); - return *this = std::move(t); - } - } - do_assign(e, tag_type()); - return *this; - } - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR number& assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - using tag_type = std::integral_constant<bool, is_equivalent_number_type<number, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value>; - - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_IF_CONSTEXPR(std::is_same<self_type, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value) - { - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - { - const detail::scoped_default_precision<number<Backend, ExpressionTemplates>> precision_guard(e); - - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t; - t.assign(e); - return *this = std::move(t); - } - } - } - do_assign(e, tag_type()); - return *this; - } - BOOST_MP_CXX14_CONSTEXPR number& assign(const value_type& a, const value_type& b) - { - assign_components(backend(), a.backend(), b.backend()); - return *this; - } - template <class V, class U> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(std::is_convertible<V, value_type>::value&& std::is_convertible<U, value_type>::value && !std::is_same<value_type, self_type>::value), number&>::type - assign(const V& v1, const U& v2, unsigned Digits) - { - self_type r(v1, v2, Digits); - boost::multiprecision::detail::scoped_source_precision<self_type> scope; - return *this = r; - } - BOOST_MP_CXX14_CONSTEXPR number& assign(const value_type & a, const value_type & b, unsigned Digits) - { - this->precision(Digits); - boost::multiprecision::detail::scoped_target_precision<self_type> scoped; - assign_components(backend(), canonical_value(detail::evaluate_if_expression(a)), canonical_value(detail::evaluate_if_expression(b))); - return *this; - } - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator=(const number& e) - noexcept(noexcept(std::declval<Backend&>() = std::declval<Backend const&>())) - { - m_backend = e.m_backend; - return *this; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator=(const V& v) - noexcept(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) - { - m_backend = canonical_value(v); - return *this; - } - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<Backend, ExpressionTemplates>& assign(const V& v) - noexcept(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) - { - m_backend = canonical_value(v); - return *this; - } - template <class V, class U> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<Backend, ExpressionTemplates>& assign(const V& v, const U& digits10_or_component) - noexcept(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) - { - number t(v, digits10_or_component); - boost::multiprecision::detail::scoped_source_precision<self_type> scope; - static_cast<void>(scope); - return *this = t; - } - template <class Other, expression_template_option ET> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!boost::multiprecision::detail::is_explicitly_convertible<Other, Backend>::value, number<Backend, ExpressionTemplates>&>::type - assign(const number<Other, ET>& v) - { - // - // Attempt a generic interconvertion: - // - using detail::generic_interconvert; - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v); - detail::scoped_default_precision<number<Other, ET> > precision_guard2(*this, v); - // - // If the current precision of *this differs from that of value v, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(v); - return *this = std::move(t); - } - generic_interconvert(backend(), v.backend(), number_category<Backend>(), number_category<Other>()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR number(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value>::type* = nullptr) - { - // - // No preicsion guard here, we already have one in operator= - // - *this = e; - } - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - explicit BOOST_MP_CXX14_CONSTEXPR number(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, - typename std::enable_if<!std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value && boost::multiprecision::detail::is_explicitly_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value>::type* = nullptr) - { - // - // No precision guard as assign has one already: - // - assign(e); - } - - // rvalues: - BOOST_MP_FORCEINLINE constexpr number(number&& r) - noexcept(noexcept(Backend(std::declval<Backend>()))) - : m_backend(static_cast<Backend&&>(r.m_backend)) - {} - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator=(number&& r) noexcept(noexcept(std::declval<Backend&>() = std::declval<Backend>())) - { - m_backend = static_cast<Backend&&>(r.m_backend); - return *this; - } - template <class Other, expression_template_option ET> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number(number<Other, ET>&& val, - typename std::enable_if<(std::is_convertible<Other, Backend>::value && !detail::is_restricted_conversion<Other, Backend>::value)>::type* = nullptr) - noexcept(noexcept(Backend(std::declval<Other const&>()))) - : m_backend(static_cast<number<Other, ET>&&>(val).backend()) {} - template <class Other, expression_template_option ET> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(std::is_convertible<Other, Backend>::value && !detail::is_restricted_conversion<Other, Backend>::value), number&>::type - operator=(number<Other, ET>&& val) - noexcept(noexcept(Backend(std::declval<Other const&>()))) - { - m_backend = std::move(val).backend(); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR number& operator+=(const self_type& val) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, val); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this + val); - return *this = std::move(t); - } - do_add(detail::expression<detail::terminal, self_type>(val), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator+=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // Create a copy if e contains this, but not if we're just doing a - // x += x - if ((contains_self(e) && !is_self(e))) - { - self_type temp(e); - do_add(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_add(e, tag()); - } - return *this; - } - - template <class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR number& operator+=(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_IF_CONSTEXPR(std::is_same<self_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value) - { - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this + e); - return *this = std::move(t); - } - } - // - // Fused multiply-add: - // - using default_ops::eval_multiply_add; - eval_multiply_add(m_backend, canonical_value(e.left_ref()), canonical_value(e.right_ref())); - return *this; - } - - template <class V> - typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - BOOST_MP_CXX14_CONSTEXPR operator+=(const V& v) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v); - // - // If the current precision of *this differs from that of value v, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this + v); - return *this = std::move(t); - } - - using default_ops::eval_add; - eval_add(m_backend, canonical_value(v)); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR number& operator-=(const self_type& val) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, val); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this - val); - return *this = std::move(t); - } - do_subtract(detail::expression<detail::terminal, self_type>(val), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator-=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // Create a copy if e contains this: - if (contains_self(e)) - { - self_type temp(e); - do_subtract(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_subtract(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - - template <class V> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator-=(const V& v) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v); - // - // If the current precision of *this differs from that of value v, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this - v); - return *this = std::move(t); - } - - using default_ops::eval_subtract; - eval_subtract(m_backend, canonical_value(v)); - return *this; - } - - template <class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR number& operator-=(const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_IF_CONSTEXPR(std::is_same<self_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>::value) - { - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this - e); - return *this = std::move(t); - } - } - // - // Fused multiply-subtract: - // - using default_ops::eval_multiply_subtract; - eval_multiply_subtract(m_backend, canonical_value(e.left_ref()), canonical_value(e.right_ref())); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR number& operator*=(const self_type& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this * e); - return *this = std::move(t); - } - do_multiplies(detail::expression<detail::terminal, self_type>(e), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator*=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // Create a temporary if the RHS references *this, but not - // if we're just doing an x *= x; - if ((contains_self(e) && !is_self(e))) - { - self_type temp(e); - do_multiplies(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_multiplies(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - - template <class V> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator*=(const V& v) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v); - // - // If the current precision of *this differs from that of value v, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this * v); - return *this = std::move(t); - } - - using default_ops::eval_multiply; - eval_multiply(m_backend, canonical_value(v)); - return *this; - } - - BOOST_MP_CXX14_CONSTEXPR number& operator%=(const self_type& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this % e); - return *this = std::move(t); - } - do_modulus(detail::expression<detail::terminal, self_type>(e), detail::terminal()); - return *this; - } - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator%=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // Create a temporary if the RHS references *this: - if (contains_self(e)) - { - self_type temp(e); - do_modulus(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_modulus(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - template <class V> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator%=(const V& v) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - using default_ops::eval_modulus; - eval_modulus(m_backend, canonical_value(v)); - return *this; - } - - // - // These operators are *not* proto-ized. - // The issue is that the increment/decrement must happen - // even if the result of the operator *is never used*. - // Possibly we could modify our expression wrapper to - // execute the increment/decrement on destruction, but - // correct implementation will be tricky, so defered for now... - // - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator++() - { - using default_ops::eval_increment; - eval_increment(m_backend); - return *this; - } - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator--() - { - using default_ops::eval_decrement; - eval_decrement(m_backend); - return *this; - } - - inline BOOST_MP_CXX14_CONSTEXPR number operator++(int) - { - using default_ops::eval_increment; - self_type temp(*this); - eval_increment(m_backend); - return temp; - } - - inline BOOST_MP_CXX14_CONSTEXPR number operator--(int) - { - using default_ops::eval_decrement; - self_type temp(*this); - eval_decrement(m_backend); - return temp; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<V>::value, number&>::type operator<<=(V val) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The left-shift operation is only valid for integer types"); - detail::check_shift_range(val, std::integral_constant<bool, (sizeof(V) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<V>::value && boost::multiprecision::detail::is_integral<V>::value > ()); - eval_left_shift(m_backend, static_cast<std::size_t>(canonical_value(val))); - return *this; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<V>::value, number&>::type operator>>=(V val) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The right-shift operation is only valid for integer types"); - detail::check_shift_range(val, std::integral_constant<bool, (sizeof(V) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<V>::value && boost::multiprecision::detail::is_integral<V>::value>()); - eval_right_shift(m_backend, static_cast<std::size_t>(canonical_value(val))); - return *this; - } - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator/=(const self_type& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // - // If the current precision of *this differs from that of expression e, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this / e); - return *this = std::move(t); - } - do_divide(detail::expression<detail::terminal, self_type>(e), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator/=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, e); - // Create a temporary if the RHS references *this: - if (contains_self(e)) - { - self_type temp(e); - do_divide(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_divide(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator/=(const V& v) - { - detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v); - // - // If the current precision of *this differs from that of value v, then we - // create a temporary (which will have the correct precision thanks to precision_guard) - // and then move the result into *this. In C++17 we add a leading "if constexpr" - // which causes this code to be eliminated in the common case that this type is - // not actually variable precision. Pre C++17 this code should still be mostly - // optimised away, but we can't prevent instantiation of the dead code leading - // to longer build and possibly link times. - // - BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number) - if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of<self_type>(*this)) - { - number t(*this / v); - return *this = std::move(t); - } - - using default_ops::eval_divide; - eval_divide(m_backend, canonical_value(v)); - return *this; - } - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator&=(const self_type& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types"); - do_bitwise_and(detail::expression<detail::terminal, self_type>(e), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator&=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types"); - // Create a temporary if the RHS references *this, but not - // if we're just doing an x &= x; - if (contains_self(e) && !is_self(e)) - { - self_type temp(e); - do_bitwise_and(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_bitwise_and(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator&=(const V& v) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types"); - using default_ops::eval_bitwise_and; - eval_bitwise_and(m_backend, canonical_value(v)); - return *this; - } - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator|=(const self_type& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types"); - do_bitwise_or(detail::expression<detail::terminal, self_type>(e), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator|=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types"); - // Create a temporary if the RHS references *this, but not - // if we're just doing an x |= x; - if (contains_self(e) && !is_self(e)) - { - self_type temp(e); - do_bitwise_or(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_bitwise_or(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator|=(const V& v) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types"); - using default_ops::eval_bitwise_or; - eval_bitwise_or(m_backend, canonical_value(v)); - return *this; - } - - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number& operator^=(const self_type& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types"); - do_bitwise_xor(detail::expression<detail::terminal, self_type>(e), detail::terminal()); - return *this; - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, self_type>::value, number&>::type operator^=(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types"); - if (contains_self(e)) - { - self_type temp(e); - do_bitwise_xor(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - else - { - do_bitwise_xor(e, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::tag_type()); - } - return *this; - } - - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type - operator^=(const V& v) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types"); - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(m_backend, canonical_value(v)); - return *this; - } - // - // swap: - // - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void swap(self_type& other) noexcept(noexcept(std::declval<Backend>().swap(std::declval<Backend&>()))) - { - m_backend.swap(other.backend()); - } - // - // Zero and sign: - // - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool is_zero() const - { - using default_ops::eval_is_zero; - return eval_is_zero(m_backend); - } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR int sign() const - { - using default_ops::eval_get_sign; - return eval_get_sign(m_backend); - } - // - // String conversion functions: - // - std::string str(std::streamsize digits = 0, std::ios_base::fmtflags f = std::ios_base::fmtflags(0)) const - { - return m_backend.str(digits, f); - } - - #ifndef BOOST_MP_STANDALONE - template <class Archive> - void serialize(Archive& ar, const unsigned int /*version*/) - { - ar& boost::make_nvp("backend", m_backend); - } - #endif - - private: - template <class T> - BOOST_MP_CXX14_CONSTEXPR void convert_to_imp(T* result) const - { - using default_ops::eval_convert_to; - eval_convert_to(result, m_backend); - } - template <class B2, expression_template_option ET> - BOOST_MP_CXX14_CONSTEXPR void convert_to_imp(number<B2, ET>* result) const - { - result->assign(*this); - } - BOOST_MP_CXX14_CONSTEXPR void convert_to_imp(std::string* result) const - { - *result = this->str(); - } - - public: - template <class T> - BOOST_MP_CXX14_CONSTEXPR T convert_to() const - { - T result = T(); - convert_to_imp(&result); - return result; - } - // - // Use in boolean context, and explicit conversion operators: - // -#if BOOST_WORKAROUND(BOOST_MSVC, < 1900) || (defined(__apple_build_version__) && BOOST_WORKAROUND(__clang_major__, < 9)) - template <class T> -#else - template <class T, class = typename std::enable_if<std::is_enum<T>::value || !(std::is_constructible<T, detail::convertible_to<self_type const&> >::value || !std::is_default_constructible<T>::value || (!boost::multiprecision::detail::is_arithmetic<T>::value && !boost::multiprecision::detail::is_complex<T>::value)), T>::type> -#endif - explicit BOOST_MP_CXX14_CONSTEXPR operator T() const - { - return this->template convert_to<T>(); - } - BOOST_MP_FORCEINLINE explicit BOOST_MP_CXX14_CONSTEXPR operator bool() const - { - return !is_zero(); - } - // - // Default precision: - // - static BOOST_MP_CXX14_CONSTEXPR unsigned default_precision() noexcept - { - return Backend::default_precision(); - } - static BOOST_MP_CXX14_CONSTEXPR void default_precision(unsigned digits10) - { - Backend::default_precision(digits10); - Backend::thread_default_precision(digits10); - } - static BOOST_MP_CXX14_CONSTEXPR unsigned thread_default_precision() noexcept - { - return Backend::thread_default_precision(); - } - static BOOST_MP_CXX14_CONSTEXPR void thread_default_precision(unsigned digits10) - { - Backend::thread_default_precision(digits10); - } - BOOST_MP_CXX14_CONSTEXPR unsigned precision() const noexcept - { - return m_backend.precision(); - } - BOOST_MP_CXX14_CONSTEXPR void precision(unsigned digits10) - { - m_backend.precision(digits10); - } - // - // Variable precision options: - // - static constexpr variable_precision_options default_variable_precision_options()noexcept - { - return Backend::default_variable_precision_options(); - } - static constexpr variable_precision_options thread_default_variable_precision_options()noexcept - { - return Backend::thread_default_variable_precision_options(); - } - static BOOST_MP_CXX14_CONSTEXPR void default_variable_precision_options(variable_precision_options opts) - { - Backend::default_variable_precision_options(opts); - } - static BOOST_MP_CXX14_CONSTEXPR void thread_default_variable_precision_options(variable_precision_options opts) - { - Backend::thread_default_variable_precision_options(opts); - } - // - // Comparison: - // - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR int compare(const number<Backend, ExpressionTemplates>& o) const - noexcept(noexcept(std::declval<Backend>().compare(std::declval<Backend>()))) - { - return m_backend.compare(o.m_backend); - } - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<V>::value && (number_category<Backend>::value != number_kind_complex), int>::type compare(const V& o) const - { - using default_ops::eval_get_sign; - if (o == 0) - return eval_get_sign(m_backend); - return m_backend.compare(canonical_value(o)); - } - template <class V> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<V>::value && (number_category<Backend>::value == number_kind_complex), int>::type compare(const V& o) const - { - using default_ops::eval_get_sign; - return m_backend.compare(canonical_value(o)); - } - // - // Direct access to the underlying backend: - // - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR Backend& backend() & noexcept - { - return m_backend; - } - BOOST_MP_FORCEINLINE constexpr const Backend& backend() const& noexcept { return m_backend; } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR Backend&& backend() && noexcept { return static_cast<Backend&&>(m_backend); } - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR Backend const&& backend() const&& noexcept { return static_cast<Backend const&&>(m_backend); } - // - // Complex number real and imag: - // - BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<number<Backend, ExpressionTemplates> >::type - real() const - { - using default_ops::eval_real; - detail::scoped_default_precision<typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type> precision_guard(*this); - typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type result; - eval_real(result.backend(), backend()); - return result; - } - BOOST_MP_CXX14_CONSTEXPR typename scalar_result_from_possible_complex<number<Backend, ExpressionTemplates> >::type - imag() const - { - using default_ops::eval_imag; - detail::scoped_default_precision<typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type> precision_guard(*this); - typename scalar_result_from_possible_complex<multiprecision::number<Backend, ExpressionTemplates> >::type result; - eval_imag(result.backend(), backend()); - return result; - } - template <class T> - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<T, self_type>::value, self_type&>::type real(const T& val) - { - using default_ops::eval_set_real; - eval_set_real(backend(), canonical_value(val)); - return *this; - } - template <class T> - inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<T, self_type>::value && number_category<self_type>::value == number_kind_complex, self_type&>::type imag(const T& val) - { - using default_ops::eval_set_imag; - eval_set_imag(backend(), canonical_value(val)); - return *this; - } - - private: - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_assignable<number, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value>::type - do_assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, const std::integral_constant<bool, false>&) - { - // The result of the expression isn't the same type as this - - // create a temporary result and assign it to *this: - using temp_type = typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type; - temp_type t(e); - *this = std::move(t); - } - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!std::is_assignable<number, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value>::type - do_assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, const std::integral_constant<bool, false>&) - { - // The result of the expression isn't the same type as this - - // create a temporary result and assign it to *this: - using temp_type = typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type; - temp_type t(e); - this->assign(t); - } - - template <class tag, class Arg1, class Arg2, class Arg3, class Arg4> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e, const std::integral_constant<bool, true>&) - { - do_assign(e, tag()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::add_immediates&) - { - using default_ops::eval_add; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_add(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::subtract_immediates&) - { - using default_ops::eval_subtract; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_subtract(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::multiply_immediates&) - { - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_multiply(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::multiply_add&) - { - using default_ops::eval_multiply_add; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_multiply_add(m_backend, canonical_value(e.left().value()), canonical_value(e.middle().value()), canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::multiply_subtract&) - { - using default_ops::eval_multiply_subtract; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_multiply_subtract(m_backend, canonical_value(e.left().value()), canonical_value(e.middle().value()), canonical_value(e.right().value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::divide_immediates&) - { - using default_ops::eval_divide; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_divide(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::negate&) - { - using left_type = typename Exp::left_type; - do_assign(e.left(), typename left_type::tag_type()); - m_backend.negate(); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::plus&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - constexpr int const left_depth = left_type::depth; - constexpr int const right_depth = right_type::depth; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && br) - { - self_type temp(e); - temp.m_backend.swap(this->m_backend); - } - else if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_add(e.right(), typename right_type::tag_type()); - } - else if (br && is_self(e.right())) - { - // Ignore the right node, it's *this, just add the left: - do_add(e.left(), typename left_type::tag_type()); - } - else if (!br && (bl || (left_depth >= right_depth))) - { // br is always false, but if bl is true we must take the this branch: - do_assign(e.left(), typename left_type::tag_type()); - do_add(e.right(), typename right_type::tag_type()); - } - else - { - do_assign(e.right(), typename right_type::tag_type()); - do_add(e.left(), typename left_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::minus&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - constexpr int const left_depth = left_type::depth; - constexpr int const right_depth = right_type::depth; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && br) - { - self_type temp(e); - temp.m_backend.swap(this->m_backend); - } - else if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just subtract the right: - do_subtract(e.right(), typename right_type::tag_type()); - } - else if (br && is_self(e.right())) - { - // Ignore the right node, it's *this, just subtract the left and negate the result: - do_subtract(e.left(), typename left_type::tag_type()); - m_backend.negate(); - } - else if (!br && (bl || (left_depth >= right_depth))) - { // br is always false, but if bl is true we must take the this branch: - do_assign(e.left(), typename left_type::tag_type()); - do_subtract(e.right(), typename right_type::tag_type()); - } - else - { - do_assign(e.right(), typename right_type::tag_type()); - do_subtract(e.left(), typename left_type::tag_type()); - m_backend.negate(); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::multiplies&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - constexpr int const left_depth = left_type::depth; - constexpr int const right_depth = right_type::depth; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && br) - { - self_type temp(e); - temp.m_backend.swap(this->m_backend); - } - else if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_multiplies(e.right(), typename right_type::tag_type()); - } - else if (br && is_self(e.right())) - { - // Ignore the right node, it's *this, just add the left: - do_multiplies(e.left(), typename left_type::tag_type()); - } - else if (!br && (bl || (left_depth >= right_depth))) - { // br is always false, but if bl is true we must take the this branch: - do_assign(e.left(), typename left_type::tag_type()); - do_multiplies(e.right(), typename right_type::tag_type()); - } - else - { - do_assign(e.right(), typename right_type::tag_type()); - do_multiplies(e.left(), typename left_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::divides&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_divide(e.right(), typename right_type::tag_type()); - } - else if (br) - { - self_type temp(e); - temp.m_backend.swap(this->m_backend); - } - else - { - do_assign(e.left(), typename left_type::tag_type()); - do_divide(e.right(), typename right_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::modulus&) - { - // - // This operation is only valid for integer backends: - // - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_modulus(e.right(), typename right_type::tag_type()); - } - else if (br) - { - self_type temp(e); - temp.m_backend.swap(this->m_backend); - } - else - { - do_assign(e.left(), typename left_type::tag_type()); - do_modulus(e.right(), typename right_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::modulus_immediates&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - using default_ops::eval_modulus; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_modulus(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_and&) - { - // - // This operation is only valid for integer backends: - // - static_assert(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types"); - - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - constexpr int const left_depth = left_type::depth; - constexpr int const right_depth = right_type::depth; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_bitwise_and(e.right(), typename right_type::tag_type()); - } - else if (br && is_self(e.right())) - { - do_bitwise_and(e.left(), typename left_type::tag_type()); - } - else if (!br && (bl || (left_depth >= right_depth))) - { - do_assign(e.left(), typename left_type::tag_type()); - do_bitwise_and(e.right(), typename right_type::tag_type()); - } - else - { - do_assign(e.right(), typename right_type::tag_type()); - do_bitwise_and(e.left(), typename left_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_and_immediates&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types"); - using default_ops::eval_bitwise_and; - eval_bitwise_and(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_or&) - { - // - // This operation is only valid for integer backends: - // - static_assert(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types"); - - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - constexpr int const left_depth = left_type::depth; - constexpr int const right_depth = right_type::depth; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_bitwise_or(e.right(), typename right_type::tag_type()); - } - else if (br && is_self(e.right())) - { - do_bitwise_or(e.left(), typename left_type::tag_type()); - } - else if (!br && (bl || (left_depth >= right_depth))) - { - do_assign(e.left(), typename left_type::tag_type()); - do_bitwise_or(e.right(), typename right_type::tag_type()); - } - else - { - do_assign(e.right(), typename right_type::tag_type()); - do_bitwise_or(e.left(), typename left_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_or_immediates&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types"); - using default_ops::eval_bitwise_or; - eval_bitwise_or(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_xor&) - { - // - // This operation is only valid for integer backends: - // - static_assert(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types"); - - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - - constexpr int const left_depth = left_type::depth; - constexpr int const right_depth = right_type::depth; - - bool bl = contains_self(e.left()); - bool br = contains_self(e.right()); - - if (bl && is_self(e.left())) - { - // Ignore the left node, it's *this, just add the right: - do_bitwise_xor(e.right(), typename right_type::tag_type()); - } - else if (br && is_self(e.right())) - { - do_bitwise_xor(e.left(), typename left_type::tag_type()); - } - else if (!br && (bl || (left_depth >= right_depth))) - { - do_assign(e.left(), typename left_type::tag_type()); - do_bitwise_xor(e.right(), typename right_type::tag_type()); - } - else - { - do_assign(e.right(), typename right_type::tag_type()); - do_bitwise_xor(e.left(), typename left_type::tag_type()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_xor_immediates&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types"); - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::terminal&) - { - if (!is_self(e)) - { - m_backend = canonical_value(e.value()); - } - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::function&) - { - using tag_type = typename Exp::arity; - boost::multiprecision::detail::maybe_promote_precision(this); - do_assign_function(e, tag_type()); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::shift_left&) - { - // We can only shift by an integer value, not an arbitrary expression: - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type ; - using right_arity = typename right_type::arity; - static_assert(right_arity::value == 0, "The left shift operator requires an integer value for the shift operand."); - using right_value_type = typename right_type::result_type; - static_assert(boost::multiprecision::detail::is_integral<right_value_type>::value, "The left shift operator requires an integer value for the shift operand."); - using tag_type = typename left_type::tag_type; - do_assign_left_shift(e.left(), canonical_value(e.right().value()), tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::shift_right&) - { - // We can only shift by an integer value, not an arbitrary expression: - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type ; - using right_arity = typename right_type::arity; - static_assert(right_arity::value == 0, "The left shift operator requires an integer value for the shift operand."); - using right_value_type = typename right_type::result_type; - static_assert(boost::multiprecision::detail::is_integral<right_value_type>::value, "The left shift operator requires an integer value for the shift operand."); - using tag_type = typename left_type::tag_type; - do_assign_right_shift(e.left(), canonical_value(e.right().value()), tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::bitwise_complement&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ~ operation is only valid for integer types"); - using default_ops::eval_complement; - self_type temp(e.left()); - eval_complement(m_backend, temp.backend()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign(const Exp& e, const detail::complement_immediates&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ~ operation is only valid for integer types"); - using default_ops::eval_complement; - eval_complement(m_backend, canonical_value(e.left().value())); - } - - template <class Exp, class Val> - BOOST_MP_CXX14_CONSTEXPR void do_assign_right_shift(const Exp& e, const Val& val, const detail::terminal&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The right shift operation is only valid for integer types"); - using default_ops::eval_right_shift; - detail::check_shift_range(val, std::integral_constant<bool, (sizeof(Val) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<Val>::value&& boost::multiprecision::detail::is_integral<Val>::value>()); - eval_right_shift(m_backend, canonical_value(e.value()), static_cast<std::size_t>(val)); - } - - template <class Exp, class Val> - BOOST_MP_CXX14_CONSTEXPR void do_assign_left_shift(const Exp& e, const Val& val, const detail::terminal&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The left shift operation is only valid for integer types"); - using default_ops::eval_left_shift; - detail::check_shift_range(val, std::integral_constant<bool, (sizeof(Val) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<Val>::value&& boost::multiprecision::detail::is_integral<Val>::value>()); - eval_left_shift(m_backend, canonical_value(e.value()), static_cast<std::size_t>(val)); - } - - template <class Exp, class Val, class Tag> - BOOST_MP_CXX14_CONSTEXPR void do_assign_right_shift(const Exp& e, const Val& val, const Tag&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The right shift operation is only valid for integer types"); - using default_ops::eval_right_shift; - self_type temp(e); - detail::check_shift_range(val, std::integral_constant<bool, (sizeof(Val) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<Val>::value&& boost::multiprecision::detail::is_integral<Val>::value>()); - eval_right_shift(m_backend, temp.backend(), static_cast<std::size_t>(val)); - } - - template <class Exp, class Val, class Tag> - BOOST_MP_CXX14_CONSTEXPR void do_assign_left_shift(const Exp& e, const Val& val, const Tag&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The left shift operation is only valid for integer types"); - using default_ops::eval_left_shift; - self_type temp(e); - detail::check_shift_range(val, std::integral_constant<bool, (sizeof(Val) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<Val>::value&& boost::multiprecision::detail::is_integral<Val>::value>()); - eval_left_shift(m_backend, temp.backend(), static_cast<std::size_t>(val)); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function(const Exp& e, const std::integral_constant<int, 1>&) - { - e.left().value()(&m_backend); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function(const Exp& e, const std::integral_constant<int, 2>&) - { - using right_type = typename Exp::right_type ; - using tag_type = typename right_type::tag_type; - do_assign_function_1(e.left().value(), e.right_ref(), tag_type()); - } - template <class F, class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_1(const F& f, const Exp& val, const detail::terminal&) - { - f(m_backend, function_arg_value(val)); - } - template <class F, class Exp, class Tag> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_1(const F& f, const Exp& val, const Tag&) - { - typename Exp::result_type t(val); - f(m_backend, t.backend()); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function(const Exp& e, const std::integral_constant<int, 3>&) - { - using middle_type = typename Exp::middle_type ; - using tag_type = typename middle_type::tag_type; - using end_type = typename Exp::right_type ; - using end_tag = typename end_type::tag_type ; - do_assign_function_2(e.left().value(), e.middle_ref(), e.right_ref(), tag_type(), end_tag()); - } - template <class F, class Exp1, class Exp2> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const detail::terminal&) - { - f(m_backend, function_arg_value(val1), function_arg_value(val2)); - } - template <class F, class Exp1, class Exp2, class Tag1> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const detail::terminal&) - { - typename Exp1::result_type temp1(val1); - f(m_backend, std::move(temp1.backend()), function_arg_value(val2)); - } - template <class F, class Exp1, class Exp2, class Tag2> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const Tag2&) - { - typename Exp2::result_type temp2(val2); - f(m_backend, function_arg_value(val1), std::move(temp2.backend())); - } - template <class F, class Exp1, class Exp2, class Tag1, class Tag2> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const Tag2&) - { - typename Exp1::result_type temp1(val1); - typename Exp2::result_type temp2(val2); - f(m_backend, std::move(temp1.backend()), std::move(temp2.backend())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function(const Exp& e, const std::integral_constant<int, 4>&) - { - using left_type = typename Exp::left_middle_type ; - using left_tag_type = typename left_type::tag_type ; - using middle_type = typename Exp::right_middle_type; - using middle_tag_type = typename middle_type::tag_type ; - using right_type = typename Exp::right_type ; - using right_tag_type = typename right_type::tag_type ; - do_assign_function_3a(e.left().value(), e.left_middle_ref(), e.right_middle_ref(), e.right_ref(), left_tag_type(), middle_tag_type(), right_tag_type()); - } - - template <class F, class Exp1, class Exp2, class Exp3, class Tag2, class Tag3> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_3a(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&, const Tag2& t2, const Tag3& t3) - { - do_assign_function_3b(f, val1, val2, val3, t2, t3); - } - template <class F, class Exp1, class Exp2, class Exp3, class Tag1, class Tag2, class Tag3> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_3a(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag1&, const Tag2& t2, const Tag3& t3) - { - typename Exp1::result_type t(val1); - do_assign_function_3b(f, std::move(t), val2, val3, t2, t3); - } - template <class F, class Exp1, class Exp2, class Exp3, class Tag3> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_3b(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&, const Tag3& t3) - { - do_assign_function_3c(f, val1, val2, val3, t3); - } - template <class F, class Exp1, class Exp2, class Exp3, class Tag2, class Tag3> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_3b(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag2& /*t2*/, const Tag3& t3) - { - typename Exp2::result_type t(val2); - do_assign_function_3c(f, val1, std::move(t), val3, t3); - } - template <class F, class Exp1, class Exp2, class Exp3> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_3c(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&) - { - f(m_backend, function_arg_value(val1), function_arg_value(val2), function_arg_value(val3)); - } - template <class F, class Exp1, class Exp2, class Exp3, class Tag3> - BOOST_MP_CXX14_CONSTEXPR void do_assign_function_3c(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag3& /*t3*/) - { - typename Exp3::result_type t(val3); - do_assign_function_3c(f, val1, val2, std::move(t), detail::terminal()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const detail::terminal&) - { - using default_ops::eval_add; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_add(m_backend, canonical_value(e.value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const detail::negate&) - { - using left_type = typename Exp::left_type; - boost::multiprecision::detail::maybe_promote_precision(this); - do_subtract(e.left(), typename left_type::tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const detail::plus&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_add(e.left(), typename left_type::tag_type()); - do_add(e.right(), typename right_type::tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const detail::minus&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_add(e.left(), typename left_type::tag_type()); - do_subtract(e.right(), typename right_type::tag_type()); - } - - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const unknown&) - { - self_type temp(e); - do_add(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const detail::add_immediates&) - { - using default_ops::eval_add; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_add(m_backend, canonical_value(e.left().value())); - eval_add(m_backend, canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_add(const Exp& e, const detail::subtract_immediates&) - { - using default_ops::eval_add; - using default_ops::eval_subtract; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_add(m_backend, canonical_value(e.left().value())); - eval_subtract(m_backend, canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const detail::terminal&) - { - using default_ops::eval_subtract; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_subtract(m_backend, canonical_value(e.value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const detail::negate&) - { - using left_type = typename Exp::left_type; - do_add(e.left(), typename left_type::tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const detail::plus&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_subtract(e.left(), typename left_type::tag_type()); - do_subtract(e.right(), typename right_type::tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const detail::minus&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_subtract(e.left(), typename left_type::tag_type()); - do_add(e.right(), typename right_type::tag_type()); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const detail::add_immediates&) - { - using default_ops::eval_subtract; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_subtract(m_backend, canonical_value(e.left().value())); - eval_subtract(m_backend, canonical_value(e.right().value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const detail::subtract_immediates&) - { - using default_ops::eval_add; - using default_ops::eval_subtract; - eval_subtract(m_backend, canonical_value(e.left().value())); - eval_add(m_backend, canonical_value(e.right().value())); - } - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_subtract(const Exp& e, const unknown&) - { - self_type temp(e); - do_subtract(detail::expression<detail::terminal, self_type>(temp), detail::terminal()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_multiplies(const Exp& e, const detail::terminal&) - { - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_multiply(m_backend, canonical_value(e.value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_multiplies(const Exp& e, const detail::negate&) - { - using left_type = typename Exp::left_type; - do_multiplies(e.left(), typename left_type::tag_type()); - m_backend.negate(); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_multiplies(const Exp& e, const detail::multiplies&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_multiplies(e.left(), typename left_type::tag_type()); - do_multiplies(e.right(), typename right_type::tag_type()); - } - // - // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make - // the disable_if dependent on the template argument (the size of 1 can never occur in practice). - // - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1)>::type - do_multiplies(const Exp& e, const detail::divides&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_multiplies(e.left(), typename left_type::tag_type()); - do_divide(e.right(), typename right_type::tag_type()); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_multiplies(const Exp& e, const detail::multiply_immediates&) - { - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_multiply(m_backend, canonical_value(e.left().value())); - eval_multiply(m_backend, canonical_value(e.right().value())); - } - // - // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make - // the disable_if dependent on the template argument (the size of 1 can never occur in practice). - // - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1)>::type - do_multiplies(const Exp& e, const detail::divide_immediates&) - { - using default_ops::eval_divide; - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_multiply(m_backend, canonical_value(e.left().value())); - eval_divide(m_backend, canonical_value(e.right().value())); - } - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_multiplies(const Exp& e, const unknown&) - { - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - self_type temp(e); - eval_multiply(m_backend, temp.m_backend); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_divide(const Exp& e, const detail::terminal&) - { - using default_ops::eval_divide; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_divide(m_backend, canonical_value(e.value())); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_divide(const Exp& e, const detail::negate&) - { - using left_type = typename Exp::left_type; - do_divide(e.left(), typename left_type::tag_type()); - m_backend.negate(); - } - // - // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make - // the disable_if dependent on the template argument (the size of 1 can never occur in practice). - // - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1)>::type - do_divide(const Exp& e, const detail::multiplies&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_divide(e.left(), typename left_type::tag_type()); - do_divide(e.right(), typename right_type::tag_type()); - } - // - // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make - // the disable_if dependent on the template argument (the size of 1 can never occur in practice). - // - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1)>::type - do_divide(const Exp& e, const detail::divides&) - { - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_divide(e.left(), typename left_type::tag_type()); - do_multiplies(e.right(), typename right_type::tag_type()); - } - // - // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make - // the disable_if dependent on the template argument (the size of 1 can never occur in practice). - // - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1)>::type - do_divides(const Exp& e, const detail::multiply_immediates&) - { - using default_ops::eval_divide; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_divide(m_backend, canonical_value(e.left().value())); - eval_divide(m_backend, canonical_value(e.right().value())); - } - // - // This rearrangement is disabled for integer types, the test on sizeof(Exp) is simply to make - // the disable_if dependent on the template argument (the size of 1 can never occur in practice). - // - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!(boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer || sizeof(Exp) == 1)>::type - do_divides(const Exp& e, const detail::divide_immediates&) - { - using default_ops::eval_divide; - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_divide(m_backend, canonical_value(e.left().value())); - mutiply(m_backend, canonical_value(e.right().value())); - } - - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_divide(const Exp& e, const unknown&) - { - using default_ops::eval_multiply; - boost::multiprecision::detail::maybe_promote_precision(this); - self_type temp(e); - eval_divide(m_backend, temp.m_backend); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_modulus(const Exp& e, const detail::terminal&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - using default_ops::eval_modulus; - boost::multiprecision::detail::maybe_promote_precision(this); - eval_modulus(m_backend, canonical_value(e.value())); - } - - template <class Exp, class Unknown> - BOOST_MP_CXX14_CONSTEXPR void do_modulus(const Exp& e, const Unknown&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types"); - using default_ops::eval_modulus; - boost::multiprecision::detail::maybe_promote_precision(this); - self_type temp(e); - eval_modulus(m_backend, canonical_value(temp)); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_and(const Exp& e, const detail::terminal&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types"); - using default_ops::eval_bitwise_and; - eval_bitwise_and(m_backend, canonical_value(e.value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_and(const Exp& e, const detail::bitwise_and&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types"); - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_bitwise_and(e.left(), typename left_type::tag_type()); - do_bitwise_and(e.right(), typename right_type::tag_type()); - } - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_and(const Exp& e, const unknown&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise & operation is only valid for integer types"); - using default_ops::eval_bitwise_and; - self_type temp(e); - eval_bitwise_and(m_backend, temp.m_backend); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_or(const Exp& e, const detail::terminal&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types"); - using default_ops::eval_bitwise_or; - eval_bitwise_or(m_backend, canonical_value(e.value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_or(const Exp& e, const detail::bitwise_or&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types"); - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_bitwise_or(e.left(), typename left_type::tag_type()); - do_bitwise_or(e.right(), typename right_type::tag_type()); - } - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_or(const Exp& e, const unknown&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise | operation is only valid for integer types"); - using default_ops::eval_bitwise_or; - self_type temp(e); - eval_bitwise_or(m_backend, temp.m_backend); - } - - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_xor(const Exp& e, const detail::terminal&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types"); - using default_ops::eval_bitwise_xor; - eval_bitwise_xor(m_backend, canonical_value(e.value())); - } - template <class Exp> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_xor(const Exp& e, const detail::bitwise_xor&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types"); - using left_type = typename Exp::left_type ; - using right_type = typename Exp::right_type; - do_bitwise_xor(e.left(), typename left_type::tag_type()); - do_bitwise_xor(e.right(), typename right_type::tag_type()); - } - template <class Exp, class unknown> - BOOST_MP_CXX14_CONSTEXPR void do_bitwise_xor(const Exp& e, const unknown&) - { - static_assert(number_category<Backend>::value == number_kind_integer, "The bitwise ^ operation is only valid for integer types"); - using default_ops::eval_bitwise_xor; - self_type temp(e); - eval_bitwise_xor(m_backend, temp.m_backend); - } - - // Tests if the expression contains a reference to *this: - template <class Exp> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool contains_self(const Exp& e) const noexcept - { - return contains_self(e, typename Exp::arity()); - } - template <class Exp> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool contains_self(const Exp& e, std::integral_constant<int, 0> const&) const noexcept - { - return is_realy_self(e.value()); - } - template <class Exp> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool contains_self(const Exp& e, std::integral_constant<int, 1> const&) const noexcept - { - using child_type = typename Exp::left_type; - return contains_self(e.left(), typename child_type::arity()); - } - template <class Exp> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool contains_self(const Exp& e, std::integral_constant<int, 2> const&) const noexcept - { - using child0_type = typename Exp::left_type ; - using child1_type = typename Exp::right_type; - return contains_self(e.left(), typename child0_type::arity()) || contains_self(e.right(), typename child1_type::arity()); - } - template <class Exp> - BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR bool contains_self(const Exp& e, std::integral_constant<int, 3> const&) const noexcept - { - using child0_type = typename Exp::left_type ; - using child1_type = typename Exp::middle_type; - using child2_type = typename Exp::right_type ; - return contains_self(e.left(), typename child0_type::arity()) || contains_self(e.middle(), typename child1_type::arity()) || contains_self(e.right(), typename child2_type::arity()); - } - - // Test if the expression is a reference to *this: - template <class Exp> - BOOST_MP_FORCEINLINE constexpr bool is_self(const Exp& e) const noexcept - { - return is_self(e, typename Exp::arity()); - } - template <class Exp> - BOOST_MP_FORCEINLINE constexpr bool is_self(const Exp& e, std::integral_constant<int, 0> const&) const noexcept - { - return is_realy_self(e.value()); - } - template <class Exp, int v> - BOOST_MP_FORCEINLINE constexpr bool is_self(const Exp&, std::integral_constant<int, v> const&) const noexcept - { - return false; - } - - template <class Val> - BOOST_MP_FORCEINLINE constexpr bool is_realy_self(const Val&) const noexcept { return false; } - BOOST_MP_FORCEINLINE constexpr bool is_realy_self(const self_type& v) const noexcept { return &v == this; } - - static BOOST_MP_FORCEINLINE constexpr const Backend& function_arg_value(const self_type& v) noexcept { return v.backend(); } - template <class Other, expression_template_option ET2> - static BOOST_MP_FORCEINLINE constexpr const Other& function_arg_value(const number<Other, ET2>& v) noexcept { return v.backend(); } - template <class V> - static BOOST_MP_FORCEINLINE constexpr const V& function_arg_value(const V& v) noexcept { return v; } - template <class A1, class A2, class A3, class A4> - static BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR const A1& function_arg_value(const detail::expression<detail::terminal, A1, A2, A3, A4>& exp) noexcept { return exp.value(); } - template <class A2, class A3, class A4> - static BOOST_MP_FORCEINLINE constexpr const Backend& function_arg_value(const detail::expression<detail::terminal, number<Backend>, A2, A3, A4>& exp) noexcept { return exp.value().backend(); } - Backend m_backend; - - public: - // - // These shouldn't really need to be public, or even member functions, but it makes implementing - // the non-member operators way easier if they are: - // - static BOOST_MP_FORCEINLINE constexpr const Backend& canonical_value(const self_type& v) noexcept { return v.m_backend; } - template <class B2, expression_template_option ET> - static BOOST_MP_FORCEINLINE constexpr const B2& canonical_value(const number<B2, ET>& v) noexcept { return v.backend(); } - template <class B2, expression_template_option ET> - static BOOST_MP_FORCEINLINE constexpr B2&& canonical_value(number<B2, ET>&& v) noexcept { return static_cast<number<B2, ET>&&>(v).backend(); } - template <class V> - static BOOST_MP_FORCEINLINE constexpr typename std::enable_if<!std::is_same<typename detail::canonical<V, Backend>::type, V>::value, typename detail::canonical<V, Backend>::type>::type - canonical_value(const V& v) noexcept { return static_cast<typename detail::canonical<V, Backend>::type>(v); } - template <class V> - static BOOST_MP_FORCEINLINE constexpr typename std::enable_if<std::is_same<typename detail::canonical<V, Backend>::type, V>::value, const V&>::type - canonical_value(const V& v) noexcept { return v; } - static BOOST_MP_FORCEINLINE typename detail::canonical<std::string, Backend>::type canonical_value(const std::string& v) noexcept { return v.c_str(); } -}; - -template <class Backend, expression_template_option ExpressionTemplates> -inline std::ostream& operator<<(std::ostream& os, const number<Backend, ExpressionTemplates>& r) -{ - std::streamsize d = os.precision(); - std::string s = r.str(d, os.flags()); - std::streamsize ss = os.width(); - if (ss > static_cast<std::streamsize>(s.size())) - { - char fill = os.fill(); - if ((os.flags() & std::ios_base::left) == std::ios_base::left) - s.append(static_cast<std::string::size_type>(ss - static_cast<std::streamsize>(s.size())), fill); - else - s.insert(static_cast<std::string::size_type>(0), static_cast<std::string::size_type>(ss - static_cast<std::streamsize>(s.size())), fill); - } - return os << s; -} - -template <class Backend, expression_template_option ExpressionTemplates> -std::string to_string(const number<Backend, ExpressionTemplates>& val) -{ - return val.str(6, std::ios_base::fixed|std::ios_base::showpoint); -} - -namespace detail { - -template <class tag, class A1, class A2, class A3, class A4> -inline std::ostream& operator<<(std::ostream& os, const expression<tag, A1, A2, A3, A4>& r) -{ - using value_type = typename expression<tag, A1, A2, A3, A4>::result_type; - value_type temp(r); - return os << temp; -} -// -// What follows is the input streaming code: this is not "proper" iostream code at all -// but that's fiendishly hard to write when dealing with multiple backends all -// with different requirements... yes we could deligate this to the backend author... -// but we really want backends to be EASY to write! -// For now just pull in all the characters that could possibly form the number -// and let the backend's string parser make use of it. This fixes most use cases -// including CSV type formats such as those used by the Random lib. -// -inline std::string read_string_while(std::istream& is, std::string const& permitted_chars) -{ - std::ios_base::iostate state = std::ios_base::goodbit; - const std::istream::sentry sentry_check(is); - std::string result; - - if (sentry_check) - { - int c = is.rdbuf()->sgetc(); - - for (;; c = is.rdbuf()->snextc()) - if (std::istream::traits_type::eq_int_type(std::istream::traits_type::eof(), c)) - { // end of file: - state |= std::ios_base::eofbit; - break; - } - else if (permitted_chars.find_first_of(std::istream::traits_type::to_char_type(c)) == std::string::npos) - { - // Invalid numeric character, stop reading: - //is.rdbuf()->sputbackc(static_cast<char>(c)); - break; - } - else - { - result.append(1, std::istream::traits_type::to_char_type(c)); - } - } - - if (!result.size()) - state |= std::ios_base::failbit; - is.setstate(state); - return result; -} - -} // namespace detail - -template <class Backend, expression_template_option ExpressionTemplates> -inline std::istream& operator>>(std::istream& is, number<Backend, ExpressionTemplates>& r) -{ - bool hex_format = (is.flags() & std::ios_base::hex) == std::ios_base::hex; - bool oct_format = (is.flags() & std::ios_base::oct) == std::ios_base::oct; - std::string s; - switch (boost::multiprecision::number_category<number<Backend, ExpressionTemplates> >::value) - { - case boost::multiprecision::number_kind_integer: - if (oct_format) - s = detail::read_string_while(is, "+-01234567"); - else if (hex_format) - s = detail::read_string_while(is, "+-xXabcdefABCDEF0123456789"); - else - s = detail::read_string_while(is, "+-0123456789"); - break; - case boost::multiprecision::number_kind_rational: - if (oct_format) - s = detail::read_string_while(is, "+-01234567/"); - else if (hex_format) - s = detail::read_string_while(is, "+-xXabcdefABCDEF0123456789/"); - else - s = detail::read_string_while(is, "+-0123456789/"); - break; - case boost::multiprecision::number_kind_floating_point: - BOOST_IF_CONSTEXPR(std::is_same<number<Backend, ExpressionTemplates>, typename number<Backend, ExpressionTemplates>::value_type>::value) - s = detail::read_string_while(is, "+-eE.0123456789infINFnanNANinfinityINFINITY"); - else - // Interval: - s = detail::read_string_while(is, "+-eE.0123456789infINFnanNANinfinityINFINITY{,}"); - break; - case boost::multiprecision::number_kind_complex: - s = detail::read_string_while(is, "+-eE.0123456789infINFnanNANinfinityINFINITY,()"); - break; - default: - is >> s; - } - if (s.size()) - { - if (hex_format && (number_category<Backend>::value == number_kind_integer) && ((s[0] != '0') || (s[1] != 'x'))) - s.insert(s.find_first_not_of("+-"), "0x"); - if (oct_format && (number_category<Backend>::value == number_kind_integer) && (s[0] != '0')) - s.insert(s.find_first_not_of("+-"), "0"); - r.assign(s); - } - else if (!is.fail()) - is.setstate(std::istream::failbit); - return is; -} - -template <class Backend, expression_template_option ExpressionTemplates> -BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b) - noexcept(noexcept(std::declval<number<Backend, ExpressionTemplates>&>() = std::declval<number<Backend, ExpressionTemplates>&>())) -{ - a.swap(b); -} -// -// Boost.Hash support, just call hash_value for the backend, which may or may not be supported: -// -template <class Backend, expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t hash_value(const number<Backend, ExpressionTemplates>& val) -{ - return hash_value(val.backend()); -} - -namespace detail { - -BOOST_MP_FORCEINLINE bool istream_peek(std::istream& is, char& c, bool have_hex) -{ - int i = is.peek(); - c = static_cast<char>(i); - return (EOF != i) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))); -} - -} // namespace detail - -} // namespace multiprecision - -template <class T> -class rational; - -template <class Backend, multiprecision::expression_template_option ExpressionTemplates> -inline std::istream& operator>>(std::istream& is, rational<multiprecision::number<Backend, ExpressionTemplates> >& r) -{ - std::string s1; - multiprecision::number<Backend, ExpressionTemplates> v1, v2; - char c; - bool have_hex = false; - bool hex_format = (is.flags() & std::ios_base::hex) == std::ios_base::hex; - bool oct_format = (is.flags() & std::ios_base::oct) == std::ios_base::oct; - - while (multiprecision::detail::istream_peek(is, c, have_hex)) - { - if (c == 'x' || c == 'X') - have_hex = true; - s1.append(1, c); - is.get(); - } - if (hex_format && ((s1[0] != '0') || (s1[1] != 'x'))) - s1.insert(static_cast<std::string::size_type>(0), "0x"); - if (oct_format && (s1[0] != '0')) - s1.insert(static_cast<std::string::size_type>(0), "0"); - v1.assign(s1); - s1.erase(); - if (c == '/') - { - is.get(); - while (multiprecision::detail::istream_peek(is, c, have_hex)) - { - if (c == 'x' || c == 'X') - have_hex = true; - s1.append(1, c); - is.get(); - } - if (hex_format && ((s1[0] != '0') || (s1[1] != 'x'))) - s1.insert(static_cast<std::string::size_type>(0), "0x"); - if (oct_format && (s1[0] != '0')) - s1.insert(static_cast<std::string::size_type>(0), "0"); - v2.assign(s1); - } - else - v2 = 1; - r.assign(v1, v2); - return is; -} - -template <class T, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<T, ExpressionTemplates> numerator(const rational<multiprecision::number<T, ExpressionTemplates> >& a) -{ - return a.numerator(); -} - -template <class T, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR multiprecision::number<T, ExpressionTemplates> denominator(const rational<multiprecision::number<T, ExpressionTemplates> >& a) -{ - return a.denominator(); -} - -template <class T, multiprecision::expression_template_option ExpressionTemplates> -inline BOOST_MP_CXX14_CONSTEXPR std::size_t hash_value(const rational<multiprecision::number<T, ExpressionTemplates> >& val) -{ - std::size_t result = hash_value(val.numerator()); - boost::multiprecision::detail::hash_combine(result, hash_value(val.denominator())); - return result; -} - -namespace multiprecision { - -template <class I> -struct component_type<boost::rational<I> > -{ - using type = I; -}; - -} // namespace multiprecision - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -} // namespace boost - -namespace std { - -template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates> -struct hash<boost::multiprecision::number<Backend, ExpressionTemplates> > -{ - BOOST_MP_CXX14_CONSTEXPR std::size_t operator()(const boost::multiprecision::number<Backend, ExpressionTemplates>& val) const { return hash_value(val); } -}; -template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates> -struct hash<boost::rational<boost::multiprecision::number<Backend, ExpressionTemplates> > > -{ - BOOST_MP_CXX14_CONSTEXPR std::size_t operator()(const boost::rational<boost::multiprecision::number<Backend, ExpressionTemplates> >& val) const - { - std::size_t result = hash_value(val.numerator()); - boost::multiprecision::detail::hash_combine(result, hash_value(val.denominator())); - return result; - } -}; - -} // namespace std - -#include <boost/multiprecision/detail/ublas_interop.hpp> - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/rational_adaptor.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/rational_adaptor.hpp deleted file mode 100644 index baa7631268..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/rational_adaptor.hpp +++ /dev/null @@ -1,1296 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2020 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_RATIONAL_ADAPTOR_HPP -#define BOOST_MP_RATIONAL_ADAPTOR_HPP - -#include <boost/multiprecision/number.hpp> -#include <boost/multiprecision/detail/hash.hpp> -#include <boost/multiprecision/detail/float128_functions.hpp> -#include <boost/multiprecision/detail/no_exceptions_support.hpp> - -namespace boost { -namespace multiprecision { -namespace backends { - -template <class Backend> -struct rational_adaptor -{ - // - // Each backend need to declare 3 type lists which declare the types - // with which this can interoperate. These lists must at least contain - // the widest type in each category - so "long long" must be the final - // type in the signed_types list for example. Any narrower types if not - // present in the list will get promoted to the next wider type that is - // in the list whenever mixed arithmetic involving that type is encountered. - // - typedef typename Backend::signed_types signed_types; - typedef typename Backend::unsigned_types unsigned_types; - typedef typename Backend::float_types float_types; - - typedef typename std::tuple_element<0, unsigned_types>::type ui_type; - - static Backend get_one() - { - Backend t; - t = static_cast<ui_type>(1); - return t; - } - static Backend get_zero() - { - Backend t; - t = static_cast<ui_type>(0); - return t; - } - - static const Backend& one() - { - static const Backend result(get_one()); - return result; - } - static const Backend& zero() - { - static const Backend result(get_zero()); - return result; - } - - void normalize() - { - using default_ops::eval_gcd; - using default_ops::eval_eq; - using default_ops::eval_divide; - using default_ops::eval_get_sign; - - int s = eval_get_sign(m_denom); - - if(s == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - } - else if (s < 0) - { - m_num.negate(); - m_denom.negate(); - } - - Backend g, t; - eval_gcd(g, m_num, m_denom); - if (!eval_eq(g, one())) - { - eval_divide(t, m_num, g); - m_num.swap(t); - eval_divide(t, m_denom, g); - m_denom = std::move(t); - } - } - - // We must have a default constructor: - rational_adaptor() - : m_num(zero()), m_denom(one()) {} - - rational_adaptor(const rational_adaptor& o) : m_num(o.m_num), m_denom(o.m_denom) {} - rational_adaptor(rational_adaptor&& o) = default; - - // Optional constructors, we can make this type slightly more efficient - // by providing constructors from any type we can handle natively. - // These will also cause number<> to be implicitly constructible - // from these types unless we make such constructors explicit. - // - template <class Arithmetic> - rational_adaptor(const Arithmetic& val, typename std::enable_if<std::is_constructible<Backend, Arithmetic>::value && !std::is_floating_point<Arithmetic>::value>::type const* = nullptr) - : m_num(val), m_denom(one()) {} - - // - // Pass-through 2-arg construction of components: - // - template <class T, class U> - rational_adaptor(const T& a, const U& b, typename std::enable_if<std::is_constructible<Backend, T const&>::value && std::is_constructible<Backend, U const&>::value>::type const* = nullptr) - : m_num(a), m_denom(b) - { - normalize(); - } - template <class T, class U> - rational_adaptor(T&& a, const U& b, typename std::enable_if<std::is_constructible<Backend, T>::value && std::is_constructible<Backend, U>::value>::type const* = nullptr) - : m_num(static_cast<T&&>(a)), m_denom(b) - { - normalize(); - } - template <class T, class U> - rational_adaptor(T&& a, U&& b, typename std::enable_if<std::is_constructible<Backend, T>::value && std::is_constructible<Backend, U>::value>::type const* = nullptr) - : m_num(static_cast<T&&>(a)), m_denom(static_cast<U&&>(b)) - { - normalize(); - } - template <class T, class U> - rational_adaptor(const T& a, U&& b, typename std::enable_if<std::is_constructible<Backend, T>::value && std::is_constructible<Backend, U>::value>::type const* = nullptr) - : m_num(a), m_denom(static_cast<U&&>(b)) - { - normalize(); - } - // - // In the absense of converting constructors, operator= takes the strain. - // In addition to the usual suspects, there must be one operator= for each type - // listed in signed_types, unsigned_types, and float_types plus a string constructor. - // - rational_adaptor& operator=(const rational_adaptor& o) = default; - rational_adaptor& operator=(rational_adaptor&& o) = default; - template <class Arithmetic> - inline typename std::enable_if<!std::is_floating_point<Arithmetic>::value, rational_adaptor&>::type operator=(const Arithmetic& i) - { - m_num = i; - m_denom = one(); - return *this; - } - rational_adaptor& operator=(const char* s) - { - using default_ops::eval_eq; - - std::string s1; - multiprecision::number<Backend> v1, v2; - char c; - bool have_hex = false; - const char* p = s; // saved for later - - while ((0 != (c = *s)) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F')))) - { - if (c == 'x' || c == 'X') - have_hex = true; - s1.append(1, c); - ++s; - } - v1.assign(s1); - s1.erase(); - if (c == '/') - { - ++s; - while ((0 != (c = *s)) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F')))) - { - if (c == 'x' || c == 'X') - have_hex = true; - s1.append(1, c); - ++s; - } - v2.assign(s1); - } - else - v2 = 1; - if (*s) - { - BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Could not parse the string \"") + p + std::string("\" as a valid rational number."))); - } - multiprecision::number<Backend> gcd; - eval_gcd(gcd.backend(), v1.backend(), v2.backend()); - if (!eval_eq(gcd.backend(), one())) - { - v1 /= gcd; - v2 /= gcd; - } - num() = std::move(std::move(v1).backend()); - denom() = std::move(std::move(v2).backend()); - return *this; - } - template <class Float> - typename std::enable_if<std::is_floating_point<Float>::value, rational_adaptor&>::type operator=(Float i) - { - using default_ops::eval_eq; - BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp; - - int e; - Float f = frexp(i, &e); -#ifdef BOOST_HAS_FLOAT128 - f = ldexp(f, std::is_same<float128_type, Float>::value ? 113 : std::numeric_limits<Float>::digits); - e -= std::is_same<float128_type, Float>::value ? 113 : std::numeric_limits<Float>::digits; -#else - f = ldexp(f, std::numeric_limits<Float>::digits); - e -= std::numeric_limits<Float>::digits; -#endif - number<Backend> num(f); - number<Backend> denom(1u); - if (e > 0) - { - num <<= e; - } - else if (e < 0) - { - denom <<= -e; - } - number<Backend> gcd; - eval_gcd(gcd.backend(), num.backend(), denom.backend()); - if (!eval_eq(gcd.backend(), one())) - { - num /= gcd; - denom /= gcd; - } - this->num() = std::move(std::move(num).backend()); - this->denom() = std::move(std::move(denom).backend()); - return *this; - } - - void swap(rational_adaptor& o) - { - m_num.swap(o.m_num); - m_denom.swap(o.m_denom); - } - std::string str(std::streamsize digits, std::ios_base::fmtflags f) const - { - using default_ops::eval_eq; - // - // We format the string ourselves so we can match what GMP's mpq type does: - // - std::string result = num().str(digits, f); - if (!eval_eq(denom(), one())) - { - result.append(1, '/'); - result.append(denom().str(digits, f)); - } - return result; - } - void negate() - { - m_num.negate(); - } - int compare(const rational_adaptor& o) const - { - std::ptrdiff_t s1 = eval_get_sign(*this); - std::ptrdiff_t s2 = eval_get_sign(o); - if (s1 != s2) - { - return s1 < s2 ? -1 : 1; - } - else if (s1 == 0) - return 0; // both zero. - - bool neg = false; - if (s1 >= 0) - { - s1 = eval_msb(num()) + eval_msb(o.denom()); - s2 = eval_msb(o.num()) + eval_msb(denom()); - } - else - { - Backend t(num()); - t.negate(); - s1 = eval_msb(t) + eval_msb(o.denom()); - t = o.num(); - t.negate(); - s2 = eval_msb(t) + eval_msb(denom()); - neg = true; - } - s1 -= s2; - if (s1 < -1) - return neg ? 1 : -1; - else if (s1 > 1) - return neg ? -1 : 1; - - Backend t1, t2; - eval_multiply(t1, num(), o.denom()); - eval_multiply(t2, o.num(), denom()); - return t1.compare(t2); - } - // - // Comparison with arithmetic types, default just constructs a temporary: - // - template <class A> - typename std::enable_if<boost::multiprecision::detail::is_arithmetic<A>::value, int>::type compare(A i) const - { - rational_adaptor t; - t = i; // Note: construct directly from i if supported. - return compare(t); - } - - Backend& num() { return m_num; } - const Backend& num()const { return m_num; } - Backend& denom() { return m_denom; } - const Backend& denom()const { return m_denom; } - - #ifndef BOOST_MP_STANDALONE - template <class Archive> - void serialize(Archive& ar, const std::integral_constant<bool, true>&) - { - // Saving - number<Backend> n(num()), d(denom()); - ar& boost::make_nvp("numerator", n); - ar& boost::make_nvp("denominator", d); - } - template <class Archive> - void serialize(Archive& ar, const std::integral_constant<bool, false>&) - { - // Loading - number<Backend> n, d; - ar& boost::make_nvp("numerator", n); - ar& boost::make_nvp("denominator", d); - num() = n.backend(); - denom() = d.backend(); - } - template <class Archive> - void serialize(Archive& ar, const unsigned int /*version*/) - { - using tag = typename Archive::is_saving; - using saving_tag = std::integral_constant<bool, tag::value>; - serialize(ar, saving_tag()); - } - #endif // BOOST_MP_STANDALONE - - private: - Backend m_num, m_denom; -}; - -// -// Helpers: -// -template <class T> -inline constexpr typename std::enable_if<std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_signed, bool>::type -is_minus_one(const T&) -{ - return false; -} -template <class T> -inline constexpr typename std::enable_if<!std::numeric_limits<T>::is_specialized || std::numeric_limits<T>::is_signed, bool>::type -is_minus_one(const T& val) -{ - return val == -1; -} - -// -// Required non-members: -// -template <class Backend> -inline void eval_add(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - eval_add_subtract_imp(a, a, b, true); -} -template <class Backend> -inline void eval_subtract(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - eval_add_subtract_imp(a, a, b, false); -} - -template <class Backend> -inline void eval_multiply(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - eval_multiply_imp(a, a, b.num(), b.denom()); -} - -template <class Backend> -void eval_divide(rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - using default_ops::eval_divide; - rational_adaptor<Backend> t; - eval_divide(t, a, b); - a = std::move(t); -} -// -// Conversions: -// -template <class R, class IntBackend> -inline typename std::enable_if<number_category<R>::value == number_kind_floating_point>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend) -{ - // - // The generic conversion is as good as anything we can write here: - // - ::boost::multiprecision::detail::generic_convert_rational_to_float(*result, backend); -} - -template <class R, class IntBackend> -inline typename std::enable_if<(number_category<R>::value != number_kind_integer) && (number_category<R>::value != number_kind_floating_point) && !std::is_enum<R>::value>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend) -{ - using default_ops::eval_convert_to; - R d; - eval_convert_to(result, backend.num()); - eval_convert_to(&d, backend.denom()); - *result /= d; -} - -template <class R, class Backend> -inline typename std::enable_if<number_category<R>::value == number_kind_integer>::type eval_convert_to(R* result, const rational_adaptor<Backend>& backend) -{ - using default_ops::eval_divide; - using default_ops::eval_convert_to; - Backend t; - eval_divide(t, backend.num(), backend.denom()); - eval_convert_to(result, t); -} - -// -// Hashing support, not strictly required, but it is used in our tests: -// -template <class Backend> -inline std::size_t hash_value(const rational_adaptor<Backend>& arg) -{ - std::size_t result = hash_value(arg.num()); - std::size_t result2 = hash_value(arg.denom()); - boost::multiprecision::detail::hash_combine(result, result2); - return result; -} -// -// assign_components: -// -template <class Backend> -void assign_components(rational_adaptor<Backend>& result, Backend const& a, Backend const& b) -{ - using default_ops::eval_gcd; - using default_ops::eval_divide; - using default_ops::eval_eq; - using default_ops::eval_is_zero; - using default_ops::eval_get_sign; - - if (eval_is_zero(b)) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - } - Backend g; - eval_gcd(g, a, b); - if (eval_eq(g, rational_adaptor<Backend>::one())) - { - result.num() = a; - result.denom() = b; - } - else - { - eval_divide(result.num(), a, g); - eval_divide(result.denom(), b, g); - } - if (eval_get_sign(result.denom()) < 0) - { - result.num().negate(); - result.denom().negate(); - } -} -// -// Again for arithmetic types, overload for whatever arithmetic types are directly supported: -// -template <class Backend, class Arithmetic1, class Arithmetic2> -inline void assign_components(rational_adaptor<Backend>& result, const Arithmetic1& a, typename std::enable_if<std::is_arithmetic<Arithmetic1>::value && std::is_arithmetic<Arithmetic2>::value, const Arithmetic2&>::type b) -{ - using default_ops::eval_gcd; - using default_ops::eval_divide; - using default_ops::eval_eq; - - if (b == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - } - - Backend g; - result.num() = a; - eval_gcd(g, result.num(), b); - if (eval_eq(g, rational_adaptor<Backend>::one())) - { - result.denom() = b; - } - else - { - eval_divide(result.num(), g); - eval_divide(result.denom(), b, g); - } - if (eval_get_sign(result.denom()) < 0) - { - result.num().negate(); - result.denom().negate(); - } -} -template <class Backend, class Arithmetic1, class Arithmetic2> -inline void assign_components(rational_adaptor<Backend>& result, const Arithmetic1& a, typename std::enable_if<!std::is_arithmetic<Arithmetic1>::value || !std::is_arithmetic<Arithmetic2>::value, const Arithmetic2&>::type b) -{ - using default_ops::eval_gcd; - using default_ops::eval_divide; - using default_ops::eval_eq; - - Backend g; - result.num() = a; - result.denom() = b; - - if (eval_get_sign(result.denom()) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - } - - eval_gcd(g, result.num(), result.denom()); - if (!eval_eq(g, rational_adaptor<Backend>::one())) - { - eval_divide(result.num(), g); - eval_divide(result.denom(), g); - } - if (eval_get_sign(result.denom()) < 0) - { - result.num().negate(); - result.denom().negate(); - } -} -// -// Optional comparison operators: -// -template <class Backend> -inline bool eval_is_zero(const rational_adaptor<Backend>& arg) -{ - using default_ops::eval_is_zero; - return eval_is_zero(arg.num()); -} - -template <class Backend> -inline int eval_get_sign(const rational_adaptor<Backend>& arg) -{ - using default_ops::eval_get_sign; - return eval_get_sign(arg.num()); -} - -template <class Backend> -inline bool eval_eq(const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - using default_ops::eval_eq; - return eval_eq(a.num(), b.num()) && eval_eq(a.denom(), b.denom()); -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value&& std::is_integral<Arithmetic>::value, bool>::type - eval_eq(const rational_adaptor<Backend>& a, Arithmetic b) -{ - using default_ops::eval_eq; - return eval_eq(a.denom(), rational_adaptor<Backend>::one()) && eval_eq(a.num(), b); -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value&& std::is_integral<Arithmetic>::value, bool>::type - eval_eq(Arithmetic b, const rational_adaptor<Backend>& a) -{ - using default_ops::eval_eq; - return eval_eq(a.denom(), rational_adaptor<Backend>::one()) && eval_eq(a.num(), b); -} - -// -// Arithmetic operations, starting with addition: -// -template <class Backend, class Arithmetic> -void eval_add_subtract_imp(rational_adaptor<Backend>& result, const Arithmetic& arg, bool isaddition) -{ - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_add; - using default_ops::eval_gcd; - Backend t; - eval_multiply(t, result.denom(), arg); - if (isaddition) - eval_add(result.num(), t); - else - eval_subtract(result.num(), t); - // - // There is no need to re-normalize here, we have - // (a + bm) / b - // and gcd(a + bm, b) = gcd(a, b) = 1 - // - /* - eval_gcd(t, result.num(), result.denom()); - if (!eval_eq(t, rational_adaptor<Backend>::one()) != 0) - { - Backend t2; - eval_divide(t2, result.num(), t); - t2.swap(result.num()); - eval_divide(t2, result.denom(), t); - t2.swap(result.denom()); - } - */ -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_add(rational_adaptor<Backend>& result, const Arithmetic& arg) -{ - eval_add_subtract_imp(result, arg, true); -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_subtract(rational_adaptor<Backend>& result, const Arithmetic& arg) -{ - eval_add_subtract_imp(result, arg, false); -} - -template <class Backend> -void eval_add_subtract_imp(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b, bool isaddition) -{ - using default_ops::eval_eq; - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_add; - using default_ops::eval_subtract; - // - // Let a = an/ad - // b = bn/bd - // g = gcd(ad, bd) - // result = rn/rd - // - // Then: - // rn = an * (bd/g) + bn * (ad/g) - // rd = ad * (bd/g) - // = (ad/g) * (bd/g) * g - // - // And the whole thing can then be rescaled by - // gcd(rn, g) - // - Backend gcd, t1, t2, t3, t4; - // - // Begin by getting the gcd of the 2 denominators: - // - eval_gcd(gcd, a.denom(), b.denom()); - // - // Do we have gcd > 1: - // - if (!eval_eq(gcd, rational_adaptor<Backend>::one())) - { - // - // Scale the denominators by gcd, and put the results in t1 and t2: - // - eval_divide(t1, b.denom(), gcd); - eval_divide(t2, a.denom(), gcd); - // - // multiply the numerators by the scale denominators and put the results in t3, t4: - // - eval_multiply(t3, a.num(), t1); - eval_multiply(t4, b.num(), t2); - // - // Add them up: - // - if (isaddition) - eval_add(t3, t4); - else - eval_subtract(t3, t4); - // - // Get the gcd of gcd and our numerator (t3): - // - eval_gcd(t4, t3, gcd); - if (eval_eq(t4, rational_adaptor<Backend>::one())) - { - result.num() = t3; - eval_multiply(result.denom(), t1, a.denom()); - } - else - { - // - // Uncommon case where gcd is not 1, divide the numerator - // and the denominator terms by the new gcd. Note we perform division - // on the existing gcd value as this is the smallest of the 3 denominator - // terms we'll be multiplying together, so there's a good chance it's a - // single limb value already: - // - eval_divide(result.num(), t3, t4); - eval_divide(t3, gcd, t4); - eval_multiply(t4, t1, t2); - eval_multiply(result.denom(), t4, t3); - } - } - else - { - // - // Most common case (approx 60%) where gcd is one: - // - eval_multiply(t1, a.num(), b.denom()); - eval_multiply(t2, a.denom(), b.num()); - if (isaddition) - eval_add(result.num(), t1, t2); - else - eval_subtract(result.num(), t1, t2); - eval_multiply(result.denom(), a.denom(), b.denom()); - } -} - - -template <class Backend> -inline void eval_add(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - eval_add_subtract_imp(result, a, b, true); -} -template <class Backend> -inline void eval_subtract(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - eval_add_subtract_imp(result, a, b, false); -} - -template <class Backend, class Arithmetic> -void eval_add_subtract_imp(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b, bool isaddition) -{ - using default_ops::eval_add; - using default_ops::eval_subtract; - using default_ops::eval_multiply; - - if (&result == &a) - return eval_add_subtract_imp(result, b, isaddition); - - eval_multiply(result.num(), a.denom(), b); - if (isaddition) - eval_add(result.num(), a.num()); - else - BOOST_IF_CONSTEXPR(std::numeric_limits<Backend>::is_signed == false) - { - Backend t; - eval_subtract(t, a.num(), result.num()); - result.num() = std::move(t); - } - else - { - eval_subtract(result.num(), a.num()); - result.negate(); - } - result.denom() = a.denom(); - // - // There is no need to re-normalize here, we have - // (a + bm) / b - // and gcd(a + bm, b) = gcd(a, b) = 1 - // -} -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_add(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b) -{ - eval_add_subtract_imp(result, a, b, true); -} -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_subtract(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b) -{ - eval_add_subtract_imp(result, a, b, false); -} - -// -// Multiplication: -// -template <class Backend> -void eval_multiply_imp(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Backend& b_num, const Backend& b_denom) -{ - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_gcd; - using default_ops::eval_get_sign; - using default_ops::eval_eq; - - Backend gcd_left, gcd_right, t1, t2; - eval_gcd(gcd_left, a.num(), b_denom); - eval_gcd(gcd_right, b_num, a.denom()); - // - // Unit gcd's are the most likely case: - // - bool b_left = eval_eq(gcd_left, rational_adaptor<Backend>::one()); - bool b_right = eval_eq(gcd_right, rational_adaptor<Backend>::one()); - - if (b_left && b_right) - { - eval_multiply(result.num(), a.num(), b_num); - eval_multiply(result.denom(), a.denom(), b_denom); - } - else if (b_left) - { - eval_divide(t2, b_num, gcd_right); - eval_multiply(result.num(), a.num(), t2); - eval_divide(t1, a.denom(), gcd_right); - eval_multiply(result.denom(), t1, b_denom); - } - else if (b_right) - { - eval_divide(t1, a.num(), gcd_left); - eval_multiply(result.num(), t1, b_num); - eval_divide(t2, b_denom, gcd_left); - eval_multiply(result.denom(), a.denom(), t2); - } - else - { - eval_divide(t1, a.num(), gcd_left); - eval_divide(t2, b_num, gcd_right); - eval_multiply(result.num(), t1, t2); - eval_divide(t1, a.denom(), gcd_right); - eval_divide(t2, b_denom, gcd_left); - eval_multiply(result.denom(), t1, t2); - } - // - // We may have b_denom negative if this is actually division, if so just correct things now: - // - if (eval_get_sign(b_denom) < 0) - { - result.num().negate(); - result.denom().negate(); - } -} - -template <class Backend> -void eval_multiply(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - using default_ops::eval_multiply; - - if (&a == &b) - { - // squaring, gcd's are 1: - eval_multiply(result.num(), a.num(), b.num()); - eval_multiply(result.denom(), a.denom(), b.denom()); - return; - } - eval_multiply_imp(result, a, b.num(), b.denom()); -} - -template <class Backend, class Arithmetic> -void eval_multiply_imp(Backend& result_num, Backend& result_denom, Arithmetic arg) -{ - if (arg == 0) - { - result_num = rational_adaptor<Backend>::zero(); - result_denom = rational_adaptor<Backend>::one(); - return; - } - else if (arg == 1) - return; - - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_gcd; - using default_ops::eval_convert_to; - - Backend gcd, t; - Arithmetic integer_gcd; - eval_gcd(gcd, result_denom, arg); - eval_convert_to(&integer_gcd, gcd); - arg /= integer_gcd; - if (boost::multiprecision::detail::unsigned_abs(arg) > 1) - { - eval_multiply(t, result_num, arg); - result_num = std::move(t); - } - else if (is_minus_one(arg)) - result_num.negate(); - if (integer_gcd > 1) - { - eval_divide(t, result_denom, integer_gcd); - result_denom = std::move(t); - } -} -template <class Backend> -void eval_multiply_imp(Backend& result_num, Backend& result_denom, Backend arg) -{ - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_gcd; - using default_ops::eval_convert_to; - using default_ops::eval_is_zero; - using default_ops::eval_eq; - using default_ops::eval_get_sign; - - if (eval_is_zero(arg)) - { - result_num = rational_adaptor<Backend>::zero(); - result_denom = rational_adaptor<Backend>::one(); - return; - } - else if (eval_eq(arg, rational_adaptor<Backend>::one())) - return; - - Backend gcd, t; - eval_gcd(gcd, result_denom, arg); - if (!eval_eq(gcd, rational_adaptor<Backend>::one())) - { - eval_divide(t, arg, gcd); - arg = t; - } - else - t = arg; - if (eval_get_sign(arg) < 0) - t.negate(); - - if (!eval_eq(t, rational_adaptor<Backend>::one())) - { - eval_multiply(t, result_num, arg); - result_num = std::move(t); - } - else if (eval_get_sign(arg) < 0) - result_num.negate(); - if (!eval_eq(gcd, rational_adaptor<Backend>::one())) - { - eval_divide(t, result_denom, gcd); - result_denom = std::move(t); - } -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_multiply(rational_adaptor<Backend>& result, const Arithmetic& arg) -{ - eval_multiply_imp(result.num(), result.denom(), arg); -} - -template <class Backend, class Arithmetic> -typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && std::is_integral<Arithmetic>::value>::type - eval_multiply_imp(rational_adaptor<Backend>& result, const Backend& a_num, const Backend& a_denom, Arithmetic b) -{ - if (b == 0) - { - result.num() = rational_adaptor<Backend>::zero(); - result.denom() = rational_adaptor<Backend>::one(); - return; - } - else if (b == 1) - { - result.num() = a_num; - result.denom() = a_denom; - return; - } - - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_gcd; - using default_ops::eval_convert_to; - - Backend gcd; - Arithmetic integer_gcd; - eval_gcd(gcd, a_denom, b); - eval_convert_to(&integer_gcd, gcd); - b /= integer_gcd; - if (boost::multiprecision::detail::unsigned_abs(b) > 1) - eval_multiply(result.num(), a_num, b); - else if (is_minus_one(b)) - { - result.num() = a_num; - result.num().negate(); - } - else - result.num() = a_num; - if (integer_gcd > 1) - eval_divide(result.denom(), a_denom, integer_gcd); - else - result.denom() = a_denom; -} -template <class Backend> -inline void eval_multiply_imp(rational_adaptor<Backend>& result, const Backend& a_num, const Backend& a_denom, const Backend& b) -{ - result.num() = a_num; - result.denom() = a_denom; - eval_multiply_imp(result.num(), result.denom(), b); -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_multiply(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const Arithmetic& b) -{ - if (&result == &a) - return eval_multiply(result, b); - - eval_multiply_imp(result, a.num(), a.denom(), b); -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_multiply(rational_adaptor<Backend>& result, const Arithmetic& b, const rational_adaptor<Backend>& a) -{ - return eval_multiply(result, a, b); -} - -// -// Division: -// -template <class Backend> -inline void eval_divide(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, const rational_adaptor<Backend>& b) -{ - using default_ops::eval_multiply; - using default_ops::eval_get_sign; - - if (eval_get_sign(b.num()) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - return; - } - if (&a == &b) - { - // Huh? Really? - result.num() = result.denom() = rational_adaptor<Backend>::one(); - return; - } - if (&result == &b) - { - rational_adaptor<Backend> t(b); - return eval_divide(result, a, t); - } - eval_multiply_imp(result, a, b.denom(), b.num()); -} - -template <class Backend, class Arithmetic> -inline typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && (std::is_integral<Arithmetic>::value || std::is_same<Arithmetic, Backend>::value)>::type - eval_divide(rational_adaptor<Backend>& result, const Arithmetic& b, const rational_adaptor<Backend>& a) -{ - using default_ops::eval_get_sign; - - if (eval_get_sign(a.num()) == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - return; - } - if (&a == &result) - { - eval_multiply_imp(result.denom(), result.num(), b); - result.num().swap(result.denom()); - } - else - eval_multiply_imp(result, a.denom(), a.num(), b); - - if (eval_get_sign(result.denom()) < 0) - { - result.num().negate(); - result.denom().negate(); - } -} - -template <class Backend, class Arithmetic> -typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && std::is_integral<Arithmetic>::value>::type -eval_divide(rational_adaptor<Backend>& result, Arithmetic arg) -{ - if (arg == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - return; - } - else if (arg == 1) - return; - else if (is_minus_one(arg)) - { - result.negate(); - return; - } - if (eval_get_sign(result) == 0) - { - return; - } - - - using default_ops::eval_multiply; - using default_ops::eval_gcd; - using default_ops::eval_convert_to; - using default_ops::eval_divide; - - Backend gcd, t; - Arithmetic integer_gcd; - eval_gcd(gcd, result.num(), arg); - eval_convert_to(&integer_gcd, gcd); - arg /= integer_gcd; - - eval_multiply(t, result.denom(), boost::multiprecision::detail::unsigned_abs(arg)); - result.denom() = std::move(t); - if (arg < 0) - { - result.num().negate(); - } - if (integer_gcd > 1) - { - eval_divide(t, result.num(), integer_gcd); - result.num() = std::move(t); - } -} -template <class Backend> -void eval_divide(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, Backend arg) -{ - using default_ops::eval_multiply; - using default_ops::eval_gcd; - using default_ops::eval_convert_to; - using default_ops::eval_divide; - using default_ops::eval_is_zero; - using default_ops::eval_eq; - using default_ops::eval_get_sign; - - if (eval_is_zero(arg)) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - return; - } - else if (eval_eq(a, rational_adaptor<Backend>::one()) || (eval_get_sign(a) == 0)) - { - if (&result != &a) - result = a; - return; - } - - Backend gcd, u_arg, t; - eval_gcd(gcd, a.num(), arg); - bool has_unit_gcd = eval_eq(gcd, rational_adaptor<Backend>::one()); - if (!has_unit_gcd) - { - eval_divide(u_arg, arg, gcd); - arg = u_arg; - } - else - u_arg = arg; - if (eval_get_sign(u_arg) < 0) - u_arg.negate(); - - eval_multiply(t, a.denom(), u_arg); - result.denom() = std::move(t); - - if (!has_unit_gcd) - { - eval_divide(t, a.num(), gcd); - result.num() = std::move(t); - } - else if (&result != &a) - result.num() = a.num(); - - if (eval_get_sign(arg) < 0) - { - result.num().negate(); - } -} -template <class Backend> -void eval_divide(rational_adaptor<Backend>& result, Backend arg) -{ - eval_divide(result, result, arg); -} - -template <class Backend, class Arithmetic> -typename std::enable_if<std::is_convertible<Arithmetic, Backend>::value && std::is_integral<Arithmetic>::value>::type - eval_divide(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& a, Arithmetic arg) -{ - if (&result == &a) - return eval_divide(result, arg); - if (arg == 0) - { - BOOST_MP_THROW_EXCEPTION(std::overflow_error("Integer division by zero")); - return; - } - else if (arg == 1) - { - result = a; - return; - } - else if (is_minus_one(arg)) - { - result = a; - result.num().negate(); - return; - } - - if (eval_get_sign(a) == 0) - { - result = a; - return; - } - - using default_ops::eval_multiply; - using default_ops::eval_divide; - using default_ops::eval_gcd; - using default_ops::eval_convert_to; - - Backend gcd; - Arithmetic integer_gcd; - eval_gcd(gcd, a.num(), arg); - eval_convert_to(&integer_gcd, gcd); - arg /= integer_gcd; - eval_multiply(result.denom(), a.denom(), boost::multiprecision::detail::unsigned_abs(arg)); - - if (integer_gcd > 1) - { - eval_divide(result.num(), a.num(), integer_gcd); - } - else - result.num() = a.num(); - if (arg < 0) - { - result.num().negate(); - } -} - -// -// Increment and decrement: -// -template <class Backend> -inline void eval_increment(rational_adaptor<Backend>& arg) -{ - using default_ops::eval_add; - eval_add(arg.num(), arg.denom()); -} -template <class Backend> -inline void eval_decrement(rational_adaptor<Backend>& arg) -{ - using default_ops::eval_subtract; - eval_subtract(arg.num(), arg.denom()); -} - -// -// abs: -// -template <class Backend> -inline void eval_abs(rational_adaptor<Backend>& result, const rational_adaptor<Backend>& arg) -{ - using default_ops::eval_abs; - eval_abs(result.num(), arg.num()); - result.denom() = arg.denom(); -} - -} // namespace backends - -// -// Import the backend into this namespace: -// -using boost::multiprecision::backends::rational_adaptor; -// -// Define a category for this number type, one of: -// -// number_kind_integer -// number_kind_floating_point -// number_kind_rational -// number_kind_fixed_point -// number_kind_complex -// -template<class Backend> -struct number_category<rational_adaptor<Backend> > : public std::integral_constant<int, number_kind_rational> -{}; - -template <class IntBackend> -struct expression_template_default<backends::rational_adaptor<IntBackend> > : public expression_template_default<IntBackend> -{}; - -template <class Backend, expression_template_option ExpressionTemplates> -struct component_type<number<rational_adaptor<Backend>, ExpressionTemplates> > -{ - typedef number<Backend, ExpressionTemplates> type; -}; - -template <class IntBackend, expression_template_option ET> -inline number<IntBackend, ET> numerator(const number<rational_adaptor<IntBackend>, ET>& val) -{ - return val.backend().num(); -} -template <class IntBackend, expression_template_option ET> -inline number<IntBackend, ET> denominator(const number<rational_adaptor<IntBackend>, ET>& val) -{ - return val.backend().denom(); -} - -template <class Backend> -struct is_unsigned_number<rational_adaptor<Backend> > : public is_unsigned_number<Backend> -{}; - - -}} // namespace boost::multiprecision - -namespace std { - - template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates> - class numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> > : public std::numeric_limits<boost::multiprecision::number<IntBackend, ExpressionTemplates> > - { - using base_type = std::numeric_limits<boost::multiprecision::number<IntBackend> >; - using number_type = boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend> >; - - public: - static constexpr bool is_integer = false; - static constexpr bool is_exact = true; - static constexpr number_type(min)() { return (base_type::min)(); } - static constexpr number_type(max)() { return (base_type::max)(); } - static constexpr number_type lowest() { return -(max)(); } - static constexpr number_type epsilon() { return base_type::epsilon(); } - static constexpr number_type round_error() { return epsilon() / 2; } - static constexpr number_type infinity() { return base_type::infinity(); } - static constexpr number_type quiet_NaN() { return base_type::quiet_NaN(); } - static constexpr number_type signaling_NaN() { return base_type::signaling_NaN(); } - static constexpr number_type denorm_min() { return base_type::denorm_min(); } - }; - - template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates> - constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> >::is_integer; - template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates> - constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> >::is_exact; - -} // namespace std - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/explicit_conversion.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/explicit_conversion.hpp deleted file mode 100644 index e32534eea8..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/explicit_conversion.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Vicente J. Botet Escriba 2009-2011 -// Copyright 2012 John Maddock. 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) - -#ifndef BOOST_MP_EXPLICIT_CONVERSION_HPP -#define BOOST_MP_EXPLICIT_CONVERSION_HPP - -#include <type_traits> -#include <boost/multiprecision/detail/standalone_config.hpp> -#include <boost/multiprecision/detail/number_base.hpp> // number_category - -namespace boost { -namespace multiprecision { -namespace detail { - -template <unsigned int N> -struct dummy_size -{}; - -template <typename S, typename T> -struct has_generic_interconversion -{ - using type = typename std::conditional< - is_number<S>::value && is_number<T>::value, - typename std::conditional< - number_category<S>::value == number_kind_integer, - typename std::conditional< - number_category<T>::value == number_kind_integer || number_category<T>::value == number_kind_floating_point || number_category<T>::value == number_kind_rational || number_category<T>::value == number_kind_fixed_point, - std::true_type, - std::false_type >::type, - typename std::conditional< - number_category<S>::value == number_kind_rational, - typename std::conditional< - number_category<T>::value == number_kind_rational || number_category<T>::value == number_kind_rational, - std::true_type, - std::false_type >::type, - typename std::conditional< - number_category<T>::value == number_kind_floating_point, - std::true_type, - std::false_type >::type>::type>::type, - std::false_type >::type; -}; - -template <typename S, typename T> -struct is_explicitly_convertible_imp -{ - template <typename S1, typename T1> - static int selector(dummy_size<static_cast<unsigned int>(sizeof(new T1(std::declval<S1>())))>*); - - template <typename S1, typename T1> - static char selector(...); - - static constexpr bool value = sizeof(selector<S, T>(nullptr)) == sizeof(int); - - using type = std::integral_constant<bool, value>; -}; - -template <typename From, typename To> -struct is_explicitly_convertible : public is_explicitly_convertible_imp<From, To>::type -{ -}; - -}}} // namespace boost::multiprecision::detail - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_backend.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_backend.hpp deleted file mode 100644 index 46cee4df37..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_backend.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2015 John Maddock. 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) - -#ifndef BOOST_MP_IS_BACKEND_HPP -#define BOOST_MP_IS_BACKEND_HPP - -#include <type_traits> -#include <boost/multiprecision/detail/number_base.hpp> - -namespace boost { namespace multiprecision { namespace detail { - -template <class T> -struct has_signed_types -{ - template <class U> - static double check(U*, typename U::signed_types* = nullptr); - static char check(...); - static T* get(); - static constexpr bool value = sizeof(check(get())) == sizeof(double); -}; -template <class T> -struct has_unsigned_types -{ - template <class U> - static double check(U*, typename U::unsigned_types* = nullptr); - static char check(...); - static T* get(); - static constexpr bool value = sizeof(check(get())) == sizeof(double); -}; -template <class T> -struct has_float_types -{ - template <class U> - static double check(U*, typename U::float_types* = nullptr); - static char check(...); - static T* get(); - static constexpr bool value = sizeof(check(get())) == sizeof(double); -}; - -template <class T> -struct is_backend : public std::integral_constant<bool, has_signed_types<T>::value && has_unsigned_types<T>::value && has_float_types<T>::value> {}; - -template <class Backend> -struct other_backend -{ - using type = typename std::conditional< - std::is_same<number<Backend>, number<Backend, et_on> >::value, - number<Backend, et_off>, number<Backend, et_on> >::type; -}; - -template <class B, class V> -struct number_from_backend -{ - using type = typename std::conditional< - std::is_convertible<V, number<B> >::value, - number<B>, - typename other_backend<B>::type>::type; -}; - -template <bool b, class T, class U> -struct is_first_backend_imp : public std::false_type {}; - -template <class T, class U> - struct is_first_backend_imp<true, T, U> : public std::integral_constant < bool, std::is_convertible<U, number<T, et_on> >::value || std::is_convertible<U, number<T, et_off> >::value> {}; - -template <class T, class U> -struct is_first_backend : is_first_backend_imp<is_backend<T>::value, T, U> -{}; - -template <bool b, class T, class U> -struct is_second_backend_imp -{ - static constexpr bool value = false; -}; -template <class T, class U> -struct is_second_backend_imp<true, T, U> -{ - static constexpr bool value = (std::is_convertible<T, number<U, et_on> >::value || std::is_convertible<T, number<U, et_off> >::value) && !is_first_backend<T, U>::value; -}; - -template <class T, class U> -struct is_second_backend : is_second_backend_imp<is_backend<U>::value, T, U> -{}; - -} -} -} // namespace boost::multiprecision::detail - -#endif // BOOST_MP_IS_BACKEND_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_byte_container.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_byte_container.hpp deleted file mode 100644 index 998a704214..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_byte_container.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2015 John Maddock. 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) - -#ifndef BOOST_IS_BYTE_CONTAINER_HPP -#define BOOST_IS_BYTE_CONTAINER_HPP - -#include <iterator> -#include <type_traits> - -namespace boost { namespace multiprecision { namespace detail { - -template <class T> -struct has_member_const_iterator -{ - template <class U> - static double check(U*, typename U::const_iterator* = nullptr); - static char check(...); - static T* get(); - static constexpr bool value = sizeof(check(get())) == sizeof(double); -}; - - -template <class C, class Iterator> -struct is_byte_container_imp_2 -{ - using container_value_type = typename std::remove_cv<typename std::iterator_traits<typename C::const_iterator>::value_type>::type; - static constexpr bool value = boost::multiprecision::detail::is_integral<container_value_type>::value && (sizeof(container_value_type) == 1); -}; - -template <class C> -struct is_byte_container_imp_2<C, void> : public std::false_type -{}; - -template <class C, bool b> -struct is_byte_container_imp : public is_byte_container_imp_2<C, typename C::const_iterator> -{ -}; - -template <class C> -struct is_byte_container_imp<C, false> : public std::false_type -{}; - -template <class C> -struct is_byte_container : public is_byte_container_imp<C, has_member_const_iterator<C>::value> -{}; - -}}} // namespace boost::multiprecision::detail - -#endif // BOOST_IS_BYTE_CONTAINER_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_complex.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_complex.hpp deleted file mode 100644 index 73da1f04e1..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_complex.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2018 John Maddock. 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) - -#ifndef BOOST_MP_IS_COMPLEX_HPP -#define BOOST_MP_IS_COMPLEX_HPP - -#include <type_traits> -#include <complex> - -namespace boost { namespace multiprecision { namespace detail { - -template <class T> struct is_complex : public std::integral_constant<bool, false> {}; - -template <class T> struct is_complex<std::complex<T> > : public std::integral_constant<bool, true> {}; - -} -} -} // namespace boost::multiprecision::detail - -#endif // BOOST_MP_IS_BACKEND_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_convertible_arithmetic.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_convertible_arithmetic.hpp deleted file mode 100644 index cf17aa88f8..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_convertible_arithmetic.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2021 John Maddock. 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) - -#ifndef BOOST_IS_CONVERTIBLE_ARITHMETIC_HPP -#define BOOST_IS_CONVERTIBLE_ARITHMETIC_HPP - -#include <type_traits> -#include <boost/multiprecision/detail/number_base.hpp> -#include <boost/multiprecision/detail/standalone_config.hpp> - -namespace boost { namespace multiprecision { namespace detail { - -template <class V, class Backend> -struct is_convertible_arithmetic -{ - static constexpr bool value = boost::multiprecision::detail::is_arithmetic<V>::value; -}; -// -// For extension types, we don't *require* interoperability, -// so only enable it if we can convert the type to the backend -// losslessly, ie not via conversion to a narrower type. -// Note that backends with templated constructors/=operators -// will not be selected here, so these need to either specialize -// this trait, or provide a proper non-template constructor/=operator -// for the extension types it supports. -// -#ifdef BOOST_HAS_FLOAT128 -template <class Backend> -struct is_convertible_arithmetic<float128_type, Backend> -{ - static constexpr bool value = std::is_assignable<Backend, convertible_to<float128_type>>::value; -}; -#endif -#ifdef BOOST_HAS_INT128 -template <class Backend> -struct is_convertible_arithmetic<int128_type, Backend> -{ - static constexpr bool value = std::is_assignable<Backend, convertible_to<int128_type>>::value; -}; -template <class Backend> -struct is_convertible_arithmetic<uint128_type, Backend> -{ - static constexpr bool value = std::is_assignable<Backend, convertible_to<uint128_type>>::value; -}; -#endif - -}}} // namespace boost::multiprecision::detail - -#endif // BOOST_IS_BYTE_CONTAINER_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_restricted_conversion.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_restricted_conversion.hpp deleted file mode 100644 index a36dc4ebc9..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_restricted_conversion.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Vicente J. Botet Escriba 2009-2011 -// Copyright 2012 John Maddock. 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) - -#ifndef BOOST_MP_IS_RESTRICTED_CONVERSION_HPP -#define BOOST_MP_IS_RESTRICTED_CONVERSION_HPP - -#include <boost/multiprecision/traits/explicit_conversion.hpp> -#include <boost/multiprecision/detail/number_base.hpp> - -namespace boost { namespace multiprecision { namespace detail { - -template <class From, class To> -struct is_lossy_conversion -{ - static constexpr bool category_conditional_is_true = - ( (static_cast<boost::multiprecision::number_category_type>(number_category<From>::value) == number_kind_floating_point) - && (static_cast<boost::multiprecision::number_category_type>(number_category<To >::value) == number_kind_integer)) - || ( (static_cast<boost::multiprecision::number_category_type>(number_category<From>::value) == number_kind_rational) - && (static_cast<boost::multiprecision::number_category_type>(number_category<To >::value) == number_kind_integer)) - || ( (static_cast<boost::multiprecision::number_category_type>(number_category<From>::value) == number_kind_fixed_point) - && (static_cast<boost::multiprecision::number_category_type>(number_category<To >::value) == number_kind_integer)) - || (static_cast<boost::multiprecision::number_category_type>(number_category<From>::value) == number_kind_unknown) - || (static_cast<boost::multiprecision::number_category_type>(number_category<To >::value) == number_kind_unknown); - - using type = typename std::conditional<category_conditional_is_true, - std::integral_constant<bool, true>, - std::integral_constant<bool, false>>::type; - - static constexpr bool value = type::value; -}; - -template <typename From, typename To> -struct is_restricted_conversion -{ - using type = typename std::conditional< - ((is_explicitly_convertible<From, To>::value && !std::is_convertible<From, To>::value) || is_lossy_conversion<From, To>::value), - std::integral_constant<bool, true>, - std::integral_constant<bool, false>>::type; - static constexpr const bool value = type::value; -}; - -}}} // namespace boost::multiprecision::detail - -#endif // BOOST_MP_IS_RESTRICTED_CONVERSION_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_variable_precision.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_variable_precision.hpp deleted file mode 100644 index f42fb2c645..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_variable_precision.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2018 John Maddock. 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) - -#ifndef BOOST_MP_IS_VARIABLE_PRECISION_HPP -#define BOOST_MP_IS_VARIABLE_PRECISION_HPP - -#include <boost/multiprecision/detail/number_base.hpp> - -namespace boost { namespace multiprecision { namespace detail { - -template <class Backend> -struct is_variable_precision : public std::integral_constant<bool, false> -{}; - -template <class Backend, expression_template_option ExpressionTemplates> -struct is_variable_precision<number<Backend, ExpressionTemplates> > : public is_variable_precision<Backend> -{}; - -} -} -} // namespace boost::multiprecision::detail - -#endif // BOOST_MP_IS_BACKEND_HPP diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/max_digits10.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/max_digits10.hpp deleted file mode 100644 index 8e6d2371c8..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/max_digits10.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_MAX_DIGITS10_HPP -#define BOOST_MP_MAX_DIGITS10_HPP - -namespace boost { -namespace multiprecision { -namespace detail { - -template <unsigned digits> -struct calc_max_digits10 -{ - static constexpr unsigned max_digits_10(unsigned d) - { - // - // We need ceil(log10(2) * d) + 1 decimal places to - // guarantee round tripping, see: https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/ - // and references therein. Since log10(2) is irrational, then d*log10(2) will - // never be exactly an integer so we can replace by trunc(log10(2) * d) + 2 - // and avoid the call to ceil: - // - return static_cast<unsigned>(0.301029995663981195213738894724493026768189881462108541310 * d) + 2; - } - static constexpr unsigned value = max_digits_10(digits); -}; - -template <std::size_t digits> -struct calc_max_digits10_s -{ - static constexpr std::size_t max_digits_10(std::size_t d) - { - // - // We need ceil(log10(2) * d) + 1 decimal places to - // guarantee round tripping, see: https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/ - // and references therein. Since log10(2) is irrational, then d*log10(2) will - // never be exactly an integer so we can replace by trunc(log10(2) * d) + 2 - // and avoid the call to ceil: - // - return static_cast<std::size_t>(static_cast<std::size_t>(0.301029995663981195213738894724493026768189881462108541310 * static_cast<double>(d)) + 2u); - } - static constexpr std::size_t value = max_digits_10(digits); -}; - -template <unsigned digits> -struct calc_digits10 -{ - static constexpr unsigned digits_10(unsigned d) - { - // - // We need floor(log10(2) * (d-1)), see: - // https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/ - // and references therein. - // - return static_cast<unsigned>(0.301029995663981195213738894724493026768189881462108541310 * static_cast<double>(d - 1u)); - } - static constexpr unsigned value = digits_10(digits); -}; - -template <std::size_t digits> -struct calc_digits10_s -{ - static constexpr std::size_t digits_10(std::size_t d) - { - // - // We need floor(log10(2) * (d-1)), see: - // https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/ - // and references therein. - // - return static_cast<std::size_t>(0.301029995663981195213738894724493026768189881462108541310 * static_cast<double>(d - 1u)); - } - static constexpr std::size_t value = digits_10(digits); -}; - -}}} // namespace boost::multiprecision::detail - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/std_integer_traits.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/std_integer_traits.hpp deleted file mode 100644 index e8fafde181..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/std_integer_traits.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/////////////////////////////////////////////////////////////// -// Copyright 2012 John Maddock. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_MP_STD_INTEGER_TRAITS_HPP -#define BOOST_MP_STD_INTEGER_TRAITS_HPP - -#include <type_traits> -#include <boost/multiprecision/detail/standalone_config.hpp> - -namespace boost { -namespace multiprecision { -namespace detail { - -template <class T> -struct is_signed : public std::is_signed<T> {}; -template <class T> -struct is_unsigned : public std::is_unsigned<T> {}; -template <class T> -struct is_integral : public std::is_integral<T> {}; -template <class T> -struct is_arithmetic : public std::is_arithmetic<T> {}; -template <class T> -struct make_unsigned : public std::make_unsigned<T> {}; -template <class T> -struct make_signed : public std::make_signed<T> {}; - -#ifdef BOOST_HAS_INT128 - -template <> -struct is_signed<int128_type> : public std::integral_constant<bool, true> {}; -template <> -struct is_signed<uint128_type> : public std::integral_constant<bool, false> {}; -template <> -struct is_unsigned<int128_type> : public std::integral_constant<bool, false> {}; -template <> -struct is_unsigned<uint128_type> : public std::integral_constant<bool, true> {}; -template <> -struct is_integral<int128_type> : public std::integral_constant<bool, true> {}; -template <> -struct is_integral<uint128_type> : public std::integral_constant<bool, true> {}; -template <> -struct is_arithmetic<int128_type> : public std::integral_constant<bool, true> {}; -template <> -struct is_arithmetic<uint128_type> : public std::integral_constant<bool, true> {}; -template <> -struct make_unsigned<int128_type> -{ - using type = uint128_type; -}; -template <> -struct make_unsigned<uint128_type> -{ - using type = uint128_type; -}; -template <> -struct make_signed<int128_type> -{ - using type = int128_type; -}; -template <> -struct make_signed<uint128_type> -{ - using type = int128_type; -}; - -#endif - -}}} // namespace boost::multiprecision::detail - -#endif diff --git a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/transcendental_reduction_type.hpp b/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/transcendental_reduction_type.hpp deleted file mode 100644 index c433a6376a..0000000000 --- a/contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/transcendental_reduction_type.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright 2020 John Maddock. 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) - -#ifndef BOOST_MP_TRANSCENDENTAL_REDUCTION_TYPE_HPP -#define BOOST_MP_TRANSCENDENTAL_REDUCTION_TYPE_HPP - -namespace boost { namespace multiprecision { namespace detail { - -template <class T> -struct transcendental_reduction_type -{ - using type = T; -}; - -} -} -} // namespace boost::multiprecision::detail - -#endif // BOOST_MP_TRANSCENDENTAL_REDUCTION_TYPE_HPP |