diff --git a/doc/common_factor.html b/doc/common_factor.html index aa041425a..4f8a1d43b 100644 --- a/doc/common_factor.html +++ b/doc/common_factor.html @@ -23,20 +23,35 @@ programming problems.

-

Synopsis

+

Header <boost/math/common_factor.hpp>

+ +

This header simply includes the headers <boost/math/common_factor_ct.hpp> +and <boost/math/common_factor_rt.hpp>. +It used to contain the code, but the compile-time and run-time +facilities were moved to separate headers (since they were independent), +and this header maintains compatibility.

+ +

Synopsis

namespace boost
 {
@@ -62,7 +77,9 @@ template < unsigned long Value1, unsigned long Value2 >
 }
 
-

GCD Function Object

+

Header <boost/math/common_factor_rt.hpp>

+ +

GCD Function Object

template < typename IntegerType >
 class boost::math::gcd_evaluator
@@ -79,20 +96,20 @@ public:
 };
 
-

The boost::math::gcd_evaluator class template defines -a function object class to return the greatest common divisor of two +

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 +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.

+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.

-

LCM Function Object

+

LCM Function Object

template < typename IntegerType >
 class boost::math::lcm_evaluator
@@ -109,22 +126,22 @@ public:
 };
 
-

The boost::math::lcm_evaluator class template defines -a function object class to return the least common multiple of two +

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.

+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.

+multiples, then the type should specialize on the +lcm_evaluator class template.

-

Run-time GCD & LCM Determination

+

Run-time GCD & LCM Determination

template < typename IntegerType >
 IntegerType  boost::math::gcd( IntegerType const &a, IntegerType const &b );
@@ -133,17 +150,18 @@ 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.

+

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.

-

Compile-time GCD & LCM Determination

+

Header <boost/math/common_factor_ct.hpp>

template < unsigned long Value1, unsigned long Value2 >
 struct boost::math::static_gcd
@@ -158,13 +176,14 @@ struct boost::math::static_lcm
 };
 
-

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.

+

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.

Example

@@ -211,6 +230,16 @@ 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.

+

History

+ +
+
2 Jul 2002 +
Compile-time and run-time items separated to new headers. + +
7 Nov 2001 +
Initial version +
+

Credits

The author of the Boost compilation of GCD and LCM computations is


-

Revised November 7, 2001

+

Revised July 2, 2002

-

© Copyright Daryle Walker 2001. Permission to copy, use, +

© Copyright Daryle Walker 2001-2002. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim diff --git a/doc/index.html b/doc/index.html index bea4f3d5f..d26236eea 100644 --- a/doc/index.html +++ b/doc/index.html @@ -70,6 +70,8 @@ <boost/math/common_factor.hpp>
+ <boost/math/common_factor_ct.hpp>
+ <boost/math/common_factor_rt.hpp>

documentation Compile-time and run-time class and function @@ -87,7 +89,7 @@ items.


-

Revised 30 November, 2001

+

Revised 2 July, 2002

\ No newline at end of file diff --git a/include/boost/math/common_factor.hpp b/include/boost/math/common_factor.hpp index 10196fee6..c2a99885e 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 diff --git a/include/boost/math_fwd.hpp b/include/boost/math_fwd.hpp index 9a07e4323..ed315be69 100644 --- a/include/boost/math_fwd.hpp +++ b/include/boost/math_fwd.hpp @@ -1,6 +1,6 @@ // Boost math_fwd.hpp header file ------------------------------------------// -// (C) Copyright boost.org 2001. Permission to copy, use, modify, sell +// (C) Copyright boost.org 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 @@ -75,16 +75,24 @@ template < > // From -------------------------------------// -template < typename IntegerType > - class gcd_evaluator; -template < typename IntegerType > - class lcm_evaluator; +// Only #includes other headers + + +// From ----------------------------------// template < unsigned long Value1, unsigned long Value2 > struct static_gcd; template < unsigned long Value1, unsigned long Value2 > struct static_lcm; + +// From ----------------------------------// + +template < typename IntegerType > + class gcd_evaluator; +template < typename IntegerType > + class lcm_evaluator; + // Also has a couple of function templates