OSDN Git Service

2010-11-04 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / ratio
1 // ratio -*- C++ -*-
2
3 // Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the 
7 // terms of the GNU General Public License as published by the 
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file ratio
26  *  This is a Standard C++ Library header.
27  */
28
29 #ifndef _GLIBCXX_RATIO
30 #define _GLIBCXX_RATIO 1
31
32 #pragma GCC system_header
33
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37
38 #include <type_traits>
39 #include <cstdint>
40
41 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
42
43 _GLIBCXX_BEGIN_NAMESPACE(std)
44
45   /**
46    * @defgroup ratio Rational Arithmetic
47    * @ingroup utilities
48    *
49    * Compile time representation of finite rational numbers.
50    * @{
51    */
52
53   template<intmax_t _Pn>
54     struct __static_sign
55     : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1>
56     { };
57
58   template<intmax_t _Pn>
59     struct __static_abs
60     : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value>
61     { };
62
63   template<intmax_t _Pn, intmax_t _Qn>
64     struct __static_gcd;
65  
66   template<intmax_t _Pn, intmax_t _Qn>
67     struct __static_gcd
68     : __static_gcd<_Qn, (_Pn % _Qn)>
69     { };
70
71   template<intmax_t _Pn>
72     struct __static_gcd<_Pn, 0>
73     : integral_constant<intmax_t, __static_abs<_Pn>::value>
74     { };
75
76   template<intmax_t _Qn>
77     struct __static_gcd<0, _Qn>
78     : integral_constant<intmax_t, __static_abs<_Qn>::value>
79     { };
80
81   // Let c = 2^(half # of bits in an intmax_t)
82   // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
83   // The multiplication of N and M becomes,
84   // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
85   // Multiplication is safe if each term and the sum of the terms
86   // is representable by intmax_t.
87   template<intmax_t _Pn, intmax_t _Qn>
88     struct __safe_multiply
89     {
90     private:
91       static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
92
93       static const uintmax_t __a0 = __static_abs<_Pn>::value % __c;
94       static const uintmax_t __a1 = __static_abs<_Pn>::value / __c;
95       static const uintmax_t __b0 = __static_abs<_Qn>::value % __c;
96       static const uintmax_t __b1 = __static_abs<_Qn>::value / __c;
97
98       static_assert(__a1 == 0 || __b1 == 0, 
99         "overflow in multiplication");
100       static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1), 
101         "overflow in multiplication");
102       static_assert(__b0 * __a0 <= __INTMAX_MAX__, 
103         "overflow in multiplication");
104       static_assert((__a0 * __b1 + __b0 * __a1) * __c <= 
105         __INTMAX_MAX__ -  __b0 * __a0, "overflow in multiplication");
106
107     public:
108       static const intmax_t value = _Pn * _Qn;
109     };
110
111   // Helpers for __safe_add
112   template<intmax_t _Pn, intmax_t _Qn, bool>
113     struct __add_overflow_check_impl
114     : integral_constant<bool, (_Pn <= __INTMAX_MAX__ - _Qn)>
115     { };
116
117   template<intmax_t _Pn, intmax_t _Qn>
118     struct __add_overflow_check_impl<_Pn, _Qn, false>
119     : integral_constant<bool, (_Pn >= -__INTMAX_MAX__ - _Qn)>
120     { };
121
122   template<intmax_t _Pn, intmax_t _Qn>
123     struct __add_overflow_check
124     : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)>
125     { };
126
127   template<intmax_t _Pn, intmax_t _Qn>
128     struct __safe_add
129     {
130       static_assert(__add_overflow_check<_Pn, _Qn>::value != 0, 
131         "overflow in addition");
132
133       static const intmax_t value = _Pn + _Qn;
134     };
135
136   /**
137    *  @brief Provides compile-time rational arithmetic.
138    *
139    *  This class template represents any finite rational number with a
140    *  numerator and denominator representable by compile-time constants of
141    *  type intmax_t. The ratio is simplified when instantiated.
142    *
143    *  For example:
144    *  @code
145    *    std::ratio<7,-21>::num == -1;
146    *    std::ratio<7,-21>::den == 3;
147    *  @endcode
148    *  
149   */
150   template<intmax_t _Num, intmax_t _Den = 1>
151     struct ratio
152     {
153       static_assert(_Den != 0, "denominator cannot be zero");
154       static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__,
155                     "out of range");
156
157       // Note: sign(N) * abs(N) == N
158       static constexpr intmax_t num =
159         _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value;
160
161       static constexpr intmax_t den =
162         __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value;
163
164       typedef ratio<num, den> type;
165     };
166
167   template<intmax_t _Num, intmax_t _Den>
168     constexpr intmax_t ratio<_Num, _Den>::num;
169
170   template<intmax_t _Num, intmax_t _Den>
171     constexpr intmax_t ratio<_Num, _Den>::den;
172
173   /// ratio_add
174   template<typename _R1, typename _R2>
175     struct ratio_add
176     {
177     private:
178       static const intmax_t __gcd =
179         __static_gcd<_R1::den, _R2::den>::value;
180       
181     public:
182       typedef ratio<
183         __safe_add<
184           __safe_multiply<_R1::num, (_R2::den / __gcd)>::value,
185           __safe_multiply<_R2::num, (_R1::den / __gcd)>::value>::value,
186         __safe_multiply<_R1::den, (_R2::den / __gcd)>::value> type;
187
188       static constexpr intmax_t num = type::num;
189       static constexpr intmax_t den = type::den;
190     };
191
192   template<typename _R1, typename _R2>
193     constexpr intmax_t ratio_add<_R1, _R2>::num;
194
195   template<typename _R1, typename _R2>
196     constexpr intmax_t ratio_add<_R1, _R2>::den;
197
198   /// ratio_subtract
199   template<typename _R1, typename _R2>
200     struct ratio_subtract
201     {
202       typedef typename ratio_add<
203         _R1,
204         ratio<-_R2::num, _R2::den>>::type type;
205
206       static constexpr intmax_t num = type::num;
207       static constexpr intmax_t den = type::den;
208     };
209
210   template<typename _R1, typename _R2>
211     constexpr intmax_t ratio_subtract<_R1, _R2>::num;
212
213   template<typename _R1, typename _R2>
214     constexpr intmax_t ratio_subtract<_R1, _R2>::den;
215
216   /// ratio_multiply
217   template<typename _R1, typename _R2>
218     struct ratio_multiply
219     {
220     private:
221       static const intmax_t __gcd1 =
222         __static_gcd<_R1::num, _R2::den>::value;
223       static const intmax_t __gcd2 =
224         __static_gcd<_R2::num, _R1::den>::value;
225
226     public:
227       typedef ratio<
228         __safe_multiply<(_R1::num / __gcd1),
229                         (_R2::num / __gcd2)>::value,
230         __safe_multiply<(_R1::den / __gcd2),
231                         (_R2::den / __gcd1)>::value> type;
232
233       static constexpr intmax_t num = type::num;
234       static constexpr intmax_t den = type::den;
235     };
236
237   template<typename _R1, typename _R2>
238     constexpr intmax_t ratio_multiply<_R1, _R2>::num;
239
240   template<typename _R1, typename _R2>
241     constexpr intmax_t ratio_multiply<_R1, _R2>::den;
242
243   /// ratio_divide
244   template<typename _R1, typename _R2>
245     struct ratio_divide
246     {
247       static_assert(_R2::num != 0, "division by 0");
248
249       typedef typename ratio_multiply<
250         _R1,
251         ratio<_R2::den, _R2::num>>::type type;
252
253       static constexpr intmax_t num = type::num;
254       static constexpr intmax_t den = type::den;
255     };
256
257   template<typename _R1, typename _R2>
258     constexpr intmax_t ratio_divide<_R1, _R2>::num;
259
260   template<typename _R1, typename _R2>
261     constexpr intmax_t ratio_divide<_R1, _R2>::den;
262
263   /// ratio_equal
264   template<typename _R1, typename _R2>
265     struct ratio_equal
266     : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den>
267     { };
268   
269   /// ratio_not_equal
270   template<typename _R1, typename _R2>
271     struct ratio_not_equal
272     : integral_constant<bool, !ratio_equal<_R1, _R2>::value>
273     { };
274
275   template<typename _R1>
276     struct __ratio_less_impl_1
277     : integral_constant<bool, _R1::num < _R1::den>
278     { }; 
279
280   template<typename _R1, typename _R2,
281            bool = (_R1::num == 0 || _R2::num == 0
282                    || (__static_sign<_R1::num>::value
283                        != __static_sign<_R2::num>::value)),
284            bool = (__static_sign<_R1::num>::value == -1
285                    && __static_sign<_R2::num>::value == -1)>
286     struct __ratio_less_impl
287     : __ratio_less_impl_1<typename ratio_divide<_R1, _R2>::type>::type
288     { };
289
290   template<typename _R1, typename _R2>
291     struct __ratio_less_impl<_R1, _R2, true, false>
292     : integral_constant<bool, _R1::num < _R2::num>
293     { };
294
295   template<typename _R1, typename _R2>
296     struct __ratio_less_impl<_R1, _R2, false, true>
297     : __ratio_less_impl_1<typename ratio_divide<_R2, _R1>::type>::type
298     { };
299
300   /// ratio_less
301   template<typename _R1, typename _R2>
302     struct ratio_less
303     : __ratio_less_impl<_R1, _R2>::type
304     { };
305     
306   /// ratio_less_equal
307   template<typename _R1, typename _R2>
308     struct ratio_less_equal
309     : integral_constant<bool, !ratio_less<_R2, _R1>::value>
310     { };
311   
312   /// ratio_greater
313   template<typename _R1, typename _R2>
314     struct ratio_greater
315     : integral_constant<bool, ratio_less<_R2, _R1>::value>
316     { };
317
318   /// ratio_greater_equal
319   template<typename _R1, typename _R2>
320     struct ratio_greater_equal
321     : integral_constant<bool, !ratio_less<_R1, _R2>::value>
322     { };
323
324   typedef ratio<1,       1000000000000000000> atto;
325   typedef ratio<1,          1000000000000000> femto;
326   typedef ratio<1,             1000000000000> pico;
327   typedef ratio<1,                1000000000> nano;
328   typedef ratio<1,                   1000000> micro;
329   typedef ratio<1,                      1000> milli;
330   typedef ratio<1,                       100> centi;
331   typedef ratio<1,                        10> deci;
332   typedef ratio<                       10, 1> deca;
333   typedef ratio<                      100, 1> hecto;
334   typedef ratio<                     1000, 1> kilo;
335   typedef ratio<                  1000000, 1> mega;
336   typedef ratio<               1000000000, 1> giga;
337   typedef ratio<            1000000000000, 1> tera;
338   typedef ratio<         1000000000000000, 1> peta;
339   typedef ratio<      1000000000000000000, 1> exa;
340
341   // @} group ratio
342 _GLIBCXX_END_NAMESPACE
343
344 #endif //_GLIBCXX_USE_C99_STDINT_TR1
345
346 #endif //__GXX_EXPERIMENTAL_CXX0X__
347
348 #endif //_GLIBCXX_RATIO