summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/math/common_factor_rt.hpp')
-rw-r--r--3rdParty/Boost/src/boost/math/common_factor_rt.hpp530
1 files changed, 530 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/math/common_factor_rt.hpp b/3rdParty/Boost/src/boost/math/common_factor_rt.hpp
new file mode 100644
index 0000000..4582a96
--- /dev/null
+++ b/3rdParty/Boost/src/boost/math/common_factor_rt.hpp
@@ -0,0 +1,530 @@
+// Boost common_factor_rt.hpp header file ----------------------------------//
+
+// (C) Copyright Daryle Walker and Paul Moore 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.
+
+// boostinspect:nolicense (don't complain about the lack of a Boost license)
+// (Paul Moore hasn't been in contact for years, so there's no way to change the
+// license.)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
+#define BOOST_MATH_COMMON_FACTOR_RT_HPP
+
+#include <boost/math_fwd.hpp> // self include
+
+#include <boost/config.hpp> // for BOOST_NESTED_TEMPLATE, etc.
+#include <boost/limits.hpp> // for std::numeric_limits
+#include <climits> // for CHAR_MIN
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127 4244) // Conditional expression is constant
+#endif
+
+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
+{
+ // 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<RingType>( 0 );
+ #else
+ RingType zero = static_cast<RingType>( 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<IntegerType>( 0 );
+ IntegerType const result = gcd_euclidean( a, b );
+
+ return ( result < zero ) ? static_cast<IntegerType>(-result) : result;
+ }
+
+ // Greatest common divisor for unsigned binary integers
+ template < typename BuiltInUnsigned >
+ BuiltInUnsigned
+ gcd_binary
+ (
+ BuiltInUnsigned u,
+ BuiltInUnsigned v
+ )
+ {
+ if ( u && v )
+ {
+ // Shift out common factors of 2
+ unsigned shifts = 0;
+
+ while ( !(u & 1u) && !(v & 1u) )
+ {
+ ++shifts;
+ u >>= 1;
+ v >>= 1;
+ }
+
+ // Start with the still-even one, if any
+ BuiltInUnsigned r[] = { u, v };
+ unsigned which = static_cast<bool>( u & 1u );
+
+ // Whittle down the values via their differences
+ do
+ {
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
+ while ( !(r[ which ] & 1u) )
+ {
+ r[ which ] = (r[which] >> 1);
+ }
+#else
+ // Remove factors of two from the even one
+ while ( !(r[ which ] & 1u) )
+ {
+ r[ which ] >>= 1;
+ }
+#endif
+
+ // Replace the larger of the two with their difference
+ if ( r[!which] > r[which] )
+ {
+ which ^= 1u;
+ }
+
+ r[ which ] -= r[ !which ];
+ }
+ while ( r[which] );
+
+ // Shift-in the common factor of 2 to the residues' GCD
+ return r[ !which ] << shifts;
+ }
+ else
+ {
+ // At least one input is zero, return the other
+ // (adding since zero is the additive identity)
+ // or zero if both are zero.
+ return u + v;
+ }
+ }
+
+ // 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<RingType>( 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<IntegerType>( 0 );
+ IntegerType const result = lcm_euclidean( a, b );
+
+ return ( result < zero ) ? static_cast<IntegerType>(-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<IsSpecialized, IsSigned>
+ ::BOOST_NESTED_TEMPLATE helper<T>
+ {
+ };
+#endif
+
+ 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<T,
+ limits_type::is_specialized, limits_type::is_signed> 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
+
+ // Specialize for the built-in integers
+#define BOOST_PRIVATE_GCD_UF( Ut ) \
+ template < > struct gcd_optimal_evaluator<Ut> \
+ { Ut operator ()( Ut a, Ut b ) const { return gcd_binary( a, b ); } }
+
+ BOOST_PRIVATE_GCD_UF( unsigned char );
+ BOOST_PRIVATE_GCD_UF( unsigned short );
+ BOOST_PRIVATE_GCD_UF( unsigned );
+ BOOST_PRIVATE_GCD_UF( unsigned long );
+
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_PRIVATE_GCD_UF( boost::ulong_long_type );
+#elif defined(BOOST_HAS_MS_INT64)
+ BOOST_PRIVATE_GCD_UF( unsigned __int64 );
+#endif
+
+#if CHAR_MIN == 0
+ BOOST_PRIVATE_GCD_UF( char ); // char is unsigned
+#endif
+
+#undef BOOST_PRIVATE_GCD_UF
+
+#define BOOST_PRIVATE_GCD_SF( St, Ut ) \
+ template < > struct gcd_optimal_evaluator<St> \
+ { St operator ()( St a, St b ) const { Ut const a_abs = \
+ static_cast<Ut>( a < 0 ? -a : +a ), b_abs = static_cast<Ut>( \
+ b < 0 ? -b : +b ); return static_cast<St>( \
+ gcd_optimal_evaluator<Ut>()(a_abs, b_abs) ); } }
+
+ BOOST_PRIVATE_GCD_SF( signed char, unsigned char );
+ BOOST_PRIVATE_GCD_SF( short, unsigned short );
+ BOOST_PRIVATE_GCD_SF( int, unsigned );
+ BOOST_PRIVATE_GCD_SF( long, unsigned long );
+
+#if CHAR_MIN < 0
+ BOOST_PRIVATE_GCD_SF( char, unsigned char ); // char is signed
+#endif
+
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_PRIVATE_GCD_SF( boost::long_long_type, boost::ulong_long_type );
+#elif defined(BOOST_HAS_MS_INT64)
+ BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 );
+#endif
+
+#undef BOOST_PRIVATE_GCD_SF
+
+#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<IsSpecialized, IsSigned>
+ ::BOOST_NESTED_TEMPLATE helper<T>
+ {
+ };
+#endif
+
+ 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<T,
+ limits_type::is_specialized, limits_type::is_signed> 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<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 );
+ }
+
+} // namespace detail
+
+
+// Greatest common divisor evaluator member function definition ------------//
+
+template < typename IntegerType >
+inline
+typename gcd_evaluator<IntegerType>::result_type
+gcd_evaluator<IntegerType>::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<IntegerType>::result_type
+lcm_evaluator<IntegerType>::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<IntegerType> solver;
+
+ return solver( a, b );
+}
+
+template < typename IntegerType >
+inline
+IntegerType
+lcm
+(
+ IntegerType const & a,
+ IntegerType const & b
+)
+{
+ lcm_evaluator<IntegerType> solver;
+
+ return solver( a, b );
+}
+
+
+} // namespace math
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_MATH_COMMON_FACTOR_RT_HPP