1 // Boost common_factor_rt.hpp header file ----------------------------------//
3 // (C) Copyright Daryle Walker and Paul Moore 2001-2002. Permission to copy,
4 // use, modify, sell and distribute this software is granted provided this
5 // copyright notice appears in all copies. This software is provided "as is"
6 // without express or implied warranty, and with no claim as to its suitability
9 // See http://www.boost.org for updates, documentation, and revision history.
11 #ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
12 #define BOOST_MATH_COMMON_FACTOR_RT_HPP
14 #include <boost/math_fwd.hpp> // self include
16 #include <boost/config.hpp> // for BOOST_NESTED_TEMPLATE, etc.
17 #include <boost/limits.hpp> // for std::numeric_limits
26 // Forward declarations for function templates -----------------------------//
28 template < typename IntegerType >
29 IntegerType gcd( IntegerType const &a, IntegerType const &b );
31 template < typename IntegerType >
32 IntegerType lcm( IntegerType const &a, IntegerType const &b );
35 // Greatest common divisor evaluator class declaration ---------------------//
37 template < typename IntegerType >
42 typedef IntegerType result_type, first_argument_type, second_argument_type;
44 // Function object interface
45 result_type operator ()( first_argument_type const &a,
46 second_argument_type const &b ) const;
48 }; // boost::math::gcd_evaluator
51 // Least common multiple evaluator class declaration -----------------------//
53 template < typename IntegerType >
58 typedef IntegerType result_type, first_argument_type, second_argument_type;
60 // Function object interface
61 result_type operator ()( first_argument_type const &a,
62 second_argument_type const &b ) const;
64 }; // boost::math::lcm_evaluator
67 // Implementation details --------------------------------------------------//
71 // Greatest common divisor for rings (including unsigned integers)
72 template < typename RingType >
80 // Avoid repeated construction
82 RingType const zero = static_cast<RingType>( 0 );
84 RingType zero = static_cast<RingType>( 0 );
87 // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)]
100 // Greatest common divisor for (signed) integers
101 template < typename IntegerType >
106 IntegerType const & a,
107 IntegerType const & b
110 // Avoid repeated construction
111 IntegerType const zero = static_cast<IntegerType>( 0 );
112 IntegerType const result = gcd_euclidean( a, b );
114 return ( result < zero ) ? -result : result;
117 // Least common multiple for rings (including unsigned integers)
118 template < typename RingType >
127 RingType const zero = static_cast<RingType>( 0 );
128 RingType const temp = gcd_euclidean( a, b );
130 return ( temp != zero ) ? ( a / temp * b ) : zero;
133 // Least common multiple for (signed) integers
134 template < typename IntegerType >
139 IntegerType const & a,
140 IntegerType const & b
143 // Avoid repeated construction
144 IntegerType const zero = static_cast<IntegerType>( 0 );
145 IntegerType const result = lcm_euclidean( a, b );
147 return ( result < zero ) ? -result : result;
150 // Function objects to find the best way of computing GCD or LCM
151 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
152 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
153 template < typename T, bool IsSpecialized, bool IsSigned >
154 struct gcd_optimal_evaluator_helper_t
156 T operator ()( T const &a, T const &b )
158 return gcd_euclidean( a, b );
162 template < typename T >
163 struct gcd_optimal_evaluator_helper_t< T, true, true >
165 T operator ()( T const &a, T const &b )
167 return gcd_integer( a, b );
171 template < bool IsSpecialized, bool IsSigned >
172 struct gcd_optimal_evaluator_helper2_t
174 template < typename T >
177 T operator ()( T const &a, T const &b )
179 return gcd_euclidean( a, b );
185 struct gcd_optimal_evaluator_helper2_t< true, true >
187 template < typename T >
190 T operator ()( T const &a, T const &b )
192 return gcd_integer( a, b );
197 template < typename T, bool IsSpecialized, bool IsSigned >
198 struct gcd_optimal_evaluator_helper_t
199 : gcd_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
200 ::BOOST_NESTED_TEMPLATE helper<T>
205 template < typename T >
206 struct gcd_optimal_evaluator
208 T operator ()( T const &a, T const &b )
210 typedef ::std::numeric_limits<T> limits_type;
212 typedef gcd_optimal_evaluator_helper_t<T,
213 limits_type::is_specialized, limits_type::is_signed> helper_type;
217 return solver( a, b );
220 #else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
221 template < typename T >
222 struct gcd_optimal_evaluator
224 T operator ()( T const &a, T const &b )
226 return gcd_integer( a, b );
231 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
232 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
233 template < typename T, bool IsSpecialized, bool IsSigned >
234 struct lcm_optimal_evaluator_helper_t
236 T operator ()( T const &a, T const &b )
238 return lcm_euclidean( a, b );
242 template < typename T >
243 struct lcm_optimal_evaluator_helper_t< T, true, true >
245 T operator ()( T const &a, T const &b )
247 return lcm_integer( a, b );
251 template < bool IsSpecialized, bool IsSigned >
252 struct lcm_optimal_evaluator_helper2_t
254 template < typename T >
257 T operator ()( T const &a, T const &b )
259 return lcm_euclidean( a, b );
265 struct lcm_optimal_evaluator_helper2_t< true, true >
267 template < typename T >
270 T operator ()( T const &a, T const &b )
272 return lcm_integer( a, b );
277 template < typename T, bool IsSpecialized, bool IsSigned >
278 struct lcm_optimal_evaluator_helper_t
279 : lcm_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
280 ::BOOST_NESTED_TEMPLATE helper<T>
285 template < typename T >
286 struct lcm_optimal_evaluator
288 T operator ()( T const &a, T const &b )
290 typedef ::std::numeric_limits<T> limits_type;
292 typedef lcm_optimal_evaluator_helper_t<T,
293 limits_type::is_specialized, limits_type::is_signed> helper_type;
297 return solver( a, b );
300 #else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
301 template < typename T >
302 struct lcm_optimal_evaluator
304 T operator ()( T const &a, T const &b )
306 return lcm_integer( a, b );
311 // Functions to find the GCD or LCM in the best way
312 template < typename T >
321 gcd_optimal_evaluator<T> solver;
323 return solver( a, b );
326 template < typename T >
335 lcm_optimal_evaluator<T> solver;
337 return solver( a, b );
340 } // namespace detail
343 // Greatest common divisor evaluator member function definition ------------//
345 template < typename IntegerType >
347 typename gcd_evaluator<IntegerType>::result_type
348 gcd_evaluator<IntegerType>::operator ()
350 first_argument_type const & a,
351 second_argument_type const & b
354 return detail::gcd_optimal( a, b );
358 // Least common multiple evaluator member function definition --------------//
360 template < typename IntegerType >
362 typename lcm_evaluator<IntegerType>::result_type
363 lcm_evaluator<IntegerType>::operator ()
365 first_argument_type const & a,
366 second_argument_type const & b
369 return detail::lcm_optimal( a, b );
373 // Greatest common divisor and least common multiple function definitions --//
375 template < typename IntegerType >
380 IntegerType const & a,
381 IntegerType const & b
384 gcd_evaluator<IntegerType> solver;
386 return solver( a, b );
389 template < typename IntegerType >
394 IntegerType const & a,
395 IntegerType const & b
398 lcm_evaluator<IntegerType> solver;
400 return solver( a, b );
408 #endif // BOOST_MATH_COMMON_FACTOR_RT_HPP