source: NonGTP/Boost/boost/math/common_factor_ct.hpp @ 857

Revision 857, 5.3 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  Boost common_factor_ct.hpp header file  ----------------------------------//
2
3//  (C) Copyright Daryle Walker and Stephen Cleary 2001-2002.
4//  Distributed under the Boost Software License, Version 1.0. (See
5//  accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7
8//  See http://www.boost.org for updates, documentation, and revision history.
9
10#ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP
11#define BOOST_MATH_COMMON_FACTOR_CT_HPP
12
13#include <boost/math_fwd.hpp>  // self include
14
15#include <boost/config.hpp>  // for BOOST_STATIC_CONSTANT, etc.
16
17
18namespace boost
19{
20namespace math
21{
22
23
24//  Implementation details  --------------------------------------------------//
25
26namespace detail
27{
28#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
29    // Build GCD with Euclid's recursive algorithm
30    template < unsigned long Value1, unsigned long Value2 >
31    struct static_gcd_helper_t
32    {
33    private:
34        BOOST_STATIC_CONSTANT( unsigned long, new_value1 = Value2 );
35        BOOST_STATIC_CONSTANT( unsigned long, new_value2 = Value1 % Value2 );
36
37        #ifndef __BORLANDC__
38        #define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast<unsigned long>(Value)
39        #else
40        typedef static_gcd_helper_t  self_type;
41        #define BOOST_DETAIL_GCD_HELPER_VAL(Value)  (self_type:: Value )
42        #endif
43
44        typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1),
45         BOOST_DETAIL_GCD_HELPER_VAL(new_value2) >  next_step_type;
46
47        #undef BOOST_DETAIL_GCD_HELPER_VAL
48
49    public:
50        BOOST_STATIC_CONSTANT( unsigned long, value = next_step_type::value );
51    };
52
53    // Non-recursive case
54    template < unsigned long Value1 >
55    struct static_gcd_helper_t< Value1, 0UL >
56    {
57        BOOST_STATIC_CONSTANT( unsigned long, value = Value1 );
58    };
59#else
60    // Use inner class template workaround from Peter Dimov
61    template < unsigned long Value1 >
62    struct static_gcd_helper2_t
63    {
64        template < unsigned long Value2 >
65        struct helper
66        {
67            BOOST_STATIC_CONSTANT( unsigned long, value
68             = static_gcd_helper2_t<Value2>::BOOST_NESTED_TEMPLATE
69             helper<Value1 % Value2>::value );
70        };
71
72        template <  >
73        struct helper< 0UL >
74        {
75            BOOST_STATIC_CONSTANT( unsigned long, value = Value1 );
76        };
77    };
78
79    // Special case
80    template <  >
81    struct static_gcd_helper2_t< 0UL >
82    {
83        template < unsigned long Value2 >
84        struct helper
85        {
86            BOOST_STATIC_CONSTANT( unsigned long, value = Value2 );
87        };
88    };
89
90    // Build the GCD from the above template(s)
91    template < unsigned long Value1, unsigned long Value2 >
92    struct static_gcd_helper_t
93    {
94        BOOST_STATIC_CONSTANT( unsigned long, value
95         = static_gcd_helper2_t<Value1>::BOOST_NESTED_TEMPLATE
96         helper<Value2>::value );
97    };
98#endif
99
100#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
101    // Build the LCM from the GCD
102    template < unsigned long Value1, unsigned long Value2 >
103    struct static_lcm_helper_t
104    {
105        typedef static_gcd_helper_t<Value1, Value2>  gcd_type;
106
107        BOOST_STATIC_CONSTANT( unsigned long, value = Value1 / gcd_type::value
108         * Value2 );
109    };
110
111    // Special case for zero-GCD values
112    template < >
113    struct static_lcm_helper_t< 0UL, 0UL >
114    {
115        BOOST_STATIC_CONSTANT( unsigned long, value = 0UL );
116    };
117#else
118    // Adapt GCD's inner class template workaround for LCM
119    template < unsigned long Value1 >
120    struct static_lcm_helper2_t
121    {
122        template < unsigned long Value2 >
123        struct helper
124        {
125            typedef static_gcd_helper_t<Value1, Value2>  gcd_type;
126
127            BOOST_STATIC_CONSTANT( unsigned long, value = Value1
128             / gcd_type::value * Value2 );
129        };
130
131        template <  >
132        struct helper< 0UL >
133        {
134            BOOST_STATIC_CONSTANT( unsigned long, value = 0UL );
135        };
136    };
137
138    // Special case
139    template <  >
140    struct static_lcm_helper2_t< 0UL >
141    {
142        template < unsigned long Value2 >
143        struct helper
144        {
145            BOOST_STATIC_CONSTANT( unsigned long, value = 0UL );
146        };
147    };
148
149    // Build the LCM from the above template(s)
150    template < unsigned long Value1, unsigned long Value2 >
151    struct static_lcm_helper_t
152    {
153        BOOST_STATIC_CONSTANT( unsigned long, value
154         = static_lcm_helper2_t<Value1>::BOOST_NESTED_TEMPLATE
155         helper<Value2>::value );
156    };
157#endif
158
159}  // namespace detail
160
161
162//  Compile-time greatest common divisor evaluator class declaration  --------//
163
164template < unsigned long Value1, unsigned long Value2 >
165struct static_gcd
166{
167    BOOST_STATIC_CONSTANT( unsigned long, value
168     = (detail::static_gcd_helper_t<Value1, Value2>::value) );
169
170};  // boost::math::static_gcd
171
172
173//  Compile-time least common multiple evaluator class declaration  ----------//
174
175template < unsigned long Value1, unsigned long Value2 >
176struct static_lcm
177{
178    BOOST_STATIC_CONSTANT( unsigned long, value
179     = (detail::static_lcm_helper_t<Value1, Value2>::value) );
180
181};  // boost::math::static_lcm
182
183
184}  // namespace math
185}  // namespace boost
186
187
188#endif  // BOOST_MATH_COMMON_FACTOR_CT_HPP
Note: See TracBrowser for help on using the repository browser.