ratio revision 227825
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===---------------------------- ratio -----------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_RATIO
12227825Stheraven#define _LIBCPP_RATIO
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    ratio synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheraventemplate <intmax_t N, intmax_t D = 1>
21227825Stheravenclass ratio
22227825Stheraven{
23227825Stheravenpublic:
24227825Stheraven    static const intmax_t num;
25227825Stheraven    static const intmax_t den;
26227825Stheraven    typedef ratio<num, den> type;
27227825Stheraven};
28227825Stheraven
29227825Stheraven// ratio arithmetic
30227825Stheraventemplate <class R1, class R2> using ratio_add = ...;
31227825Stheraventemplate <class R1, class R2> using ratio_subtract = ...;
32227825Stheraventemplate <class R1, class R2> using ratio_multiply = ...;
33227825Stheraventemplate <class R1, class R2> using ratio_divide = ...;
34227825Stheraven
35227825Stheraven// ratio comparison
36227825Stheraventemplate <class R1, class R2> struct ratio_equal;
37227825Stheraventemplate <class R1, class R2> struct ratio_not_equal;
38227825Stheraventemplate <class R1, class R2> struct ratio_less;
39227825Stheraventemplate <class R1, class R2> struct ratio_less_equal;
40227825Stheraventemplate <class R1, class R2> struct ratio_greater;
41227825Stheraventemplate <class R1, class R2> struct ratio_greater_equal;
42227825Stheraven
43227825Stheraven// convenience SI typedefs
44227825Stheraventypedef ratio<1, 1000000000000000000000000> yocto;  // not supported
45227825Stheraventypedef ratio<1,    1000000000000000000000> zepto;  // not supported
46227825Stheraventypedef ratio<1,       1000000000000000000> atto;
47227825Stheraventypedef ratio<1,          1000000000000000> femto;
48227825Stheraventypedef ratio<1,             1000000000000> pico;
49227825Stheraventypedef ratio<1,                1000000000> nano;
50227825Stheraventypedef ratio<1,                   1000000> micro;
51227825Stheraventypedef ratio<1,                      1000> milli;
52227825Stheraventypedef ratio<1,                       100> centi;
53227825Stheraventypedef ratio<1,                        10> deci;
54227825Stheraventypedef ratio<                       10, 1> deca;
55227825Stheraventypedef ratio<                      100, 1> hecto;
56227825Stheraventypedef ratio<                     1000, 1> kilo;
57227825Stheraventypedef ratio<                  1000000, 1> mega;
58227825Stheraventypedef ratio<               1000000000, 1> giga;
59227825Stheraventypedef ratio<            1000000000000, 1> tera;
60227825Stheraventypedef ratio<         1000000000000000, 1> peta;
61227825Stheraventypedef ratio<      1000000000000000000, 1> exa;
62227825Stheraventypedef ratio<   1000000000000000000000, 1> zetta;  // not supported
63227825Stheraventypedef ratio<1000000000000000000000000, 1> yotta;  // not supported
64227825Stheraven
65227825Stheraven}
66227825Stheraven*/
67227825Stheraven
68227825Stheraven#include <__config>
69227825Stheraven#include <cstdint>
70227825Stheraven#include <climits>
71227825Stheraven#include <type_traits>
72227825Stheraven
73227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
74227825Stheraven#pragma GCC system_header
75227825Stheraven#endif
76227825Stheraven
77227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
78227825Stheraven
79227825Stheraven// __static_gcd
80227825Stheraven
81227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
82227825Stheravenstruct __static_gcd
83227825Stheraven{
84227825Stheraven    static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value;
85227825Stheraven};
86227825Stheraven
87227825Stheraventemplate <intmax_t _Xp>
88227825Stheravenstruct __static_gcd<_Xp, 0>
89227825Stheraven{
90227825Stheraven    static const intmax_t value = _Xp;
91227825Stheraven};
92227825Stheraven
93227825Stheraventemplate <>
94227825Stheravenstruct __static_gcd<0, 0>
95227825Stheraven{
96227825Stheraven    static const intmax_t value = 1;
97227825Stheraven};
98227825Stheraven
99227825Stheraven// __static_lcm
100227825Stheraven
101227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
102227825Stheravenstruct __static_lcm
103227825Stheraven{
104227825Stheraven    static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp;
105227825Stheraven};
106227825Stheraven
107227825Stheraventemplate <intmax_t _Xp>
108227825Stheravenstruct __static_abs
109227825Stheraven{
110227825Stheraven    static const intmax_t value = _Xp < 0 ? -_Xp : _Xp;
111227825Stheraven};
112227825Stheraven
113227825Stheraventemplate <intmax_t _Xp>
114227825Stheravenstruct __static_sign
115227825Stheraven{
116227825Stheraven    static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1);
117227825Stheraven};
118227825Stheraven
119227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
120227825Stheravenclass __ll_add;
121227825Stheraven
122227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
123227825Stheravenclass __ll_add<_Xp, _Yp, 1>
124227825Stheraven{
125227825Stheraven    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
126227825Stheraven    static const intmax_t max = -min;
127227825Stheraven
128227825Stheraven    static_assert(_Xp <= max - _Yp, "overflow in __ll_add");
129227825Stheravenpublic:
130227825Stheraven    static const intmax_t value = _Xp + _Yp;
131227825Stheraven};
132227825Stheraven
133227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
134227825Stheravenclass __ll_add<_Xp, _Yp, 0>
135227825Stheraven{
136227825Stheravenpublic:
137227825Stheraven    static const intmax_t value = _Xp;
138227825Stheraven};
139227825Stheraven
140227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
141227825Stheravenclass __ll_add<_Xp, _Yp, -1>
142227825Stheraven{
143227825Stheraven    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
144227825Stheraven    static const intmax_t max = -min;
145227825Stheraven
146227825Stheraven    static_assert(min - _Yp <= _Xp, "overflow in __ll_add");
147227825Stheravenpublic:
148227825Stheraven    static const intmax_t value = _Xp + _Yp;
149227825Stheraven};
150227825Stheraven
151227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
152227825Stheravenclass __ll_sub;
153227825Stheraven
154227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
155227825Stheravenclass __ll_sub<_Xp, _Yp, 1>
156227825Stheraven{
157227825Stheraven    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
158227825Stheraven    static const intmax_t max = -min;
159227825Stheraven
160227825Stheraven    static_assert(min + _Yp <= _Xp, "overflow in __ll_sub");
161227825Stheravenpublic:
162227825Stheraven    static const intmax_t value = _Xp - _Yp;
163227825Stheraven};
164227825Stheraven
165227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
166227825Stheravenclass __ll_sub<_Xp, _Yp, 0>
167227825Stheraven{
168227825Stheravenpublic:
169227825Stheraven    static const intmax_t value = _Xp;
170227825Stheraven};
171227825Stheraven
172227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
173227825Stheravenclass __ll_sub<_Xp, _Yp, -1>
174227825Stheraven{
175227825Stheraven    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
176227825Stheraven    static const intmax_t max = -min;
177227825Stheraven
178227825Stheraven    static_assert(_Xp <= max + _Yp, "overflow in __ll_sub");
179227825Stheravenpublic:
180227825Stheraven    static const intmax_t value = _Xp - _Yp;
181227825Stheraven};
182227825Stheraven
183227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
184227825Stheravenclass __ll_mul
185227825Stheraven{
186227825Stheraven    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
187227825Stheraven    static const intmax_t min = nan + 1;
188227825Stheraven    static const intmax_t max = -min;
189227825Stheraven    static const intmax_t __a_x = __static_abs<_Xp>::value;
190227825Stheraven    static const intmax_t __a_y = __static_abs<_Yp>::value;
191227825Stheraven
192227825Stheraven    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
193227825Stheravenpublic:
194227825Stheraven    static const intmax_t value = _Xp * _Yp;
195227825Stheraven};
196227825Stheraven
197227825Stheraventemplate <intmax_t _Yp>
198227825Stheravenclass __ll_mul<0, _Yp>
199227825Stheraven{
200227825Stheravenpublic:
201227825Stheraven    static const intmax_t value = 0;
202227825Stheraven};
203227825Stheraven
204227825Stheraventemplate <intmax_t _Xp>
205227825Stheravenclass __ll_mul<_Xp, 0>
206227825Stheraven{
207227825Stheravenpublic:
208227825Stheraven    static const intmax_t value = 0;
209227825Stheraven};
210227825Stheraven
211227825Stheraventemplate <>
212227825Stheravenclass __ll_mul<0, 0>
213227825Stheraven{
214227825Stheravenpublic:
215227825Stheraven    static const intmax_t value = 0;
216227825Stheraven};
217227825Stheraven
218227825Stheraven// Not actually used but left here in case needed in future maintenance
219227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp>
220227825Stheravenclass __ll_div
221227825Stheraven{
222227825Stheraven    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
223227825Stheraven    static const intmax_t min = nan + 1;
224227825Stheraven    static const intmax_t max = -min;
225227825Stheraven
226227825Stheraven    static_assert(_Xp != nan && _Yp != nan && _Yp != 0, "overflow in __ll_div");
227227825Stheravenpublic:
228227825Stheraven    static const intmax_t value = _Xp / _Yp;
229227825Stheraven};
230227825Stheraven
231227825Stheraventemplate <intmax_t _Num, intmax_t _Den = 1>
232227825Stheravenclass _LIBCPP_VISIBLE ratio
233227825Stheraven{
234227825Stheraven    static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range");
235227825Stheraven    static_assert(_Den != 0, "ratio divide by 0");
236227825Stheraven    static_assert(__static_abs<_Den>::value >  0, "ratio denominator is out of range");
237227825Stheraven    static const intmax_t __na = __static_abs<_Num>::value;
238227825Stheraven    static const intmax_t __da = __static_abs<_Den>::value;
239227825Stheraven    static const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;
240227825Stheraven    static const intmax_t __gcd = __static_gcd<__na, __da>::value;
241227825Stheravenpublic:
242227825Stheraven    static const intmax_t num = __s * __na / __gcd;
243227825Stheraven    static const intmax_t den = __da / __gcd;
244227825Stheraven
245227825Stheraven    typedef ratio<num, den> type;
246227825Stheraven};
247227825Stheraven
248227825Stheraventemplate <intmax_t _Num, intmax_t _Den> const intmax_t ratio<_Num, _Den>::num;
249227825Stheraventemplate <intmax_t _Num, intmax_t _Den> const intmax_t ratio<_Num, _Den>::den;
250227825Stheraven
251227825Stheraventemplate <class _Tp>                    struct __is_ratio                     : false_type {};
252227825Stheraventemplate <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type  {};
253227825Stheraven
254227825Stheraventypedef ratio<1LL, 1000000000000000000LL> atto;
255227825Stheraventypedef ratio<1LL,    1000000000000000LL> femto;
256227825Stheraventypedef ratio<1LL,       1000000000000LL> pico;
257227825Stheraventypedef ratio<1LL,          1000000000LL> nano;
258227825Stheraventypedef ratio<1LL,             1000000LL> micro;
259227825Stheraventypedef ratio<1LL,                1000LL> milli;
260227825Stheraventypedef ratio<1LL,                 100LL> centi;
261227825Stheraventypedef ratio<1LL,                  10LL> deci;
262227825Stheraventypedef ratio<                 10LL, 1LL> deca;
263227825Stheraventypedef ratio<                100LL, 1LL> hecto;
264227825Stheraventypedef ratio<               1000LL, 1LL> kilo;
265227825Stheraventypedef ratio<            1000000LL, 1LL> mega;
266227825Stheraventypedef ratio<         1000000000LL, 1LL> giga;
267227825Stheraventypedef ratio<      1000000000000LL, 1LL> tera;
268227825Stheraventypedef ratio<   1000000000000000LL, 1LL> peta;
269227825Stheraventypedef ratio<1000000000000000000LL, 1LL> exa;
270227825Stheraven
271227825Stheraventemplate <class _R1, class _R2>
272227825Stheravenstruct __ratio_multiply
273227825Stheraven{
274227825Stheravenprivate:
275227825Stheraven    static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value;
276227825Stheraven    static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value;
277227825Stheravenpublic:
278227825Stheraven    typedef typename ratio
279227825Stheraven        <
280227825Stheraven            __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value,
281227825Stheraven            __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value
282227825Stheraven        >::type type;
283227825Stheraven};
284227825Stheraven
285227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
286227825Stheraven
287227825Stheraventemplate <class _R1, class _R2> using ratio_multiply
288227825Stheraven                                    = typename __ratio_multiply<_R1, _R2>::type;
289227825Stheraven
290227825Stheraven#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
291227825Stheraven
292227825Stheraventemplate <class _R1, class _R2>
293227825Stheravenstruct _LIBCPP_VISIBLE ratio_multiply
294227825Stheraven    : public __ratio_multiply<_R1, _R2>::type {};
295227825Stheraven
296227825Stheraven#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
297227825Stheraven
298227825Stheraventemplate <class _R1, class _R2>
299227825Stheravenstruct __ratio_divide
300227825Stheraven{
301227825Stheravenprivate:
302227825Stheraven    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
303227825Stheraven    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
304227825Stheravenpublic:
305227825Stheraven    typedef typename ratio
306227825Stheraven        <
307227825Stheraven            __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
308227825Stheraven            __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
309227825Stheraven        >::type type;
310227825Stheraven};
311227825Stheraven
312227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
313227825Stheraven
314227825Stheraventemplate <class _R1, class _R2> using ratio_divide
315227825Stheraven                                      = typename __ratio_divide<_R1, _R2>::type;
316227825Stheraven
317227825Stheraven#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
318227825Stheraven
319227825Stheraventemplate <class _R1, class _R2>
320227825Stheravenstruct _LIBCPP_VISIBLE ratio_divide
321227825Stheraven    : public __ratio_divide<_R1, _R2>::type {};
322227825Stheraven
323227825Stheraven#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
324227825Stheraven
325227825Stheraventemplate <class _R1, class _R2>
326227825Stheravenstruct __ratio_add
327227825Stheraven{
328227825Stheravenprivate:
329227825Stheraven    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
330227825Stheraven    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
331227825Stheravenpublic:
332227825Stheraven    typedef typename ratio_multiply
333227825Stheraven        <
334227825Stheraven            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
335227825Stheraven            ratio
336227825Stheraven            <
337227825Stheraven                __ll_add
338227825Stheraven                <
339227825Stheraven                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
340227825Stheraven                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
341227825Stheraven                >::value,
342227825Stheraven                _R2::den
343227825Stheraven            >
344227825Stheraven        >::type type;
345227825Stheraven};
346227825Stheraven
347227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
348227825Stheraven
349227825Stheraventemplate <class _R1, class _R2> using ratio_add
350227825Stheraven                                         = typename __ratio_add<_R1, _R2>::type;
351227825Stheraven
352227825Stheraven#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
353227825Stheraven
354227825Stheraventemplate <class _R1, class _R2>
355227825Stheravenstruct _LIBCPP_VISIBLE ratio_add
356227825Stheraven    : public __ratio_add<_R1, _R2>::type {};
357227825Stheraven
358227825Stheraven#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
359227825Stheraven
360227825Stheraventemplate <class _R1, class _R2>
361227825Stheravenstruct __ratio_subtract
362227825Stheraven{
363227825Stheravenprivate:
364227825Stheraven    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
365227825Stheraven    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
366227825Stheravenpublic:
367227825Stheraven    typedef typename ratio_multiply
368227825Stheraven        <
369227825Stheraven            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
370227825Stheraven            ratio
371227825Stheraven            <
372227825Stheraven                __ll_sub
373227825Stheraven                <
374227825Stheraven                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
375227825Stheraven                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
376227825Stheraven                >::value,
377227825Stheraven                _R2::den
378227825Stheraven            >
379227825Stheraven        >::type type;
380227825Stheraven};
381227825Stheraven
382227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
383227825Stheraven
384227825Stheraventemplate <class _R1, class _R2> using ratio_subtract
385227825Stheraven                                    = typename __ratio_subtract<_R1, _R2>::type;
386227825Stheraven
387227825Stheraven#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
388227825Stheraven
389227825Stheraventemplate <class _R1, class _R2>
390227825Stheravenstruct _LIBCPP_VISIBLE ratio_subtract
391227825Stheraven    : public __ratio_subtract<_R1, _R2>::type {};
392227825Stheraven
393227825Stheraven#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
394227825Stheraven
395227825Stheraven// ratio_equal
396227825Stheraven
397227825Stheraventemplate <class _R1, class _R2>
398227825Stheravenstruct _LIBCPP_VISIBLE ratio_equal
399227825Stheraven    : public integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> {};
400227825Stheraven
401227825Stheraventemplate <class _R1, class _R2>
402227825Stheravenstruct _LIBCPP_VISIBLE ratio_not_equal
403227825Stheraven    : public integral_constant<bool, !ratio_equal<_R1, _R2>::value> {};
404227825Stheraven
405227825Stheraven// ratio_less
406227825Stheraven
407227825Stheraventemplate <class _R1, class _R2, bool _Odd = false,
408227825Stheraven          intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den,
409227825Stheraven          intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den>
410227825Stheravenstruct __ratio_less1
411227825Stheraven{
412227825Stheraven    static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2;
413227825Stheraven};
414227825Stheraven
415227825Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Q>
416227825Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Q, 0, _Q, 0>
417227825Stheraven{
418227825Stheraven    static const bool value = false;
419227825Stheraven};
420227825Stheraven
421227825Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Q, intmax_t _M2>
422227825Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Q, 0, _Q, _M2>
423227825Stheraven{
424227825Stheraven    static const bool value = !_Odd;
425227825Stheraven};
426227825Stheraven
427227825Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Q, intmax_t _M1>
428227825Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Q, _M1, _Q, 0>
429227825Stheraven{
430227825Stheraven    static const bool value = _Odd;
431227825Stheraven};
432227825Stheraven
433227825Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Q, intmax_t _M1,
434227825Stheraven                                                        intmax_t _M2>
435227825Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Q, _M1, _Q, _M2>
436227825Stheraven{
437227825Stheraven    static const bool value = __ratio_less1<ratio<_R1::den, _M1>,
438227825Stheraven                                            ratio<_R2::den, _M2>, !_Odd>::value;
439227825Stheraven};
440227825Stheraven
441227825Stheraventemplate <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value,
442227825Stheraven                                intmax_t _S2 = __static_sign<_R2::num>::value>
443227825Stheravenstruct __ratio_less
444227825Stheraven{
445227825Stheraven    static const bool value = _S1 < _S2;
446227825Stheraven};
447227825Stheraven
448227825Stheraventemplate <class _R1, class _R2>
449227825Stheravenstruct __ratio_less<_R1, _R2, 1LL, 1LL>
450227825Stheraven{
451227825Stheraven    static const bool value = __ratio_less1<_R1, _R2>::value;
452227825Stheraven};
453227825Stheraven
454227825Stheraventemplate <class _R1, class _R2>
455227825Stheravenstruct __ratio_less<_R1, _R2, -1LL, -1LL>
456227825Stheraven{
457227825Stheraven    static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value;
458227825Stheraven};
459227825Stheraven
460227825Stheraventemplate <class _R1, class _R2>
461227825Stheravenstruct _LIBCPP_VISIBLE ratio_less
462227825Stheraven    : public integral_constant<bool, __ratio_less<_R1, _R2>::value> {};
463227825Stheraven
464227825Stheraventemplate <class _R1, class _R2>
465227825Stheravenstruct _LIBCPP_VISIBLE ratio_less_equal
466227825Stheraven    : public integral_constant<bool, !ratio_less<_R2, _R1>::value> {};
467227825Stheraven
468227825Stheraventemplate <class _R1, class _R2>
469227825Stheravenstruct _LIBCPP_VISIBLE ratio_greater
470227825Stheraven    : public integral_constant<bool, ratio_less<_R2, _R1>::value> {};
471227825Stheraven
472227825Stheraventemplate <class _R1, class _R2>
473227825Stheravenstruct _LIBCPP_VISIBLE ratio_greater_equal
474227825Stheraven    : public integral_constant<bool, !ratio_less<_R1, _R2>::value> {};
475227825Stheraven
476227825Stheraventemplate <class _R1, class _R2>
477227825Stheravenstruct __ratio_gcd
478227825Stheraven{
479227825Stheraven    typedef ratio<__static_gcd<_R1::num, _R2::num>::value,
480227825Stheraven                  __static_lcm<_R1::den, _R2::den>::value> type;
481227825Stheraven};
482227825Stheraven
483227825Stheraven_LIBCPP_END_NAMESPACE_STD
484227825Stheraven
485227825Stheraven#endif  // _LIBCPP_RATIO
486