Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / math / common_factor_rt.hpp
1 //  Boost common_factor_rt.hpp header file  ----------------------------------//
2
3 //  (C) Copyright Daryle Walker and Paul Moore 2001-2002.  Permission to copy,
4 //  use, modify, sell and distribute this software is granted provided this
5 //  copyright notice appears in all copies.  This software is provided "as is"
6 //  without express or implied warranty, and with no claim as to its suitability
7 //  for any purpose. 
8
9 //  See http://www.boost.org for updates, documentation, and revision history. 
10
11 #ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
12 #define BOOST_MATH_COMMON_FACTOR_RT_HPP
13
14 #include <boost/math_fwd.hpp>  // self include
15
16 #include <boost/config.hpp>  // for BOOST_NESTED_TEMPLATE, etc.
17 #include <boost/limits.hpp>  // for std::numeric_limits
18
19
20 namespace boost
21 {
22 namespace math
23 {
24
25
26 //  Forward declarations for function templates  -----------------------------//
27
28 template < typename IntegerType >
29     IntegerType  gcd( IntegerType const &a, IntegerType const &b );
30
31 template < typename IntegerType >
32     IntegerType  lcm( IntegerType const &a, IntegerType const &b );
33
34
35 //  Greatest common divisor evaluator class declaration  ---------------------//
36
37 template < typename IntegerType >
38 class gcd_evaluator
39 {
40 public:
41     // Types
42     typedef IntegerType  result_type, first_argument_type, second_argument_type;
43
44     // Function object interface
45     result_type  operator ()( first_argument_type const &a,
46      second_argument_type const &b ) const;
47
48 };  // boost::math::gcd_evaluator
49
50
51 //  Least common multiple evaluator class declaration  -----------------------//
52
53 template < typename IntegerType >
54 class lcm_evaluator
55 {
56 public:
57     // Types
58     typedef IntegerType  result_type, first_argument_type, second_argument_type;
59
60     // Function object interface
61     result_type  operator ()( first_argument_type const &a,
62      second_argument_type const &b ) const;
63
64 };  // boost::math::lcm_evaluator
65
66
67 //  Implementation details  --------------------------------------------------//
68
69 namespace detail
70 {
71     // Greatest common divisor for rings (including unsigned integers)
72     template < typename RingType >
73     RingType
74     gcd_euclidean
75     (
76         RingType  a,
77         RingType  b
78     )
79     {
80         // Avoid repeated construction
81         #ifndef __BORLANDC__
82         RingType const  zero = static_cast<RingType>( 0 );
83         #else
84         RingType  zero = static_cast<RingType>( 0 );
85         #endif
86
87         // Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)]
88         while ( true )
89         {
90             if ( a == zero )
91                 return b;
92             b %= a;
93
94             if ( b == zero )
95                 return a;
96             a %= b;
97         }
98     }
99
100     // Greatest common divisor for (signed) integers
101     template < typename IntegerType >
102     inline
103     IntegerType
104     gcd_integer
105     (
106         IntegerType const &  a,
107         IntegerType const &  b
108     )
109     {
110         // Avoid repeated construction
111         IntegerType const  zero = static_cast<IntegerType>( 0 );
112         IntegerType const  result = gcd_euclidean( a, b );
113
114         return ( result < zero ) ? -result : result;
115     }
116
117     // Least common multiple for rings (including unsigned integers)
118     template < typename RingType >
119     inline
120     RingType
121     lcm_euclidean
122     (
123         RingType const &  a,
124         RingType const &  b
125     )
126     {
127         RingType const  zero = static_cast<RingType>( 0 );
128         RingType const  temp = gcd_euclidean( a, b );
129
130         return ( temp != zero ) ? ( a / temp * b ) : zero;
131     }
132
133     // Least common multiple for (signed) integers
134     template < typename IntegerType >
135     inline
136     IntegerType
137     lcm_integer
138     (
139         IntegerType const &  a,
140         IntegerType const &  b
141     )
142     {
143         // Avoid repeated construction
144         IntegerType const  zero = static_cast<IntegerType>( 0 );
145         IntegerType const  result = lcm_euclidean( a, b );
146
147         return ( result < zero ) ? -result : result;
148     }
149
150     // Function objects to find the best way of computing GCD or LCM
151 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
152 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
153     template < typename T, bool IsSpecialized, bool IsSigned >
154     struct gcd_optimal_evaluator_helper_t
155     {
156         T  operator ()( T const &a, T const &b )
157         {
158             return gcd_euclidean( a, b );
159         }
160     };
161
162     template < typename T >
163     struct gcd_optimal_evaluator_helper_t< T, true, true >
164     {
165         T  operator ()( T const &a, T const &b )
166         {
167             return gcd_integer( a, b );
168         }
169     };
170 #else
171     template < bool IsSpecialized, bool IsSigned >
172     struct gcd_optimal_evaluator_helper2_t
173     {
174         template < typename T >
175         struct helper
176         {
177             T  operator ()( T const &a, T const &b )
178             {
179                 return gcd_euclidean( a, b );
180             }
181         };
182     };
183
184     template < >
185     struct gcd_optimal_evaluator_helper2_t< true, true >
186     {
187         template < typename T >
188         struct helper
189         {
190             T  operator ()( T const &a, T const &b )
191             {
192                 return gcd_integer( a, b );
193             }
194         };
195     };
196
197     template < typename T, bool IsSpecialized, bool IsSigned >
198     struct gcd_optimal_evaluator_helper_t
199         : gcd_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
200            ::BOOST_NESTED_TEMPLATE helper<T>
201     {
202     };
203 #endif
204
205     template < typename T >
206     struct gcd_optimal_evaluator
207     {
208         T  operator ()( T const &a, T const &b )
209         {
210             typedef ::std::numeric_limits<T>  limits_type;
211
212             typedef gcd_optimal_evaluator_helper_t<T,
213              limits_type::is_specialized, limits_type::is_signed>  helper_type;
214
215             helper_type  solver;
216
217             return solver( a, b );
218         }
219     };
220 #else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
221     template < typename T >
222     struct gcd_optimal_evaluator
223     {
224         T  operator ()( T const &a, T const &b )
225         {
226             return gcd_integer( a, b );
227         }
228     };
229 #endif
230
231 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
232 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
233     template < typename T, bool IsSpecialized, bool IsSigned >
234     struct lcm_optimal_evaluator_helper_t
235     {
236         T  operator ()( T const &a, T const &b )
237         {
238             return lcm_euclidean( a, b );
239         }
240     };
241
242     template < typename T >
243     struct lcm_optimal_evaluator_helper_t< T, true, true >
244     {
245         T  operator ()( T const &a, T const &b )
246         {
247             return lcm_integer( a, b );
248         }
249     };
250 #else
251     template < bool IsSpecialized, bool IsSigned >
252     struct lcm_optimal_evaluator_helper2_t
253     {
254         template < typename T >
255         struct helper
256         {
257             T  operator ()( T const &a, T const &b )
258             {
259                 return lcm_euclidean( a, b );
260             }
261         };
262     };
263
264     template < >
265     struct lcm_optimal_evaluator_helper2_t< true, true >
266     {
267         template < typename T >
268         struct helper
269         {
270             T  operator ()( T const &a, T const &b )
271             {
272                 return lcm_integer( a, b );
273             }
274         };
275     };
276
277     template < typename T, bool IsSpecialized, bool IsSigned >
278     struct lcm_optimal_evaluator_helper_t
279         : lcm_optimal_evaluator_helper2_t<IsSpecialized, IsSigned>
280            ::BOOST_NESTED_TEMPLATE helper<T>
281     {
282     };
283 #endif
284
285     template < typename T >
286     struct lcm_optimal_evaluator
287     {
288         T  operator ()( T const &a, T const &b )
289         {
290             typedef ::std::numeric_limits<T>  limits_type;
291
292             typedef lcm_optimal_evaluator_helper_t<T,
293              limits_type::is_specialized, limits_type::is_signed>  helper_type;
294
295             helper_type  solver;
296
297             return solver( a, b );
298         }
299     };
300 #else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
301     template < typename T >
302     struct lcm_optimal_evaluator
303     {
304         T  operator ()( T const &a, T const &b )
305         {
306             return lcm_integer( a, b );
307         }
308     };
309 #endif
310
311     // Functions to find the GCD or LCM in the best way
312     template < typename T >
313     inline
314     T
315     gcd_optimal
316     (
317         T const &  a,
318         T const &  b
319     )
320     {
321         gcd_optimal_evaluator<T>  solver;
322
323         return solver( a, b );
324     }
325
326     template < typename T >
327     inline
328     T
329     lcm_optimal
330     (
331         T const &  a,
332         T const &  b
333     )
334     {
335         lcm_optimal_evaluator<T>  solver;
336
337         return solver( a, b );
338     }
339
340 }  // namespace detail
341
342
343 //  Greatest common divisor evaluator member function definition  ------------//
344
345 template < typename IntegerType >
346 inline
347 typename gcd_evaluator<IntegerType>::result_type
348 gcd_evaluator<IntegerType>::operator ()
349 (
350     first_argument_type const &   a,
351     second_argument_type const &  b
352 ) const
353 {
354     return detail::gcd_optimal( a, b );
355 }
356
357
358 //  Least common multiple evaluator member function definition  --------------//
359
360 template < typename IntegerType >
361 inline
362 typename lcm_evaluator<IntegerType>::result_type
363 lcm_evaluator<IntegerType>::operator ()
364 (
365     first_argument_type const &   a,
366     second_argument_type const &  b
367 ) const
368 {
369     return detail::lcm_optimal( a, b );
370 }
371
372
373 //  Greatest common divisor and least common multiple function definitions  --//
374
375 template < typename IntegerType >
376 inline
377 IntegerType
378 gcd
379 (
380     IntegerType const &  a,
381     IntegerType const &  b
382 )
383 {
384     gcd_evaluator<IntegerType>  solver;
385
386     return solver( a, b );
387 }
388
389 template < typename IntegerType >
390 inline
391 IntegerType
392 lcm
393 (
394     IntegerType const &  a,
395     IntegerType const &  b
396 )
397 {
398     lcm_evaluator<IntegerType>  solver;
399
400     return solver( a, b );
401 }
402
403
404 }  // namespace math
405 }  // namespace boost
406
407
408 #endif  // BOOST_MATH_COMMON_FACTOR_RT_HPP