From 5f810b275473215c15919a67b23dbb3fed39eacc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 29 Nov 2001 21:42:58 +0000 Subject: [PATCH 01/43] Daryle Walker's GCD library submission [SVN r11814] --- include/boost/math/common_factor.hpp | 464 +++++++++++++++++++++++++++ test/common_factor_test.cpp | 115 +++++++ 2 files changed, 579 insertions(+) create mode 100644 include/boost/math/common_factor.hpp create mode 100644 test/common_factor_test.cpp diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp new file mode 100644 index 0000000..4be4315 --- /dev/null +++ b/include/boost/math/common_factor.hpp @@ -0,0 +1,464 @@ +// Boost common_factor.hpp header file -------------------------------------// + +// (C) Copyright Daryle Walker, Stephen Cleary, Paul Moore 2001. Permission +// to copy, use, modify, sell and distribute this software is granted provided +// this copyright notice appears in all copies. This software is provided "as +// is" without express or implied warranty, and with no claim as to its +// suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_HPP +#define BOOST_MATH_COMMON_FACTOR_HPP + +#include // self include + +#include // for BOOST_STATIC_CONSTANT, etc. +#include // for std::numeric_limits + + +namespace boost +{ +namespace math +{ + + +// Forward declarations for function templates -----------------------------// + +template < typename IntegerType > + IntegerType gcd( IntegerType const &a, IntegerType const &b ); + +template < typename IntegerType > + IntegerType lcm( IntegerType const &a, IntegerType const &b ); + + +// Greatest common divisor evaluator class declaration ---------------------// + +template < typename IntegerType > +class gcd_evaluator +{ +public: + // Types + typedef IntegerType result_type, first_argument_type, second_argument_type; + + // Function object interface + result_type operator ()( first_argument_type const &a, + second_argument_type const &b ) const; + +}; // boost::math::gcd_evaluator + + +// Least common multiple evaluator class declaration -----------------------// + +template < typename IntegerType > +class lcm_evaluator +{ +public: + // Types + typedef IntegerType result_type, first_argument_type, second_argument_type; + + // Function object interface + result_type operator ()( first_argument_type const &a, + second_argument_type const &b ) const; + +}; // boost::math::lcm_evaluator + + +// Implementation details --------------------------------------------------// + +namespace detail +{ +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // Build GCD with Euclid's recursive algorithm + template < unsigned long Value1, unsigned long Value2 > + struct static_gcd_helper_t + { + private: + BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 ); + BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 ); + + #ifndef __BORLANDC__ + #define BOOST_DETAIL_GCD_HELPER_VAL(Value) 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( unsigned long, value = next_step_type::value ); + }; + + // Non-recursive case + template < unsigned long Value1 > + struct static_gcd_helper_t< Value1, 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); + }; +#else + // Use inner class template workaround from Peter Dimov + template < unsigned long Value1 > + struct static_gcd_helper2_t + { + template < unsigned long Value2 > + struct helper + { + BOOST_STATIC_CONSTANT( unsigned long, value + = static_gcd_helper2_t::helper::value ); + }; + + template < > + struct helper< 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); + }; + }; + + // Special case + template < > + struct static_gcd_helper2_t< 0UL > + { + template < unsigned long Value2 > + struct helper + { + BOOST_STATIC_CONSTANT( unsigned long, value = Value2 ); + }; + }; + + // Build the GCD from the above template(s) + template < unsigned long Value1, unsigned long Value2 > + struct static_gcd_helper_t + { + BOOST_STATIC_CONSTANT( unsigned long, value + = static_gcd_helper2_t::helper::value ); + }; +#endif + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // Build the LCM from the GCD + template < unsigned long Value1, unsigned long Value2 > + struct static_lcm_helper_t + { + typedef static_gcd_helper_t gcd_type; + + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value + * Value2 ); + }; + + // Special case for zero-GCD values + template < > + struct static_lcm_helper_t< 0UL, 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + }; +#else + // Adapt GCD's inner class template workaround for LCM + template < unsigned long Value1 > + struct static_lcm_helper2_t + { + template < unsigned long Value2 > + struct helper + { + typedef static_gcd_helper_t gcd_type; + + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 + / gcd_type::value * Value2 ); + }; + + template < > + struct helper< 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + }; + }; + + // Special case + template < > + struct static_lcm_helper2_t< 0UL > + { + template < unsigned long Value2 > + struct helper + { + BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + }; + }; + + // Build the LCM from the above template(s) + template < unsigned long Value1, unsigned long Value2 > + struct static_lcm_helper_t + { + BOOST_STATIC_CONSTANT( unsigned long, value + = static_lcm_helper2_t::helper::value ); + }; +#endif + + // Greatest common divisor for rings (including unsigned integers) + template < typename RingType > + RingType + gcd_euclidean + ( + RingType a, + RingType b + ) + { + // Avoid repeated construction + #ifndef __BORLANDC__ + RingType const zero = static_cast( 0 ); + #else + RingType zero = static_cast( 0 ); + #endif + + // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)] + while ( true ) + { + if ( a == zero ) + return b; + b %= a; + + if ( b == zero ) + return a; + a %= b; + } + } + + // Greatest common divisor for (signed) integers + template < typename IntegerType > + inline + IntegerType + gcd_integer + ( + IntegerType const & a, + IntegerType const & b + ) + { + // Avoid repeated construction + IntegerType const zero = static_cast( 0 ); + IntegerType const result = gcd_euclidean( a, b ); + + return ( result < zero ) ? -result : result; + } + + // Least common multiple for rings (including unsigned integers) + template < typename RingType > + inline + RingType + lcm_euclidean + ( + RingType const & a, + RingType const & b + ) + { + RingType const zero = static_cast( 0 ); + RingType const temp = gcd_euclidean( a, b ); + + return ( temp != zero ) ? ( a / temp * b ) : zero; + } + + // Least common multiple for (signed) integers + template < typename IntegerType > + inline + IntegerType + lcm_integer + ( + IntegerType const & a, + IntegerType const & b + ) + { + // Avoid repeated construction + IntegerType const zero = static_cast( 0 ); + IntegerType const result = lcm_euclidean( a, b ); + + return ( result < zero ) ? -result : result; + } + + // Function objects to find the best way of computing GCD or LCM + template < typename T > + struct gcd_optimal_evaluator + { + template < bool IsSpecialized, bool IsSigned > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return gcd_euclidean( a, b ); + } + }; + + template < > + struct helper< true, true > + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; + + T operator ()( T const &a, T const &b ) + { + typedef ::std::numeric_limits limits_type; + + typedef helper + helper_type; + + helper_type solver; + + return solver( a, b ); + } + }; + + template < typename T > + struct lcm_optimal_evaluator + { + template < bool IsSpecialized, bool IsSigned > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return lcm_euclidean( a, b ); + } + }; + + template < > + struct helper< true, true > + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; + + T operator ()( T const &a, T const &b ) + { + typedef ::std::numeric_limits limits_type; + + typedef helper + helper_type; + + helper_type solver; + + return solver( a, b ); + } + }; + + // Functions to find the GCD or LCM in the best way + template < typename T > + inline + gcd_optimal + ( + T const & a, + T const & b + ) + { + gcd_optimal_evaluator solver; + + return solver( a, b ); + } + + template < typename T > + inline + lcm_optimal + ( + T const & a, + T const & b + ) + { + lcm_optimal_evaluator solver; + + return solver( a, b ); + } + +} // namespace detail + + +// Compile-time greatest common divisor evaluator class declaration --------// + +template < unsigned long Value1, unsigned long Value2 > +struct static_gcd +{ + BOOST_STATIC_CONSTANT( unsigned long, value + = (detail::static_gcd_helper_t::value) ); + +}; // boost::math::static_gcd + + +// Compile-time least common multiple evaluator class declaration ----------// + +template < unsigned long Value1, unsigned long Value2 > +struct static_lcm +{ + BOOST_STATIC_CONSTANT( unsigned long, value + = (detail::static_lcm_helper_t::value) ); + +}; // boost::math::static_lcm + + +// Greatest common divisor evaluator member function definition ------------// + +template < typename IntegerType > +inline +typename gcd_evaluator::result_type +gcd_evaluator::operator () +( + first_argument_type const & a, + second_argument_type const & b +) const +{ + return detail::gcd_optimal( a, b ); +} + + +// Least common multiple evaluator member function definition --------------// + +template < typename IntegerType > +inline +typename lcm_evaluator::result_type +lcm_evaluator::operator () +( + first_argument_type const & a, + second_argument_type const & b +) const +{ + return detail::lcm_optimal( a, b ); +} + + +// Greatest common divisor and least common multiple function definitions --// + +template < typename IntegerType > +inline +IntegerType +gcd +( + IntegerType const & a, + IntegerType const & b +) +{ + gcd_evaluator solver; + + return solver( a, b ); +} + +template < typename IntegerType > +inline +IntegerType +lcm +( + IntegerType const & a, + IntegerType const & b +) +{ + lcm_evaluator solver; + + return solver( a, b ); +} + + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_COMMON_FACTOR_HPP diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp new file mode 100644 index 0000000..d1c53a3 --- /dev/null +++ b/test/common_factor_test.cpp @@ -0,0 +1,115 @@ +// Boost GCD & LCM common_factor.hpp test program --------------------------// + +// (C) Copyright Daryle Walker 2001. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright +// notice appears in all copies. This software is provided "as is" without +// express or implied warranty, and with no claim as to its suitability for +// any purpose. + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 07 Nov 2001 Initial version (Daryle Walker) + +#define BOOST_INCLUDE_MAIN + +#include // for BOOST_MSVC +#include // for boost::exit_success +#include // for boost::math::gcd, etc. +#include // for main, BOOST_TEST + +#include // for std::cout (std::endl indirectly) + + +// Control to determine what kind of built-in integers are used +#ifndef CONTROL_INT_TYPE +#define CONTROL_INT_TYPE int +#endif + + +// Main testing function +int +test_main +( + int , // "argc" is unused + char * [] // "argv" is unused +) +{ + using std::cout; + using std::endl; + +#ifndef BOOST_MSVC + using boost::math::gcd; + using boost::math::static_gcd; + using boost::math::lcm; + using boost::math::static_lcm; +#else + using namespace boost::math; +#endif + + typedef CONTROL_INT_TYPE int_type; + + // GCD tests + cout << "Doing tests on gcd." << endl; + + BOOST_TEST( gcd( 1, -1) == 1 ); + BOOST_TEST( gcd( -1, 1) == 1 ); + BOOST_TEST( gcd( 1, 1) == 1 ); + BOOST_TEST( gcd( -1, -1) == 1 ); + BOOST_TEST( gcd( 0, 0) == 0 ); + BOOST_TEST( gcd( 7, 0) == 7 ); + BOOST_TEST( gcd( 0, 9) == 9 ); + BOOST_TEST( gcd( -7, 0) == 7 ); + BOOST_TEST( gcd( 0, -9) == 9 ); + BOOST_TEST( gcd( 42, 30) == 6 ); + BOOST_TEST( gcd( 6, -9) == 3 ); + BOOST_TEST( gcd(-10, -10) == 10 ); + BOOST_TEST( gcd(-25, -10) == 5 ); + BOOST_TEST( gcd( 3, 7) == 1 ); + BOOST_TEST( gcd( 8, 9) == 1 ); + BOOST_TEST( gcd( 7, 49) == 7 ); + + cout << "Doing tests on static_gcd." << endl; + + BOOST_TEST( (static_gcd< 1, 1>::value) == 1 ); + BOOST_TEST( (static_gcd< 0, 0>::value) == 0 ); + BOOST_TEST( (static_gcd< 7, 0>::value) == 7 ); + BOOST_TEST( (static_gcd< 0, 9>::value) == 9 ); + BOOST_TEST( (static_gcd<42, 30>::value) == 6 ); + BOOST_TEST( (static_gcd< 3, 7>::value) == 1 ); + BOOST_TEST( (static_gcd< 8, 9>::value) == 1 ); + BOOST_TEST( (static_gcd< 7, 49>::value) == 7 ); + + // LCM tests + cout << "Doing tests on lcm." << endl; + + BOOST_TEST( lcm( 1, -1) == 1 ); + BOOST_TEST( lcm( -1, 1) == 1 ); + BOOST_TEST( lcm( 1, 1) == 1 ); + BOOST_TEST( lcm( -1, -1) == 1 ); + BOOST_TEST( lcm( 0, 0) == 0 ); + BOOST_TEST( lcm( 6, 0) == 0 ); + BOOST_TEST( lcm( 0, 7) == 0 ); + BOOST_TEST( lcm( -5, 0) == 0 ); + BOOST_TEST( lcm( 0, -4) == 0 ); + BOOST_TEST( lcm( 18, 30) == 90 ); + BOOST_TEST( lcm( -6, 9) == 18 ); + BOOST_TEST( lcm(-10, -10) == 10 ); + BOOST_TEST( lcm( 25, -10) == 50 ); + BOOST_TEST( lcm( 3, 7) == 21 ); + BOOST_TEST( lcm( 8, 9) == 72 ); + BOOST_TEST( lcm( 7, 49) == 49 ); + + cout << "Doing tests on static_lcm." << endl; + + BOOST_TEST( (static_lcm< 1, 1>::value) == 1 ); + BOOST_TEST( (static_lcm< 0, 0>::value) == 0 ); + BOOST_TEST( (static_lcm< 6, 0>::value) == 0 ); + BOOST_TEST( (static_lcm< 0, 7>::value) == 0 ); + BOOST_TEST( (static_lcm<18, 30>::value) == 90 ); + BOOST_TEST( (static_lcm< 3, 7>::value) == 21 ); + BOOST_TEST( (static_lcm< 8, 9>::value) == 72 ); + BOOST_TEST( (static_lcm< 7, 49>::value) == 49 ); + + return boost::exit_success; +} From f6738d210c8b6f42b30f4e2de8cbb713af4a26e8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 5 Dec 2001 20:56:26 +0000 Subject: [PATCH 02/43] fix errors (from Daryle Walker) [SVN r11935] --- include/boost/math/common_factor.hpp | 82 ++++++++++++++-------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp index 4be4315..af984f9 100644 --- a/include/boost/math/common_factor.hpp +++ b/include/boost/math/common_factor.hpp @@ -276,33 +276,33 @@ namespace detail } // Function objects to find the best way of computing GCD or LCM + template < typename T, bool IsSpecialized, bool IsSigned > + struct gcd_optimal_evaluator_helper + { + T operator ()( T const &a, T const &b ) + { + return gcd_euclidean( a, b ); + } + }; + + template < typename T > + struct gcd_optimal_evaluator_helper< T, true, true > + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; + template < typename T > struct gcd_optimal_evaluator { - template < bool IsSpecialized, bool IsSigned > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return gcd_euclidean( a, b ); - } - }; - - template < > - struct helper< true, true > - { - T operator ()( T const &a, T const &b ) - { - return gcd_integer( a, b ); - } - }; - T operator ()( T const &a, T const &b ) { typedef ::std::numeric_limits limits_type; - typedef helper - helper_type; + typedef gcd_optimal_evaluator_helper helper_type; helper_type solver; @@ -310,33 +310,33 @@ namespace detail } }; + template < typename T, bool IsSpecialized, bool IsSigned > + struct lcm_optimal_evaluator_helper + { + T operator ()( T const &a, T const &b ) + { + return lcm_euclidean( a, b ); + } + }; + + template < typename T > + struct lcm_optimal_evaluator_helper< T, true, true > + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; + template < typename T > struct lcm_optimal_evaluator { - template < bool IsSpecialized, bool IsSigned > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return lcm_euclidean( a, b ); - } - }; - - template < > - struct helper< true, true > - { - T operator ()( T const &a, T const &b ) - { - return lcm_integer( a, b ); - } - }; - T operator ()( T const &a, T const &b ) { typedef ::std::numeric_limits limits_type; - typedef helper - helper_type; + typedef lcm_optimal_evaluator_helper helper_type; helper_type solver; @@ -347,6 +347,7 @@ namespace detail // Functions to find the GCD or LCM in the best way template < typename T > inline + T gcd_optimal ( T const & a, @@ -360,6 +361,7 @@ namespace detail template < typename T > inline + T lcm_optimal ( T const & a, From 6a8080014ac7a871cb430f290720323be82d4871 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 11 Dec 2001 04:59:26 +0000 Subject: [PATCH 03/43] Integrated MSVC fixes from Daryle [SVN r12012] --- include/boost/math/common_factor.hpp | 92 +++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 10 deletions(-) diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp index af984f9..0db82bc 100644 --- a/include/boost/math/common_factor.hpp +++ b/include/boost/math/common_factor.hpp @@ -134,7 +134,8 @@ namespace detail struct static_gcd_helper_t { BOOST_STATIC_CONSTANT( unsigned long, value - = static_gcd_helper2_t::helper::value ); + = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE + helper::value ); }; #endif @@ -192,7 +193,8 @@ namespace detail struct static_lcm_helper_t { BOOST_STATIC_CONSTANT( unsigned long, value - = static_lcm_helper2_t::helper::value ); + = static_lcm_helper2_t::BOOST_NESTED_TEMPLATE + helper::value ); }; #endif @@ -276,8 +278,9 @@ namespace detail } // Function objects to find the best way of computing GCD or LCM +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > - struct gcd_optimal_evaluator_helper + struct gcd_optimal_evaluator_helper_t { T operator ()( T const &a, T const &b ) { @@ -286,13 +289,47 @@ namespace detail }; template < typename T > - struct gcd_optimal_evaluator_helper< T, true, true > + struct gcd_optimal_evaluator_helper_t< T, true, true > { T operator ()( T const &a, T const &b ) { return gcd_integer( a, b ); } }; +#else + template < bool IsSpecialized, bool IsSigned > + struct gcd_optimal_evaluator_helper2_t + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return gcd_euclidean( a, b ); + } + }; + }; + + template < > + struct gcd_optimal_evaluator_helper2_t< true, true > + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; + }; + + template < typename T, bool IsSpecialized, bool IsSigned > + struct gcd_optimal_evaluator_helper_t + : gcd_optimal_evaluator_helper2_t + ::BOOST_NESTED_TEMPLATE helper + { + }; +#endif template < typename T > struct gcd_optimal_evaluator @@ -301,8 +338,8 @@ namespace detail { typedef ::std::numeric_limits limits_type; - typedef gcd_optimal_evaluator_helper helper_type; + typedef gcd_optimal_evaluator_helper_t helper_type; helper_type solver; @@ -310,8 +347,9 @@ namespace detail } }; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > - struct lcm_optimal_evaluator_helper + struct lcm_optimal_evaluator_helper_t { T operator ()( T const &a, T const &b ) { @@ -320,13 +358,47 @@ namespace detail }; template < typename T > - struct lcm_optimal_evaluator_helper< T, true, true > + struct lcm_optimal_evaluator_helper_t< T, true, true > { T operator ()( T const &a, T const &b ) { return lcm_integer( a, b ); } }; +#else + template < bool IsSpecialized, bool IsSigned > + struct lcm_optimal_evaluator_helper2_t + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return lcm_euclidean( a, b ); + } + }; + }; + + template < > + struct lcm_optimal_evaluator_helper2_t< true, true > + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; + }; + + template < typename T, bool IsSpecialized, bool IsSigned > + struct lcm_optimal_evaluator_helper_t + : lcm_optimal_evaluator_helper2_t + ::BOOST_NESTED_TEMPLATE helper + { + }; +#endif template < typename T > struct lcm_optimal_evaluator @@ -335,8 +407,8 @@ namespace detail { typedef ::std::numeric_limits limits_type; - typedef lcm_optimal_evaluator_helper helper_type; + typedef lcm_optimal_evaluator_helper_t helper_type; helper_type solver; From 82ad7a9edb3fecda9c2295f187484d6a0f09274b Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 6 May 2002 10:35:57 +0000 Subject: [PATCH 04/43] Added fixes for the case that BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS is defined. [SVN r13684] --- include/boost/math/common_factor.hpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp index 0db82bc..10196fe 100644 --- a/include/boost/math/common_factor.hpp +++ b/include/boost/math/common_factor.hpp @@ -278,6 +278,7 @@ namespace detail } // Function objects to find the best way of computing GCD or LCM +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > struct gcd_optimal_evaluator_helper_t @@ -346,7 +347,18 @@ namespace detail return solver( a, b ); } }; +#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + template < typename T > + struct gcd_optimal_evaluator + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; +#endif +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > struct lcm_optimal_evaluator_helper_t @@ -415,6 +427,16 @@ namespace detail return solver( a, b ); } }; +#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + template < typename T > + struct lcm_optimal_evaluator + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; +#endif // Functions to find the GCD or LCM in the best way template < typename T > From bb16ad8ea0a7e475d202db71eafc94e84d8f7ab9 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 6 May 2002 10:36:32 +0000 Subject: [PATCH 05/43] Added tests for unsigned int types [SVN r13685] --- test/common_factor_test.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index d1c53a3..e068efd 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -48,6 +48,7 @@ test_main #endif typedef CONTROL_INT_TYPE int_type; + typedef unsigned CONTROL_INT_TYPE uint_type; // GCD tests cout << "Doing tests on gcd." << endl; @@ -69,6 +70,18 @@ test_main BOOST_TEST( gcd( 8, 9) == 1 ); BOOST_TEST( gcd( 7, 49) == 7 ); + // GCD tests + cout << "Doing tests on unsigned-gcd." << endl; + + BOOST_TEST( gcd( 1u, 1u) == 1u ); + BOOST_TEST( gcd( 0u, 0u) == 0u ); + BOOST_TEST( gcd( 7u, 0u) == 7u ); + BOOST_TEST( gcd( 0u, 9u) == 9u ); + BOOST_TEST( gcd( 42u, 30u) == 6u ); + BOOST_TEST( gcd( 3u, 7u) == 1u ); + BOOST_TEST( gcd( 8u, 9u) == 1u ); + BOOST_TEST( gcd( 7u, 49u) == 7u ); + cout << "Doing tests on static_gcd." << endl; BOOST_TEST( (static_gcd< 1, 1>::value) == 1 ); @@ -100,6 +113,17 @@ test_main BOOST_TEST( lcm( 8, 9) == 72 ); BOOST_TEST( lcm( 7, 49) == 49 ); + cout << "Doing tests on unsigned-lcm." << endl; + + BOOST_TEST( lcm( 1u, 1u) == 1u ); + BOOST_TEST( lcm( 0u, 0u) == 0u ); + BOOST_TEST( lcm( 6u, 0u) == 0u ); + BOOST_TEST( lcm( 0u, 7u) == 0u ); + BOOST_TEST( lcm( 18u, 30u) == 90u ); + BOOST_TEST( lcm( 3u, 7u) == 21u ); + BOOST_TEST( lcm( 8u, 9u) == 72u ); + BOOST_TEST( lcm( 7u, 49u) == 49u ); + cout << "Doing tests on static_lcm." << endl; BOOST_TEST( (static_lcm< 1, 1>::value) == 1 ); From 56bd3fd0b34e8eb75d45a072836e5f3ff4b46929 Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Tue, 2 Jul 2002 07:51:48 +0000 Subject: [PATCH 06/43] Moved the Compile-Time and Run-Time components to separate headers [SVN r14272] --- include/boost/math/common_factor_ct.hpp | 188 +++++++++++ include/boost/math/common_factor_rt.hpp | 408 ++++++++++++++++++++++++ 2 files changed, 596 insertions(+) create mode 100644 include/boost/math/common_factor_ct.hpp create mode 100644 include/boost/math/common_factor_rt.hpp diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp new file mode 100644 index 0000000..d116c4b --- /dev/null +++ b/include/boost/math/common_factor_ct.hpp @@ -0,0 +1,188 @@ +// Boost common_factor_ct.hpp header file ----------------------------------// + +// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002. Permission to +// copy, use, modify, sell and distribute this software is granted provided +// this copyright notice appears in all copies. This software is provided "as +// is" without express or implied warranty, and with no claim as to its +// suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP +#define BOOST_MATH_COMMON_FACTOR_CT_HPP + +#include // self include + +#include // for BOOST_STATIC_CONSTANT, etc. + + +namespace boost +{ +namespace math +{ + + +// Implementation details --------------------------------------------------// + +namespace detail +{ +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // Build GCD with Euclid's recursive algorithm + template < unsigned long Value1, unsigned long Value2 > + struct static_gcd_helper_t + { + private: + BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 ); + BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 ); + + #ifndef __BORLANDC__ + #define BOOST_DETAIL_GCD_HELPER_VAL(Value) 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( unsigned long, value = next_step_type::value ); + }; + + // Non-recursive case + template < unsigned long Value1 > + struct static_gcd_helper_t< Value1, 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); + }; +#else + // Use inner class template workaround from Peter Dimov + template < unsigned long Value1 > + struct static_gcd_helper2_t + { + template < unsigned long Value2 > + struct helper + { + BOOST_STATIC_CONSTANT( unsigned long, value + = static_gcd_helper2_t::helper::value ); + }; + + template < > + struct helper< 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); + }; + }; + + // Special case + template < > + struct static_gcd_helper2_t< 0UL > + { + template < unsigned long Value2 > + struct helper + { + BOOST_STATIC_CONSTANT( unsigned long, value = Value2 ); + }; + }; + + // Build the GCD from the above template(s) + template < unsigned long Value1, unsigned long Value2 > + struct static_gcd_helper_t + { + BOOST_STATIC_CONSTANT( unsigned long, value + = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE + helper::value ); + }; +#endif + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // Build the LCM from the GCD + template < unsigned long Value1, unsigned long Value2 > + struct static_lcm_helper_t + { + typedef static_gcd_helper_t gcd_type; + + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value + * Value2 ); + }; + + // Special case for zero-GCD values + template < > + struct static_lcm_helper_t< 0UL, 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + }; +#else + // Adapt GCD's inner class template workaround for LCM + template < unsigned long Value1 > + struct static_lcm_helper2_t + { + template < unsigned long Value2 > + struct helper + { + typedef static_gcd_helper_t gcd_type; + + BOOST_STATIC_CONSTANT( unsigned long, value = Value1 + / gcd_type::value * Value2 ); + }; + + template < > + struct helper< 0UL > + { + BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + }; + }; + + // Special case + template < > + struct static_lcm_helper2_t< 0UL > + { + template < unsigned long Value2 > + struct helper + { + BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + }; + }; + + // Build the LCM from the above template(s) + template < unsigned long Value1, unsigned long Value2 > + struct static_lcm_helper_t + { + BOOST_STATIC_CONSTANT( unsigned long, value + = static_lcm_helper2_t::BOOST_NESTED_TEMPLATE + helper::value ); + }; +#endif + +} // namespace detail + + +// Compile-time greatest common divisor evaluator class declaration --------// + +template < unsigned long Value1, unsigned long Value2 > +struct static_gcd +{ + BOOST_STATIC_CONSTANT( unsigned long, value + = (detail::static_gcd_helper_t::value) ); + +}; // boost::math::static_gcd + + +// Compile-time least common multiple evaluator class declaration ----------// + +template < unsigned long Value1, unsigned long Value2 > +struct static_lcm +{ + BOOST_STATIC_CONSTANT( unsigned long, value + = (detail::static_lcm_helper_t::value) ); + +}; // boost::math::static_lcm + + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_COMMON_FACTOR_CT_HPP diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp new file mode 100644 index 0000000..5b8cd45 --- /dev/null +++ b/include/boost/math/common_factor_rt.hpp @@ -0,0 +1,408 @@ +// Boost common_factor_rt.hpp header file ----------------------------------// + +// (C) Copyright Daryle Walker and Paul Moore 2001-2002. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its suitability +// for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP +#define BOOST_MATH_COMMON_FACTOR_RT_HPP + +#include // self include + +#include // for BOOST_NESTED_TEMPLATE, etc. +#include // for std::numeric_limits + + +namespace boost +{ +namespace math +{ + + +// Forward declarations for function templates -----------------------------// + +template < typename IntegerType > + IntegerType gcd( IntegerType const &a, IntegerType const &b ); + +template < typename IntegerType > + IntegerType lcm( IntegerType const &a, IntegerType const &b ); + + +// Greatest common divisor evaluator class declaration ---------------------// + +template < typename IntegerType > +class gcd_evaluator +{ +public: + // Types + typedef IntegerType result_type, first_argument_type, second_argument_type; + + // Function object interface + result_type operator ()( first_argument_type const &a, + second_argument_type const &b ) const; + +}; // boost::math::gcd_evaluator + + +// Least common multiple evaluator class declaration -----------------------// + +template < typename IntegerType > +class lcm_evaluator +{ +public: + // Types + typedef IntegerType result_type, first_argument_type, second_argument_type; + + // Function object interface + result_type operator ()( first_argument_type const &a, + second_argument_type const &b ) const; + +}; // boost::math::lcm_evaluator + + +// Implementation details --------------------------------------------------// + +namespace detail +{ + // Greatest common divisor for rings (including unsigned integers) + template < typename RingType > + RingType + gcd_euclidean + ( + RingType a, + RingType b + ) + { + // Avoid repeated construction + #ifndef __BORLANDC__ + RingType const zero = static_cast( 0 ); + #else + RingType zero = static_cast( 0 ); + #endif + + // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)] + while ( true ) + { + if ( a == zero ) + return b; + b %= a; + + if ( b == zero ) + return a; + a %= b; + } + } + + // Greatest common divisor for (signed) integers + template < typename IntegerType > + inline + IntegerType + gcd_integer + ( + IntegerType const & a, + IntegerType const & b + ) + { + // Avoid repeated construction + IntegerType const zero = static_cast( 0 ); + IntegerType const result = gcd_euclidean( a, b ); + + return ( result < zero ) ? -result : result; + } + + // Least common multiple for rings (including unsigned integers) + template < typename RingType > + inline + RingType + lcm_euclidean + ( + RingType const & a, + RingType const & b + ) + { + RingType const zero = static_cast( 0 ); + RingType const temp = gcd_euclidean( a, b ); + + return ( temp != zero ) ? ( a / temp * b ) : zero; + } + + // Least common multiple for (signed) integers + template < typename IntegerType > + inline + IntegerType + lcm_integer + ( + IntegerType const & a, + IntegerType const & b + ) + { + // Avoid repeated construction + IntegerType const zero = static_cast( 0 ); + IntegerType const result = lcm_euclidean( a, b ); + + return ( result < zero ) ? -result : result; + } + + // Function objects to find the best way of computing GCD or LCM +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template < typename T, bool IsSpecialized, bool IsSigned > + struct gcd_optimal_evaluator_helper_t + { + T operator ()( T const &a, T const &b ) + { + return gcd_euclidean( a, b ); + } + }; + + template < typename T > + struct gcd_optimal_evaluator_helper_t< T, true, true > + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; +#else + template < bool IsSpecialized, bool IsSigned > + struct gcd_optimal_evaluator_helper2_t + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return gcd_euclidean( a, b ); + } + }; + }; + + template < > + struct gcd_optimal_evaluator_helper2_t< true, true > + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; + }; + + template < typename T, bool IsSpecialized, bool IsSigned > + struct gcd_optimal_evaluator_helper_t + : gcd_optimal_evaluator_helper2_t + ::BOOST_NESTED_TEMPLATE helper + { + }; +#endif + + template < typename T > + struct gcd_optimal_evaluator + { + T operator ()( T const &a, T const &b ) + { + typedef ::std::numeric_limits limits_type; + + typedef gcd_optimal_evaluator_helper_t helper_type; + + helper_type solver; + + return solver( a, b ); + } + }; +#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + template < typename T > + struct gcd_optimal_evaluator + { + T operator ()( T const &a, T const &b ) + { + return gcd_integer( a, b ); + } + }; +#endif + +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template < typename T, bool IsSpecialized, bool IsSigned > + struct lcm_optimal_evaluator_helper_t + { + T operator ()( T const &a, T const &b ) + { + return lcm_euclidean( a, b ); + } + }; + + template < typename T > + struct lcm_optimal_evaluator_helper_t< T, true, true > + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; +#else + template < bool IsSpecialized, bool IsSigned > + struct lcm_optimal_evaluator_helper2_t + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return lcm_euclidean( a, b ); + } + }; + }; + + template < > + struct lcm_optimal_evaluator_helper2_t< true, true > + { + template < typename T > + struct helper + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; + }; + + template < typename T, bool IsSpecialized, bool IsSigned > + struct lcm_optimal_evaluator_helper_t + : lcm_optimal_evaluator_helper2_t + ::BOOST_NESTED_TEMPLATE helper + { + }; +#endif + + template < typename T > + struct lcm_optimal_evaluator + { + T operator ()( T const &a, T const &b ) + { + typedef ::std::numeric_limits limits_type; + + typedef lcm_optimal_evaluator_helper_t helper_type; + + helper_type solver; + + return solver( a, b ); + } + }; +#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + template < typename T > + struct lcm_optimal_evaluator + { + T operator ()( T const &a, T const &b ) + { + return lcm_integer( a, b ); + } + }; +#endif + + // Functions to find the GCD or LCM in the best way + template < typename T > + inline + T + gcd_optimal + ( + T const & a, + T const & b + ) + { + gcd_optimal_evaluator solver; + + return solver( a, b ); + } + + template < typename T > + inline + T + lcm_optimal + ( + T const & a, + T const & b + ) + { + lcm_optimal_evaluator solver; + + return solver( a, b ); + } + +} // namespace detail + + +// Greatest common divisor evaluator member function definition ------------// + +template < typename IntegerType > +inline +typename gcd_evaluator::result_type +gcd_evaluator::operator () +( + first_argument_type const & a, + second_argument_type const & b +) const +{ + return detail::gcd_optimal( a, b ); +} + + +// Least common multiple evaluator member function definition --------------// + +template < typename IntegerType > +inline +typename lcm_evaluator::result_type +lcm_evaluator::operator () +( + first_argument_type const & a, + second_argument_type const & b +) const +{ + return detail::lcm_optimal( a, b ); +} + + +// Greatest common divisor and least common multiple function definitions --// + +template < typename IntegerType > +inline +IntegerType +gcd +( + IntegerType const & a, + IntegerType const & b +) +{ + gcd_evaluator solver; + + return solver( a, b ); +} + +template < typename IntegerType > +inline +IntegerType +lcm +( + IntegerType const & a, + IntegerType const & b +) +{ + lcm_evaluator solver; + + return solver( a, b ); +} + + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_COMMON_FACTOR_RT_HPP From 9880cf69dce28f27bd939d065ef5b915448ebe90 Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Tue, 2 Jul 2002 08:31:15 +0000 Subject: [PATCH 07/43] Adjusted for moving the Compile-Time and Run-Time GCD and LCM components to new, separate headers [SVN r14273] --- include/boost/math/common_factor.hpp | 557 +-------------------------- 1 file changed, 7 insertions(+), 550 deletions(-) diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp index 10196fe..c2a9988 100644 --- a/include/boost/math/common_factor.hpp +++ b/include/boost/math/common_factor.hpp @@ -1,560 +1,17 @@ // Boost common_factor.hpp header file -------------------------------------// -// (C) Copyright Daryle Walker, Stephen Cleary, Paul Moore 2001. Permission -// to copy, use, modify, sell and distribute this software is granted provided -// this copyright notice appears in all copies. This software is provided "as -// is" without express or implied warranty, and with no claim as to its -// suitability for any purpose. +// (C) Copyright Daryle Walker 2001-2002. Permission to copy, use, modify, +// sell and distribute this software is granted provided this copyright notice +// appears in all copies. This software is provided "as is" without express +// or implied warranty, and with no claim as to its suitability for any +// purpose. // See http://www.boost.org for updates, documentation, and revision history. #ifndef BOOST_MATH_COMMON_FACTOR_HPP #define BOOST_MATH_COMMON_FACTOR_HPP -#include // self include - -#include // for BOOST_STATIC_CONSTANT, etc. -#include // for std::numeric_limits - - -namespace boost -{ -namespace math -{ - - -// Forward declarations for function templates -----------------------------// - -template < typename IntegerType > - IntegerType gcd( IntegerType const &a, IntegerType const &b ); - -template < typename IntegerType > - IntegerType lcm( IntegerType const &a, IntegerType const &b ); - - -// Greatest common divisor evaluator class declaration ---------------------// - -template < typename IntegerType > -class gcd_evaluator -{ -public: - // Types - typedef IntegerType result_type, first_argument_type, second_argument_type; - - // Function object interface - result_type operator ()( first_argument_type const &a, - second_argument_type const &b ) const; - -}; // boost::math::gcd_evaluator - - -// Least common multiple evaluator class declaration -----------------------// - -template < typename IntegerType > -class lcm_evaluator -{ -public: - // Types - typedef IntegerType result_type, first_argument_type, second_argument_type; - - // Function object interface - result_type operator ()( first_argument_type const &a, - second_argument_type const &b ) const; - -}; // boost::math::lcm_evaluator - - -// Implementation details --------------------------------------------------// - -namespace detail -{ -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - // Build GCD with Euclid's recursive algorithm - template < unsigned long Value1, unsigned long Value2 > - struct static_gcd_helper_t - { - private: - BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 ); - BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 ); - - #ifndef __BORLANDC__ - #define BOOST_DETAIL_GCD_HELPER_VAL(Value) 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( unsigned long, value = next_step_type::value ); - }; - - // Non-recursive case - template < unsigned long Value1 > - struct static_gcd_helper_t< Value1, 0UL > - { - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); - }; -#else - // Use inner class template workaround from Peter Dimov - template < unsigned long Value1 > - struct static_gcd_helper2_t - { - template < unsigned long Value2 > - struct helper - { - BOOST_STATIC_CONSTANT( unsigned long, value - = static_gcd_helper2_t::helper::value ); - }; - - template < > - struct helper< 0UL > - { - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); - }; - }; - - // Special case - template < > - struct static_gcd_helper2_t< 0UL > - { - template < unsigned long Value2 > - struct helper - { - BOOST_STATIC_CONSTANT( unsigned long, value = Value2 ); - }; - }; - - // Build the GCD from the above template(s) - template < unsigned long Value1, unsigned long Value2 > - struct static_gcd_helper_t - { - BOOST_STATIC_CONSTANT( unsigned long, value - = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE - helper::value ); - }; -#endif - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - // Build the LCM from the GCD - template < unsigned long Value1, unsigned long Value2 > - struct static_lcm_helper_t - { - typedef static_gcd_helper_t gcd_type; - - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value - * Value2 ); - }; - - // Special case for zero-GCD values - template < > - struct static_lcm_helper_t< 0UL, 0UL > - { - BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); - }; -#else - // Adapt GCD's inner class template workaround for LCM - template < unsigned long Value1 > - struct static_lcm_helper2_t - { - template < unsigned long Value2 > - struct helper - { - typedef static_gcd_helper_t gcd_type; - - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 - / gcd_type::value * Value2 ); - }; - - template < > - struct helper< 0UL > - { - BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); - }; - }; - - // Special case - template < > - struct static_lcm_helper2_t< 0UL > - { - template < unsigned long Value2 > - struct helper - { - BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); - }; - }; - - // Build the LCM from the above template(s) - template < unsigned long Value1, unsigned long Value2 > - struct static_lcm_helper_t - { - BOOST_STATIC_CONSTANT( unsigned long, value - = static_lcm_helper2_t::BOOST_NESTED_TEMPLATE - helper::value ); - }; -#endif - - // Greatest common divisor for rings (including unsigned integers) - template < typename RingType > - RingType - gcd_euclidean - ( - RingType a, - RingType b - ) - { - // Avoid repeated construction - #ifndef __BORLANDC__ - RingType const zero = static_cast( 0 ); - #else - RingType zero = static_cast( 0 ); - #endif - - // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)] - while ( true ) - { - if ( a == zero ) - return b; - b %= a; - - if ( b == zero ) - return a; - a %= b; - } - } - - // Greatest common divisor for (signed) integers - template < typename IntegerType > - inline - IntegerType - gcd_integer - ( - IntegerType const & a, - IntegerType const & b - ) - { - // Avoid repeated construction - IntegerType const zero = static_cast( 0 ); - IntegerType const result = gcd_euclidean( a, b ); - - return ( result < zero ) ? -result : result; - } - - // Least common multiple for rings (including unsigned integers) - template < typename RingType > - inline - RingType - lcm_euclidean - ( - RingType const & a, - RingType const & b - ) - { - RingType const zero = static_cast( 0 ); - RingType const temp = gcd_euclidean( a, b ); - - return ( temp != zero ) ? ( a / temp * b ) : zero; - } - - // Least common multiple for (signed) integers - template < typename IntegerType > - inline - IntegerType - lcm_integer - ( - IntegerType const & a, - IntegerType const & b - ) - { - // Avoid repeated construction - IntegerType const zero = static_cast( 0 ); - IntegerType const result = lcm_euclidean( a, b ); - - return ( result < zero ) ? -result : result; - } - - // Function objects to find the best way of computing GCD or LCM -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template < typename T, bool IsSpecialized, bool IsSigned > - struct gcd_optimal_evaluator_helper_t - { - T operator ()( T const &a, T const &b ) - { - return gcd_euclidean( a, b ); - } - }; - - template < typename T > - struct gcd_optimal_evaluator_helper_t< T, true, true > - { - T operator ()( T const &a, T const &b ) - { - return gcd_integer( a, b ); - } - }; -#else - template < bool IsSpecialized, bool IsSigned > - struct gcd_optimal_evaluator_helper2_t - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return gcd_euclidean( a, b ); - } - }; - }; - - template < > - struct gcd_optimal_evaluator_helper2_t< true, true > - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return gcd_integer( a, b ); - } - }; - }; - - template < typename T, bool IsSpecialized, bool IsSigned > - struct gcd_optimal_evaluator_helper_t - : gcd_optimal_evaluator_helper2_t - ::BOOST_NESTED_TEMPLATE helper - { - }; -#endif - - template < typename T > - struct gcd_optimal_evaluator - { - T operator ()( T const &a, T const &b ) - { - typedef ::std::numeric_limits limits_type; - - typedef gcd_optimal_evaluator_helper_t helper_type; - - helper_type solver; - - return solver( a, b ); - } - }; -#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - template < typename T > - struct gcd_optimal_evaluator - { - T operator ()( T const &a, T const &b ) - { - return gcd_integer( a, b ); - } - }; -#endif - -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template < typename T, bool IsSpecialized, bool IsSigned > - struct lcm_optimal_evaluator_helper_t - { - T operator ()( T const &a, T const &b ) - { - return lcm_euclidean( a, b ); - } - }; - - template < typename T > - struct lcm_optimal_evaluator_helper_t< T, true, true > - { - T operator ()( T const &a, T const &b ) - { - return lcm_integer( a, b ); - } - }; -#else - template < bool IsSpecialized, bool IsSigned > - struct lcm_optimal_evaluator_helper2_t - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return lcm_euclidean( a, b ); - } - }; - }; - - template < > - struct lcm_optimal_evaluator_helper2_t< true, true > - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return lcm_integer( a, b ); - } - }; - }; - - template < typename T, bool IsSpecialized, bool IsSigned > - struct lcm_optimal_evaluator_helper_t - : lcm_optimal_evaluator_helper2_t - ::BOOST_NESTED_TEMPLATE helper - { - }; -#endif - - template < typename T > - struct lcm_optimal_evaluator - { - T operator ()( T const &a, T const &b ) - { - typedef ::std::numeric_limits limits_type; - - typedef lcm_optimal_evaluator_helper_t helper_type; - - helper_type solver; - - return solver( a, b ); - } - }; -#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - template < typename T > - struct lcm_optimal_evaluator - { - T operator ()( T const &a, T const &b ) - { - return lcm_integer( a, b ); - } - }; -#endif - - // Functions to find the GCD or LCM in the best way - template < typename T > - inline - T - gcd_optimal - ( - T const & a, - T const & b - ) - { - gcd_optimal_evaluator solver; - - return solver( a, b ); - } - - template < typename T > - inline - T - lcm_optimal - ( - T const & a, - T const & b - ) - { - lcm_optimal_evaluator solver; - - return solver( a, b ); - } - -} // namespace detail - - -// Compile-time greatest common divisor evaluator class declaration --------// - -template < unsigned long Value1, unsigned long Value2 > -struct static_gcd -{ - BOOST_STATIC_CONSTANT( unsigned long, value - = (detail::static_gcd_helper_t::value) ); - -}; // boost::math::static_gcd - - -// Compile-time least common multiple evaluator class declaration ----------// - -template < unsigned long Value1, unsigned long Value2 > -struct static_lcm -{ - BOOST_STATIC_CONSTANT( unsigned long, value - = (detail::static_lcm_helper_t::value) ); - -}; // boost::math::static_lcm - - -// Greatest common divisor evaluator member function definition ------------// - -template < typename IntegerType > -inline -typename gcd_evaluator::result_type -gcd_evaluator::operator () -( - first_argument_type const & a, - second_argument_type const & b -) const -{ - return detail::gcd_optimal( a, b ); -} - - -// Least common multiple evaluator member function definition --------------// - -template < typename IntegerType > -inline -typename lcm_evaluator::result_type -lcm_evaluator::operator () -( - first_argument_type const & a, - second_argument_type const & b -) const -{ - return detail::lcm_optimal( a, b ); -} - - -// Greatest common divisor and least common multiple function definitions --// - -template < typename IntegerType > -inline -IntegerType -gcd -( - IntegerType const & a, - IntegerType const & b -) -{ - gcd_evaluator solver; - - return solver( a, b ); -} - -template < typename IntegerType > -inline -IntegerType -lcm -( - IntegerType const & a, - IntegerType const & b -) -{ - lcm_evaluator solver; - - return solver( a, b ); -} - - -} // namespace math -} // namespace boost - +#include +#include #endif // BOOST_MATH_COMMON_FACTOR_HPP From fadad77a3953ce65b6dff0c1156d3b8889b6272f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Sch=C3=B6pflin?= Date: Tue, 1 Oct 2002 13:31:42 +0000 Subject: [PATCH 08/43] Merged fix from release branch to main trunk. [SVN r15607] --- include/boost/math/common_factor_ct.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp index d116c4b..6c88636 100644 --- a/include/boost/math/common_factor_ct.hpp +++ b/include/boost/math/common_factor_ct.hpp @@ -36,7 +36,7 @@ namespace detail BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 ); #ifndef __BORLANDC__ - #define BOOST_DETAIL_GCD_HELPER_VAL(Value) Value + #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 ) From cd696b2f6ac4458d3b8400a3a84999481088b9c7 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 30 Jul 2004 04:46:56 +0000 Subject: [PATCH 09/43] License update [SVN r24180] --- include/boost/math/common_factor.hpp | 9 ++++----- test/common_factor_test.cpp | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp index c2a9988..21a71e4 100644 --- a/include/boost/math/common_factor.hpp +++ b/include/boost/math/common_factor.hpp @@ -1,10 +1,9 @@ // Boost common_factor.hpp header file -------------------------------------// -// (C) Copyright Daryle Walker 2001-2002. Permission to copy, use, modify, -// sell and distribute this software is granted provided this copyright notice -// appears in all copies. This software is provided "as is" without express -// or implied warranty, and with no claim as to its suitability for any -// purpose. +// (C) Copyright Daryle Walker 2001-2002. +// 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) // See http://www.boost.org for updates, documentation, and revision history. diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index e068efd..f5ee1ae 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -1,10 +1,9 @@ // Boost GCD & LCM common_factor.hpp test program --------------------------// -// (C) Copyright Daryle Walker 2001. Permission to copy, use, modify, sell -// and distribute this software is granted provided this copyright -// notice appears in all copies. This software is provided "as is" without -// express or implied warranty, and with no claim as to its suitability for -// any purpose. +// (C) Copyright Daryle Walker 2001. +// 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) // See http://www.boost.org for most recent version including documentation. From 791b547d25bf2bc40994384f78bfaf1ec7f4a343 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 28 Sep 2004 12:55:45 +0000 Subject: [PATCH 10/43] Changed files to BSL based on permissions in blanket-permission.txt [SVN r25451] --- include/boost/math/common_factor_ct.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp index 6c88636..f5d7c3e 100644 --- a/include/boost/math/common_factor_ct.hpp +++ b/include/boost/math/common_factor_ct.hpp @@ -1,10 +1,9 @@ // Boost common_factor_ct.hpp header file ----------------------------------// -// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002. Permission to -// copy, use, modify, sell and distribute this software is granted provided -// this copyright notice appears in all copies. This software is provided "as -// is" without express or implied warranty, and with no claim as to its -// suitability for any purpose. +// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002. +// 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) // See http://www.boost.org for updates, documentation, and revision history. From 6e6179b932d7e8cb83a3a194e6368b1efd8cd3a5 Mon Sep 17 00:00:00 2001 From: Stefan Slapeta Date: Thu, 3 Feb 2005 12:27:14 +0000 Subject: [PATCH 11/43] Replaced BOOST_TEST [SVN r27050] --- test/common_factor_test.cpp | 130 ++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index f5ee1ae..daf05f8 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -15,7 +15,7 @@ #include // for BOOST_MSVC #include // for boost::exit_success #include // for boost::math::gcd, etc. -#include // for main, BOOST_TEST +#include // for main, BOOST_CHECK #include // for std::cout (std::endl indirectly) @@ -52,87 +52,87 @@ test_main // GCD tests cout << "Doing tests on gcd." << endl; - BOOST_TEST( gcd( 1, -1) == 1 ); - BOOST_TEST( gcd( -1, 1) == 1 ); - BOOST_TEST( gcd( 1, 1) == 1 ); - BOOST_TEST( gcd( -1, -1) == 1 ); - BOOST_TEST( gcd( 0, 0) == 0 ); - BOOST_TEST( gcd( 7, 0) == 7 ); - BOOST_TEST( gcd( 0, 9) == 9 ); - BOOST_TEST( gcd( -7, 0) == 7 ); - BOOST_TEST( gcd( 0, -9) == 9 ); - BOOST_TEST( gcd( 42, 30) == 6 ); - BOOST_TEST( gcd( 6, -9) == 3 ); - BOOST_TEST( gcd(-10, -10) == 10 ); - BOOST_TEST( gcd(-25, -10) == 5 ); - BOOST_TEST( gcd( 3, 7) == 1 ); - BOOST_TEST( gcd( 8, 9) == 1 ); - BOOST_TEST( gcd( 7, 49) == 7 ); + BOOST_CHECK( gcd( 1, -1) == 1 ); + BOOST_CHECK( gcd( -1, 1) == 1 ); + BOOST_CHECK( gcd( 1, 1) == 1 ); + BOOST_CHECK( gcd( -1, -1) == 1 ); + BOOST_CHECK( gcd( 0, 0) == 0 ); + BOOST_CHECK( gcd( 7, 0) == 7 ); + BOOST_CHECK( gcd( 0, 9) == 9 ); + BOOST_CHECK( gcd( -7, 0) == 7 ); + BOOST_CHECK( gcd( 0, -9) == 9 ); + BOOST_CHECK( gcd( 42, 30) == 6 ); + BOOST_CHECK( gcd( 6, -9) == 3 ); + BOOST_CHECK( gcd(-10, -10) == 10 ); + BOOST_CHECK( gcd(-25, -10) == 5 ); + BOOST_CHECK( gcd( 3, 7) == 1 ); + BOOST_CHECK( gcd( 8, 9) == 1 ); + BOOST_CHECK( gcd( 7, 49) == 7 ); // GCD tests cout << "Doing tests on unsigned-gcd." << endl; - BOOST_TEST( gcd( 1u, 1u) == 1u ); - BOOST_TEST( gcd( 0u, 0u) == 0u ); - BOOST_TEST( gcd( 7u, 0u) == 7u ); - BOOST_TEST( gcd( 0u, 9u) == 9u ); - BOOST_TEST( gcd( 42u, 30u) == 6u ); - BOOST_TEST( gcd( 3u, 7u) == 1u ); - BOOST_TEST( gcd( 8u, 9u) == 1u ); - BOOST_TEST( gcd( 7u, 49u) == 7u ); + BOOST_CHECK( gcd( 1u, 1u) == 1u ); + BOOST_CHECK( gcd( 0u, 0u) == 0u ); + BOOST_CHECK( gcd( 7u, 0u) == 7u ); + BOOST_CHECK( gcd( 0u, 9u) == 9u ); + BOOST_CHECK( gcd( 42u, 30u) == 6u ); + BOOST_CHECK( gcd( 3u, 7u) == 1u ); + BOOST_CHECK( gcd( 8u, 9u) == 1u ); + BOOST_CHECK( gcd( 7u, 49u) == 7u ); cout << "Doing tests on static_gcd." << endl; - BOOST_TEST( (static_gcd< 1, 1>::value) == 1 ); - BOOST_TEST( (static_gcd< 0, 0>::value) == 0 ); - BOOST_TEST( (static_gcd< 7, 0>::value) == 7 ); - BOOST_TEST( (static_gcd< 0, 9>::value) == 9 ); - BOOST_TEST( (static_gcd<42, 30>::value) == 6 ); - BOOST_TEST( (static_gcd< 3, 7>::value) == 1 ); - BOOST_TEST( (static_gcd< 8, 9>::value) == 1 ); - BOOST_TEST( (static_gcd< 7, 49>::value) == 7 ); + BOOST_CHECK( (static_gcd< 1, 1>::value) == 1 ); + BOOST_CHECK( (static_gcd< 0, 0>::value) == 0 ); + BOOST_CHECK( (static_gcd< 7, 0>::value) == 7 ); + BOOST_CHECK( (static_gcd< 0, 9>::value) == 9 ); + BOOST_CHECK( (static_gcd<42, 30>::value) == 6 ); + BOOST_CHECK( (static_gcd< 3, 7>::value) == 1 ); + BOOST_CHECK( (static_gcd< 8, 9>::value) == 1 ); + BOOST_CHECK( (static_gcd< 7, 49>::value) == 7 ); // LCM tests cout << "Doing tests on lcm." << endl; - BOOST_TEST( lcm( 1, -1) == 1 ); - BOOST_TEST( lcm( -1, 1) == 1 ); - BOOST_TEST( lcm( 1, 1) == 1 ); - BOOST_TEST( lcm( -1, -1) == 1 ); - BOOST_TEST( lcm( 0, 0) == 0 ); - BOOST_TEST( lcm( 6, 0) == 0 ); - BOOST_TEST( lcm( 0, 7) == 0 ); - BOOST_TEST( lcm( -5, 0) == 0 ); - BOOST_TEST( lcm( 0, -4) == 0 ); - BOOST_TEST( lcm( 18, 30) == 90 ); - BOOST_TEST( lcm( -6, 9) == 18 ); - BOOST_TEST( lcm(-10, -10) == 10 ); - BOOST_TEST( lcm( 25, -10) == 50 ); - BOOST_TEST( lcm( 3, 7) == 21 ); - BOOST_TEST( lcm( 8, 9) == 72 ); - BOOST_TEST( lcm( 7, 49) == 49 ); + BOOST_CHECK( lcm( 1, -1) == 1 ); + BOOST_CHECK( lcm( -1, 1) == 1 ); + BOOST_CHECK( lcm( 1, 1) == 1 ); + BOOST_CHECK( lcm( -1, -1) == 1 ); + BOOST_CHECK( lcm( 0, 0) == 0 ); + BOOST_CHECK( lcm( 6, 0) == 0 ); + BOOST_CHECK( lcm( 0, 7) == 0 ); + BOOST_CHECK( lcm( -5, 0) == 0 ); + BOOST_CHECK( lcm( 0, -4) == 0 ); + BOOST_CHECK( lcm( 18, 30) == 90 ); + BOOST_CHECK( lcm( -6, 9) == 18 ); + BOOST_CHECK( lcm(-10, -10) == 10 ); + BOOST_CHECK( lcm( 25, -10) == 50 ); + BOOST_CHECK( lcm( 3, 7) == 21 ); + BOOST_CHECK( lcm( 8, 9) == 72 ); + BOOST_CHECK( lcm( 7, 49) == 49 ); cout << "Doing tests on unsigned-lcm." << endl; - BOOST_TEST( lcm( 1u, 1u) == 1u ); - BOOST_TEST( lcm( 0u, 0u) == 0u ); - BOOST_TEST( lcm( 6u, 0u) == 0u ); - BOOST_TEST( lcm( 0u, 7u) == 0u ); - BOOST_TEST( lcm( 18u, 30u) == 90u ); - BOOST_TEST( lcm( 3u, 7u) == 21u ); - BOOST_TEST( lcm( 8u, 9u) == 72u ); - BOOST_TEST( lcm( 7u, 49u) == 49u ); + BOOST_CHECK( lcm( 1u, 1u) == 1u ); + BOOST_CHECK( lcm( 0u, 0u) == 0u ); + BOOST_CHECK( lcm( 6u, 0u) == 0u ); + BOOST_CHECK( lcm( 0u, 7u) == 0u ); + BOOST_CHECK( lcm( 18u, 30u) == 90u ); + BOOST_CHECK( lcm( 3u, 7u) == 21u ); + BOOST_CHECK( lcm( 8u, 9u) == 72u ); + BOOST_CHECK( lcm( 7u, 49u) == 49u ); cout << "Doing tests on static_lcm." << endl; - BOOST_TEST( (static_lcm< 1, 1>::value) == 1 ); - BOOST_TEST( (static_lcm< 0, 0>::value) == 0 ); - BOOST_TEST( (static_lcm< 6, 0>::value) == 0 ); - BOOST_TEST( (static_lcm< 0, 7>::value) == 0 ); - BOOST_TEST( (static_lcm<18, 30>::value) == 90 ); - BOOST_TEST( (static_lcm< 3, 7>::value) == 21 ); - BOOST_TEST( (static_lcm< 8, 9>::value) == 72 ); - BOOST_TEST( (static_lcm< 7, 49>::value) == 49 ); + BOOST_CHECK( (static_lcm< 1, 1>::value) == 1 ); + BOOST_CHECK( (static_lcm< 0, 0>::value) == 0 ); + BOOST_CHECK( (static_lcm< 6, 0>::value) == 0 ); + BOOST_CHECK( (static_lcm< 0, 7>::value) == 0 ); + BOOST_CHECK( (static_lcm<18, 30>::value) == 90 ); + BOOST_CHECK( (static_lcm< 3, 7>::value) == 21 ); + BOOST_CHECK( (static_lcm< 8, 9>::value) == 72 ); + BOOST_CHECK( (static_lcm< 7, 49>::value) == 49 ); return boost::exit_success; } From c041451a54beb47baceb2e8f8438ba95d6ebb45b Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Mon, 7 Feb 2005 14:34:32 +0000 Subject: [PATCH 12/43] Added missing 'typename' [SVN r27219] --- include/boost/math/common_factor_ct.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp index f5d7c3e..63d2a56 100644 --- a/include/boost/math/common_factor_ct.hpp +++ b/include/boost/math/common_factor_ct.hpp @@ -65,7 +65,8 @@ namespace detail struct helper { BOOST_STATIC_CONSTANT( unsigned long, value - = static_gcd_helper2_t::helper::value ); + = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE + helper::value ); }; template < > From c8faa83d4765690bb52e6ea673b1811945ee2c32 Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Fri, 3 Nov 2006 03:08:27 +0000 Subject: [PATCH 13/43] Changed test to use Boost.Test's unit test system [SVN r35815] --- test/common_factor_test.cpp | 222 ++++++++++++++++++++++-------------- 1 file changed, 136 insertions(+), 86 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index daf05f8..661bdff 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -1,6 +1,6 @@ // Boost GCD & LCM common_factor.hpp test program --------------------------// -// (C) Copyright Daryle Walker 2001. +// (C) Copyright Daryle Walker 2001, 2006. // 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) @@ -8,81 +8,93 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 02 Nov 2006 Change to Boost.Test's unit test system // 07 Nov 2001 Initial version (Daryle Walker) -#define BOOST_INCLUDE_MAIN +#define BOOST_TEST_MAIN "Boost.Math GCD & LCM unit tests" #include // for BOOST_MSVC -#include // for boost::exit_success #include // for boost::math::gcd, etc. -#include // for main, BOOST_CHECK - -#include // for std::cout (std::endl indirectly) +#include // for boost::mpl::list +#include +#include -// Control to determine what kind of built-in integers are used -#ifndef CONTROL_INT_TYPE -#define CONTROL_INT_TYPE int -#endif +namespace { + +// TODO: add new signed and unsigned types here, with and without numeric_limits +// specialization; add polynominal/non-real type; especially after any switch to +// the binary-GCD algorithm for built-in types + +// Various types to test with each GCD/LCM +typedef ::boost::mpl::list builtin_signed_test_types; +typedef ::boost::mpl::list + builtin_unsigned_test_types; + +} // namespace -// Main testing function -int -test_main -( - int , // "argc" is unused - char * [] // "argv" is unused -) -{ - using std::cout; - using std::endl; +// GCD tests +BOOST_AUTO_TEST_SUITE( gcd_test_suite ) +// GCD on built-in signed integer types +BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_int_test, T, builtin_signed_test_types ) +{ #ifndef BOOST_MSVC using boost::math::gcd; - using boost::math::static_gcd; - using boost::math::lcm; - using boost::math::static_lcm; #else using namespace boost::math; #endif - typedef CONTROL_INT_TYPE int_type; - typedef unsigned CONTROL_INT_TYPE uint_type; + // Originally from Boost.Rational tests + BOOST_CHECK_EQUAL( gcd( 1, -1), static_cast( 1) ); + BOOST_CHECK_EQUAL( gcd( -1, 1), static_cast( 1) ); + BOOST_CHECK_EQUAL( gcd( 1, 1), static_cast( 1) ); + BOOST_CHECK_EQUAL( gcd( -1, -1), static_cast( 1) ); + BOOST_CHECK_EQUAL( gcd( 0, 0), static_cast( 0) ); + BOOST_CHECK_EQUAL( gcd( 7, 0), static_cast( 7) ); + BOOST_CHECK_EQUAL( gcd( 0, 9), static_cast( 9) ); + BOOST_CHECK_EQUAL( gcd( -7, 0), static_cast( 7) ); + BOOST_CHECK_EQUAL( gcd( 0, -9), static_cast( 9) ); + BOOST_CHECK_EQUAL( gcd( 42, 30), static_cast( 6) ); + BOOST_CHECK_EQUAL( gcd( 6, -9), static_cast( 3) ); + BOOST_CHECK_EQUAL( gcd(-10, -10), static_cast(10) ); + BOOST_CHECK_EQUAL( gcd(-25, -10), static_cast( 5) ); + BOOST_CHECK_EQUAL( gcd( 3, 7), static_cast( 1) ); + BOOST_CHECK_EQUAL( gcd( 8, 9), static_cast( 1) ); + BOOST_CHECK_EQUAL( gcd( 7, 49), static_cast( 7) ); +} - // GCD tests - cout << "Doing tests on gcd." << endl; +// GCD on built-in unsigned integer types +BOOST_AUTO_TEST_CASE_TEMPLATE(gcd_unsigned_test, T, builtin_unsigned_test_types) +{ +#ifndef BOOST_MSVC + using boost::math::gcd; +#else + using namespace boost::math; +#endif - BOOST_CHECK( gcd( 1, -1) == 1 ); - BOOST_CHECK( gcd( -1, 1) == 1 ); - BOOST_CHECK( gcd( 1, 1) == 1 ); - BOOST_CHECK( gcd( -1, -1) == 1 ); - BOOST_CHECK( gcd( 0, 0) == 0 ); - BOOST_CHECK( gcd( 7, 0) == 7 ); - BOOST_CHECK( gcd( 0, 9) == 9 ); - BOOST_CHECK( gcd( -7, 0) == 7 ); - BOOST_CHECK( gcd( 0, -9) == 9 ); - BOOST_CHECK( gcd( 42, 30) == 6 ); - BOOST_CHECK( gcd( 6, -9) == 3 ); - BOOST_CHECK( gcd(-10, -10) == 10 ); - BOOST_CHECK( gcd(-25, -10) == 5 ); - BOOST_CHECK( gcd( 3, 7) == 1 ); - BOOST_CHECK( gcd( 8, 9) == 1 ); - BOOST_CHECK( gcd( 7, 49) == 7 ); + BOOST_CHECK_EQUAL( gcd( 1u, 1u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( gcd( 0u, 0u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( gcd( 7u, 0u), static_cast( 7u) ); + BOOST_CHECK_EQUAL( gcd( 0u, 9u), static_cast( 9u) ); + BOOST_CHECK_EQUAL( gcd( 42u, 30u), static_cast( 6u) ); + BOOST_CHECK_EQUAL( gcd( 3u, 7u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( gcd( 8u, 9u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( gcd( 7u, 49u), static_cast( 7u) ); +} - // GCD tests - cout << "Doing tests on unsigned-gcd." << endl; - - BOOST_CHECK( gcd( 1u, 1u) == 1u ); - BOOST_CHECK( gcd( 0u, 0u) == 0u ); - BOOST_CHECK( gcd( 7u, 0u) == 7u ); - BOOST_CHECK( gcd( 0u, 9u) == 9u ); - BOOST_CHECK( gcd( 42u, 30u) == 6u ); - BOOST_CHECK( gcd( 3u, 7u) == 1u ); - BOOST_CHECK( gcd( 8u, 9u) == 1u ); - BOOST_CHECK( gcd( 7u, 49u) == 7u ); - - cout << "Doing tests on static_gcd." << endl; +// GCD at compile-time +BOOST_AUTO_TEST_CASE( gcd_static_test ) +{ +#ifndef BOOST_MSVC + using boost::math::static_gcd; +#else + using namespace boost::math; +#endif + // Can't use "BOOST_CHECK_EQUAL", otherwise the "value" member will be + // disqualified as compile-time-only constant, needing explicit definition BOOST_CHECK( (static_gcd< 1, 1>::value) == 1 ); BOOST_CHECK( (static_gcd< 0, 0>::value) == 0 ); BOOST_CHECK( (static_gcd< 7, 0>::value) == 7 ); @@ -91,40 +103,76 @@ test_main BOOST_CHECK( (static_gcd< 3, 7>::value) == 1 ); BOOST_CHECK( (static_gcd< 8, 9>::value) == 1 ); BOOST_CHECK( (static_gcd< 7, 49>::value) == 7 ); +} - // LCM tests - cout << "Doing tests on lcm." << endl; +// TODO: non-built-in signed and unsigned integer tests, with and without +// numeric_limits specialization; polynominal tests; note any changes if +// built-ins switch to binary-GCD algorithm - BOOST_CHECK( lcm( 1, -1) == 1 ); - BOOST_CHECK( lcm( -1, 1) == 1 ); - BOOST_CHECK( lcm( 1, 1) == 1 ); - BOOST_CHECK( lcm( -1, -1) == 1 ); - BOOST_CHECK( lcm( 0, 0) == 0 ); - BOOST_CHECK( lcm( 6, 0) == 0 ); - BOOST_CHECK( lcm( 0, 7) == 0 ); - BOOST_CHECK( lcm( -5, 0) == 0 ); - BOOST_CHECK( lcm( 0, -4) == 0 ); - BOOST_CHECK( lcm( 18, 30) == 90 ); - BOOST_CHECK( lcm( -6, 9) == 18 ); - BOOST_CHECK( lcm(-10, -10) == 10 ); - BOOST_CHECK( lcm( 25, -10) == 50 ); - BOOST_CHECK( lcm( 3, 7) == 21 ); - BOOST_CHECK( lcm( 8, 9) == 72 ); - BOOST_CHECK( lcm( 7, 49) == 49 ); +BOOST_AUTO_TEST_SUITE_END() - cout << "Doing tests on unsigned-lcm." << endl; - BOOST_CHECK( lcm( 1u, 1u) == 1u ); - BOOST_CHECK( lcm( 0u, 0u) == 0u ); - BOOST_CHECK( lcm( 6u, 0u) == 0u ); - BOOST_CHECK( lcm( 0u, 7u) == 0u ); - BOOST_CHECK( lcm( 18u, 30u) == 90u ); - BOOST_CHECK( lcm( 3u, 7u) == 21u ); - BOOST_CHECK( lcm( 8u, 9u) == 72u ); - BOOST_CHECK( lcm( 7u, 49u) == 49u ); +// LCM tests +BOOST_AUTO_TEST_SUITE( lcm_test_suite ) - cout << "Doing tests on static_lcm." << endl; +// LCM on built-in signed integer types +BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_int_test, T, builtin_signed_test_types ) +{ +#ifndef BOOST_MSVC + using boost::math::lcm; +#else + using namespace boost::math; +#endif + // Originally from Boost.Rational tests + BOOST_CHECK_EQUAL( lcm( 1, -1), static_cast( 1) ); + BOOST_CHECK_EQUAL( lcm( -1, 1), static_cast( 1) ); + BOOST_CHECK_EQUAL( lcm( 1, 1), static_cast( 1) ); + BOOST_CHECK_EQUAL( lcm( -1, -1), static_cast( 1) ); + BOOST_CHECK_EQUAL( lcm( 0, 0), static_cast( 0) ); + BOOST_CHECK_EQUAL( lcm( 6, 0), static_cast( 0) ); + BOOST_CHECK_EQUAL( lcm( 0, 7), static_cast( 0) ); + BOOST_CHECK_EQUAL( lcm( -5, 0), static_cast( 0) ); + BOOST_CHECK_EQUAL( lcm( 0, -4), static_cast( 0) ); + BOOST_CHECK_EQUAL( lcm( 18, 30), static_cast(90) ); + BOOST_CHECK_EQUAL( lcm( -6, 9), static_cast(18) ); + BOOST_CHECK_EQUAL( lcm(-10, -10), static_cast(10) ); + BOOST_CHECK_EQUAL( lcm( 25, -10), static_cast(50) ); + BOOST_CHECK_EQUAL( lcm( 3, 7), static_cast(21) ); + BOOST_CHECK_EQUAL( lcm( 8, 9), static_cast(72) ); + BOOST_CHECK_EQUAL( lcm( 7, 49), static_cast(49) ); +} + +// LCM on built-in unsigned integer types +BOOST_AUTO_TEST_CASE_TEMPLATE(lcm_unsigned_test, T, builtin_unsigned_test_types) +{ +#ifndef BOOST_MSVC + using boost::math::lcm; +#else + using namespace boost::math; +#endif + + BOOST_CHECK_EQUAL( lcm( 1u, 1u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( lcm( 0u, 0u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( lcm( 6u, 0u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( lcm( 0u, 7u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( lcm( 18u, 30u), static_cast(90u) ); + BOOST_CHECK_EQUAL( lcm( 3u, 7u), static_cast(21u) ); + BOOST_CHECK_EQUAL( lcm( 8u, 9u), static_cast(72u) ); + BOOST_CHECK_EQUAL( lcm( 7u, 49u), static_cast(49u) ); +} + +// LCM at compile-time +BOOST_AUTO_TEST_CASE( lcm_static_test ) +{ +#ifndef BOOST_MSVC + using boost::math::static_lcm; +#else + using namespace boost::math; +#endif + + // Can't use "BOOST_CHECK_EQUAL", otherwise the "value" member will be + // disqualified as compile-time-only constant, needing explicit definition BOOST_CHECK( (static_lcm< 1, 1>::value) == 1 ); BOOST_CHECK( (static_lcm< 0, 0>::value) == 0 ); BOOST_CHECK( (static_lcm< 6, 0>::value) == 0 ); @@ -133,6 +181,8 @@ test_main BOOST_CHECK( (static_lcm< 3, 7>::value) == 21 ); BOOST_CHECK( (static_lcm< 8, 9>::value) == 72 ); BOOST_CHECK( (static_lcm< 7, 49>::value) == 49 ); - - return boost::exit_success; } + +// TODO: see GCD to-do + +BOOST_AUTO_TEST_SUITE_END() From 56b287a59020232337ffa7fc65acf9d1d03bbe5e Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Fri, 3 Nov 2006 22:43:34 +0000 Subject: [PATCH 14/43] Added custom integer types, signed and unsigned, with and without std::numeric_limits<> specializations, to test [SVN r35830] --- test/common_factor_test.cpp | 305 ++++++++++++++++++++++++++++++++---- 1 file changed, 277 insertions(+), 28 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 661bdff..6a897c6 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -8,7 +8,8 @@ // See http://www.boost.org for most recent version including documentation. // Revision History -// 02 Nov 2006 Change to Boost.Test's unit test system +// 03 Nov 2006 Use custom numeric types (Daryle Walker) +// 02 Nov 2006 Change to Boost.Test's unit test system (Daryle Walker) // 07 Nov 2001 Initial version (Daryle Walker) #define BOOST_TEST_MAIN "Boost.Math GCD & LCM unit tests" @@ -16,29 +17,211 @@ #include // for BOOST_MSVC #include // for boost::math::gcd, etc. #include // for boost::mpl::list +#include #include #include +#include // for std::basic_istream +#include // for std::numeric_limits +#include // for std::basic_ostream + namespace { -// TODO: add new signed and unsigned types here, with and without numeric_limits -// specialization; add polynominal/non-real type; especially after any switch to -// the binary-GCD algorithm for built-in types +// TODO: add polynominal/non-real type; especially after any switch to the +// binary-GCD algorithm for built-in types + +// Custom integer class (template) +template < typename IntType, int ID = 0 > +class my_wrapped_integer + : private ::boost::shiftable1, + ::boost::operators > > +{ + // Helper type-aliases + typedef my_wrapped_integer self_type; + typedef IntType self_type::* bool_type; + + // Member data + IntType v_; + +public: + // Template parameters + typedef IntType int_type; + + static int const id = ID; + + // Lifetime management (use automatic destructor and copy constructor) + my_wrapped_integer( int_type const &v = int_type() ) : v_( v ) {} + + // Accessors + int_type value() const { return this->v_; } + + // Operators (use automatic copy assignment) + operator bool_type() const { return this->v_ ? &self_type::v_ : 0; } + + self_type & operator ++() { ++this->v_; return *this; } + self_type & operator --() { --this->v_; return *this; } + + self_type operator ~() const { return self_type( ~this->v_ ); } + self_type operator !() const { return self_type( !this->v_ ); } + self_type operator +() const { return self_type( +this->v_ ); } + self_type operator -() const { return self_type( -this->v_ ); } + + bool operator <( self_type const &r ) const { return this->v_ < r.v_; } + bool operator ==( self_type const &r ) const { return this->v_ == r.v_; } + + self_type &operator *=(self_type const &r) {this->v_ *= r.v_; return *this;} + self_type &operator /=(self_type const &r) {this->v_ /= r.v_; return *this;} + self_type &operator %=(self_type const &r) {this->v_ %= r.v_; return *this;} + self_type &operator +=(self_type const &r) {this->v_ += r.v_; return *this;} + self_type &operator -=(self_type const &r) {this->v_ -= r.v_; return *this;} + self_type &operator<<=(self_type const &r){this->v_ <<= r.v_; return *this;} + self_type &operator>>=(self_type const &r){this->v_ >>= r.v_; return *this;} + self_type &operator &=(self_type const &r) {this->v_ &= r.v_; return *this;} + self_type &operator |=(self_type const &r) {this->v_ |= r.v_; return *this;} + self_type &operator ^=(self_type const &r) {this->v_ ^= r.v_; return *this;} + + // Input & output + template < typename Ch, class Tr > + friend std::basic_istream & + operator >>( std::basic_istream &i, self_type &x ) + { return i >> x.v_; } + + template < typename Ch, class Tr > + friend std::basic_ostream & + operator <<( std::basic_ostream &o, self_type const &x ) + { return o << x.v_; } + +}; // my_wrapped_integer + +template < typename IntType, int ID > +my_wrapped_integer abs( my_wrapped_integer const &x ) +{ return ( x < my_wrapped_integer(0) ) ? -x : +x; } + +typedef my_wrapped_integer MyInt1; +typedef my_wrapped_integer MyUnsigned1; +typedef my_wrapped_integer MyInt2; +typedef my_wrapped_integer MyUnsigned2; // Various types to test with each GCD/LCM typedef ::boost::mpl::list builtin_signed_test_types; typedef ::boost::mpl::list builtin_unsigned_test_types; +typedef ::boost::mpl::list signed_test_types; +typedef ::boost::mpl::list unsigned_test_types; + } // namespace +// Specialize numeric_limits for _some_ of our types +namespace std +{ + +template < > +class numeric_limits< MyInt1 > +{ + typedef MyInt1::int_type int_type; + typedef numeric_limits limits_type; + +public: + static const bool is_specialized = limits_type::is_specialized; + + static MyInt1 min() throw() { return limits_type::min(); } + static MyInt1 max() throw() { return limits_type::max(); } + + static const int digits = limits_type::digits; + static const int digits10 = limits_type::digits10; + static const bool is_signed = limits_type::is_signed; + static const bool is_integer = limits_type::is_integer; + static const bool is_exact = limits_type::is_exact; + static const int radix = limits_type::radix; + static MyInt1 epsilon() throw() { return limits_type::epsilon(); } + static MyInt1 round_error() throw() { return limits_type::round_error(); } + + static const int min_exponent = limits_type::min_exponent; + static const int min_exponent10 = limits_type::min_exponent10; + static const int max_exponent = limits_type::max_exponent; + static const int max_exponent10 = limits_type::max_exponent10; + + static const bool has_infinity = limits_type::has_infinity; + static const bool has_quiet_NaN = limits_type::has_quiet_NaN; + static const bool has_signaling_NaN = limits_type::has_signaling_NaN; + static const float_denorm_style has_denorm = limits_type::has_denorm; + static const bool has_denorm_loss = limits_type::has_denorm_loss; + + static MyInt1 infinity() throw() { return limits_type::infinity(); } + static MyInt1 quiet_NaN() throw() { return limits_type::quiet_NaN(); } + static MyInt1 signaling_NaN() throw() {return limits_type::signaling_NaN();} + static MyInt1 denorm_min() throw() { return limits_type::denorm_min(); } + + static const bool is_iec559 = limits_type::is_iec559; + static const bool is_bounded = limits_type::is_bounded; + static const bool is_modulo = limits_type::is_modulo; + + static const bool traps = limits_type::traps; + static const bool tinyness_before = limits_type::tinyness_before; + static const float_round_style round_style = limits_type::round_style; + +}; // std::numeric_limits + +template < > +class numeric_limits< MyUnsigned1 > +{ + typedef MyUnsigned1::int_type int_type; + typedef numeric_limits limits_type; + +public: + static const bool is_specialized = limits_type::is_specialized; + + static MyUnsigned1 min() throw() { return limits_type::min(); } + static MyUnsigned1 max() throw() { return limits_type::max(); } + + static const int digits = limits_type::digits; + static const int digits10 = limits_type::digits10; + static const bool is_signed = limits_type::is_signed; + static const bool is_integer = limits_type::is_integer; + static const bool is_exact = limits_type::is_exact; + static const int radix = limits_type::radix; + static MyUnsigned1 epsilon() throw() { return limits_type::epsilon(); } + static MyUnsigned1 round_error() throw(){return limits_type::round_error();} + + static const int min_exponent = limits_type::min_exponent; + static const int min_exponent10 = limits_type::min_exponent10; + static const int max_exponent = limits_type::max_exponent; + static const int max_exponent10 = limits_type::max_exponent10; + + static const bool has_infinity = limits_type::has_infinity; + static const bool has_quiet_NaN = limits_type::has_quiet_NaN; + static const bool has_signaling_NaN = limits_type::has_signaling_NaN; + static const float_denorm_style has_denorm = limits_type::has_denorm; + static const bool has_denorm_loss = limits_type::has_denorm_loss; + + static MyUnsigned1 infinity() throw() { return limits_type::infinity(); } + static MyUnsigned1 quiet_NaN() throw() { return limits_type::quiet_NaN(); } + static MyUnsigned1 signaling_NaN() throw() + { return limits_type::signaling_NaN(); } + static MyUnsigned1 denorm_min() throw(){ return limits_type::denorm_min(); } + + static const bool is_iec559 = limits_type::is_iec559; + static const bool is_bounded = limits_type::is_bounded; + static const bool is_modulo = limits_type::is_modulo; + + static const bool traps = limits_type::traps; + static const bool tinyness_before = limits_type::tinyness_before; + static const float_round_style round_style = limits_type::round_style; + +}; // std::numeric_limits + +} // namespace std + + // GCD tests BOOST_AUTO_TEST_SUITE( gcd_test_suite ) -// GCD on built-in signed integer types -BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_int_test, T, builtin_signed_test_types ) +// GCD on signed integer types +BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_int_test, T, signed_test_types ) { #ifndef BOOST_MSVC using boost::math::gcd; @@ -65,8 +248,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_int_test, T, builtin_signed_test_types ) BOOST_CHECK_EQUAL( gcd( 7, 49), static_cast( 7) ); } -// GCD on built-in unsigned integer types -BOOST_AUTO_TEST_CASE_TEMPLATE(gcd_unsigned_test, T, builtin_unsigned_test_types) +// GCD on unmarked signed integer type +BOOST_AUTO_TEST_CASE( gcd_unmarked_int_test ) { #ifndef BOOST_MSVC using boost::math::gcd; @@ -74,14 +257,47 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(gcd_unsigned_test, T, builtin_unsigned_test_types) using namespace boost::math; #endif - BOOST_CHECK_EQUAL( gcd( 1u, 1u), static_cast( 1u) ); - BOOST_CHECK_EQUAL( gcd( 0u, 0u), static_cast( 0u) ); - BOOST_CHECK_EQUAL( gcd( 7u, 0u), static_cast( 7u) ); - BOOST_CHECK_EQUAL( gcd( 0u, 9u), static_cast( 9u) ); - BOOST_CHECK_EQUAL( gcd( 42u, 30u), static_cast( 6u) ); - BOOST_CHECK_EQUAL( gcd( 3u, 7u), static_cast( 1u) ); - BOOST_CHECK_EQUAL( gcd( 8u, 9u), static_cast( 1u) ); - BOOST_CHECK_EQUAL( gcd( 7u, 49u), static_cast( 7u) ); + // The regular signed-integer GCD function performs the unsigned version, + // then does an absolute-value on the result. Signed types that are not + // marked as such (due to no std::numeric_limits specialization) may be off + // by a sign. + BOOST_CHECK_EQUAL( abs(gcd( 1, -1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(gcd( -1, 1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(gcd( 1, 1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(gcd( -1, -1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(gcd( 0, 0 )), MyInt2( 0) ); + BOOST_CHECK_EQUAL( abs(gcd( 7, 0 )), MyInt2( 7) ); + BOOST_CHECK_EQUAL( abs(gcd( 0, 9 )), MyInt2( 9) ); + BOOST_CHECK_EQUAL( abs(gcd( -7, 0 )), MyInt2( 7) ); + BOOST_CHECK_EQUAL( abs(gcd( 0, -9 )), MyInt2( 9) ); + BOOST_CHECK_EQUAL( abs(gcd( 42, 30 )), MyInt2( 6) ); + BOOST_CHECK_EQUAL( abs(gcd( 6, -9 )), MyInt2( 3) ); + BOOST_CHECK_EQUAL( abs(gcd( -10, -10 )), MyInt2(10) ); + BOOST_CHECK_EQUAL( abs(gcd( -25, -10 )), MyInt2( 5) ); + BOOST_CHECK_EQUAL( abs(gcd( 3, 7 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(gcd( 8, 9 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(gcd( 7, 49 )), MyInt2( 7) ); +} + +// GCD on unsigned integer types +BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_unsigned_test, T, unsigned_test_types ) +{ +#ifndef BOOST_MSVC + using boost::math::gcd; +#else + using namespace boost::math; +#endif + + // Note that unmarked types (i.e. have no std::numeric_limits + // specialization) are treated like non/unsigned types + BOOST_CHECK_EQUAL( gcd( 1u, 1u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( gcd( 0u, 0u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( gcd( 7u, 0u), static_cast( 7u) ); + BOOST_CHECK_EQUAL( gcd( 0u, 9u), static_cast( 9u) ); + BOOST_CHECK_EQUAL( gcd(42u, 30u), static_cast( 6u) ); + BOOST_CHECK_EQUAL( gcd( 3u, 7u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( gcd( 8u, 9u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( gcd( 7u, 49u), static_cast( 7u) ); } // GCD at compile-time @@ -115,8 +331,8 @@ BOOST_AUTO_TEST_SUITE_END() // LCM tests BOOST_AUTO_TEST_SUITE( lcm_test_suite ) -// LCM on built-in signed integer types -BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_int_test, T, builtin_signed_test_types ) +// LCM on signed integer types +BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_int_test, T, signed_test_types ) { #ifndef BOOST_MSVC using boost::math::lcm; @@ -143,8 +359,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_int_test, T, builtin_signed_test_types ) BOOST_CHECK_EQUAL( lcm( 7, 49), static_cast(49) ); } -// LCM on built-in unsigned integer types -BOOST_AUTO_TEST_CASE_TEMPLATE(lcm_unsigned_test, T, builtin_unsigned_test_types) +// LCM on unmarked signed integer type +BOOST_AUTO_TEST_CASE( lcm_unmarked_int_test ) { #ifndef BOOST_MSVC using boost::math::lcm; @@ -152,14 +368,47 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(lcm_unsigned_test, T, builtin_unsigned_test_types) using namespace boost::math; #endif - BOOST_CHECK_EQUAL( lcm( 1u, 1u), static_cast( 1u) ); - BOOST_CHECK_EQUAL( lcm( 0u, 0u), static_cast( 0u) ); - BOOST_CHECK_EQUAL( lcm( 6u, 0u), static_cast( 0u) ); - BOOST_CHECK_EQUAL( lcm( 0u, 7u), static_cast( 0u) ); - BOOST_CHECK_EQUAL( lcm( 18u, 30u), static_cast(90u) ); - BOOST_CHECK_EQUAL( lcm( 3u, 7u), static_cast(21u) ); - BOOST_CHECK_EQUAL( lcm( 8u, 9u), static_cast(72u) ); - BOOST_CHECK_EQUAL( lcm( 7u, 49u), static_cast(49u) ); + // The regular signed-integer LCM function performs the unsigned version, + // then does an absolute-value on the result. Signed types that are not + // marked as such (due to no std::numeric_limits specialization) may be off + // by a sign. + BOOST_CHECK_EQUAL( abs(lcm( 1, -1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(lcm( -1, 1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(lcm( 1, 1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(lcm( -1, -1 )), MyInt2( 1) ); + BOOST_CHECK_EQUAL( abs(lcm( 0, 0 )), MyInt2( 0) ); + BOOST_CHECK_EQUAL( abs(lcm( 6, 0 )), MyInt2( 0) ); + BOOST_CHECK_EQUAL( abs(lcm( 0, 7 )), MyInt2( 0) ); + BOOST_CHECK_EQUAL( abs(lcm( -5, 0 )), MyInt2( 0) ); + BOOST_CHECK_EQUAL( abs(lcm( 0, -4 )), MyInt2( 0) ); + BOOST_CHECK_EQUAL( abs(lcm( 18, 30 )), MyInt2(90) ); + BOOST_CHECK_EQUAL( abs(lcm( -6, 9 )), MyInt2(18) ); + BOOST_CHECK_EQUAL( abs(lcm( -10, -10 )), MyInt2(10) ); + BOOST_CHECK_EQUAL( abs(lcm( 25, -10 )), MyInt2(50) ); + BOOST_CHECK_EQUAL( abs(lcm( 3, 7 )), MyInt2(21) ); + BOOST_CHECK_EQUAL( abs(lcm( 8, 9 )), MyInt2(72) ); + BOOST_CHECK_EQUAL( abs(lcm( 7, 49 )), MyInt2(49) ); +} + +// LCM on unsigned integer types +BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_unsigned_test, T, unsigned_test_types ) +{ +#ifndef BOOST_MSVC + using boost::math::lcm; +#else + using namespace boost::math; +#endif + + // Note that unmarked types (i.e. have no std::numeric_limits + // specialization) are treated like non/unsigned types + BOOST_CHECK_EQUAL( lcm( 1u, 1u), static_cast( 1u) ); + BOOST_CHECK_EQUAL( lcm( 0u, 0u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( lcm( 6u, 0u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( lcm( 0u, 7u), static_cast( 0u) ); + BOOST_CHECK_EQUAL( lcm(18u, 30u), static_cast(90u) ); + BOOST_CHECK_EQUAL( lcm( 3u, 7u), static_cast(21u) ); + BOOST_CHECK_EQUAL( lcm( 8u, 9u), static_cast(72u) ); + BOOST_CHECK_EQUAL( lcm( 7u, 49u), static_cast(49u) ); } // LCM at compile-time From 1f5f827a5e5f5d22403d7e82d35ccc1dd7693a8f Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Sun, 5 Nov 2006 07:10:42 +0000 Subject: [PATCH 15/43] Changed GCD for built-in integer types to use the binary-GCD algorithm [SVN r35850] --- include/boost/math/common_factor_rt.hpp | 100 ++++++++++++++++++++++++ test/common_factor_test.cpp | 25 ++++-- 2 files changed, 118 insertions(+), 7 deletions(-) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index 5b8cd45..97006c5 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -114,6 +114,62 @@ namespace detail return ( result < zero ) ? -result : result; } + // Greatest common divisor for unsigned binary integers + template < typename BuiltInUnsigned > + BuiltInUnsigned + gcd_binary + ( + BuiltInUnsigned u, + BuiltInUnsigned v + ) + { + if ( u && v ) + { + // Shift out common factors of 2 + unsigned shifts = 0; + + while ( !(u & 1u) && !(v & 1u) ) + { + ++shifts; + u >>= 1; + v >>= 1; + } + + // Start with the still-even one, if any + BuiltInUnsigned r[] = { u, v }; + unsigned which = static_cast( u & 1u ); + + // Whittle down the values via their differences + do + { + // Remove factors of two from the even one + while ( !(r[ which ] & 1u) ) + { + r[ which ] >>= 1; + } + + // Replace the larger of the two with their difference + if ( r[!which] > r[which] ) + { + which ^= 1u; + } + + r[ which ] -= r[ !which ]; + } + while ( r[which] ); + + // Shift-in the common factor of 2 to the residues' GCD + return r[ !which ] << shifts; + } + else + { + // At least one input is zero, return the other + // (adding since zero is the additive identity) + // or zero if both are zero. + return u + v; + } + } + // Least common multiple for rings (including unsigned integers) template < typename RingType > inline @@ -228,6 +284,50 @@ namespace detail }; #endif + // Specialize for the built-in integers +#define BOOST_PRIVATE_GCD_UF( Ut ) \ + template < > struct gcd_optimal_evaluator \ + { Ut operator ()( Ut a, Ut b ) const { return gcd_binary( a, b ); } } + + BOOST_PRIVATE_GCD_UF( unsigned char ); + BOOST_PRIVATE_GCD_UF( unsigned short ); + BOOST_PRIVATE_GCD_UF( unsigned ); + BOOST_PRIVATE_GCD_UF( unsigned long ); + +#ifdef BOOST_HAS_LONG_LONG + BOOST_PRIVATE_GCD_UF( unsigned long long ); +#endif + +#ifdef BOOST_HAS_MS_INT64 + BOOST_PRIVATE_GCD_UF( unsigned __int64 ); +#endif + +#undef BOOST_PRIVATE_GCD_UF + +#define BOOST_PRIVATE_GCD_SF( St, Ut ) \ + template < > struct gcd_optimal_evaluator \ + { St operator ()( St a, St b ) const { Ut const a_abs = \ + static_cast( a < 0 ? -a : +a ), b_abs = static_cast( \ + b < 0 ? -b : +b ); return static_cast( \ + gcd_optimal_evaluator()(a_abs, b_abs) ); } } + + BOOST_PRIVATE_GCD_SF( signed char, unsigned char ); + BOOST_PRIVATE_GCD_SF( short, unsigned short ); + BOOST_PRIVATE_GCD_SF( int, unsigned ); + BOOST_PRIVATE_GCD_SF( long, unsigned long ); + + BOOST_PRIVATE_GCD_SF( char, unsigned char ); // should work even if unsigned + +#ifdef BOOST_HAS_LONG_LONG + BOOST_PRIVATE_GCD_SF( long long, unsigned long long ); +#endif + +#ifdef BOOST_HAS_MS_INT64 + BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 ); +#endif + +#undef BOOST_PRIVATE_GCD_SF + #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 6a897c6..80bc11c 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -8,6 +8,7 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker) // 03 Nov 2006 Use custom numeric types (Daryle Walker) // 02 Nov 2006 Change to Boost.Test's unit test system (Daryle Walker) // 07 Nov 2001 Initial version (Daryle Walker) @@ -104,13 +105,23 @@ typedef my_wrapped_integer MyInt2; typedef my_wrapped_integer MyUnsigned2; // Various types to test with each GCD/LCM -typedef ::boost::mpl::list builtin_signed_test_types; -typedef ::boost::mpl::list - builtin_unsigned_test_types; - -typedef ::boost::mpl::list signed_test_types; -typedef ::boost::mpl::list unsigned_test_types; +typedef ::boost::mpl::list signed_test_types; +typedef ::boost::mpl::list unsigned_test_types; } // namespace From 80b59192ae78012b451ff45ce365c5a1fed09448 Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Fri, 10 Nov 2006 23:15:49 +0000 Subject: [PATCH 16/43] Made the GCD specializations for '(unsigned) long long' and '(unsigned) __int64' mutually exclusive, following the lead of . [SVN r35999] --- include/boost/math/common_factor_rt.hpp | 8 ++------ test/common_factor_test.cpp | 9 ++++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index 97006c5..c02d12a 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -296,9 +296,7 @@ namespace detail #ifdef BOOST_HAS_LONG_LONG BOOST_PRIVATE_GCD_UF( unsigned long long ); -#endif - -#ifdef BOOST_HAS_MS_INT64 +#elif defined(BOOST_HAS_MS_INT64) BOOST_PRIVATE_GCD_UF( unsigned __int64 ); #endif @@ -320,9 +318,7 @@ namespace detail #ifdef BOOST_HAS_LONG_LONG BOOST_PRIVATE_GCD_SF( long long, unsigned long long ); -#endif - -#ifdef BOOST_HAS_MS_INT64 +#elif defined(BOOST_HAS_MS_INT64) BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 ); #endif diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 80bc11c..8c7c7ef 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -8,6 +8,7 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 10 Nov 2006 Make long long and __int64 mutually exclusive (Daryle Walker) // 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker) // 03 Nov 2006 Use custom numeric types (Daryle Walker) // 02 Nov 2006 Change to Boost.Test's unit test system (Daryle Walker) @@ -15,7 +16,7 @@ #define BOOST_TEST_MAIN "Boost.Math GCD & LCM unit tests" -#include // for BOOST_MSVC +#include // for BOOST_MSVC, etc. #include // for boost::math::gcd, etc. #include // for boost::mpl::list #include @@ -108,8 +109,7 @@ typedef my_wrapped_integer MyUnsigned2; typedef ::boost::mpl::list signed_test_types; @@ -117,8 +117,7 @@ typedef ::boost::mpl::list unsigned_test_types; From 18a37cbab2ea0f150b62470c99cde4a3abb36d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20M=2E=20L=C3=B3pez=20Mu=C3=B1oz?= Date: Mon, 4 Dec 2006 07:04:33 +0000 Subject: [PATCH 17/43] various fixes for old compilers [SVN r36259] --- test/common_factor_test.cpp | 129 +++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 52 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 8c7c7ef..fcd2034 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -8,6 +8,7 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 01 Dec 2006 Various fixes for old compilers (Joaquín M López Muñoz) // 10 Nov 2006 Make long long and __int64 mutually exclusive (Daryle Walker) // 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker) // 03 Nov 2006 Use custom numeric types (Daryle Walker) @@ -17,6 +18,7 @@ #define BOOST_TEST_MAIN "Boost.Math GCD & LCM unit tests" #include // for BOOST_MSVC, etc. +#include #include // for boost::math::gcd, etc. #include // for boost::mpl::list #include @@ -50,7 +52,7 @@ public: // Template parameters typedef IntType int_type; - static int const id = ID; + BOOST_STATIC_CONSTANT(int,id = ID); // Lifetime management (use automatic destructor and copy constructor) my_wrapped_integer( int_type const &v = int_type() ) : v_( v ) {} @@ -84,14 +86,10 @@ public: self_type &operator ^=(self_type const &r) {this->v_ ^= r.v_; return *this;} // Input & output - template < typename Ch, class Tr > - friend std::basic_istream & - operator >>( std::basic_istream &i, self_type &x ) + friend std::istream & operator >>( std::istream &i, self_type &x ) { return i >> x.v_; } - template < typename Ch, class Tr > - friend std::basic_ostream & - operator <<( std::basic_ostream &o, self_type const &x ) + friend std::ostream & operator <<( std::ostream &o, self_type const &x ) { return o << x.v_; } }; // my_wrapped_integer @@ -105,6 +103,13 @@ typedef my_wrapped_integer MyUnsigned1; typedef my_wrapped_integer MyInt2; typedef my_wrapped_integer MyUnsigned2; +// Without these explicit instantiations, MSVC++ 6.5/7.0 does not find +// some friend operators in certain contexts. +MyInt1 dummy1; +MyUnsigned1 dummy2; +MyInt2 dummy3; +MyUnsigned2 dummy4; + // Various types to test with each GCD/LCM typedef ::boost::mpl::list typedef numeric_limits limits_type; public: - static const bool is_specialized = limits_type::is_specialized; + BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized); static MyInt1 min() throw() { return limits_type::min(); } static MyInt1 max() throw() { return limits_type::max(); } - static const int digits = limits_type::digits; - static const int digits10 = limits_type::digits10; - static const bool is_signed = limits_type::is_signed; - static const bool is_integer = limits_type::is_integer; - static const bool is_exact = limits_type::is_exact; - static const int radix = limits_type::radix; + BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); + BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); + BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed); + BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer); + BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact); + BOOST_STATIC_CONSTANT(int, radix = limits_type::radix); static MyInt1 epsilon() throw() { return limits_type::epsilon(); } static MyInt1 round_error() throw() { return limits_type::round_error(); } - static const int min_exponent = limits_type::min_exponent; - static const int min_exponent10 = limits_type::min_exponent10; - static const int max_exponent = limits_type::max_exponent; - static const int max_exponent10 = limits_type::max_exponent10; + BOOST_STATIC_CONSTANT(int, min_exponent = limits_type::min_exponent); + BOOST_STATIC_CONSTANT(int, min_exponent10 = limits_type::min_exponent10); + BOOST_STATIC_CONSTANT(int, max_exponent = limits_type::max_exponent); + BOOST_STATIC_CONSTANT(int, max_exponent10 = limits_type::max_exponent10); - static const bool has_infinity = limits_type::has_infinity; - static const bool has_quiet_NaN = limits_type::has_quiet_NaN; - static const bool has_signaling_NaN = limits_type::has_signaling_NaN; - static const float_denorm_style has_denorm = limits_type::has_denorm; - static const bool has_denorm_loss = limits_type::has_denorm_loss; + BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN); + BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN); + BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm); + BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss); static MyInt1 infinity() throw() { return limits_type::infinity(); } static MyInt1 quiet_NaN() throw() { return limits_type::quiet_NaN(); } static MyInt1 signaling_NaN() throw() {return limits_type::signaling_NaN();} static MyInt1 denorm_min() throw() { return limits_type::denorm_min(); } - static const bool is_iec559 = limits_type::is_iec559; - static const bool is_bounded = limits_type::is_bounded; - static const bool is_modulo = limits_type::is_modulo; + BOOST_STATIC_CONSTANT(bool, is_iec559 = limits_type::is_iec559); + BOOST_STATIC_CONSTANT(bool, is_bounded = limits_type::is_bounded); + BOOST_STATIC_CONSTANT(bool, is_modulo = limits_type::is_modulo); - static const bool traps = limits_type::traps; - static const bool tinyness_before = limits_type::tinyness_before; - static const float_round_style round_style = limits_type::round_style; + BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps); + BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before); + BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style); }; // std::numeric_limits @@ -183,30 +188,30 @@ class numeric_limits< MyUnsigned1 > typedef numeric_limits limits_type; public: - static const bool is_specialized = limits_type::is_specialized; + BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized); static MyUnsigned1 min() throw() { return limits_type::min(); } static MyUnsigned1 max() throw() { return limits_type::max(); } - static const int digits = limits_type::digits; - static const int digits10 = limits_type::digits10; - static const bool is_signed = limits_type::is_signed; - static const bool is_integer = limits_type::is_integer; - static const bool is_exact = limits_type::is_exact; - static const int radix = limits_type::radix; + BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); + BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); + BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed); + BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer); + BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact); + BOOST_STATIC_CONSTANT(int, radix = limits_type::radix); static MyUnsigned1 epsilon() throw() { return limits_type::epsilon(); } static MyUnsigned1 round_error() throw(){return limits_type::round_error();} - static const int min_exponent = limits_type::min_exponent; - static const int min_exponent10 = limits_type::min_exponent10; - static const int max_exponent = limits_type::max_exponent; - static const int max_exponent10 = limits_type::max_exponent10; + BOOST_STATIC_CONSTANT(int, min_exponent = limits_type::min_exponent); + BOOST_STATIC_CONSTANT(int, min_exponent10 = limits_type::min_exponent10); + BOOST_STATIC_CONSTANT(int, max_exponent = limits_type::max_exponent); + BOOST_STATIC_CONSTANT(int, max_exponent10 = limits_type::max_exponent10); - static const bool has_infinity = limits_type::has_infinity; - static const bool has_quiet_NaN = limits_type::has_quiet_NaN; - static const bool has_signaling_NaN = limits_type::has_signaling_NaN; - static const float_denorm_style has_denorm = limits_type::has_denorm; - static const bool has_denorm_loss = limits_type::has_denorm_loss; + BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN); + BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN); + BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm); + BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss); static MyUnsigned1 infinity() throw() { return limits_type::infinity(); } static MyUnsigned1 quiet_NaN() throw() { return limits_type::quiet_NaN(); } @@ -214,18 +219,38 @@ public: { return limits_type::signaling_NaN(); } static MyUnsigned1 denorm_min() throw(){ return limits_type::denorm_min(); } - static const bool is_iec559 = limits_type::is_iec559; - static const bool is_bounded = limits_type::is_bounded; - static const bool is_modulo = limits_type::is_modulo; + BOOST_STATIC_CONSTANT(bool, is_iec559 = limits_type::is_iec559); + BOOST_STATIC_CONSTANT(bool, is_bounded = limits_type::is_bounded); + BOOST_STATIC_CONSTANT(bool, is_modulo = limits_type::is_modulo); - static const bool traps = limits_type::traps; - static const bool tinyness_before = limits_type::tinyness_before; - static const float_round_style round_style = limits_type::round_style; + BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps); + BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before); + BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style); }; // std::numeric_limits -} // namespace std +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +// MSVC 6.0 lacks operator<< for __int64, see +// http://support.microsoft.com/default.aspx?scid=kb;en-us;168440 +inline ostream& operator<<(ostream& os, __int64 i) +{ + char buf[20]; + sprintf(buf,"%I64d", i); + os << buf; + return os; +} + +inline ostream& operator<<(ostream& os, unsigned __int64 i) +{ + char buf[20]; + sprintf(buf,"%I64u", i); + os << buf; + return os; +} +#endif + +} // namespace std // GCD tests BOOST_AUTO_TEST_SUITE( gcd_test_suite ) From f1076ff42c6f35633ab9ebc4ac282e0eee9fd508 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 19 Feb 2007 10:00:41 +0000 Subject: [PATCH 18/43] STLport workaround. [SVN r37001] --- test/common_factor_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index fcd2034..b25f010 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -163,7 +163,7 @@ public: BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity); BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN); BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN); - BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm); + BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = (float_denorm_style)limits_type::has_denorm); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss); static MyInt1 infinity() throw() { return limits_type::infinity(); } @@ -177,7 +177,7 @@ public: BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps); BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before); - BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style); + BOOST_STATIC_CONSTANT(float_round_style, round_style = (float_round_style)limits_type::round_style); }; // std::numeric_limits @@ -210,7 +210,7 @@ public: BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity); BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN); BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN); - BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm); + BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = (float_denorm_style)limits_type::has_denorm); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss); static MyUnsigned1 infinity() throw() { return limits_type::infinity(); } @@ -225,7 +225,7 @@ public: BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps); BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before); - BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style); + BOOST_STATIC_CONSTANT(float_round_style, round_style = (float_round_style)limits_type::round_style); }; // std::numeric_limits From a9d91361fa169e4fe53e5643b03022010c86c737 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 20 Feb 2007 13:28:39 +0000 Subject: [PATCH 19/43] Undo previous fix, it causes regressions. [SVN r37022] --- test/common_factor_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index b25f010..fcd2034 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -163,7 +163,7 @@ public: BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity); BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN); BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN); - BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = (float_denorm_style)limits_type::has_denorm); + BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss); static MyInt1 infinity() throw() { return limits_type::infinity(); } @@ -177,7 +177,7 @@ public: BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps); BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before); - BOOST_STATIC_CONSTANT(float_round_style, round_style = (float_round_style)limits_type::round_style); + BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style); }; // std::numeric_limits @@ -210,7 +210,7 @@ public: BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity); BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN); BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN); - BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = (float_denorm_style)limits_type::has_denorm); + BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm); BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss); static MyUnsigned1 infinity() throw() { return limits_type::infinity(); } @@ -225,7 +225,7 @@ public: BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps); BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before); - BOOST_STATIC_CONSTANT(float_round_style, round_style = (float_round_style)limits_type::round_style); + BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style); }; // std::numeric_limits From 307fee457a7951ed0ba15be4c7038a939ac66926 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sat, 6 Oct 2007 11:12:33 +0000 Subject: [PATCH 20/43] Fix Borland infinite looping issue. [SVN r39723] --- include/boost/math/common_factor_rt.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index c02d12a..6200b96 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -15,6 +15,7 @@ #include // for BOOST_NESTED_TEMPLATE, etc. #include // for std::numeric_limits +#include namespace boost @@ -142,11 +143,18 @@ namespace detail // Whittle down the values via their differences do { +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + while ( !(r[ which ] & 1u) ) + { + r[ which ] = (r[which] >> 1); + } +#else // Remove factors of two from the even one while ( !(r[ which ] & 1u) ) { r[ which ] >>= 1; } +#endif // Replace the larger of the two with their difference if ( r[!which] > r[which] ) From 217fa37de2cbe8a58c0d2128e4b731f687981d03 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 7 Feb 2008 10:13:31 +0000 Subject: [PATCH 21/43] Fix min/max usage violation. [SVN r43145] --- test/common_factor_test.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index fcd2034..c78b99b 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -129,6 +129,7 @@ typedef ::boost::mpl::list public: BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized); - static MyInt1 min() throw() { return limits_type::min(); } - static MyInt1 max() throw() { return limits_type::max(); } + static MyInt1 min BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::min)(); } + static MyInt1 max BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::max)(); } BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); @@ -190,8 +191,8 @@ class numeric_limits< MyUnsigned1 > public: BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized); - static MyUnsigned1 min() throw() { return limits_type::min(); } - static MyUnsigned1 max() throw() { return limits_type::max(); } + static MyUnsigned1 min BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::min)(); } + static MyUnsigned1 max BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::max)(); } BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); From e20431e7136529df88126fd7b23943e43b081cd3 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 29 Apr 2008 10:05:11 +0000 Subject: [PATCH 22/43] Changed long long to boost::long_long_type and unsigned long long to boost::ulong_long_type. A couple of other typo corrections, to get the code compiling with g++ -pedantic. [SVN r44877] --- include/boost/math/common_factor_rt.hpp | 4 ++-- test/common_factor_test.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index 6200b96..e7b2500 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -303,7 +303,7 @@ namespace detail BOOST_PRIVATE_GCD_UF( unsigned long ); #ifdef BOOST_HAS_LONG_LONG - BOOST_PRIVATE_GCD_UF( unsigned long long ); + BOOST_PRIVATE_GCD_UF( boost::ulong_long_type ); #elif defined(BOOST_HAS_MS_INT64) BOOST_PRIVATE_GCD_UF( unsigned __int64 ); #endif @@ -325,7 +325,7 @@ namespace detail BOOST_PRIVATE_GCD_SF( char, unsigned char ); // should work even if unsigned #ifdef BOOST_HAS_LONG_LONG - BOOST_PRIVATE_GCD_SF( long long, unsigned long long ); + BOOST_PRIVATE_GCD_SF( boost::long_long_type, boost::ulong_long_type ); #elif defined(BOOST_HAS_MS_INT64) BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 ); #endif diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index c78b99b..65907b2 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -113,7 +113,7 @@ MyUnsigned2 dummy4; // Various types to test with each GCD/LCM typedef ::boost::mpl::list Date: Sun, 29 Jun 2008 09:02:05 +0000 Subject: [PATCH 23/43] Fix more inspect report issues, and regenerated the docs. [SVN r46839] --- test/common_factor_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 65907b2..baeef15 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -8,7 +8,7 @@ // See http://www.boost.org for most recent version including documentation. // Revision History -// 01 Dec 2006 Various fixes for old compilers (Joaquín M López Muñoz) +// 01 Dec 2006 Various fixes for old compilers (Joaquín M Lopez Munoz) // 10 Nov 2006 Make long long and __int64 mutually exclusive (Daryle Walker) // 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker) // 03 Nov 2006 Use custom numeric types (Daryle Walker) From bdafb0701200cf0bcc100fde36b8b30e2a94e48c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Jul 2008 09:58:27 +0000 Subject: [PATCH 24/43] Replace a couple of non-ascii symbols. [SVN r46943] --- test/common_factor_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index baeef15..04897da 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -8,7 +8,7 @@ // See http://www.boost.org for most recent version including documentation. // Revision History -// 01 Dec 2006 Various fixes for old compilers (Joaquín M Lopez Munoz) +// 01 Dec 2006 Various fixes for old compilers (Joaquin M Lopez Munoz) // 10 Nov 2006 Make long long and __int64 mutually exclusive (Daryle Walker) // 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker) // 03 Nov 2006 Use custom numeric types (Daryle Walker) From 7c528c325e1e95acc48efbb5bbcd23ca01aca95f Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Sun, 27 Jul 2008 23:43:04 +0000 Subject: [PATCH 25/43] Tweaked files to pass inspection report; one file had some min/max violations; but all had to have 'boostinspect:nolicense' set because a copyrighter, Paul Moore, has disappeared, so his files can never be changed to the main Boost license [SVN r47847] --- include/boost/math/common_factor_rt.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index e7b2500..f45f3a0 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -6,6 +6,10 @@ // without express or implied warranty, and with no claim as to its suitability // for any purpose. +// boostinspect:nolicense (don't complain about the lack of a Boost license) +// (Paul Moore hasn't been in contact for years, so there's no way to change the +// license.) + // See http://www.boost.org for updates, documentation, and revision history. #ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP From 5174291e08214d1d07ce8e46aaa85c85713047c9 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Fri, 7 May 2010 15:36:09 +0000 Subject: [PATCH 26/43] Fix failures when used with an expression-template enabled number type such as the gmpxx clases. Add additional concept check for integer code using gmp classes. Fixes #4139. [SVN r61837] --- include/boost/math/common_factor_rt.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index f45f3a0..ef2a967 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -78,8 +78,8 @@ namespace detail RingType gcd_euclidean ( - RingType a, - RingType b + RingType a, + RingType b ) { // Avoid repeated construction @@ -116,7 +116,7 @@ namespace detail IntegerType const zero = static_cast( 0 ); IntegerType const result = gcd_euclidean( a, b ); - return ( result < zero ) ? -result : result; + return ( result < zero ) ? static_cast(-result) : result; } // Greatest common divisor for unsigned binary integers @@ -212,7 +212,7 @@ namespace detail IntegerType const zero = static_cast( 0 ); IntegerType const result = lcm_euclidean( a, b ); - return ( result < zero ) ? -result : result; + return ( result < zero ) ? static_cast(-result) : result; } // Function objects to find the best way of computing GCD or LCM From d38557f5f37a3daf707f13f8f413630fb90b01f0 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 28 Jun 2010 15:32:19 +0000 Subject: [PATCH 27/43] Make the compile time gcd facilities work with greatest integer types, and be mpl compatible. [SVN r63408] --- include/boost/math/common_factor_ct.hpp | 70 +++++++++++-------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp index 63d2a56..848c925 100644 --- a/include/boost/math/common_factor_ct.hpp +++ b/include/boost/math/common_factor_ct.hpp @@ -11,31 +11,29 @@ #define BOOST_MATH_COMMON_FACTOR_CT_HPP #include // self include - #include // for BOOST_STATIC_CONSTANT, etc. - +#include namespace boost { namespace math { - // Implementation details --------------------------------------------------// namespace detail { #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Build GCD with Euclid's recursive algorithm - template < unsigned long Value1, unsigned long Value2 > + template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd_helper_t { private: - BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 ); - BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 ); + 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) + #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 ) @@ -47,24 +45,24 @@ namespace detail #undef BOOST_DETAIL_GCD_HELPER_VAL public: - BOOST_STATIC_CONSTANT( unsigned long, value = next_step_type::value ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = next_step_type::value ); }; // Non-recursive case - template < unsigned long Value1 > + template < static_gcd_type Value1 > struct static_gcd_helper_t< Value1, 0UL > { - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 ); }; #else // Use inner class template workaround from Peter Dimov - template < unsigned long Value1 > + template < static_gcd_type Value1 > struct static_gcd_helper2_t { - template < unsigned long Value2 > + template < static_gcd_type Value2 > struct helper { - BOOST_STATIC_CONSTANT( unsigned long, value + BOOST_STATIC_CONSTANT( static_gcd_type, value = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE helper::value ); }; @@ -72,7 +70,7 @@ namespace detail template < > struct helper< 0UL > { - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 ); }; }; @@ -80,18 +78,18 @@ namespace detail template < > struct static_gcd_helper2_t< 0UL > { - template < unsigned long Value2 > + template < static_gcd_type Value2 > struct helper { - BOOST_STATIC_CONSTANT( unsigned long, value = Value2 ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value2 ); }; }; // Build the GCD from the above template(s) - template < unsigned long Value1, unsigned long Value2 > + template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd_helper_t { - BOOST_STATIC_CONSTANT( unsigned long, value + BOOST_STATIC_CONSTANT( static_gcd_type, value = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE helper::value ); }; @@ -99,12 +97,12 @@ namespace detail #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Build the LCM from the GCD - template < unsigned long Value1, unsigned long Value2 > + template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm_helper_t { typedef static_gcd_helper_t gcd_type; - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value * Value2 ); }; @@ -112,26 +110,26 @@ namespace detail template < > struct static_lcm_helper_t< 0UL, 0UL > { - BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); }; #else // Adapt GCD's inner class template workaround for LCM - template < unsigned long Value1 > + template < static_gcd_type Value1 > struct static_lcm_helper2_t { - template < unsigned long Value2 > + template < static_gcd_type Value2 > struct helper { typedef static_gcd_helper_t gcd_type; - BOOST_STATIC_CONSTANT( unsigned long, value = Value1 + BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value * Value2 ); }; template < > struct helper< 0UL > { - BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); }; }; @@ -139,18 +137,18 @@ namespace detail template < > struct static_lcm_helper2_t< 0UL > { - template < unsigned long Value2 > + template < static_gcd_type Value2 > struct helper { - BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); + BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); }; }; // Build the LCM from the above template(s) - template < unsigned long Value1, unsigned long Value2 > + template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm_helper_t { - BOOST_STATIC_CONSTANT( unsigned long, value + BOOST_STATIC_CONSTANT( static_gcd_type, value = static_lcm_helper2_t::BOOST_NESTED_TEMPLATE helper::value ); }; @@ -161,23 +159,17 @@ namespace detail // Compile-time greatest common divisor evaluator class declaration --------// -template < unsigned long Value1, unsigned long Value2 > -struct static_gcd +template < static_gcd_type Value1, static_gcd_type Value2 > +struct static_gcd : public mpl::integral_c::value) > { - BOOST_STATIC_CONSTANT( unsigned long, value - = (detail::static_gcd_helper_t::value) ); - }; // boost::math::static_gcd // Compile-time least common multiple evaluator class declaration ----------// -template < unsigned long Value1, unsigned long Value2 > -struct static_lcm +template < static_gcd_type Value1, static_gcd_type Value2 > +struct static_lcm : public mpl::integral_c::value) > { - BOOST_STATIC_CONSTANT( unsigned long, value - = (detail::static_lcm_helper_t::value) ); - }; // boost::math::static_lcm From ce4bd6cc981001723d2986bb778a453448523430 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 1 Jul 2010 17:47:51 +0000 Subject: [PATCH 28/43] Fix signed/unsigned comparison warnings when char is unsigned. [SVN r63496] --- include/boost/math/common_factor_rt.hpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index ef2a967..1a70bff 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -19,6 +19,7 @@ #include // for BOOST_NESTED_TEMPLATE, etc. #include // for std::numeric_limits +#include // for CHAR_MIN #include @@ -312,6 +313,10 @@ namespace detail BOOST_PRIVATE_GCD_UF( unsigned __int64 ); #endif +#if CHAR_MIN == 0 + BOOST_PRIVATE_GCD_UF( char ); // char is unsigned +#endif + #undef BOOST_PRIVATE_GCD_UF #define BOOST_PRIVATE_GCD_SF( St, Ut ) \ @@ -326,7 +331,9 @@ namespace detail BOOST_PRIVATE_GCD_SF( int, unsigned ); BOOST_PRIVATE_GCD_SF( long, unsigned long ); - BOOST_PRIVATE_GCD_SF( char, unsigned char ); // should work even if unsigned +#if CHAR_MIN < 0 + BOOST_PRIVATE_GCD_SF( char, unsigned char ); // char is signed +#endif #ifdef BOOST_HAS_LONG_LONG BOOST_PRIVATE_GCD_SF( boost::long_long_type, boost::ulong_long_type ); From 72b569f84f41b582e29d238d47220d06c2b04a41 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 3 Mar 2011 11:09:23 +0000 Subject: [PATCH 29/43] MSVC warning suppression. [SVN r69509] --- include/boost/math/common_factor_rt.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index 1a70bff..4582a96 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -22,6 +22,10 @@ #include // for CHAR_MIN #include +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4127 4244) // Conditional expression is constant +#endif namespace boost { @@ -519,5 +523,8 @@ lcm } // namespace math } // namespace boost +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif #endif // BOOST_MATH_COMMON_FACTOR_RT_HPP From eea434b0f1fcc6356bdf6beeef7a9c0c35d8b750 Mon Sep 17 00:00:00 2001 From: Gennadiy Rozental Date: Wed, 5 Oct 2011 10:28:08 +0000 Subject: [PATCH 30/43] eliminated test_case_template.hpp [SVN r74735] --- test/common_factor_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 04897da..8fd7288 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -23,7 +23,6 @@ #include // for boost::mpl::list #include #include -#include #include // for std::basic_istream #include // for std::numeric_limits From fecb6b5509270b998e7bceebeef22811c1062c11 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Wed, 11 Jul 2012 17:26:05 +0000 Subject: [PATCH 31/43] Fix numeric_limits specialization. [SVN r79419] --- test/common_factor_test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index 8fd7288..db9032e 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -148,6 +148,9 @@ public: BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); +#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST + BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10); +#endif BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed); BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer); BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact); @@ -195,6 +198,9 @@ public: BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); +#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST + BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10); +#endif BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed); BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer); BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact); From 9f43b6a7d679af8e8204014578ecefeaea3ca497 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 27 Nov 2012 14:19:45 +0000 Subject: [PATCH 32/43] Removed missed usage of deprecated macros in Boost.Math [SVN r81586] --- test/common_factor_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common_factor_test.cpp b/test/common_factor_test.cpp index db9032e..11c32a6 100644 --- a/test/common_factor_test.cpp +++ b/test/common_factor_test.cpp @@ -148,7 +148,7 @@ public: BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); -#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST +#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10); #endif BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed); @@ -198,7 +198,7 @@ public: BOOST_STATIC_CONSTANT(int, digits = limits_type::digits); BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10); -#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST +#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10); #endif BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed); From b70c89a3fffe9968682c06243fb78139644578ba Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:17:48 +0000 Subject: [PATCH 33/43] Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Process #ifndef...#else...#endif blocks. [SVN r86245] --- include/boost/math/common_factor_ct.hpp | 83 ------------------------- include/boost/math/common_factor_rt.hpp | 70 --------------------- 2 files changed, 153 deletions(-) diff --git a/include/boost/math/common_factor_ct.hpp b/include/boost/math/common_factor_ct.hpp index 848c925..bf58b94 100644 --- a/include/boost/math/common_factor_ct.hpp +++ b/include/boost/math/common_factor_ct.hpp @@ -23,7 +23,6 @@ namespace math namespace detail { -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Build GCD with Euclid's recursive algorithm template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd_helper_t @@ -54,48 +53,7 @@ namespace detail { BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 ); }; -#else - // Use inner class template workaround from Peter Dimov - template < static_gcd_type Value1 > - struct static_gcd_helper2_t - { - template < static_gcd_type Value2 > - struct helper - { - BOOST_STATIC_CONSTANT( static_gcd_type, value - = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE - helper::value ); - }; - template < > - struct helper< 0UL > - { - BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 ); - }; - }; - - // Special case - template < > - struct static_gcd_helper2_t< 0UL > - { - template < static_gcd_type Value2 > - struct helper - { - BOOST_STATIC_CONSTANT( static_gcd_type, value = Value2 ); - }; - }; - - // Build the GCD from the above template(s) - template < static_gcd_type Value1, static_gcd_type Value2 > - struct static_gcd_helper_t - { - BOOST_STATIC_CONSTANT( static_gcd_type, value - = static_gcd_helper2_t::BOOST_NESTED_TEMPLATE - helper::value ); - }; -#endif - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Build the LCM from the GCD template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm_helper_t @@ -112,47 +70,6 @@ namespace detail { BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); }; -#else - // Adapt GCD's inner class template workaround for LCM - template < static_gcd_type Value1 > - struct static_lcm_helper2_t - { - template < static_gcd_type Value2 > - struct helper - { - typedef static_gcd_helper_t gcd_type; - - BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 - / gcd_type::value * Value2 ); - }; - - template < > - struct helper< 0UL > - { - BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); - }; - }; - - // Special case - template < > - struct static_lcm_helper2_t< 0UL > - { - template < static_gcd_type Value2 > - struct helper - { - BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL ); - }; - }; - - // Build the LCM from the above template(s) - template < static_gcd_type Value1, static_gcd_type Value2 > - struct static_lcm_helper_t - { - BOOST_STATIC_CONSTANT( static_gcd_type, value - = static_lcm_helper2_t::BOOST_NESTED_TEMPLATE - helper::value ); - }; -#endif } // namespace detail diff --git a/include/boost/math/common_factor_rt.hpp b/include/boost/math/common_factor_rt.hpp index 4582a96..10a92eb 100644 --- a/include/boost/math/common_factor_rt.hpp +++ b/include/boost/math/common_factor_rt.hpp @@ -222,7 +222,6 @@ namespace detail // Function objects to find the best way of computing GCD or LCM #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > struct gcd_optimal_evaluator_helper_t { @@ -240,40 +239,6 @@ namespace detail return gcd_integer( a, b ); } }; -#else - template < bool IsSpecialized, bool IsSigned > - struct gcd_optimal_evaluator_helper2_t - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return gcd_euclidean( a, b ); - } - }; - }; - - template < > - struct gcd_optimal_evaluator_helper2_t< true, true > - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return gcd_integer( a, b ); - } - }; - }; - - template < typename T, bool IsSpecialized, bool IsSigned > - struct gcd_optimal_evaluator_helper_t - : gcd_optimal_evaluator_helper2_t - ::BOOST_NESTED_TEMPLATE helper - { - }; -#endif template < typename T > struct gcd_optimal_evaluator @@ -348,7 +313,6 @@ namespace detail #undef BOOST_PRIVATE_GCD_SF #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template < typename T, bool IsSpecialized, bool IsSigned > struct lcm_optimal_evaluator_helper_t { @@ -366,40 +330,6 @@ namespace detail return lcm_integer( a, b ); } }; -#else - template < bool IsSpecialized, bool IsSigned > - struct lcm_optimal_evaluator_helper2_t - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return lcm_euclidean( a, b ); - } - }; - }; - - template < > - struct lcm_optimal_evaluator_helper2_t< true, true > - { - template < typename T > - struct helper - { - T operator ()( T const &a, T const &b ) - { - return lcm_integer( a, b ); - } - }; - }; - - template < typename T, bool IsSpecialized, bool IsSigned > - struct lcm_optimal_evaluator_helper_t - : lcm_optimal_evaluator_helper2_t - ::BOOST_NESTED_TEMPLATE helper - { - }; -#endif template < typename T > struct lcm_optimal_evaluator From dcf16f30bce45396a4366076bb1d4a7cc8c226c8 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 9 Oct 2007 17:17:50 +0000 Subject: [PATCH 34/43] Added refactored docs for existing Boost.Math libraries. [SVN r39851] --- doc/gcd/math-gcd.qbk | 243 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 doc/gcd/math-gcd.qbk diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk new file mode 100644 index 0000000..625b2a5 --- /dev/null +++ b/doc/gcd/math-gcd.qbk @@ -0,0 +1,243 @@ +[article GCD and LCM + [quickbook 1.3] + [copyright 2001-2002 Daryle Walker] + [license + 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 http://www.boost.org/LICENSE_1_0.txt]) + ] + [authors [Walker, Daryle]] + [category math] + [last-revision $Date: 2006-12-29 11:08:32 +0000 (Fri, 29 Dec 2006) $] +] + + +[section:gcd_lcm Greatest Common Divisor and Least Common Multiple] + +[section Introduction] + +The class and function templates in +provide run-time and compile-time evaluation of the greatest common divisor +(GCD) or least common multiple (LCM) of two integers. +These facilities are useful for many numeric-oriented generic +programming problems. + +[endsect] + +[section Synopsis] + + namespace boost + { + namespace math + { + + template < typename IntegerType > + class gcd_evaluator; + template < typename IntegerType > + class lcm_evaluator; + + template < typename IntegerType > + IntegerType gcd( IntegerType const &a, IntegerType const &b ); + template < typename IntegerType > + IntegerType lcm( IntegerType const &a, IntegerType const &b ); + + template < unsigned long Value1, unsigned long Value2 > + struct static_gcd; + template < unsigned long Value1, unsigned long Value2 > + struct static_lcm; + + } + } + +[endsect] + +[section GCD Function Object] + +[*Header: ] [@../../../../../boost/math/common_factor_rt.hpp ] + + template < typename IntegerType > + class boost::math::gcd_evaluator + { + public: + // Types + typedef IntegerType result_type; + typedef IntegerType first_argument_type; + typedef IntegerType second_argument_type; + + // Function object interface + result_type operator ()( first_argument_type const &a, + second_argument_type const &b ) const; + }; + +The boost::math::gcd_evaluator class template defines a function object +class to return the greatest common divisor of two integers. +The template is parameterized by a single type, called IntegerType here. +This type should be a numeric type that represents integers. +The result of the function object is always nonnegative, even if either of +the operator arguments is negative. + +This function object class template is used in the corresponding version of +the GCD function template. If a numeric type wants to customize evaluations +of its greatest common divisors, then the type should specialize on the +gcd_evaluator class template. + +[endsect] + +[section LCM Function Object] + +[*Header: ] [@../../../../../boost/math/common_factor_rt.hpp ] + + template < typename IntegerType > + class boost::math::lcm_evaluator + { + public: + // Types + typedef IntegerType result_type; + typedef IntegerType first_argument_type; + typedef IntegerType second_argument_type; + + // Function object interface + result_type operator ()( first_argument_type const &a, + second_argument_type const &b ) const; + }; + +The boost::math::lcm_evaluator class template defines a function object +class to return the least common multiple of two integers. The template +is parameterized by a single type, called IntegerType here. This type +should be a numeric type that represents integers. The result of the +function object is always nonnegative, even if either of the operator +arguments is negative. If the least common multiple is beyond the range +of the integer type, the results are undefined. + +This function object class template is used in the corresponding version +of the LCM function template. If a numeric type wants to customize +evaluations of its least common multiples, then the type should +specialize on the lcm_evaluator class template. + +[endsect] + +[section:run_time Run-time GCD & LCM Determination] + +[*Header: ] [@../../../../../boost/math/common_factor_rt.hpp ] + + template < typename IntegerType > + IntegerType boost::math::gcd( IntegerType const &a, IntegerType const &b ); + + template < typename IntegerType > + IntegerType boost::math::lcm( IntegerType const &a, IntegerType const &b ); + +The boost::math::gcd function template returns the greatest common +(nonnegative) divisor of the two integers passed to it. +The boost::math::lcm function template returns the least common +(nonnegative) multiple of the two integers passed to it. +The function templates are parameterized on the function arguments' +IntegerType, which is also the return type. Internally, these function +templates use an object of the corresponding version of the +gcd_evaluator and lcm_evaluator class templates, respectively. + +[endsect] + +[section:compile_time Compile time GCD and LCM determination] + +[*Header: ] [@../../../../../boost/math/common_factor_ct.hpp ] + + template < unsigned long Value1, unsigned long Value2 > + struct boost::math::static_gcd + { + static unsigned long const value = implementation_defined; + }; + + template < unsigned long Value1, unsigned long Value2 > + struct boost::math::static_lcm + { + static unsigned long const value = implementation_defined; + }; + +The boost::math::static_gcd and boost::math::static_lcm class templates +take two value-based template parameters of the unsigned long type +and have a single static constant data member, value, of that same type. +The value of that member is the greatest common factor or least +common multiple, respectively, of the template arguments. +A compile-time error will occur if the least common multiple +is beyond the range of an unsigned long. + +[h3 Example] + + #include + #include + #include + + + int main() + { + using std::cout; + using std::endl; + + cout << "The GCD and LCM of 6 and 15 are " + << boost::math::gcd(6, 15) << " and " + << boost::math::lcm(6, 15) << ", respectively." + << endl; + + cout << "The GCD and LCM of 8 and 9 are " + << boost::math::static_gcd<8, 9>::value + << " and " + << boost::math::static_lcm<8, 9>::value + << ", respectively." << endl; + + int a[] = { 4, 5, 6 }, b[] = { 7, 8, 9 }, c[3]; + std::transform( a, a + 3, b, c, boost::math::gcd_evaluator() ); + std::copy( c, c + 3, std::ostream_iterator(cout, " ") ); + } + +[endsect] + +[section:header Header ] + +This header simply includes the headers +[@../../../../../boost/math/common_factor_ct.hpp ] +and [@../../../../../boost/math/common_factor_rt.hpp ]. + +Note this is a legacy header: it used to contain the actual implementation, +but the compile-time and run-time facilities +were moved to separate headers (since they were independent of each other). + +[endsect] + +[section:demo Demonstration Program] + +The program [@../../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from +instantiating various examples of the run-time GCD and LCM function +templates and the compile-time GCD and LCM class templates. +(The run-time GCD and LCM class templates are tested indirectly through +the run-time function templates.) + +[endsect] + +[section Rationale] + +The greatest common divisor and least common multiple functions are +greatly used in some numeric contexts, including some of the other +Boost libraries. Centralizing these functions to one header improves +code factoring and eases maintainence. + +[endsect] + +[section History] + +* 17 Dec 2005: Converted documentation to Quickbook Format. +* 2 Jul 2002: Compile-time and run-time items separated to new headers. +* 7 Nov 2001: Initial version + +[endsect] + +[section Credits] + +The author of the Boost compilation of GCD and LCM computations is +Daryle Walker. The code was prompted by existing code hiding in the +implementations of Paul Moore's rational library and Steve Cleary's +pool library. The code had updates by Helmut Zeisel. + +[endsect] + +[endsect] + From e64047b7c789b76ae3e113473e6f162ed077912f Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 21 Feb 2008 10:37:59 +0000 Subject: [PATCH 35/43] Fix typo in example. Added links to PDF versions of the docs. Regenerated all the docs to fix people links. [SVN r43346] --- doc/gcd/math-gcd.qbk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 625b2a5..4e45bfa 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -11,6 +11,10 @@ [last-revision $Date: 2006-12-29 11:08:32 +0000 (Fri, 29 Dec 2006) $] ] +This manual is also available in +[@http:svn.boost.org/svn/boost/sandbox/pdf/math/release/math-gcd.pdf +printer friendly PDF format]. + [section:gcd_lcm Greatest Common Divisor and Least Common Multiple] From f194e652ab077f0448a576d095efcd05bb01724c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 28 May 2008 09:39:25 +0000 Subject: [PATCH 36/43] Fix links to pdfs in the maths documentation. [SVN r45861] --- doc/gcd/math-gcd.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 4e45bfa..2e3673a 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -12,7 +12,7 @@ ] This manual is also available in -[@http:svn.boost.org/svn/boost/sandbox/pdf/math/release/math-gcd.pdf +[@http://svn.boost.org/svn/boost/sandbox/pdf/math/release/math-gcd.pdf printer friendly PDF format]. From 95a4f1e235ffd69ae2732b3d3bd1e93c545bd5df Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 28 Jun 2010 15:59:21 +0000 Subject: [PATCH 37/43] Update docs to match code. [SVN r63409] --- doc/gcd/math-gcd.qbk | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 2e3673a..6607044 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -44,10 +44,12 @@ programming problems. IntegerType gcd( IntegerType const &a, IntegerType const &b ); template < typename IntegerType > IntegerType lcm( IntegerType const &a, IntegerType const &b ); + + typedef ``['see-below]`` static_gcd_type; - template < unsigned long Value1, unsigned long Value2 > + template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd; - template < unsigned long Value1, unsigned long Value2 > + template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm; } @@ -145,25 +147,31 @@ gcd_evaluator and lcm_evaluator class templates, respectively. [*Header: ] [@../../../../../boost/math/common_factor_ct.hpp ] - template < unsigned long Value1, unsigned long Value2 > - struct boost::math::static_gcd + typedef ``['unspecified]`` static_gcd_type; + + template < static_gcd_type Value1, static_gcd_type Value2 > + struct boost::math::static_gcd : public mpl::integral_c { - static unsigned long const value = implementation_defined; }; - template < unsigned long Value1, unsigned long Value2 > - struct boost::math::static_lcm + template < static_gcd_type Value1, static_gcd_type Value2 > + struct boost::math::static_lcm : public mpl::integral_c { - static unsigned long const value = implementation_defined; }; + +The type `static_gcd_type` is the widest unsigned-integer-type that is supported +for use in integral-constant-expressions by the compiler. Usually this +the same type as `boost::uintmax_t`, but may fall back to being `unsigned long` +for some older compilers. The boost::math::static_gcd and boost::math::static_lcm class templates -take two value-based template parameters of the unsigned long type -and have a single static constant data member, value, of that same type. -The value of that member is the greatest common factor or least +take two value-based template parameters of the ['static_gcd_type] type +and inherit from the type `boost::mpl::integral_c`. +Inherited from the base class, they have a member /value/ +that is the greatest common factor or least common multiple, respectively, of the template arguments. A compile-time error will occur if the least common multiple -is beyond the range of an unsigned long. +is beyond the range of `static_gcd_type`. [h3 Example] From e394f8fd864ca91569b8468c5912f9c0f36450a3 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sat, 1 Jan 2011 17:16:10 +0000 Subject: [PATCH 38/43] Change PDF URL to SF download page. Add optional index generation. [SVN r67545] --- doc/gcd/math-gcd.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 6607044..a1b6c08 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -12,7 +12,7 @@ ] This manual is also available in -[@http://svn.boost.org/svn/boost/sandbox/pdf/math/release/math-gcd.pdf +[@http://sourceforge.net/projects/boost/files/boost-docs/ printer friendly PDF format]. From 9677dbd035a3f32ce31244ed3d47f373e2ccab89 Mon Sep 17 00:00:00 2001 From: "Paul A. Bristow" Date: Mon, 3 Dec 2012 15:53:55 +0000 Subject: [PATCH 39/43] Added missing #include [SVN r81697] --- doc/gcd/math-gcd.qbk | 118 +++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index a1b6c08..455eb44 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -11,8 +11,8 @@ [last-revision $Date: 2006-12-29 11:08:32 +0000 (Fri, 29 Dec 2006) $] ] -This manual is also available in -[@http://sourceforge.net/projects/boost/files/boost-docs/ +This manual is also available in +[@http://sourceforge.net/projects/boost/files/boost-docs/ printer friendly PDF format]. @@ -20,10 +20,10 @@ printer friendly PDF format]. [section Introduction] -The class and function templates in -provide run-time and compile-time evaluation of the greatest common divisor -(GCD) or least common multiple (LCM) of two integers. -These facilities are useful for many numeric-oriented generic +The class and function templates in +provide run-time and compile-time evaluation of the greatest common divisor +(GCD) or least common multiple (LCM) of two integers. +These facilities are useful for many numeric-oriented generic programming problems. [endsect] @@ -44,7 +44,7 @@ programming problems. IntegerType gcd( IntegerType const &a, IntegerType const &b ); template < typename IntegerType > IntegerType lcm( IntegerType const &a, IntegerType const &b ); - + typedef ``['see-below]`` static_gcd_type; template < static_gcd_type Value1, static_gcd_type Value2 > @@ -54,7 +54,7 @@ programming problems. } } - + [endsect] [section GCD Function Object] @@ -75,16 +75,16 @@ programming problems. second_argument_type const &b ) const; }; -The boost::math::gcd_evaluator class template defines a function object -class to return the greatest common divisor of two integers. -The template is parameterized by a single type, called IntegerType here. -This type should be a numeric type that represents integers. -The result of the function object is always nonnegative, even if either of +The boost::math::gcd_evaluator class template defines a function object +class to return the greatest common divisor of two integers. +The template is parameterized by a single type, called IntegerType here. +This type should be a numeric type that represents integers. +The result of the function object is always nonnegative, even if either of the operator arguments is negative. -This function object class template is used in the corresponding version of -the GCD function template. If a numeric type wants to customize evaluations -of its greatest common divisors, then the type should specialize on the +This function object class template is used in the corresponding version of +the GCD function template. If a numeric type wants to customize evaluations +of its greatest common divisors, then the type should specialize on the gcd_evaluator class template. [endsect] @@ -107,17 +107,17 @@ gcd_evaluator class template. second_argument_type const &b ) const; }; -The boost::math::lcm_evaluator class template defines a function object -class to return the least common multiple of two integers. The template -is parameterized by a single type, called IntegerType here. This type -should be a numeric type that represents integers. The result of the -function object is always nonnegative, even if either of the operator -arguments is negative. If the least common multiple is beyond the range +The boost::math::lcm_evaluator class template defines a function object +class to return the least common multiple of two integers. The template +is parameterized by a single type, called IntegerType here. This type +should be a numeric type that represents integers. The result of the +function object is always nonnegative, even if either of the operator +arguments is negative. If the least common multiple is beyond the range of the integer type, the results are undefined. -This function object class template is used in the corresponding version -of the LCM function template. If a numeric type wants to customize -evaluations of its least common multiples, then the type should +This function object class template is used in the corresponding version +of the LCM function template. If a numeric type wants to customize +evaluations of its least common multiples, then the type should specialize on the lcm_evaluator class template. [endsect] @@ -132,13 +132,13 @@ specialize on the lcm_evaluator class template. template < typename IntegerType > IntegerType boost::math::lcm( IntegerType const &a, IntegerType const &b ); -The boost::math::gcd function template returns the greatest common -(nonnegative) divisor of the two integers passed to it. -The boost::math::lcm function template returns the least common -(nonnegative) multiple of the two integers passed to it. -The function templates are parameterized on the function arguments' -IntegerType, which is also the return type. Internally, these function -templates use an object of the corresponding version of the +The boost::math::gcd function template returns the greatest common +(nonnegative) divisor of the two integers passed to it. +The boost::math::lcm function template returns the least common +(nonnegative) multiple of the two integers passed to it. +The function templates are parameterized on the function arguments' +IntegerType, which is also the return type. Internally, these function +templates use an object of the corresponding version of the gcd_evaluator and lcm_evaluator class templates, respectively. [endsect] @@ -158,19 +158,19 @@ gcd_evaluator and lcm_evaluator class templates, respectively. struct boost::math::static_lcm : public mpl::integral_c { }; - -The type `static_gcd_type` is the widest unsigned-integer-type that is supported + +The type `static_gcd_type` is the widest unsigned-integer-type that is supported for use in integral-constant-expressions by the compiler. Usually this the same type as `boost::uintmax_t`, but may fall back to being `unsigned long` for some older compilers. -The boost::math::static_gcd and boost::math::static_lcm class templates -take two value-based template parameters of the ['static_gcd_type] type -and inherit from the type `boost::mpl::integral_c`. -Inherited from the base class, they have a member /value/ -that is the greatest common factor or least -common multiple, respectively, of the template arguments. -A compile-time error will occur if the least common multiple +The boost::math::static_gcd and boost::math::static_lcm class templates +take two value-based template parameters of the ['static_gcd_type] type +and inherit from the type `boost::mpl::integral_c`. +Inherited from the base class, they have a member /value/ +that is the greatest common factor or least +common multiple, respectively, of the template arguments. +A compile-time error will occur if the least common multiple is beyond the range of `static_gcd_type`. [h3 Example] @@ -178,7 +178,7 @@ is beyond the range of `static_gcd_type`. #include #include #include - + #include int main() { @@ -205,31 +205,31 @@ is beyond the range of `static_gcd_type`. [section:header Header ] -This header simply includes the headers -[@../../../../../boost/math/common_factor_ct.hpp ] +This header simply includes the headers +[@../../../../../boost/math/common_factor_ct.hpp ] and [@../../../../../boost/math/common_factor_rt.hpp ]. - -Note this is a legacy header: it used to contain the actual implementation, -but the compile-time and run-time facilities + +Note this is a legacy header: it used to contain the actual implementation, +but the compile-time and run-time facilities were moved to separate headers (since they were independent of each other). [endsect] [section:demo Demonstration Program] -The program [@../../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from -instantiating various examples of the run-time GCD and LCM function -templates and the compile-time GCD and LCM class templates. -(The run-time GCD and LCM class templates are tested indirectly through +The program [@../../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from +instantiating various examples of the run-time GCD and LCM function +templates and the compile-time GCD and LCM class templates. +(The run-time GCD and LCM class templates are tested indirectly through the run-time function templates.) [endsect] [section Rationale] -The greatest common divisor and least common multiple functions are -greatly used in some numeric contexts, including some of the other -Boost libraries. Centralizing these functions to one header improves +The greatest common divisor and least common multiple functions are +greatly used in some numeric contexts, including some of the other +Boost libraries. Centralizing these functions to one header improves code factoring and eases maintainence. [endsect] @@ -237,16 +237,16 @@ code factoring and eases maintainence. [section History] * 17 Dec 2005: Converted documentation to Quickbook Format. -* 2 Jul 2002: Compile-time and run-time items separated to new headers. -* 7 Nov 2001: Initial version +* 2 Jul 2002: Compile-time and run-time items separated to new headers. +* 7 Nov 2001: Initial version [endsect] [section Credits] -The author of the Boost compilation of GCD and LCM computations is -Daryle Walker. The code was prompted by existing code hiding in the -implementations of Paul Moore's rational library and Steve Cleary's +The author of the Boost compilation of GCD and LCM computations is +Daryle Walker. The code was prompted by existing code hiding in the +implementations of Paul Moore's rational library and Steve Cleary's pool library. The code had updates by Helmut Zeisel. [endsect] From ae8ee599ac1185d966455cacf9ad4e968ca5cb1c Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sun, 5 May 2013 12:32:36 +0000 Subject: [PATCH 40/43] Reorganise directory structure to make things easier to find and maintain. [SVN r84143] --- doc/gcd/math-gcd.qbk | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 455eb44..4b4bbfb 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -1,22 +1,4 @@ -[article GCD and LCM - [quickbook 1.3] - [copyright 2001-2002 Daryle Walker] - [license - 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 http://www.boost.org/LICENSE_1_0.txt]) - ] - [authors [Walker, Daryle]] - [category math] - [last-revision $Date: 2006-12-29 11:08:32 +0000 (Fri, 29 Dec 2006) $] -] - -This manual is also available in -[@http://sourceforge.net/projects/boost/files/boost-docs/ -printer friendly PDF format]. - - -[section:gcd_lcm Greatest Common Divisor and Least Common Multiple] +[section:gcd_lcm Integer Utilities (Greatest Common Divisor and Least Common Multiple)] [section Introduction] @@ -59,7 +41,7 @@ programming problems. [section GCD Function Object] -[*Header: ] [@../../../../../boost/math/common_factor_rt.hpp ] +[*Header: ] [@../../../../boost/math/common_factor_rt.hpp ] template < typename IntegerType > class boost::math::gcd_evaluator @@ -91,7 +73,7 @@ gcd_evaluator class template. [section LCM Function Object] -[*Header: ] [@../../../../../boost/math/common_factor_rt.hpp ] +[*Header: ] [@../../../../boost/math/common_factor_rt.hpp ] template < typename IntegerType > class boost::math::lcm_evaluator @@ -124,7 +106,7 @@ specialize on the lcm_evaluator class template. [section:run_time Run-time GCD & LCM Determination] -[*Header: ] [@../../../../../boost/math/common_factor_rt.hpp ] +[*Header: ] [@../../../../boost/math/common_factor_rt.hpp ] template < typename IntegerType > IntegerType boost::math::gcd( IntegerType const &a, IntegerType const &b ); @@ -145,7 +127,7 @@ gcd_evaluator and lcm_evaluator class templates, respectively. [section:compile_time Compile time GCD and LCM determination] -[*Header: ] [@../../../../../boost/math/common_factor_ct.hpp ] +[*Header: ] [@../../../../boost/math/common_factor_ct.hpp ] typedef ``['unspecified]`` static_gcd_type; @@ -206,8 +188,8 @@ is beyond the range of `static_gcd_type`. [section:header Header ] This header simply includes the headers -[@../../../../../boost/math/common_factor_ct.hpp ] -and [@../../../../../boost/math/common_factor_rt.hpp ]. +[@../../../../boost/math/common_factor_ct.hpp ] +and [@../../../../boost/math/common_factor_rt.hpp ]. Note this is a legacy header: it used to contain the actual implementation, but the compile-time and run-time facilities @@ -217,7 +199,7 @@ were moved to separate headers (since they were independent of each other). [section:demo Demonstration Program] -The program [@../../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from +The program [@../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from instantiating various examples of the run-time GCD and LCM function templates and the compile-time GCD and LCM class templates. (The run-time GCD and LCM class templates are tested indirectly through From 88b3ac5619f07ff20895ae6ab3822ea4df5212a4 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 9 May 2013 09:04:20 +0000 Subject: [PATCH 41/43] Change to quickbook 1.6. Change to use chapters at the top level. Big search and replace on link names. [SVN r84201] --- doc/gcd/math-gcd.qbk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 4b4bbfb..150ac91 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -1,4 +1,5 @@ -[section:gcd_lcm Integer Utilities (Greatest Common Divisor and Least Common Multiple)] + +[mathpart gcd_lcm Integer Utilities (Greatest Common Divisor and Least Common Multiple)] [section Introduction] @@ -233,5 +234,5 @@ pool library. The code had updates by Helmut Zeisel. [endsect] -[endsect] +[endmathpart] From 4622a12f01ddfc34af14e3c39f75b72f688bc292 Mon Sep 17 00:00:00 2001 From: "Paul A. Bristow" Date: Mon, 13 May 2013 10:37:27 +0000 Subject: [PATCH 42/43] Added licence info. [SVN r84266] --- doc/gcd/math-gcd.qbk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index 150ac91..b751cc9 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -219,6 +219,7 @@ code factoring and eases maintainence. [section History] +* 13 May 2013 Moved into main Boost.Math Quickbook documentation. * 17 Dec 2005: Converted documentation to Quickbook Format. * 2 Jul 2002: Compile-time and run-time items separated to new headers. * 7 Nov 2001: Initial version @@ -236,3 +237,11 @@ pool library. The code had updates by Helmut Zeisel. [endmathpart] +[/ +Copyright 2005, 2013 Daryle Walker. +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). +] + + From 7ada3ee926b3a3ba9a81eede3c536128b3831713 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 13 Jan 2015 19:49:06 +0200 Subject: [PATCH 43/43] Reapply final math-gcd.qbk commit. --- doc/gcd/math-gcd.qbk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/gcd/math-gcd.qbk b/doc/gcd/math-gcd.qbk index b751cc9..4d3edd6 100644 --- a/doc/gcd/math-gcd.qbk +++ b/doc/gcd/math-gcd.qbk @@ -186,7 +186,7 @@ is beyond the range of `static_gcd_type`. [endsect] -[section:header Header ] +[section:gcd_header Header ] This header simply includes the headers [@../../../../boost/math/common_factor_ct.hpp ] @@ -217,7 +217,7 @@ code factoring and eases maintainence. [endsect] -[section History] +[section:gcd_history History] * 13 May 2013 Moved into main Boost.Math Quickbook documentation. * 17 Dec 2005: Converted documentation to Quickbook Format. @@ -226,7 +226,7 @@ code factoring and eases maintainence. [endsect] -[section Credits] +[section:gcd_credits Credits] The author of the Boost compilation of GCD and LCM computations is Daryle Walker. The code was prompted by existing code hiding in the