xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/ratio (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg// -*- C++ -*-
2*4d6fc14bSjoerg//===---------------------------- ratio -----------------------------------===//
3*4d6fc14bSjoerg//
4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information.
6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4d6fc14bSjoerg//
8*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
9*4d6fc14bSjoerg
10*4d6fc14bSjoerg#ifndef _LIBCPP_RATIO
11*4d6fc14bSjoerg#define _LIBCPP_RATIO
12*4d6fc14bSjoerg
13*4d6fc14bSjoerg/*
14*4d6fc14bSjoerg    ratio synopsis
15*4d6fc14bSjoerg
16*4d6fc14bSjoergnamespace std
17*4d6fc14bSjoerg{
18*4d6fc14bSjoerg
19*4d6fc14bSjoergtemplate <intmax_t N, intmax_t D = 1>
20*4d6fc14bSjoergclass ratio
21*4d6fc14bSjoerg{
22*4d6fc14bSjoergpublic:
23*4d6fc14bSjoerg    static constexpr intmax_t num;
24*4d6fc14bSjoerg    static constexpr intmax_t den;
25*4d6fc14bSjoerg    typedef ratio<num, den> type;
26*4d6fc14bSjoerg};
27*4d6fc14bSjoerg
28*4d6fc14bSjoerg// ratio arithmetic
29*4d6fc14bSjoergtemplate <class R1, class R2> using ratio_add = ...;
30*4d6fc14bSjoergtemplate <class R1, class R2> using ratio_subtract = ...;
31*4d6fc14bSjoergtemplate <class R1, class R2> using ratio_multiply = ...;
32*4d6fc14bSjoergtemplate <class R1, class R2> using ratio_divide = ...;
33*4d6fc14bSjoerg
34*4d6fc14bSjoerg// ratio comparison
35*4d6fc14bSjoergtemplate <class R1, class R2> struct ratio_equal;
36*4d6fc14bSjoergtemplate <class R1, class R2> struct ratio_not_equal;
37*4d6fc14bSjoergtemplate <class R1, class R2> struct ratio_less;
38*4d6fc14bSjoergtemplate <class R1, class R2> struct ratio_less_equal;
39*4d6fc14bSjoergtemplate <class R1, class R2> struct ratio_greater;
40*4d6fc14bSjoergtemplate <class R1, class R2> struct ratio_greater_equal;
41*4d6fc14bSjoerg
42*4d6fc14bSjoerg// convenience SI typedefs
43*4d6fc14bSjoergtypedef ratio<1, 1000000000000000000000000> yocto;  // not supported
44*4d6fc14bSjoergtypedef ratio<1,    1000000000000000000000> zepto;  // not supported
45*4d6fc14bSjoergtypedef ratio<1,       1000000000000000000> atto;
46*4d6fc14bSjoergtypedef ratio<1,          1000000000000000> femto;
47*4d6fc14bSjoergtypedef ratio<1,             1000000000000> pico;
48*4d6fc14bSjoergtypedef ratio<1,                1000000000> nano;
49*4d6fc14bSjoergtypedef ratio<1,                   1000000> micro;
50*4d6fc14bSjoergtypedef ratio<1,                      1000> milli;
51*4d6fc14bSjoergtypedef ratio<1,                       100> centi;
52*4d6fc14bSjoergtypedef ratio<1,                        10> deci;
53*4d6fc14bSjoergtypedef ratio<                       10, 1> deca;
54*4d6fc14bSjoergtypedef ratio<                      100, 1> hecto;
55*4d6fc14bSjoergtypedef ratio<                     1000, 1> kilo;
56*4d6fc14bSjoergtypedef ratio<                  1000000, 1> mega;
57*4d6fc14bSjoergtypedef ratio<               1000000000, 1> giga;
58*4d6fc14bSjoergtypedef ratio<            1000000000000, 1> tera;
59*4d6fc14bSjoergtypedef ratio<         1000000000000000, 1> peta;
60*4d6fc14bSjoergtypedef ratio<      1000000000000000000, 1> exa;
61*4d6fc14bSjoergtypedef ratio<   1000000000000000000000, 1> zetta;  // not supported
62*4d6fc14bSjoergtypedef ratio<1000000000000000000000000, 1> yotta;  // not supported
63*4d6fc14bSjoerg
64*4d6fc14bSjoerg  // 20.11.5, ratio comparison
65*4d6fc14bSjoerg  template <class R1, class R2> inline constexpr bool ratio_equal_v
66*4d6fc14bSjoerg    = ratio_equal<R1, R2>::value;                                       // C++17
67*4d6fc14bSjoerg  template <class R1, class R2> inline constexpr bool ratio_not_equal_v
68*4d6fc14bSjoerg    = ratio_not_equal<R1, R2>::value;                                   // C++17
69*4d6fc14bSjoerg  template <class R1, class R2> inline constexpr bool ratio_less_v
70*4d6fc14bSjoerg    = ratio_less<R1, R2>::value;                                        // C++17
71*4d6fc14bSjoerg  template <class R1, class R2> inline constexpr bool ratio_less_equal_v
72*4d6fc14bSjoerg    = ratio_less_equal<R1, R2>::value;                                  // C++17
73*4d6fc14bSjoerg  template <class R1, class R2> inline constexpr bool ratio_greater_v
74*4d6fc14bSjoerg    = ratio_greater<R1, R2>::value;                                     // C++17
75*4d6fc14bSjoerg  template <class R1, class R2> inline constexpr bool ratio_greater_equal_v
76*4d6fc14bSjoerg    = ratio_greater_equal<R1, R2>::value;                               // C++17
77*4d6fc14bSjoerg}
78*4d6fc14bSjoerg*/
79*4d6fc14bSjoerg
80*4d6fc14bSjoerg#include <__config>
81*4d6fc14bSjoerg#include <cstdint>
82*4d6fc14bSjoerg#include <climits>
83*4d6fc14bSjoerg#include <type_traits>
84*4d6fc14bSjoerg
85*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
86*4d6fc14bSjoerg#pragma GCC system_header
87*4d6fc14bSjoerg#endif
88*4d6fc14bSjoerg
89*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS
90*4d6fc14bSjoerg#include <__undef_macros>
91*4d6fc14bSjoerg
92*4d6fc14bSjoerg
93*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD
94*4d6fc14bSjoerg
95*4d6fc14bSjoerg// __static_gcd
96*4d6fc14bSjoerg
97*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
98*4d6fc14bSjoergstruct __static_gcd
99*4d6fc14bSjoerg{
100*4d6fc14bSjoerg    static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value;
101*4d6fc14bSjoerg};
102*4d6fc14bSjoerg
103*4d6fc14bSjoergtemplate <intmax_t _Xp>
104*4d6fc14bSjoergstruct __static_gcd<_Xp, 0>
105*4d6fc14bSjoerg{
106*4d6fc14bSjoerg    static const intmax_t value = _Xp;
107*4d6fc14bSjoerg};
108*4d6fc14bSjoerg
109*4d6fc14bSjoergtemplate <>
110*4d6fc14bSjoergstruct __static_gcd<0, 0>
111*4d6fc14bSjoerg{
112*4d6fc14bSjoerg    static const intmax_t value = 1;
113*4d6fc14bSjoerg};
114*4d6fc14bSjoerg
115*4d6fc14bSjoerg// __static_lcm
116*4d6fc14bSjoerg
117*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
118*4d6fc14bSjoergstruct __static_lcm
119*4d6fc14bSjoerg{
120*4d6fc14bSjoerg    static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp;
121*4d6fc14bSjoerg};
122*4d6fc14bSjoerg
123*4d6fc14bSjoergtemplate <intmax_t _Xp>
124*4d6fc14bSjoergstruct __static_abs
125*4d6fc14bSjoerg{
126*4d6fc14bSjoerg    static const intmax_t value = _Xp < 0 ? -_Xp : _Xp;
127*4d6fc14bSjoerg};
128*4d6fc14bSjoerg
129*4d6fc14bSjoergtemplate <intmax_t _Xp>
130*4d6fc14bSjoergstruct __static_sign
131*4d6fc14bSjoerg{
132*4d6fc14bSjoerg    static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1);
133*4d6fc14bSjoerg};
134*4d6fc14bSjoerg
135*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
136*4d6fc14bSjoergclass __ll_add;
137*4d6fc14bSjoerg
138*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
139*4d6fc14bSjoergclass __ll_add<_Xp, _Yp, 1>
140*4d6fc14bSjoerg{
141*4d6fc14bSjoerg    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
142*4d6fc14bSjoerg    static const intmax_t max = -min;
143*4d6fc14bSjoerg
144*4d6fc14bSjoerg    static_assert(_Xp <= max - _Yp, "overflow in __ll_add");
145*4d6fc14bSjoergpublic:
146*4d6fc14bSjoerg    static const intmax_t value = _Xp + _Yp;
147*4d6fc14bSjoerg};
148*4d6fc14bSjoerg
149*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
150*4d6fc14bSjoergclass __ll_add<_Xp, _Yp, 0>
151*4d6fc14bSjoerg{
152*4d6fc14bSjoergpublic:
153*4d6fc14bSjoerg    static const intmax_t value = _Xp;
154*4d6fc14bSjoerg};
155*4d6fc14bSjoerg
156*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
157*4d6fc14bSjoergclass __ll_add<_Xp, _Yp, -1>
158*4d6fc14bSjoerg{
159*4d6fc14bSjoerg    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
160*4d6fc14bSjoerg    static const intmax_t max = -min;
161*4d6fc14bSjoerg
162*4d6fc14bSjoerg    static_assert(min - _Yp <= _Xp, "overflow in __ll_add");
163*4d6fc14bSjoergpublic:
164*4d6fc14bSjoerg    static const intmax_t value = _Xp + _Yp;
165*4d6fc14bSjoerg};
166*4d6fc14bSjoerg
167*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
168*4d6fc14bSjoergclass __ll_sub;
169*4d6fc14bSjoerg
170*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
171*4d6fc14bSjoergclass __ll_sub<_Xp, _Yp, 1>
172*4d6fc14bSjoerg{
173*4d6fc14bSjoerg    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
174*4d6fc14bSjoerg    static const intmax_t max = -min;
175*4d6fc14bSjoerg
176*4d6fc14bSjoerg    static_assert(min + _Yp <= _Xp, "overflow in __ll_sub");
177*4d6fc14bSjoergpublic:
178*4d6fc14bSjoerg    static const intmax_t value = _Xp - _Yp;
179*4d6fc14bSjoerg};
180*4d6fc14bSjoerg
181*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
182*4d6fc14bSjoergclass __ll_sub<_Xp, _Yp, 0>
183*4d6fc14bSjoerg{
184*4d6fc14bSjoergpublic:
185*4d6fc14bSjoerg    static const intmax_t value = _Xp;
186*4d6fc14bSjoerg};
187*4d6fc14bSjoerg
188*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
189*4d6fc14bSjoergclass __ll_sub<_Xp, _Yp, -1>
190*4d6fc14bSjoerg{
191*4d6fc14bSjoerg    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
192*4d6fc14bSjoerg    static const intmax_t max = -min;
193*4d6fc14bSjoerg
194*4d6fc14bSjoerg    static_assert(_Xp <= max + _Yp, "overflow in __ll_sub");
195*4d6fc14bSjoergpublic:
196*4d6fc14bSjoerg    static const intmax_t value = _Xp - _Yp;
197*4d6fc14bSjoerg};
198*4d6fc14bSjoerg
199*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
200*4d6fc14bSjoergclass __ll_mul
201*4d6fc14bSjoerg{
202*4d6fc14bSjoerg    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
203*4d6fc14bSjoerg    static const intmax_t min = nan + 1;
204*4d6fc14bSjoerg    static const intmax_t max = -min;
205*4d6fc14bSjoerg    static const intmax_t __a_x = __static_abs<_Xp>::value;
206*4d6fc14bSjoerg    static const intmax_t __a_y = __static_abs<_Yp>::value;
207*4d6fc14bSjoerg
208*4d6fc14bSjoerg    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
209*4d6fc14bSjoergpublic:
210*4d6fc14bSjoerg    static const intmax_t value = _Xp * _Yp;
211*4d6fc14bSjoerg};
212*4d6fc14bSjoerg
213*4d6fc14bSjoergtemplate <intmax_t _Yp>
214*4d6fc14bSjoergclass __ll_mul<0, _Yp>
215*4d6fc14bSjoerg{
216*4d6fc14bSjoergpublic:
217*4d6fc14bSjoerg    static const intmax_t value = 0;
218*4d6fc14bSjoerg};
219*4d6fc14bSjoerg
220*4d6fc14bSjoergtemplate <intmax_t _Xp>
221*4d6fc14bSjoergclass __ll_mul<_Xp, 0>
222*4d6fc14bSjoerg{
223*4d6fc14bSjoergpublic:
224*4d6fc14bSjoerg    static const intmax_t value = 0;
225*4d6fc14bSjoerg};
226*4d6fc14bSjoerg
227*4d6fc14bSjoergtemplate <>
228*4d6fc14bSjoergclass __ll_mul<0, 0>
229*4d6fc14bSjoerg{
230*4d6fc14bSjoergpublic:
231*4d6fc14bSjoerg    static const intmax_t value = 0;
232*4d6fc14bSjoerg};
233*4d6fc14bSjoerg
234*4d6fc14bSjoerg// Not actually used but left here in case needed in future maintenance
235*4d6fc14bSjoergtemplate <intmax_t _Xp, intmax_t _Yp>
236*4d6fc14bSjoergclass __ll_div
237*4d6fc14bSjoerg{
238*4d6fc14bSjoerg    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
239*4d6fc14bSjoerg    static const intmax_t min = nan + 1;
240*4d6fc14bSjoerg    static const intmax_t max = -min;
241*4d6fc14bSjoerg
242*4d6fc14bSjoerg    static_assert(_Xp != nan && _Yp != nan && _Yp != 0, "overflow in __ll_div");
243*4d6fc14bSjoergpublic:
244*4d6fc14bSjoerg    static const intmax_t value = _Xp / _Yp;
245*4d6fc14bSjoerg};
246*4d6fc14bSjoerg
247*4d6fc14bSjoergtemplate <intmax_t _Num, intmax_t _Den = 1>
248*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS ratio
249*4d6fc14bSjoerg{
250*4d6fc14bSjoerg    static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range");
251*4d6fc14bSjoerg    static_assert(_Den != 0, "ratio divide by 0");
252*4d6fc14bSjoerg    static_assert(__static_abs<_Den>::value >  0, "ratio denominator is out of range");
253*4d6fc14bSjoerg    static _LIBCPP_CONSTEXPR const intmax_t __na = __static_abs<_Num>::value;
254*4d6fc14bSjoerg    static _LIBCPP_CONSTEXPR const intmax_t __da = __static_abs<_Den>::value;
255*4d6fc14bSjoerg    static _LIBCPP_CONSTEXPR const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;
256*4d6fc14bSjoerg    static _LIBCPP_CONSTEXPR const intmax_t __gcd = __static_gcd<__na, __da>::value;
257*4d6fc14bSjoergpublic:
258*4d6fc14bSjoerg    static _LIBCPP_CONSTEXPR const intmax_t num = __s * __na / __gcd;
259*4d6fc14bSjoerg    static _LIBCPP_CONSTEXPR const intmax_t den = __da / __gcd;
260*4d6fc14bSjoerg
261*4d6fc14bSjoerg    typedef ratio<num, den> type;
262*4d6fc14bSjoerg};
263*4d6fc14bSjoerg
264*4d6fc14bSjoergtemplate <intmax_t _Num, intmax_t _Den>
265*4d6fc14bSjoerg_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::num;
266*4d6fc14bSjoerg
267*4d6fc14bSjoergtemplate <intmax_t _Num, intmax_t _Den>
268*4d6fc14bSjoerg_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::den;
269*4d6fc14bSjoerg
270*4d6fc14bSjoergtemplate <class _Tp>                    struct __is_ratio                     : false_type {};
271*4d6fc14bSjoergtemplate <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type  {};
272*4d6fc14bSjoerg
273*4d6fc14bSjoergtypedef ratio<1LL, 1000000000000000000LL> atto;
274*4d6fc14bSjoergtypedef ratio<1LL,    1000000000000000LL> femto;
275*4d6fc14bSjoergtypedef ratio<1LL,       1000000000000LL> pico;
276*4d6fc14bSjoergtypedef ratio<1LL,          1000000000LL> nano;
277*4d6fc14bSjoergtypedef ratio<1LL,             1000000LL> micro;
278*4d6fc14bSjoergtypedef ratio<1LL,                1000LL> milli;
279*4d6fc14bSjoergtypedef ratio<1LL,                 100LL> centi;
280*4d6fc14bSjoergtypedef ratio<1LL,                  10LL> deci;
281*4d6fc14bSjoergtypedef ratio<                 10LL, 1LL> deca;
282*4d6fc14bSjoergtypedef ratio<                100LL, 1LL> hecto;
283*4d6fc14bSjoergtypedef ratio<               1000LL, 1LL> kilo;
284*4d6fc14bSjoergtypedef ratio<            1000000LL, 1LL> mega;
285*4d6fc14bSjoergtypedef ratio<         1000000000LL, 1LL> giga;
286*4d6fc14bSjoergtypedef ratio<      1000000000000LL, 1LL> tera;
287*4d6fc14bSjoergtypedef ratio<   1000000000000000LL, 1LL> peta;
288*4d6fc14bSjoergtypedef ratio<1000000000000000000LL, 1LL> exa;
289*4d6fc14bSjoerg
290*4d6fc14bSjoergtemplate <class _R1, class _R2>
291*4d6fc14bSjoergstruct __ratio_multiply
292*4d6fc14bSjoerg{
293*4d6fc14bSjoergprivate:
294*4d6fc14bSjoerg    static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value;
295*4d6fc14bSjoerg    static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value;
296*4d6fc14bSjoergpublic:
297*4d6fc14bSjoerg    typedef typename ratio
298*4d6fc14bSjoerg        <
299*4d6fc14bSjoerg            __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value,
300*4d6fc14bSjoerg            __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value
301*4d6fc14bSjoerg        >::type type;
302*4d6fc14bSjoerg};
303*4d6fc14bSjoerg
304*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
305*4d6fc14bSjoerg
306*4d6fc14bSjoergtemplate <class _R1, class _R2> using ratio_multiply
307*4d6fc14bSjoerg                                    = typename __ratio_multiply<_R1, _R2>::type;
308*4d6fc14bSjoerg
309*4d6fc14bSjoerg#else  // _LIBCPP_CXX03_LANG
310*4d6fc14bSjoerg
311*4d6fc14bSjoergtemplate <class _R1, class _R2>
312*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_multiply
313*4d6fc14bSjoerg    : public __ratio_multiply<_R1, _R2>::type {};
314*4d6fc14bSjoerg
315*4d6fc14bSjoerg#endif // _LIBCPP_CXX03_LANG
316*4d6fc14bSjoerg
317*4d6fc14bSjoergtemplate <class _R1, class _R2>
318*4d6fc14bSjoergstruct __ratio_divide
319*4d6fc14bSjoerg{
320*4d6fc14bSjoergprivate:
321*4d6fc14bSjoerg    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
322*4d6fc14bSjoerg    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
323*4d6fc14bSjoergpublic:
324*4d6fc14bSjoerg    typedef typename ratio
325*4d6fc14bSjoerg        <
326*4d6fc14bSjoerg            __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
327*4d6fc14bSjoerg            __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
328*4d6fc14bSjoerg        >::type type;
329*4d6fc14bSjoerg};
330*4d6fc14bSjoerg
331*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
332*4d6fc14bSjoerg
333*4d6fc14bSjoergtemplate <class _R1, class _R2> using ratio_divide
334*4d6fc14bSjoerg                                      = typename __ratio_divide<_R1, _R2>::type;
335*4d6fc14bSjoerg
336*4d6fc14bSjoerg#else  // _LIBCPP_CXX03_LANG
337*4d6fc14bSjoerg
338*4d6fc14bSjoergtemplate <class _R1, class _R2>
339*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_divide
340*4d6fc14bSjoerg    : public __ratio_divide<_R1, _R2>::type {};
341*4d6fc14bSjoerg
342*4d6fc14bSjoerg#endif // _LIBCPP_CXX03_LANG
343*4d6fc14bSjoerg
344*4d6fc14bSjoergtemplate <class _R1, class _R2>
345*4d6fc14bSjoergstruct __ratio_add
346*4d6fc14bSjoerg{
347*4d6fc14bSjoergprivate:
348*4d6fc14bSjoerg    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
349*4d6fc14bSjoerg    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
350*4d6fc14bSjoergpublic:
351*4d6fc14bSjoerg    typedef typename ratio_multiply
352*4d6fc14bSjoerg        <
353*4d6fc14bSjoerg            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
354*4d6fc14bSjoerg            ratio
355*4d6fc14bSjoerg            <
356*4d6fc14bSjoerg                __ll_add
357*4d6fc14bSjoerg                <
358*4d6fc14bSjoerg                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
359*4d6fc14bSjoerg                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
360*4d6fc14bSjoerg                >::value,
361*4d6fc14bSjoerg                _R2::den
362*4d6fc14bSjoerg            >
363*4d6fc14bSjoerg        >::type type;
364*4d6fc14bSjoerg};
365*4d6fc14bSjoerg
366*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
367*4d6fc14bSjoerg
368*4d6fc14bSjoergtemplate <class _R1, class _R2> using ratio_add
369*4d6fc14bSjoerg                                         = typename __ratio_add<_R1, _R2>::type;
370*4d6fc14bSjoerg
371*4d6fc14bSjoerg#else  // _LIBCPP_CXX03_LANG
372*4d6fc14bSjoerg
373*4d6fc14bSjoergtemplate <class _R1, class _R2>
374*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_add
375*4d6fc14bSjoerg    : public __ratio_add<_R1, _R2>::type {};
376*4d6fc14bSjoerg
377*4d6fc14bSjoerg#endif // _LIBCPP_CXX03_LANG
378*4d6fc14bSjoerg
379*4d6fc14bSjoergtemplate <class _R1, class _R2>
380*4d6fc14bSjoergstruct __ratio_subtract
381*4d6fc14bSjoerg{
382*4d6fc14bSjoergprivate:
383*4d6fc14bSjoerg    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
384*4d6fc14bSjoerg    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
385*4d6fc14bSjoergpublic:
386*4d6fc14bSjoerg    typedef typename ratio_multiply
387*4d6fc14bSjoerg        <
388*4d6fc14bSjoerg            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
389*4d6fc14bSjoerg            ratio
390*4d6fc14bSjoerg            <
391*4d6fc14bSjoerg                __ll_sub
392*4d6fc14bSjoerg                <
393*4d6fc14bSjoerg                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
394*4d6fc14bSjoerg                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
395*4d6fc14bSjoerg                >::value,
396*4d6fc14bSjoerg                _R2::den
397*4d6fc14bSjoerg            >
398*4d6fc14bSjoerg        >::type type;
399*4d6fc14bSjoerg};
400*4d6fc14bSjoerg
401*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
402*4d6fc14bSjoerg
403*4d6fc14bSjoergtemplate <class _R1, class _R2> using ratio_subtract
404*4d6fc14bSjoerg                                    = typename __ratio_subtract<_R1, _R2>::type;
405*4d6fc14bSjoerg
406*4d6fc14bSjoerg#else  // _LIBCPP_CXX03_LANG
407*4d6fc14bSjoerg
408*4d6fc14bSjoergtemplate <class _R1, class _R2>
409*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_subtract
410*4d6fc14bSjoerg    : public __ratio_subtract<_R1, _R2>::type {};
411*4d6fc14bSjoerg
412*4d6fc14bSjoerg#endif // _LIBCPP_CXX03_LANG
413*4d6fc14bSjoerg
414*4d6fc14bSjoerg// ratio_equal
415*4d6fc14bSjoerg
416*4d6fc14bSjoergtemplate <class _R1, class _R2>
417*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_equal
418*4d6fc14bSjoerg    : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {};
419*4d6fc14bSjoerg
420*4d6fc14bSjoergtemplate <class _R1, class _R2>
421*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_not_equal
422*4d6fc14bSjoerg    : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {};
423*4d6fc14bSjoerg
424*4d6fc14bSjoerg// ratio_less
425*4d6fc14bSjoerg
426*4d6fc14bSjoergtemplate <class _R1, class _R2, bool _Odd = false,
427*4d6fc14bSjoerg          intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den,
428*4d6fc14bSjoerg          intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den>
429*4d6fc14bSjoergstruct __ratio_less1
430*4d6fc14bSjoerg{
431*4d6fc14bSjoerg    static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2;
432*4d6fc14bSjoerg};
433*4d6fc14bSjoerg
434*4d6fc14bSjoergtemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp>
435*4d6fc14bSjoergstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, 0>
436*4d6fc14bSjoerg{
437*4d6fc14bSjoerg    static const bool value = false;
438*4d6fc14bSjoerg};
439*4d6fc14bSjoerg
440*4d6fc14bSjoergtemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M2>
441*4d6fc14bSjoergstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, _M2>
442*4d6fc14bSjoerg{
443*4d6fc14bSjoerg    static const bool value = !_Odd;
444*4d6fc14bSjoerg};
445*4d6fc14bSjoerg
446*4d6fc14bSjoergtemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1>
447*4d6fc14bSjoergstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, 0>
448*4d6fc14bSjoerg{
449*4d6fc14bSjoerg    static const bool value = _Odd;
450*4d6fc14bSjoerg};
451*4d6fc14bSjoerg
452*4d6fc14bSjoergtemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1,
453*4d6fc14bSjoerg                                                        intmax_t _M2>
454*4d6fc14bSjoergstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, _M2>
455*4d6fc14bSjoerg{
456*4d6fc14bSjoerg    static const bool value = __ratio_less1<ratio<_R1::den, _M1>,
457*4d6fc14bSjoerg                                            ratio<_R2::den, _M2>, !_Odd>::value;
458*4d6fc14bSjoerg};
459*4d6fc14bSjoerg
460*4d6fc14bSjoergtemplate <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value,
461*4d6fc14bSjoerg                                intmax_t _S2 = __static_sign<_R2::num>::value>
462*4d6fc14bSjoergstruct __ratio_less
463*4d6fc14bSjoerg{
464*4d6fc14bSjoerg    static const bool value = _S1 < _S2;
465*4d6fc14bSjoerg};
466*4d6fc14bSjoerg
467*4d6fc14bSjoergtemplate <class _R1, class _R2>
468*4d6fc14bSjoergstruct __ratio_less<_R1, _R2, 1LL, 1LL>
469*4d6fc14bSjoerg{
470*4d6fc14bSjoerg    static const bool value = __ratio_less1<_R1, _R2>::value;
471*4d6fc14bSjoerg};
472*4d6fc14bSjoerg
473*4d6fc14bSjoergtemplate <class _R1, class _R2>
474*4d6fc14bSjoergstruct __ratio_less<_R1, _R2, -1LL, -1LL>
475*4d6fc14bSjoerg{
476*4d6fc14bSjoerg    static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value;
477*4d6fc14bSjoerg};
478*4d6fc14bSjoerg
479*4d6fc14bSjoergtemplate <class _R1, class _R2>
480*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_less
481*4d6fc14bSjoerg    : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {};
482*4d6fc14bSjoerg
483*4d6fc14bSjoergtemplate <class _R1, class _R2>
484*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_less_equal
485*4d6fc14bSjoerg    : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {};
486*4d6fc14bSjoerg
487*4d6fc14bSjoergtemplate <class _R1, class _R2>
488*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_greater
489*4d6fc14bSjoerg    : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {};
490*4d6fc14bSjoerg
491*4d6fc14bSjoergtemplate <class _R1, class _R2>
492*4d6fc14bSjoergstruct _LIBCPP_TEMPLATE_VIS ratio_greater_equal
493*4d6fc14bSjoerg    : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {};
494*4d6fc14bSjoerg
495*4d6fc14bSjoergtemplate <class _R1, class _R2>
496*4d6fc14bSjoergstruct __ratio_gcd
497*4d6fc14bSjoerg{
498*4d6fc14bSjoerg    typedef ratio<__static_gcd<_R1::num, _R2::num>::value,
499*4d6fc14bSjoerg                  __static_lcm<_R1::den, _R2::den>::value> type;
500*4d6fc14bSjoerg};
501*4d6fc14bSjoerg
502*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
503*4d6fc14bSjoergtemplate <class _R1, class _R2>
504*4d6fc14bSjoerg_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_equal_v
505*4d6fc14bSjoerg    = ratio_equal<_R1, _R2>::value;
506*4d6fc14bSjoerg
507*4d6fc14bSjoergtemplate <class _R1, class _R2>
508*4d6fc14bSjoerg_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_not_equal_v
509*4d6fc14bSjoerg    = ratio_not_equal<_R1, _R2>::value;
510*4d6fc14bSjoerg
511*4d6fc14bSjoergtemplate <class _R1, class _R2>
512*4d6fc14bSjoerg_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_less_v
513*4d6fc14bSjoerg    = ratio_less<_R1, _R2>::value;
514*4d6fc14bSjoerg
515*4d6fc14bSjoergtemplate <class _R1, class _R2>
516*4d6fc14bSjoerg_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_less_equal_v
517*4d6fc14bSjoerg    = ratio_less_equal<_R1, _R2>::value;
518*4d6fc14bSjoerg
519*4d6fc14bSjoergtemplate <class _R1, class _R2>
520*4d6fc14bSjoerg_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_greater_v
521*4d6fc14bSjoerg    = ratio_greater<_R1, _R2>::value;
522*4d6fc14bSjoerg
523*4d6fc14bSjoergtemplate <class _R1, class _R2>
524*4d6fc14bSjoerg_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_greater_equal_v
525*4d6fc14bSjoerg    = ratio_greater_equal<_R1, _R2>::value;
526*4d6fc14bSjoerg#endif
527*4d6fc14bSjoerg
528*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD
529*4d6fc14bSjoerg
530*4d6fc14bSjoerg_LIBCPP_POP_MACROS
531*4d6fc14bSjoerg
532*4d6fc14bSjoerg#endif // _LIBCPP_RATIO
533