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