aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2022-12-14 13:11:45 +0300
committerthegeorg <thegeorg@yandex-team.com>2022-12-14 13:11:45 +0300
commit7b2317ba8baa3414534e276c89e74f3033be9f69 (patch)
tree34bcc887b61bd073162b9ea5f017f3f792d78a2c /contrib
parent47490f2785d458995a29c75f5dd92f68f492a065 (diff)
downloadydb-7b2317ba8baa3414534e276c89e74f3033be9f69.tar.gz
Drop MSVC-specific workaround for using int128 implementation from boost
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libs/apache/arrow/CMakeLists.txt1
-rw-r--r--contrib/libs/apache/arrow/cpp/src/arrow/util/int128_internal.h2
-rw-r--r--contrib/libs/apache/arrow/src/arrow/util/config.h2
-rw-r--r--contrib/restricted/boost/CMakeLists.darwin.txt1
-rw-r--r--contrib/restricted/boost/CMakeLists.linux-aarch64.txt1
-rw-r--r--contrib/restricted/boost/CMakeLists.linux.txt1
-rw-r--r--contrib/restricted/boost/math/include/boost/cstdfloat.hpp58
-rw-r--r--contrib/restricted/boost/math/include/boost/math/constants/calculate_constants.hpp1110
-rw-r--r--contrib/restricted/boost/math/include/boost/math/constants/constants.hpp345
-rw-r--r--contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp1057
-rw-r--r--contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex.hpp38
-rw-r--r--contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp813
-rw-r--r--contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp774
-rw-r--r--contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_limits.hpp86
-rw-r--r--contrib/restricted/boost/math/include/boost/math/cstdfloat/cstdfloat_types.hpp441
-rw-r--r--contrib/restricted/boost/math/include/boost/math/policies/error_handling.hpp892
-rw-r--r--contrib/restricted/boost/math/include/boost/math/special_functions/hypot.hpp82
-rw-r--r--contrib/restricted/boost/math/include/boost/math/special_functions/next.hpp906
-rw-r--r--contrib/restricted/boost/math/include/boost/math/special_functions/trunc.hpp160
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/complex.hpp76
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/convert_from_string.hpp54
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/cxx03_warn.hpp95
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/is_detected.hpp56
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/precision.hpp395
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/throw_exception.hpp22
-rw-r--r--contrib/restricted/boost/math/include/boost/math/tools/traits.hpp128
-rw-r--r--contrib/restricted/boost/multiprecision/CMakeLists.txt33
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int.hpp2358
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add.hpp368
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/add_unsigned.hpp387
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/bitwise.hpp889
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/checked.hpp178
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp374
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/cpp_int_config.hpp176
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/divide.hpp655
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/import_export.hpp248
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/intel_intrinsics.hpp138
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/limits.hpp268
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp293
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/misc.hpp1445
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/multiply.hpp848
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/serialize.hpp211
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/cpp_int/value_pack.hpp42
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/assert.hpp29
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/bitscan.hpp317
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/check_cpp11_config.hpp64
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/constexpr.hpp88
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/default_ops.hpp4006
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/digits.hpp49
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/empty_value.hpp87
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/endian.hpp35
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/et_ops.hpp1831
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/float128_functions.hpp93
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/fpclassify.hpp101
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/constants.hpp288
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/pow.hpp905
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trig.hpp1058
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/functions/trunc.hpp76
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/generic_interconvert.hpp687
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/hash.hpp56
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/integer_ops.hpp474
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/min_max.hpp106
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp661
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/no_exceptions_support.hpp55
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_base.hpp1699
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/number_compare.hpp848
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/precision.hpp313
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/rebind.hpp19
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/standalone_config.hpp114
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/detail/ublas_interop.hpp75
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/integer.hpp363
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/number.hpp2490
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/rational_adaptor.hpp1296
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/explicit_conversion.hpp67
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_backend.hpp91
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_byte_container.hpp51
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_complex.hpp22
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_convertible_arithmetic.hpp51
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_restricted_conversion.hpp47
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/is_variable_precision.hpp25
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/max_digits10.hpp79
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/std_integer_traits.hpp72
-rw-r--r--contrib/restricted/boost/multiprecision/include/boost/multiprecision/traits/transcendental_reduction_type.hpp21
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