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