Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / math / common_factor_ct.hpp
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
18 namespace boost
19 {
20 namespace math
21 {
22
23
24 //  Implementation details  --------------------------------------------------//
25
26 namespace 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
164 template < unsigned long Value1, unsigned long Value2 >
165 struct 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
175 template < unsigned long Value1, unsigned long Value2 >
176 struct 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