1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/math/common_factor_rt.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,408 @@
1.4 +// Boost common_factor_rt.hpp header file ----------------------------------//
1.5 +
1.6 +// (C) Copyright Daryle Walker and Paul Moore 2001-2002. Permission to copy,
1.7 +// use, modify, sell and distribute this software is granted provided this
1.8 +// copyright notice appears in all copies. This software is provided "as is"
1.9 +// without express or implied warranty, and with no claim as to its suitability
1.10 +// for any purpose.
1.11 +
1.12 +// See http://www.boost.org for updates, documentation, and revision history.
1.13 +
1.14 +#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
1.15 +#define BOOST_MATH_COMMON_FACTOR_RT_HPP
1.16 +
1.17 +#include <boost/math_fwd.hpp> // self include
1.18 +
1.19 +#include <boost/config.hpp> // for BOOST_NESTED_TEMPLATE, etc.
1.20 +#include <boost/limits.hpp> // for std::numeric_limits
1.21 +
1.22 +
1.23 +namespace boost
1.24 +{
1.25 +namespace math
1.26 +{
1.27 +
1.28 +
1.29 +// Forward declarations for function templates -----------------------------//
1.30 +
1.31 +template < typename IntegerType >
1.32 + IntegerType gcd( IntegerType const &a, IntegerType const &b );
1.33 +
1.34 +template < typename IntegerType >
1.35 + IntegerType lcm( IntegerType const &a, IntegerType const &b );
1.36 +
1.37 +
1.38 +// Greatest common divisor evaluator class declaration ---------------------//
1.39 +
1.40 +template < typename IntegerType >
1.41 +class gcd_evaluator
1.42 +{
1.43 +public:
1.44 + // Types
1.45 + typedef IntegerType result_type, first_argument_type, second_argument_type;
1.46 +
1.47 + // Function object interface
1.48 + result_type operator ()( first_argument_type const &a,
1.49 + second_argument_type const &b ) const;
1.50 +
1.51 +}; // boost::math::gcd_evaluator
1.52 +
1.53 +
1.54 +// Least common multiple evaluator class declaration -----------------------//
1.55 +
1.56 +template < typename IntegerType >
1.57 +class lcm_evaluator
1.58 +{
1.59 +public:
1.60 + // Types
1.61 + typedef IntegerType result_type, first_argument_type, second_argument_type;
1.62 +
1.63 + // Function object interface
1.64 + result_type operator ()( first_argument_type const &a,
1.65 + second_argument_type const &b ) const;
1.66 +
1.67 +}; // boost::math::lcm_evaluator
1.68 +
1.69 +
1.70 +// Implementation details --------------------------------------------------//
1.71 +
1.72 +namespace detail
1.73 +{
1.74 + // Greatest common divisor for rings (including unsigned integers)
1.75 + template < typename RingType >
1.76 + RingType
1.77 + gcd_euclidean
1.78 + (
1.79 + RingType a,
1.80 + RingType b
1.81 + )
1.82 + {
1.83 + // Avoid repeated construction
1.84 + #ifndef __BORLANDC__
1.85 + RingType const zero = static_cast<RingType>( 0 );
1.86 + #else
1.87 + RingType zero = static_cast<RingType>( 0 );
1.88 + #endif
1.89 +
1.90 + // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)]
1.91 + while ( true )
1.92 + {
1.93 + if ( a == zero )
1.94 + return b;
1.95 + b %= a;
1.96 +
1.97 + if ( b == zero )
1.98 + return a;
1.99 + a %= b;
1.100 + }
1.101 + }
1.102 +
1.103 + // Greatest common divisor for (signed) integers
1.104 + template < typename IntegerType >
1.105 + inline
1.106 + IntegerType
1.107 + gcd_integer
1.108 + (
1.109 + IntegerType const & a,
1.110 + IntegerType const & b
1.111 + )
1.112 + {
1.113 + // Avoid repeated construction
1.114 + IntegerType const zero = static_cast<IntegerType>( 0 );
1.115 + IntegerType const result = gcd_euclidean( a, b );
1.116 +
1.117 + return ( result < zero ) ? -result : result;
1.118 + }
1.119 +
1.120 + // Least common multiple for rings (including unsigned integers)
1.121 + template < typename RingType >
1.122 + inline
1.123 + RingType
1.124 + lcm_euclidean
1.125 + (
1.126 + RingType const & a,
1.127 + RingType const & b
1.128 + )
1.129 + {
1.130 + RingType const zero = static_cast<RingType>( 0 );
1.131 + RingType const temp = gcd_euclidean( a, b );
1.132 +
1.133 + return ( temp != zero ) ? ( a / temp * b ) : zero;
1.134 + }
1.135 +
1.136 + // Least common multiple for (signed) integers
1.137 + template < typename IntegerType >
1.138 + inline
1.139 + IntegerType
1.140 + lcm_integer
1.141 + (
1.142 + IntegerType const & a,
1.143 + IntegerType const & b
1.144 + )
1.145 + {
1.146 + // Avoid repeated construction
1.147 + IntegerType const zero = static_cast<IntegerType>( 0 );
1.148 + IntegerType const result = lcm_euclidean( a, b );
1.149 +
1.150 + return ( result < zero ) ? -result : result;
1.151 + }
1.152 +
1.153 + // Function objects to find the best way of computing GCD or LCM
1.154 +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.155 +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.156 + template < typename T, bool IsSpecialized, bool IsSigned >
1.157 + struct gcd_optimal_evaluator_helper_t
1.158 + {
1.159 + T operator ()( T const &a, T const &b )
1.160 + {
1.161 + return gcd_euclidean( a, b );
1.162 + }
1.163 + };
1.164 +
1.165 + template < typename T >
1.166 + struct gcd_optimal_evaluator_helper_t< T, true, true >
1.167 + {
1.168 + T operator ()( T const &a, T const &b )
1.169 + {
1.170 + return gcd_integer( a, b );
1.171 + }
1.172 + };
1.173 +#else
1.174 + template < bool IsSpecialized, bool IsSigned >
1.175 + struct gcd_optimal_evaluator_helper2_t
1.176 + {
1.177 + template < typename T >
1.178 + struct helper
1.179 + {
1.180 + T operator ()( T const &a, T const &b )
1.181 + {
1.182 + return gcd_euclidean( a, b );
1.183 + }
1.184 + };
1.185 + };
1.186 +
1.187 + template < >
1.188 + struct gcd_optimal_evaluator_helper2_t< true, true >
1.189 + {
1.190 + template < typename T >
1.191 + struct helper
1.192 + {
1.193 + T operator ()( T const &a, T const &b )
1.194 + {
1.195 + return gcd_integer( a, b );
1.196 + }
1.197 + };
1.198 + };
1.199 +
1.200 + template < typename T, bool IsSpecialized, bool IsSigned >
1.201 + struct gcd_optimal_evaluator_helper_t
1.202 + : gcd_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
1.203 + ::BOOST_NESTED_TEMPLATE helper<T>
1.204 + {
1.205 + };
1.206 +#endif
1.207 +
1.208 + template < typename T >
1.209 + struct gcd_optimal_evaluator
1.210 + {
1.211 + T operator ()( T const &a, T const &b )
1.212 + {
1.213 + typedef ::std::numeric_limits<T> limits_type;
1.214 +
1.215 + typedef gcd_optimal_evaluator_helper_t<T,
1.216 + limits_type::is_specialized, limits_type::is_signed> helper_type;
1.217 +
1.218 + helper_type solver;
1.219 +
1.220 + return solver( a, b );
1.221 + }
1.222 + };
1.223 +#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.224 + template < typename T >
1.225 + struct gcd_optimal_evaluator
1.226 + {
1.227 + T operator ()( T const &a, T const &b )
1.228 + {
1.229 + return gcd_integer( a, b );
1.230 + }
1.231 + };
1.232 +#endif
1.233 +
1.234 +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.235 +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.236 + template < typename T, bool IsSpecialized, bool IsSigned >
1.237 + struct lcm_optimal_evaluator_helper_t
1.238 + {
1.239 + T operator ()( T const &a, T const &b )
1.240 + {
1.241 + return lcm_euclidean( a, b );
1.242 + }
1.243 + };
1.244 +
1.245 + template < typename T >
1.246 + struct lcm_optimal_evaluator_helper_t< T, true, true >
1.247 + {
1.248 + T operator ()( T const &a, T const &b )
1.249 + {
1.250 + return lcm_integer( a, b );
1.251 + }
1.252 + };
1.253 +#else
1.254 + template < bool IsSpecialized, bool IsSigned >
1.255 + struct lcm_optimal_evaluator_helper2_t
1.256 + {
1.257 + template < typename T >
1.258 + struct helper
1.259 + {
1.260 + T operator ()( T const &a, T const &b )
1.261 + {
1.262 + return lcm_euclidean( a, b );
1.263 + }
1.264 + };
1.265 + };
1.266 +
1.267 + template < >
1.268 + struct lcm_optimal_evaluator_helper2_t< true, true >
1.269 + {
1.270 + template < typename T >
1.271 + struct helper
1.272 + {
1.273 + T operator ()( T const &a, T const &b )
1.274 + {
1.275 + return lcm_integer( a, b );
1.276 + }
1.277 + };
1.278 + };
1.279 +
1.280 + template < typename T, bool IsSpecialized, bool IsSigned >
1.281 + struct lcm_optimal_evaluator_helper_t
1.282 + : lcm_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
1.283 + ::BOOST_NESTED_TEMPLATE helper<T>
1.284 + {
1.285 + };
1.286 +#endif
1.287 +
1.288 + template < typename T >
1.289 + struct lcm_optimal_evaluator
1.290 + {
1.291 + T operator ()( T const &a, T const &b )
1.292 + {
1.293 + typedef ::std::numeric_limits<T> limits_type;
1.294 +
1.295 + typedef lcm_optimal_evaluator_helper_t<T,
1.296 + limits_type::is_specialized, limits_type::is_signed> helper_type;
1.297 +
1.298 + helper_type solver;
1.299 +
1.300 + return solver( a, b );
1.301 + }
1.302 + };
1.303 +#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.304 + template < typename T >
1.305 + struct lcm_optimal_evaluator
1.306 + {
1.307 + T operator ()( T const &a, T const &b )
1.308 + {
1.309 + return lcm_integer( a, b );
1.310 + }
1.311 + };
1.312 +#endif
1.313 +
1.314 + // Functions to find the GCD or LCM in the best way
1.315 + template < typename T >
1.316 + inline
1.317 + T
1.318 + gcd_optimal
1.319 + (
1.320 + T const & a,
1.321 + T const & b
1.322 + )
1.323 + {
1.324 + gcd_optimal_evaluator<T> solver;
1.325 +
1.326 + return solver( a, b );
1.327 + }
1.328 +
1.329 + template < typename T >
1.330 + inline
1.331 + T
1.332 + lcm_optimal
1.333 + (
1.334 + T const & a,
1.335 + T const & b
1.336 + )
1.337 + {
1.338 + lcm_optimal_evaluator<T> solver;
1.339 +
1.340 + return solver( a, b );
1.341 + }
1.342 +
1.343 +} // namespace detail
1.344 +
1.345 +
1.346 +// Greatest common divisor evaluator member function definition ------------//
1.347 +
1.348 +template < typename IntegerType >
1.349 +inline
1.350 +typename gcd_evaluator<IntegerType>::result_type
1.351 +gcd_evaluator<IntegerType>::operator ()
1.352 +(
1.353 + first_argument_type const & a,
1.354 + second_argument_type const & b
1.355 +) const
1.356 +{
1.357 + return detail::gcd_optimal( a, b );
1.358 +}
1.359 +
1.360 +
1.361 +// Least common multiple evaluator member function definition --------------//
1.362 +
1.363 +template < typename IntegerType >
1.364 +inline
1.365 +typename lcm_evaluator<IntegerType>::result_type
1.366 +lcm_evaluator<IntegerType>::operator ()
1.367 +(
1.368 + first_argument_type const & a,
1.369 + second_argument_type const & b
1.370 +) const
1.371 +{
1.372 + return detail::lcm_optimal( a, b );
1.373 +}
1.374 +
1.375 +
1.376 +// Greatest common divisor and least common multiple function definitions --//
1.377 +
1.378 +template < typename IntegerType >
1.379 +inline
1.380 +IntegerType
1.381 +gcd
1.382 +(
1.383 + IntegerType const & a,
1.384 + IntegerType const & b
1.385 +)
1.386 +{
1.387 + gcd_evaluator<IntegerType> solver;
1.388 +
1.389 + return solver( a, b );
1.390 +}
1.391 +
1.392 +template < typename IntegerType >
1.393 +inline
1.394 +IntegerType
1.395 +lcm
1.396 +(
1.397 + IntegerType const & a,
1.398 + IntegerType const & b
1.399 +)
1.400 +{
1.401 + lcm_evaluator<IntegerType> solver;
1.402 +
1.403 + return solver( a, b );
1.404 +}
1.405 +
1.406 +
1.407 +} // namespace math
1.408 +} // namespace boost
1.409 +
1.410 +
1.411 +#endif // BOOST_MATH_COMMON_FACTOR_RT_HPP