diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp index bf58b94eb..3ca090594 100644 --- a/include/boost/math/common_factor_ct.hpp +++ b/include/boost/math/common_factor_ct.hpp @@ -1,6 +1,6 @@ // Boost common_factor_ct.hpp header file ----------------------------------// -// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002. +// (C) Copyright John Maddock 2017. // 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) @@ -10,85 +10,16 @@ #ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP #define BOOST_MATH_COMMON_FACTOR_CT_HPP -#include // self include -#include // for BOOST_STATIC_CONSTANT, etc. -#include +#include namespace boost { namespace math { -// Implementation details --------------------------------------------------// - -namespace detail -{ - // Build GCD with Euclid's recursive algorithm - template < static_gcd_type Value1, static_gcd_type Value2 > - struct static_gcd_helper_t - { - private: - BOOST_STATIC_CONSTANT( static_gcd_type, new_value1 = Value2 ); - BOOST_STATIC_CONSTANT( static_gcd_type, new_value2 = Value1 % Value2 ); - - #ifndef __BORLANDC__ - #define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast(Value) - #else - typedef static_gcd_helper_t self_type; - #define BOOST_DETAIL_GCD_HELPER_VAL(Value) (self_type:: Value ) - #endif - - typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1), - BOOST_DETAIL_GCD_HELPER_VAL(new_value2) > next_step_type; - - #undef BOOST_DETAIL_GCD_HELPER_VAL - - public: - BOOST_STATIC_CONSTANT( static_gcd_type, value = next_step_type::value ); - }; - - // Non-recursive case - template < static_gcd_type Value1 > - struct static_gcd_helper_t< Value1, 0UL > - { - BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 ); - }; - - // Build the LCM from the GCD - template < static_gcd_type Value1, static_gcd_type Value2 > - struct static_lcm_helper_t - { - typedef static_gcd_helper_t gcd_type; - - BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value - * Value2 ); - }; - - // Special case for zero-GCD values - template < > - struct static_lcm_helper_t< 0UL, 0UL > - { - BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); - }; - -} // namespace detail - - -// Compile-time greatest common divisor evaluator class declaration --------// - -template < static_gcd_type Value1, static_gcd_type Value2 > -struct static_gcd : public mpl::integral_c::value) > -{ -}; // boost::math::static_gcd - - -// Compile-time least common multiple evaluator class declaration ----------// - -template < static_gcd_type Value1, static_gcd_type Value2 > -struct static_lcm : public mpl::integral_c::value) > -{ -}; // boost::math::static_lcm - + using boost::integer::static_gcd; + using boost::integer::static_lcm; + using boost::integer::static_gcd_type; } // namespace math } // namespace boost diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index 79520214b..42d9edfc0 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy William Murphy 2016. +// (C) Copyright John Maddock 2017. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file @@ -7,538 +7,19 @@ #ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP #define BOOST_MATH_COMMON_FACTOR_RT_HPP -#include -#include - -#include // for BOOST_NESTED_TEMPLATE, etc. -#include // for std::numeric_limits -#include // for CHAR_MIN -#include -#include -#include -#include -#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS -#include -#endif - -#if (defined(BOOST_MSVC) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) -#include -#endif - -#ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4127 4244) // Conditional expression is constant -#endif - -#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_CXX11_NOEXCEPT) -#define BOOST_GCD_NOEXCEPT(T) noexcept(std::is_arithmetic::value) -#else -#define BOOST_GCD_NOEXCEPT(T) -#endif +#include namespace boost { - - template - class rational; - namespace math { - namespace gcd_detail{ + using boost::integer::gcd; + using boost::integer::lcm; + using boost::integer::gcd_range; + using boost::integer::lcm_range; + using boost::integer::gcd_evaluator; + using boost::integer::lcm_evaluator; - // - // some helper functions which really should be constexpr already, but sadly aren't: - // -#ifndef BOOST_NO_CXX14_CONSTEXPR - template - inline constexpr T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T) - { - return a < b ? a : b; - } - template - inline constexpr auto constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) -> decltype(a.swap(b)) - { - return a.swap(b); - } - template - inline constexpr void constexpr_swap(T&a, U& b...) BOOST_GCD_NOEXCEPT(T) - { - T t(static_cast(a)); - a = static_cast(b); - b = static_cast(t); - } -#else - template - inline T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T) - { - return a < b ? a : b; - } - template - inline void constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) - { - using std::swap; - swap(a, b); - } -#endif - - template ::value || -#endif - (std::numeric_limits::is_specialized && !std::numeric_limits::is_signed)> - struct gcd_traits_abs_defaults - { - inline static BOOST_CXX14_CONSTEXPR const T& abs(const T& val) BOOST_GCD_NOEXCEPT(T) { return val; } - }; - template - struct gcd_traits_abs_defaults - { - inline static T BOOST_CXX14_CONSTEXPR abs(const T& val) BOOST_GCD_NOEXCEPT(T) - { - // This sucks, but std::abs is not constexpr :( - return val < 0 ? -val : val; - } - }; - - enum method_type - { - method_euclid = 0, - method_binary = 1, - method_mixed = 2, - }; - - - template - struct gcd_traits_defaults : public gcd_traits_abs_defaults - { - BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(T& val) BOOST_GCD_NOEXCEPT(T) - { - unsigned r = 0; - while(0 == (val & 1u)) - { -#ifdef _MSC_VER // VC++ can't handle operator >>= in constexpr code for some reason - val = val >> 1; -#else - val >>= 1; -#endif - ++r; - } - return r; - } - inline static BOOST_CXX14_CONSTEXPR bool less(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T) - { - return a < b; - } - static const method_type method = std::numeric_limits::is_specialized && std::numeric_limits::is_integer ? method_mixed : method_euclid; - }; - // - // Default gcd_traits just inherits from defaults: - // - template - struct gcd_traits : public gcd_traits_defaults {}; - -#ifdef BOOST_NO_CXX14_CONSTEXPR - // - // Some platforms have fast bitscan operations, that allow us to implement - // make_odd much more efficiently, unfortunately we can't use these if we want - // the functions to be constexpr as the compiler intrinsics aren't constexpr. - // -#if (defined(BOOST_MSVC) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) -#pragma intrinsic(_BitScanForward,) - template <> - struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned find_lsb(unsigned long val) BOOST_NOEXCEPT - { - unsigned long result; - _BitScanForward(&result, val); - return result; - } - BOOST_FORCEINLINE static unsigned make_odd(unsigned long& val) BOOST_NOEXCEPT - { - unsigned result = find_lsb(val); - val >>= result; - return result; - } - }; - -#ifdef _M_X64 -#pragma intrinsic(_BitScanForward64) - template <> - struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned find_lsb(unsigned __int64 mask) BOOST_NOEXCEPT - { - unsigned long result; - _BitScanForward64(&result, mask); - return result; - } - BOOST_FORCEINLINE static unsigned make_odd(unsigned __int64& val) BOOST_NOEXCEPT - { - unsigned result = find_lsb(val); - val >>= result; - return result; - } - }; -#endif - // - // Other integer type are trivial adaptations of the above, - // this works for signed types too, as by the time these functions - // are called, all values are > 0. - // - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(long& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(unsigned int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static signed make_odd(signed char& val)BOOST_NOEXCEPT{ signed result = gcd_traits::find_lsb(val); val >>= result; return result; } }; - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; -#ifndef BOOST_NO_INTRINSIC_WCHAR_T - template <> struct gcd_traits : public gcd_traits_defaults - { BOOST_FORCEINLINE static unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; -#endif -#ifdef _M_X64 - template <> struct gcd_traits<__int64> : public gcd_traits_defaults<__int64> - { BOOST_FORCEINLINE static unsigned make_odd(__int64& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; -#endif - -#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__)) - - template <> - struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned find_lsb(unsigned mask)BOOST_NOEXCEPT - { - return __builtin_ctz(mask); - } - BOOST_FORCEINLINE static unsigned make_odd(unsigned& val)BOOST_NOEXCEPT - { - unsigned result = find_lsb(val); - val >>= result; - return result; - } - }; - template <> - struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned find_lsb(unsigned long mask)BOOST_NOEXCEPT - { - return __builtin_ctzl(mask); - } - BOOST_FORCEINLINE static unsigned make_odd(unsigned long& val)BOOST_NOEXCEPT - { - unsigned result = find_lsb(val); - val >>= result; - return result; - } - }; - template <> - struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned find_lsb(boost::ulong_long_type mask)BOOST_NOEXCEPT - { - return __builtin_ctzll(mask); - } - BOOST_FORCEINLINE static unsigned make_odd(boost::ulong_long_type& val)BOOST_NOEXCEPT - { - unsigned result = find_lsb(val); - val >>= result; - return result; - } - }; - // - // Other integer type are trivial adaptations of the above, - // this works for signed types too, as by the time these functions - // are called, all values are > 0. - // - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(boost::long_long_type& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(long& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(int& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static signed make_odd(signed char& val)BOOST_NOEXCEPT { signed result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; -#ifndef BOOST_NO_INTRINSIC_WCHAR_T - template <> struct gcd_traits : public gcd_traits_defaults - { - BOOST_FORCEINLINE static unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } - }; -#endif -#endif -#endif // BOOST_NO_CXX14_CONSTEXPR - // - // The Mixed Binary Euclid Algorithm - // Sidi Mohamed Sedjelmaci - // Electronic Notes in Discrete Mathematics 35 (2009) 169-176 - // - template - BOOST_CXX14_CONSTEXPR T mixed_binary_gcd(T u, T v) BOOST_GCD_NOEXCEPT(T) - { - if(gcd_traits::less(u, v)) - constexpr_swap(u, v); - - unsigned shifts = 0; - - if(!u) - return v; - if(!v) - return u; - - shifts = constexpr_min(gcd_traits::make_odd(u), gcd_traits::make_odd(v)); - - while(gcd_traits::less(1, v)) - { - u %= v; - v -= u; - if(!u) - return v << shifts; - if(!v) - return u << shifts; - gcd_traits::make_odd(u); - gcd_traits::make_odd(v); - if(gcd_traits::less(u, v)) - constexpr_swap(u, v); - } - return (v == 1 ? v : u) << shifts; } - - /** Stein gcd (aka 'binary gcd') - * - * From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose - */ - template - BOOST_CXX14_CONSTEXPR SteinDomain Stein_gcd(SteinDomain m, SteinDomain n) BOOST_GCD_NOEXCEPT(SteinDomain) - { - BOOST_ASSERT(m >= 0); - BOOST_ASSERT(n >= 0); - if (m == SteinDomain(0)) - return n; - if (n == SteinDomain(0)) - return m; - // m > 0 && n > 0 - int d_m = gcd_traits::make_odd(m); - int d_n = gcd_traits::make_odd(n); - // odd(m) && odd(n) - while (m != n) - { - if (n > m) - constexpr_swap(n, m); - m -= n; - gcd_traits::make_odd(m); - } - // m == n - m <<= constexpr_min(d_m, d_n); - return m; - } - - - /** Euclidean algorithm - * - * From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose - * - */ - template - inline BOOST_CXX14_CONSTEXPR EuclideanDomain Euclid_gcd(EuclideanDomain a, EuclideanDomain b) BOOST_GCD_NOEXCEPT(EuclideanDomain) - { - while (b != EuclideanDomain(0)) - { - a %= b; - constexpr_swap(a, b); - } - return a; - } - - - template - inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c::method == method_mixed, T>::type - optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) - { - return gcd_detail::mixed_binary_gcd(a, b); - } - - template - inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c::method == method_binary, T>::type - optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) - { - return gcd_detail::Stein_gcd(a, b); - } - - template - inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c::method == method_euclid, T>::type - optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) - { - return gcd_detail::Euclid_gcd(a, b); - } - - template - inline BOOST_CXX14_CONSTEXPR T lcm_imp(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T) - { - T temp = boost::math::gcd_detail::optimal_gcd_select(a, b); -#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) - return (temp != T(0)) ? T(a / temp * b) : T(0); -#else - return temp ? T(a / temp * b) : T(0); -#endif - } - -} // namespace detail - - -template -inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer) -{ - return gcd_detail::optimal_gcd_select(static_cast(gcd_detail::gcd_traits::abs(a)), static_cast(gcd_detail::gcd_traits::abs(b))); } -template -inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer) -{ - return gcd_detail::lcm_imp(static_cast(gcd_detail::gcd_traits::abs(a)), static_cast(gcd_detail::gcd_traits::abs(b))); -} -#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES -template -inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b, Args const&... args) BOOST_GCD_NOEXCEPT(Integer) -{ - Integer t = gcd(b, args...); - return t == 1 ? 1 : gcd(a, t); -} - -template -inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b, Args const&... args) BOOST_GCD_NOEXCEPT(Integer) -{ - return lcm(a, lcm(b, args...)); -} -#endif -// -// Special handling for rationals: -// -template -inline typename boost::enable_if_c::is_specialized, boost::rational >::type gcd(boost::rational const &a, boost::rational const &b) -{ - return boost::rational(static_cast(gcd(a.numerator(), b.numerator())), static_cast(lcm(a.denominator(), b.denominator()))); -} - -template -inline typename boost::enable_if_c::is_specialized, boost::rational >::type lcm(boost::rational const &a, boost::rational const &b) -{ - return boost::rational(static_cast(lcm(a.numerator(), b.numerator())), static_cast(gcd(a.denominator(), b.denominator()))); -} -/** - * Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 - * Chapter 4.5.2, Algorithm C: Greatest common divisor of n integers. - * - * Knuth counts down from n to zero but we naturally go from first to last. - * We also return the termination position because it might be useful to know. - * - * Partly by quirk, partly by design, this algorithm is defined for n = 1, - * because the gcd of {x} is x. It is not defined for n = 0. - * - * @tparam I Input iterator. - * @return The gcd of the range and the iterator position at termination. - */ -template -std::pair::value_type, I> -gcd_range(I first, I last) BOOST_GCD_NOEXCEPT(I) -{ - BOOST_ASSERT(first != last); - typedef typename std::iterator_traits::value_type T; - - T d = *first++; - while (d != T(1) && first != last) - { - d = gcd(d, *first); - first++; - } - return std::make_pair(d, first); -} -template -std::pair::value_type, I> -lcm_range(I first, I last) BOOST_GCD_NOEXCEPT(I) -{ - BOOST_ASSERT(first != last); - typedef typename std::iterator_traits::value_type T; - - T d = *first++; - while (d != T(1) && first != last) - { - d = lcm(d, *first); - first++; - } - return std::make_pair(d, first); -} - -template < typename IntegerType > -struct gcd_evaluator -#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL - : public std::binary_function -#endif -{ -#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL - typedef IntegerType first_argument_type; - typedef IntegerType second_argument_type; - typedef IntegerType result_type; -#endif - IntegerType operator()(IntegerType const &a, IntegerType const &b)const - { - return boost::math::gcd(a, b); - } -}; - -template < typename IntegerType > -struct lcm_evaluator -#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL - : public std::binary_function -#endif -{ -#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL - typedef IntegerType first_argument_type; - typedef IntegerType second_argument_type; - typedef IntegerType result_type; -#endif - IntegerType operator()(IntegerType const &a, IntegerType const &b)const - { - return boost::math::lcm(a, b); - } -}; - -} // namespace math -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - #endif // BOOST_MATH_COMMON_FACTOR_RT_HPP diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index bf4cc577b..ccaeeb0f0 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -386,24 +386,6 @@ BOOST_AUTO_TEST_CASE( gcd_static_test ) BOOST_CHECK( (static_gcd< 7, 49>::value) == 7 ); } -BOOST_AUTO_TEST_CASE(gcd_method_test) -{ - // Verify that the 3 different methods all yield the same result: - boost::random::mt19937 gen; - boost::random::uniform_int_distribution d(0, ((std::numeric_limits::max)() / 2)); - - for (unsigned int i = 0; i < 10000; ++i) - { - int v1 = d(gen); - int v2 = d(gen); - int g = boost::math::gcd_detail::Euclid_gcd(v1, v2); - BOOST_CHECK(v1 % g == 0); - BOOST_CHECK(v2 % g == 0); - BOOST_CHECK_EQUAL(g, boost::math::gcd_detail::mixed_binary_gcd(v1, v2)); - BOOST_CHECK_EQUAL(g, boost::math::gcd_detail::Stein_gcd(v1, v2)); - } -} - BOOST_AUTO_TEST_SUITE_END() @@ -557,90 +539,3 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(gcd_and_lcm_on_rationals, T, signed_test_types) BOOST_AUTO_TEST_SUITE_END() -// -// Compile time checks come last: -// -#ifndef BOOST_NO_CXX14_CONSTEXPR - -void test_constexpr1() -{ - constexpr const boost::int64_t i = 347 * 463 * 727; - constexpr const boost::int64_t j = 191 * 347 * 281; - - constexpr const boost::int64_t k = boost::math::gcd(i, j); - constexpr const boost::int64_t l = boost::math::lcm(i, j); - - static_assert(k == 347, "Expected result not found in constexpr gcd."); - static_assert(l == 6268802158037, "Expected result not found in constexpr lcm."); -} - -void test_constexpr2() -{ - constexpr const boost::uint64_t i = 347 * 463 * 727; - constexpr const boost::uint64_t j = 191 * 347 * 281; - - constexpr const boost::uint64_t k = boost::math::gcd(i, j); - constexpr const boost::uint64_t l = boost::math::lcm(i, j); - - static_assert(k == 347, "Expected result not found in constexpr gcd."); - static_assert(l == 6268802158037, "Expected result not found in constexpr lcm."); -} - -void test_constexpr3() -{ - constexpr const boost::uint64_t i = 347 * 463 * 727; - constexpr const boost::uint64_t j = 191 * 347 * 281; - - constexpr const boost::uint64_t k = boost::math::gcd_detail::Euclid_gcd(i, j); - - static_assert(k == 347, "Expected result not found in constexpr gcd."); -} - -void test_constexpr4() -{ - constexpr const boost::uint64_t i = 347 * 463 * 727; - constexpr const boost::uint64_t j = 191 * 347 * 281; - - constexpr const boost::uint64_t k = boost::math::gcd_detail::mixed_binary_gcd(i, j); - - static_assert(k == 347, "Expected result not found in constexpr gcd."); -} - -void test_constexpr5() -{ - constexpr const boost::uint64_t i = 347 * 463 * 727; - constexpr const boost::uint64_t j = 191 * 347 * 281; - - constexpr const boost::uint64_t k = boost::math::gcd_detail::Stein_gcd(i, j); - - static_assert(k == 347, "Expected result not found in constexpr gcd."); -} -#endif - -#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) -// -// These tests don't pass with GCC-4.x: -// -#if !defined(BOOST_GCC) || (BOOST_GCC >= 50000) - -void test_noexcept(unsigned char a, unsigned char b) -{ - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); -#ifndef _MSC_VER - // This generates an internal compiler error if enabled as well as the following test: - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); -#endif - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); - static_assert(noexcept(boost::math::gcd(static_cast(a), static_cast(b))), "Expected a noexcept function."); -} - -#endif -#endif - diff --git a/test/test_polynomial.cpp b/test/test_polynomial.cpp index d1b2cb17b..ec7d300d2 100644 --- a/test/test_polynomial.cpp +++ b/test/test_polynomial.cpp @@ -20,7 +20,7 @@ using namespace boost::math; using namespace boost::math::tools; using namespace std; -using boost::math::gcd_detail::Euclid_gcd; +using boost::integer::gcd_detail::Euclid_gcd; using boost::math::tools::subresultant_gcd; template