Boost logo

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