|
Boost : |
From: Daryle Walker (darylew_at_[hidden])
Date: 2001-12-05 23:32:03
There were some problems with the detail code used in the GCD/LCM library.
I fixed the problems by rewriting part of the code, but the solution uses
partial specialization. How do I convert the code to be used in MSVC++?
(The initial problem was that I guessed [incorrectly] a MSVC-compatible
solution to the code from the start, instead of doing it right then
converting.)
//========================================================================
// Greatest common divisor for rings (including unsigned integers)
template < typename RingType >
RingType gcd_euclidean( RingType a, RingType b )
{
//...
}
// Greatest common divisor for (signed) integers
template < typename IntegerType >
inline IntegerType
gcd_integer( IntegerType const &a, IntegerType const &b )
{
//...
}
// Least common multiple for rings (including unsigned integers)
template < typename RingType >
inline RingType
lcm_euclidean( RingType const &a, RingType const &b )
{
//...
}
// Least common multiple for (signed) integers
template < typename IntegerType >
inline IntegerType
lcm_integer( IntegerType const &a, IntegerType const &b )
{
//...
}
// 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
{
T operator ()( T const &a, T const &b )
{
typedef ::std::numeric_limits<T> limits_type;
typedef gcd_optimal_evaluator_helper<T, limits_type::is_specialized,
limits_type::is_signed> helper_type;
helper_type solver;
return solver( a, b );
}
};
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
{
T operator ()( T const &a, T const &b )
{
typedef ::std::numeric_limits<T> limits_type;
typedef lcm_optimal_evaluator_helper<T, limits_type::is_specialized,
limits_type::is_signed> helper_type;
helper_type solver;
return solver( a, b );
}
};
// 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<T> solver;
return solver( a, b );
}
template < typename T >
inline T lcm_optimal( T const &a, T const &b )
{
lcm_optimal_evaluator<T> solver;
return solver( a, b );
}
//========================================================================
-- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT mac DOT com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk