| 
									
										
										
										
											2002-07-02 07:51:48 +00:00
										 |  |  | //  Boost common_factor_ct.hpp header file  ----------------------------------//
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-28 12:55:45 +00:00
										 |  |  | //  (C) Copyright Daryle Walker and Stephen Cleary 2001-2002.
 | 
					
						
							|  |  |  | //  Distributed under the Boost Software License, Version 1.0. (See
 | 
					
						
							|  |  |  | //  accompanying file LICENSE_1_0.txt or copy at
 | 
					
						
							|  |  |  | //  http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							| 
									
										
										
										
											2002-07-02 07:51:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //  See http://www.boost.org for updates, documentation, and revision history. 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP
 | 
					
						
							|  |  |  | #define BOOST_MATH_COMMON_FACTOR_CT_HPP
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/math_fwd.hpp>  // self include
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/config.hpp>  // for BOOST_STATIC_CONSTANT, etc.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace boost | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | namespace math | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //  Implementation details  --------------------------------------------------//
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace detail | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
					
						
							|  |  |  |     // Build GCD with Euclid's recursive algorithm
 | 
					
						
							|  |  |  |     template < unsigned long Value1, unsigned long Value2 > | 
					
						
							|  |  |  |     struct static_gcd_helper_t | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 ); | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #ifndef __BORLANDC__
 | 
					
						
							| 
									
										
										
										
											2002-10-01 13:31:42 +00:00
										 |  |  |         #define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast<unsigned long>(Value)
 | 
					
						
							| 
									
										
										
										
											2002-07-02 07:51:48 +00:00
										 |  |  |         #else
 | 
					
						
							|  |  |  |         typedef static_gcd_helper_t  self_type; | 
					
						
							|  |  |  |         #define BOOST_DETAIL_GCD_HELPER_VAL(Value)  (self_type:: Value )
 | 
					
						
							|  |  |  |         #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1), | 
					
						
							|  |  |  |          BOOST_DETAIL_GCD_HELPER_VAL(new_value2) >  next_step_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #undef BOOST_DETAIL_GCD_HELPER_VAL
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, value = next_step_type::value ); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Non-recursive case
 | 
					
						
							|  |  |  |     template < unsigned long Value1 > | 
					
						
							|  |  |  |     struct static_gcd_helper_t< Value1, 0UL > | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     // Use inner class template workaround from Peter Dimov
 | 
					
						
							|  |  |  |     template < unsigned long Value1 > | 
					
						
							|  |  |  |     struct static_gcd_helper2_t | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         template < unsigned long Value2 > | 
					
						
							|  |  |  |         struct helper | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_STATIC_CONSTANT( unsigned long, value | 
					
						
							| 
									
										
										
										
											2005-02-07 14:34:32 +00:00
										 |  |  |              = static_gcd_helper2_t<Value2>::BOOST_NESTED_TEMPLATE | 
					
						
							|  |  |  |              helper<Value1 % Value2>::value ); | 
					
						
							| 
									
										
										
										
											2002-07-02 07:51:48 +00:00
										 |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         template <  > | 
					
						
							|  |  |  |         struct helper< 0UL > | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_STATIC_CONSTANT( unsigned long, value = Value1 ); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Special case
 | 
					
						
							|  |  |  |     template <  > | 
					
						
							|  |  |  |     struct static_gcd_helper2_t< 0UL > | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         template < unsigned long Value2 > | 
					
						
							|  |  |  |         struct helper | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_STATIC_CONSTANT( unsigned long, value = Value2 ); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Build the GCD from the above template(s)
 | 
					
						
							|  |  |  |     template < unsigned long Value1, unsigned long Value2 > | 
					
						
							|  |  |  |     struct static_gcd_helper_t | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, value | 
					
						
							|  |  |  |          = static_gcd_helper2_t<Value1>::BOOST_NESTED_TEMPLATE | 
					
						
							|  |  |  |          helper<Value2>::value ); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
					
						
							|  |  |  |     // Build the LCM from the GCD
 | 
					
						
							|  |  |  |     template < unsigned long Value1, unsigned long Value2 > | 
					
						
							|  |  |  |     struct static_lcm_helper_t | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         typedef static_gcd_helper_t<Value1, Value2>  gcd_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value | 
					
						
							|  |  |  |          * Value2 ); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Special case for zero-GCD values
 | 
					
						
							|  |  |  |     template < > | 
					
						
							|  |  |  |     struct static_lcm_helper_t< 0UL, 0UL > | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     // Adapt GCD's inner class template workaround for LCM
 | 
					
						
							|  |  |  |     template < unsigned long Value1 > | 
					
						
							|  |  |  |     struct static_lcm_helper2_t | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         template < unsigned long Value2 > | 
					
						
							|  |  |  |         struct helper | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             typedef static_gcd_helper_t<Value1, Value2>  gcd_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             BOOST_STATIC_CONSTANT( unsigned long, value = Value1 | 
					
						
							|  |  |  |              / gcd_type::value * Value2 ); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         template <  > | 
					
						
							|  |  |  |         struct helper< 0UL > | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Special case
 | 
					
						
							|  |  |  |     template <  > | 
					
						
							|  |  |  |     struct static_lcm_helper2_t< 0UL > | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         template < unsigned long Value2 > | 
					
						
							|  |  |  |         struct helper | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             BOOST_STATIC_CONSTANT( unsigned long, value = 0UL ); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Build the LCM from the above template(s)
 | 
					
						
							|  |  |  |     template < unsigned long Value1, unsigned long Value2 > | 
					
						
							|  |  |  |     struct static_lcm_helper_t | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BOOST_STATIC_CONSTANT( unsigned long, value | 
					
						
							|  |  |  |          = static_lcm_helper2_t<Value1>::BOOST_NESTED_TEMPLATE | 
					
						
							|  |  |  |          helper<Value2>::value ); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace detail
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //  Compile-time greatest common divisor evaluator class declaration  --------//
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template < unsigned long Value1, unsigned long Value2 > | 
					
						
							|  |  |  | struct static_gcd | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     BOOST_STATIC_CONSTANT( unsigned long, value | 
					
						
							|  |  |  |      = (detail::static_gcd_helper_t<Value1, Value2>::value) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | };  // boost::math::static_gcd
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //  Compile-time least common multiple evaluator class declaration  ----------//
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template < unsigned long Value1, unsigned long Value2 > | 
					
						
							|  |  |  | struct static_lcm | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     BOOST_STATIC_CONSTANT( unsigned long, value | 
					
						
							|  |  |  |      = (detail::static_lcm_helper_t<Value1, Value2>::value) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | };  // boost::math::static_lcm
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace math
 | 
					
						
							|  |  |  | }  // namespace boost
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif  // BOOST_MATH_COMMON_FACTOR_CT_HPP
 |