xref: /llvm-project-15.0.7/libcxx/include/ratio (revision 385cc25a)
13e519524SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_RATIO
113e519524SHoward Hinnant#define _LIBCPP_RATIO
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    ratio synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnanttemplate <intmax_t N, intmax_t D = 1>
203e519524SHoward Hinnantclass ratio
213e519524SHoward Hinnant{
223e519524SHoward Hinnantpublic:
2360d5e0e0SMarshall Clow    static constexpr intmax_t num;
2460d5e0e0SMarshall Clow    static constexpr intmax_t den;
250c6a0fe7SHoward Hinnant    typedef ratio<num, den> type;
263e519524SHoward Hinnant};
273e519524SHoward Hinnant
283e519524SHoward Hinnant// ratio arithmetic
290c6a0fe7SHoward Hinnanttemplate <class R1, class R2> using ratio_add = ...;
300c6a0fe7SHoward Hinnanttemplate <class R1, class R2> using ratio_subtract = ...;
310c6a0fe7SHoward Hinnanttemplate <class R1, class R2> using ratio_multiply = ...;
320c6a0fe7SHoward Hinnanttemplate <class R1, class R2> using ratio_divide = ...;
333e519524SHoward Hinnant
343e519524SHoward Hinnant// ratio comparison
353e519524SHoward Hinnanttemplate <class R1, class R2> struct ratio_equal;
363e519524SHoward Hinnanttemplate <class R1, class R2> struct ratio_not_equal;
373e519524SHoward Hinnanttemplate <class R1, class R2> struct ratio_less;
383e519524SHoward Hinnanttemplate <class R1, class R2> struct ratio_less_equal;
393e519524SHoward Hinnanttemplate <class R1, class R2> struct ratio_greater;
403e519524SHoward Hinnanttemplate <class R1, class R2> struct ratio_greater_equal;
413e519524SHoward Hinnant
423e519524SHoward Hinnant// convenience SI typedefs
433e519524SHoward Hinnanttypedef ratio<1, 1000000000000000000000000> yocto;  // not supported
443e519524SHoward Hinnanttypedef ratio<1,    1000000000000000000000> zepto;  // not supported
453e519524SHoward Hinnanttypedef ratio<1,       1000000000000000000> atto;
463e519524SHoward Hinnanttypedef ratio<1,          1000000000000000> femto;
473e519524SHoward Hinnanttypedef ratio<1,             1000000000000> pico;
483e519524SHoward Hinnanttypedef ratio<1,                1000000000> nano;
493e519524SHoward Hinnanttypedef ratio<1,                   1000000> micro;
503e519524SHoward Hinnanttypedef ratio<1,                      1000> milli;
513e519524SHoward Hinnanttypedef ratio<1,                       100> centi;
523e519524SHoward Hinnanttypedef ratio<1,                        10> deci;
533e519524SHoward Hinnanttypedef ratio<                       10, 1> deca;
543e519524SHoward Hinnanttypedef ratio<                      100, 1> hecto;
553e519524SHoward Hinnanttypedef ratio<                     1000, 1> kilo;
563e519524SHoward Hinnanttypedef ratio<                  1000000, 1> mega;
573e519524SHoward Hinnanttypedef ratio<               1000000000, 1> giga;
583e519524SHoward Hinnanttypedef ratio<            1000000000000, 1> tera;
593e519524SHoward Hinnanttypedef ratio<         1000000000000000, 1> peta;
603e519524SHoward Hinnanttypedef ratio<      1000000000000000000, 1> exa;
613e519524SHoward Hinnanttypedef ratio<   1000000000000000000000, 1> zetta;  // not supported
623e519524SHoward Hinnanttypedef ratio<1000000000000000000000000, 1> yotta;  // not supported
633e519524SHoward Hinnant
64825a9edbSMarshall Clow  // 20.11.5, ratio comparison
6540a01d53SMarshall Clow  template <class R1, class R2> inline constexpr bool ratio_equal_v
66825a9edbSMarshall Clow    = ratio_equal<R1, R2>::value;                                       // C++17
6740a01d53SMarshall Clow  template <class R1, class R2> inline constexpr bool ratio_not_equal_v
68825a9edbSMarshall Clow    = ratio_not_equal<R1, R2>::value;                                   // C++17
6940a01d53SMarshall Clow  template <class R1, class R2> inline constexpr bool ratio_less_v
70825a9edbSMarshall Clow    = ratio_less<R1, R2>::value;                                        // C++17
7140a01d53SMarshall Clow  template <class R1, class R2> inline constexpr bool ratio_less_equal_v
72825a9edbSMarshall Clow    = ratio_less_equal<R1, R2>::value;                                  // C++17
7340a01d53SMarshall Clow  template <class R1, class R2> inline constexpr bool ratio_greater_v
74825a9edbSMarshall Clow    = ratio_greater<R1, R2>::value;                                     // C++17
7540a01d53SMarshall Clow  template <class R1, class R2> inline constexpr bool ratio_greater_equal_v
76825a9edbSMarshall Clow    = ratio_greater_equal<R1, R2>::value;                               // C++17
773e519524SHoward Hinnant}
783e519524SHoward Hinnant*/
793e519524SHoward Hinnant
80*385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
813e519524SHoward Hinnant#include <__config>
823e519524SHoward Hinnant#include <climits>
83bfbd73f8SArthur O'Dwyer#include <cstdint>
843e519524SHoward Hinnant#include <type_traits>
85bd6e6846SMark de Wever#include <version>
863e519524SHoward Hinnant
87073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
883e519524SHoward Hinnant#  pragma GCC system_header
89073458b1SHoward Hinnant#endif
903e519524SHoward Hinnant
91a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
92a016efb1SEric Fiselier#include <__undef_macros>
93a016efb1SEric Fiselier
94a016efb1SEric Fiselier
953e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
963e519524SHoward Hinnant
973e519524SHoward Hinnant// __static_gcd
983e519524SHoward Hinnant
993e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1003e519524SHoward Hinnantstruct __static_gcd
1013e519524SHoward Hinnant{
1023e519524SHoward Hinnant    static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value;
1033e519524SHoward Hinnant};
1043e519524SHoward Hinnant
1053e519524SHoward Hinnanttemplate <intmax_t _Xp>
1063e519524SHoward Hinnantstruct __static_gcd<_Xp, 0>
1073e519524SHoward Hinnant{
1083e519524SHoward Hinnant    static const intmax_t value = _Xp;
1093e519524SHoward Hinnant};
1103e519524SHoward Hinnant
11105e48587SHoward Hinnanttemplate <>
11205e48587SHoward Hinnantstruct __static_gcd<0, 0>
11305e48587SHoward Hinnant{
11405e48587SHoward Hinnant    static const intmax_t value = 1;
11505e48587SHoward Hinnant};
11605e48587SHoward Hinnant
1173e519524SHoward Hinnant// __static_lcm
1183e519524SHoward Hinnant
1193e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1203e519524SHoward Hinnantstruct __static_lcm
1213e519524SHoward Hinnant{
1223e519524SHoward Hinnant    static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp;
1233e519524SHoward Hinnant};
1243e519524SHoward Hinnant
1253e519524SHoward Hinnanttemplate <intmax_t _Xp>
1263e519524SHoward Hinnantstruct __static_abs
1273e519524SHoward Hinnant{
1283e519524SHoward Hinnant    static const intmax_t value = _Xp < 0 ? -_Xp : _Xp;
1293e519524SHoward Hinnant};
1303e519524SHoward Hinnant
1313e519524SHoward Hinnanttemplate <intmax_t _Xp>
1323e519524SHoward Hinnantstruct __static_sign
1333e519524SHoward Hinnant{
1343e519524SHoward Hinnant    static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1);
1353e519524SHoward Hinnant};
1363e519524SHoward Hinnant
1373e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
1383e519524SHoward Hinnantclass __ll_add;
1393e519524SHoward Hinnant
1403e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1413e519524SHoward Hinnantclass __ll_add<_Xp, _Yp, 1>
1423e519524SHoward Hinnant{
1433e519524SHoward Hinnant    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1443e519524SHoward Hinnant    static const intmax_t max = -min;
1453e519524SHoward Hinnant
1463e519524SHoward Hinnant    static_assert(_Xp <= max - _Yp, "overflow in __ll_add");
1473e519524SHoward Hinnantpublic:
1483e519524SHoward Hinnant    static const intmax_t value = _Xp + _Yp;
1493e519524SHoward Hinnant};
1503e519524SHoward Hinnant
1513e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1523e519524SHoward Hinnantclass __ll_add<_Xp, _Yp, 0>
1533e519524SHoward Hinnant{
1543e519524SHoward Hinnantpublic:
1553e519524SHoward Hinnant    static const intmax_t value = _Xp;
1563e519524SHoward Hinnant};
1573e519524SHoward Hinnant
1583e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1593e519524SHoward Hinnantclass __ll_add<_Xp, _Yp, -1>
1603e519524SHoward Hinnant{
1613e519524SHoward Hinnant    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1623e519524SHoward Hinnant    static const intmax_t max = -min;
1633e519524SHoward Hinnant
1643e519524SHoward Hinnant    static_assert(min - _Yp <= _Xp, "overflow in __ll_add");
1653e519524SHoward Hinnantpublic:
1663e519524SHoward Hinnant    static const intmax_t value = _Xp + _Yp;
1673e519524SHoward Hinnant};
1683e519524SHoward Hinnant
1693e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
1703e519524SHoward Hinnantclass __ll_sub;
1713e519524SHoward Hinnant
1723e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1733e519524SHoward Hinnantclass __ll_sub<_Xp, _Yp, 1>
1743e519524SHoward Hinnant{
1753e519524SHoward Hinnant    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1763e519524SHoward Hinnant    static const intmax_t max = -min;
1773e519524SHoward Hinnant
1783e519524SHoward Hinnant    static_assert(min + _Yp <= _Xp, "overflow in __ll_sub");
1793e519524SHoward Hinnantpublic:
1803e519524SHoward Hinnant    static const intmax_t value = _Xp - _Yp;
1813e519524SHoward Hinnant};
1823e519524SHoward Hinnant
1833e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1843e519524SHoward Hinnantclass __ll_sub<_Xp, _Yp, 0>
1853e519524SHoward Hinnant{
1863e519524SHoward Hinnantpublic:
1873e519524SHoward Hinnant    static const intmax_t value = _Xp;
1883e519524SHoward Hinnant};
1893e519524SHoward Hinnant
1903e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
1913e519524SHoward Hinnantclass __ll_sub<_Xp, _Yp, -1>
1923e519524SHoward Hinnant{
1933e519524SHoward Hinnant    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
1943e519524SHoward Hinnant    static const intmax_t max = -min;
1953e519524SHoward Hinnant
1963e519524SHoward Hinnant    static_assert(_Xp <= max + _Yp, "overflow in __ll_sub");
1973e519524SHoward Hinnantpublic:
1983e519524SHoward Hinnant    static const intmax_t value = _Xp - _Yp;
1993e519524SHoward Hinnant};
2003e519524SHoward Hinnant
2013e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
2023e519524SHoward Hinnantclass __ll_mul
2033e519524SHoward Hinnant{
2043e519524SHoward Hinnant    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
2053e519524SHoward Hinnant    static const intmax_t min = nan + 1;
2063e519524SHoward Hinnant    static const intmax_t max = -min;
2073e519524SHoward Hinnant    static const intmax_t __a_x = __static_abs<_Xp>::value;
2083e519524SHoward Hinnant    static const intmax_t __a_y = __static_abs<_Yp>::value;
2093e519524SHoward Hinnant
2103e519524SHoward Hinnant    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
2113e519524SHoward Hinnantpublic:
2123e519524SHoward Hinnant    static const intmax_t value = _Xp * _Yp;
2133e519524SHoward Hinnant};
2143e519524SHoward Hinnant
2153e519524SHoward Hinnanttemplate <intmax_t _Yp>
2163e519524SHoward Hinnantclass __ll_mul<0, _Yp>
2173e519524SHoward Hinnant{
2183e519524SHoward Hinnantpublic:
2193e519524SHoward Hinnant    static const intmax_t value = 0;
2203e519524SHoward Hinnant};
2213e519524SHoward Hinnant
2223e519524SHoward Hinnanttemplate <intmax_t _Xp>
2233e519524SHoward Hinnantclass __ll_mul<_Xp, 0>
2243e519524SHoward Hinnant{
2253e519524SHoward Hinnantpublic:
2263e519524SHoward Hinnant    static const intmax_t value = 0;
2273e519524SHoward Hinnant};
2283e519524SHoward Hinnant
2293e519524SHoward Hinnanttemplate <>
2303e519524SHoward Hinnantclass __ll_mul<0, 0>
2313e519524SHoward Hinnant{
2323e519524SHoward Hinnantpublic:
2333e519524SHoward Hinnant    static const intmax_t value = 0;
2343e519524SHoward Hinnant};
2353e519524SHoward Hinnant
2363e519524SHoward Hinnant// Not actually used but left here in case needed in future maintenance
2373e519524SHoward Hinnanttemplate <intmax_t _Xp, intmax_t _Yp>
2383e519524SHoward Hinnantclass __ll_div
2393e519524SHoward Hinnant{
2403e519524SHoward Hinnant    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
2413e519524SHoward Hinnant    static const intmax_t min = nan + 1;
2423e519524SHoward Hinnant    static const intmax_t max = -min;
2433e519524SHoward Hinnant
2443e519524SHoward Hinnant    static_assert(_Xp != nan && _Yp != nan && _Yp != 0, "overflow in __ll_div");
2453e519524SHoward Hinnantpublic:
2463e519524SHoward Hinnant    static const intmax_t value = _Xp / _Yp;
2473e519524SHoward Hinnant};
2483e519524SHoward Hinnant
2493e519524SHoward Hinnanttemplate <intmax_t _Num, intmax_t _Den = 1>
250e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS ratio
2513e519524SHoward Hinnant{
2523e519524SHoward Hinnant    static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range");
2533e519524SHoward Hinnant    static_assert(_Den != 0, "ratio divide by 0");
2543e519524SHoward Hinnant    static_assert(__static_abs<_Den>::value >  0, "ratio denominator is out of range");
25560d5e0e0SMarshall Clow    static _LIBCPP_CONSTEXPR const intmax_t __na = __static_abs<_Num>::value;
25660d5e0e0SMarshall Clow    static _LIBCPP_CONSTEXPR const intmax_t __da = __static_abs<_Den>::value;
25760d5e0e0SMarshall Clow    static _LIBCPP_CONSTEXPR const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;
25860d5e0e0SMarshall Clow    static _LIBCPP_CONSTEXPR const intmax_t __gcd = __static_gcd<__na, __da>::value;
2593e519524SHoward Hinnantpublic:
26060d5e0e0SMarshall Clow    static _LIBCPP_CONSTEXPR const intmax_t num = __s * __na / __gcd;
26160d5e0e0SMarshall Clow    static _LIBCPP_CONSTEXPR const intmax_t den = __da / __gcd;
2623e519524SHoward Hinnant
2633e519524SHoward Hinnant    typedef ratio<num, den> type;
2643e519524SHoward Hinnant};
2653e519524SHoward Hinnant
2661f294fd9SEric Fiseliertemplate <intmax_t _Num, intmax_t _Den>
2671f294fd9SEric Fiselier_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::num;
2681f294fd9SEric Fiselier
2691f294fd9SEric Fiseliertemplate <intmax_t _Num, intmax_t _Den>
2701f294fd9SEric Fiselier_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::den;
2713e519524SHoward Hinnant
272e31e36f9SHoward Hinnanttemplate <class _Tp>                    struct __is_ratio                     : false_type {};
2733e519524SHoward Hinnanttemplate <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type  {};
2743e519524SHoward Hinnant
2753e519524SHoward Hinnanttypedef ratio<1LL, 1000000000000000000LL> atto;
2763e519524SHoward Hinnanttypedef ratio<1LL,    1000000000000000LL> femto;
2773e519524SHoward Hinnanttypedef ratio<1LL,       1000000000000LL> pico;
2783e519524SHoward Hinnanttypedef ratio<1LL,          1000000000LL> nano;
2793e519524SHoward Hinnanttypedef ratio<1LL,             1000000LL> micro;
2803e519524SHoward Hinnanttypedef ratio<1LL,                1000LL> milli;
2813e519524SHoward Hinnanttypedef ratio<1LL,                 100LL> centi;
2823e519524SHoward Hinnanttypedef ratio<1LL,                  10LL> deci;
2833e519524SHoward Hinnanttypedef ratio<                 10LL, 1LL> deca;
2843e519524SHoward Hinnanttypedef ratio<                100LL, 1LL> hecto;
2853e519524SHoward Hinnanttypedef ratio<               1000LL, 1LL> kilo;
2863e519524SHoward Hinnanttypedef ratio<            1000000LL, 1LL> mega;
2873e519524SHoward Hinnanttypedef ratio<         1000000000LL, 1LL> giga;
2883e519524SHoward Hinnanttypedef ratio<      1000000000000LL, 1LL> tera;
2893e519524SHoward Hinnanttypedef ratio<   1000000000000000LL, 1LL> peta;
2903e519524SHoward Hinnanttypedef ratio<1000000000000000000LL, 1LL> exa;
2913e519524SHoward Hinnant
2923e519524SHoward Hinnanttemplate <class _R1, class _R2>
2930c6a0fe7SHoward Hinnantstruct __ratio_multiply
2943e519524SHoward Hinnant{
2953e519524SHoward Hinnantprivate:
2963e519524SHoward Hinnant    static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value;
2973e519524SHoward Hinnant    static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value;
2983e519524SHoward Hinnantpublic:
2993e519524SHoward Hinnant    typedef typename ratio
3003e519524SHoward Hinnant        <
3013e519524SHoward Hinnant            __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value,
3023e519524SHoward Hinnant            __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value
3033e519524SHoward Hinnant        >::type type;
3043e519524SHoward Hinnant};
3053e519524SHoward Hinnant
30654613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
307e3c67084SHoward Hinnant
308e3c67084SHoward Hinnanttemplate <class _R1, class _R2> using ratio_multiply
309e3c67084SHoward Hinnant                                    = typename __ratio_multiply<_R1, _R2>::type;
310e3c67084SHoward Hinnant
31154613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
312e3c67084SHoward Hinnant
3133e519524SHoward Hinnanttemplate <class _R1, class _R2>
314e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_multiply
3156fd5c650SHoward Hinnant    : public __ratio_multiply<_R1, _R2>::type {};
3160c6a0fe7SHoward Hinnant
31754613ab4SEric Fiselier#endif // _LIBCPP_CXX03_LANG
318e3c67084SHoward Hinnant
3190c6a0fe7SHoward Hinnanttemplate <class _R1, class _R2>
3200c6a0fe7SHoward Hinnantstruct __ratio_divide
3213e519524SHoward Hinnant{
3223e519524SHoward Hinnantprivate:
3233e519524SHoward Hinnant    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
3243e519524SHoward Hinnant    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
3253e519524SHoward Hinnantpublic:
3263e519524SHoward Hinnant    typedef typename ratio
3273e519524SHoward Hinnant        <
3283e519524SHoward Hinnant            __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
3293e519524SHoward Hinnant            __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
3303e519524SHoward Hinnant        >::type type;
3313e519524SHoward Hinnant};
3323e519524SHoward Hinnant
33354613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
334e3c67084SHoward Hinnant
335e3c67084SHoward Hinnanttemplate <class _R1, class _R2> using ratio_divide
336e3c67084SHoward Hinnant                                      = typename __ratio_divide<_R1, _R2>::type;
337e3c67084SHoward Hinnant
33854613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
339e3c67084SHoward Hinnant
3403e519524SHoward Hinnanttemplate <class _R1, class _R2>
341e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_divide
3426fd5c650SHoward Hinnant    : public __ratio_divide<_R1, _R2>::type {};
3430c6a0fe7SHoward Hinnant
34454613ab4SEric Fiselier#endif // _LIBCPP_CXX03_LANG
345e3c67084SHoward Hinnant
3460c6a0fe7SHoward Hinnanttemplate <class _R1, class _R2>
3470c6a0fe7SHoward Hinnantstruct __ratio_add
3483e519524SHoward Hinnant{
3493e519524SHoward Hinnantprivate:
3503e519524SHoward Hinnant    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
3513e519524SHoward Hinnant    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
3523e519524SHoward Hinnantpublic:
3533e519524SHoward Hinnant    typedef typename ratio_multiply
3543e519524SHoward Hinnant        <
3553e519524SHoward Hinnant            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
3563e519524SHoward Hinnant            ratio
3573e519524SHoward Hinnant            <
3583e519524SHoward Hinnant                __ll_add
3593e519524SHoward Hinnant                <
3603e519524SHoward Hinnant                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
3613e519524SHoward Hinnant                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
3623e519524SHoward Hinnant                >::value,
3633e519524SHoward Hinnant                _R2::den
3643e519524SHoward Hinnant            >
3653e519524SHoward Hinnant        >::type type;
3663e519524SHoward Hinnant};
3673e519524SHoward Hinnant
36854613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
369e3c67084SHoward Hinnant
370e3c67084SHoward Hinnanttemplate <class _R1, class _R2> using ratio_add
371e3c67084SHoward Hinnant                                         = typename __ratio_add<_R1, _R2>::type;
372e3c67084SHoward Hinnant
37354613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
374e3c67084SHoward Hinnant
3753e519524SHoward Hinnanttemplate <class _R1, class _R2>
376e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_add
3776fd5c650SHoward Hinnant    : public __ratio_add<_R1, _R2>::type {};
3780c6a0fe7SHoward Hinnant
37954613ab4SEric Fiselier#endif // _LIBCPP_CXX03_LANG
380e3c67084SHoward Hinnant
3810c6a0fe7SHoward Hinnanttemplate <class _R1, class _R2>
3820c6a0fe7SHoward Hinnantstruct __ratio_subtract
3833e519524SHoward Hinnant{
3843e519524SHoward Hinnantprivate:
3853e519524SHoward Hinnant    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
3863e519524SHoward Hinnant    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
3873e519524SHoward Hinnantpublic:
3883e519524SHoward Hinnant    typedef typename ratio_multiply
3893e519524SHoward Hinnant        <
3903e519524SHoward Hinnant            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
3913e519524SHoward Hinnant            ratio
3923e519524SHoward Hinnant            <
3933e519524SHoward Hinnant                __ll_sub
3943e519524SHoward Hinnant                <
3953e519524SHoward Hinnant                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
3963e519524SHoward Hinnant                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
3973e519524SHoward Hinnant                >::value,
3983e519524SHoward Hinnant                _R2::den
3993e519524SHoward Hinnant            >
4003e519524SHoward Hinnant        >::type type;
4013e519524SHoward Hinnant};
4023e519524SHoward Hinnant
40354613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
404e3c67084SHoward Hinnant
405e3c67084SHoward Hinnanttemplate <class _R1, class _R2> using ratio_subtract
406e3c67084SHoward Hinnant                                    = typename __ratio_subtract<_R1, _R2>::type;
407e3c67084SHoward Hinnant
40854613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
409e3c67084SHoward Hinnant
4100c6a0fe7SHoward Hinnanttemplate <class _R1, class _R2>
411e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_subtract
4126fd5c650SHoward Hinnant    : public __ratio_subtract<_R1, _R2>::type {};
4130c6a0fe7SHoward Hinnant
41454613ab4SEric Fiselier#endif // _LIBCPP_CXX03_LANG
415e3c67084SHoward Hinnant
4163e519524SHoward Hinnant// ratio_equal
4173e519524SHoward Hinnant
4183e519524SHoward Hinnanttemplate <class _R1, class _R2>
419e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_equal
420f900f702SLouis Dionne    : _BoolConstant<(_R1::num == _R2::num && _R1::den == _R2::den)> {};
4213e519524SHoward Hinnant
4223e519524SHoward Hinnanttemplate <class _R1, class _R2>
423e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_not_equal
424f900f702SLouis Dionne    : _BoolConstant<!ratio_equal<_R1, _R2>::value> {};
4253e519524SHoward Hinnant
4263e519524SHoward Hinnant// ratio_less
4273e519524SHoward Hinnant
4283e519524SHoward Hinnanttemplate <class _R1, class _R2, bool _Odd = false,
4293e519524SHoward Hinnant          intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den,
4303e519524SHoward Hinnant          intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den>
4313e519524SHoward Hinnantstruct __ratio_less1
4323e519524SHoward Hinnant{
4333e519524SHoward Hinnant    static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2;
4343e519524SHoward Hinnant};
4353e519524SHoward Hinnant
436c003db1fSHoward Hinnanttemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp>
437c003db1fSHoward Hinnantstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, 0>
4383e519524SHoward Hinnant{
4393e519524SHoward Hinnant    static const bool value = false;
4403e519524SHoward Hinnant};
4413e519524SHoward Hinnant
442c003db1fSHoward Hinnanttemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M2>
443c003db1fSHoward Hinnantstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, _M2>
4443e519524SHoward Hinnant{
4453e519524SHoward Hinnant    static const bool value = !_Odd;
4463e519524SHoward Hinnant};
4473e519524SHoward Hinnant
448c003db1fSHoward Hinnanttemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1>
449c003db1fSHoward Hinnantstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, 0>
4503e519524SHoward Hinnant{
4513e519524SHoward Hinnant    static const bool value = _Odd;
4523e519524SHoward Hinnant};
4533e519524SHoward Hinnant
454c003db1fSHoward Hinnanttemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1,
4553e519524SHoward Hinnant                                                        intmax_t _M2>
456c003db1fSHoward Hinnantstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, _M2>
4573e519524SHoward Hinnant{
4583e519524SHoward Hinnant    static const bool value = __ratio_less1<ratio<_R1::den, _M1>,
4593e519524SHoward Hinnant                                            ratio<_R2::den, _M2>, !_Odd>::value;
4603e519524SHoward Hinnant};
4613e519524SHoward Hinnant
4623e519524SHoward Hinnanttemplate <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value,
4633e519524SHoward Hinnant                                intmax_t _S2 = __static_sign<_R2::num>::value>
4643e519524SHoward Hinnantstruct __ratio_less
4653e519524SHoward Hinnant{
4663e519524SHoward Hinnant    static const bool value = _S1 < _S2;
4673e519524SHoward Hinnant};
4683e519524SHoward Hinnant
4693e519524SHoward Hinnanttemplate <class _R1, class _R2>
4703e519524SHoward Hinnantstruct __ratio_less<_R1, _R2, 1LL, 1LL>
4713e519524SHoward Hinnant{
4723e519524SHoward Hinnant    static const bool value = __ratio_less1<_R1, _R2>::value;
4733e519524SHoward Hinnant};
4743e519524SHoward Hinnant
4753e519524SHoward Hinnanttemplate <class _R1, class _R2>
4763e519524SHoward Hinnantstruct __ratio_less<_R1, _R2, -1LL, -1LL>
4773e519524SHoward Hinnant{
4783e519524SHoward Hinnant    static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value;
4793e519524SHoward Hinnant};
4803e519524SHoward Hinnant
4813e519524SHoward Hinnanttemplate <class _R1, class _R2>
482e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_less
483f900f702SLouis Dionne    : _BoolConstant<__ratio_less<_R1, _R2>::value> {};
4843e519524SHoward Hinnant
4853e519524SHoward Hinnanttemplate <class _R1, class _R2>
486e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_less_equal
487f900f702SLouis Dionne    : _BoolConstant<!ratio_less<_R2, _R1>::value> {};
4883e519524SHoward Hinnant
4893e519524SHoward Hinnanttemplate <class _R1, class _R2>
490e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_greater
491f900f702SLouis Dionne    : _BoolConstant<ratio_less<_R2, _R1>::value> {};
4923e519524SHoward Hinnant
4933e519524SHoward Hinnanttemplate <class _R1, class _R2>
494e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS ratio_greater_equal
495f900f702SLouis Dionne    : _BoolConstant<!ratio_less<_R1, _R2>::value> {};
4963e519524SHoward Hinnant
4973e519524SHoward Hinnanttemplate <class _R1, class _R2>
4983e519524SHoward Hinnantstruct __ratio_gcd
4993e519524SHoward Hinnant{
5003e519524SHoward Hinnant    typedef ratio<__static_gcd<_R1::num, _R2::num>::value,
5013e519524SHoward Hinnant                  __static_lcm<_R1::den, _R2::den>::value> type;
5023e519524SHoward Hinnant};
5033e519524SHoward Hinnant
5041711a6ecSLouis Dionne#if _LIBCPP_STD_VER > 14
50540a01d53SMarshall Clowtemplate <class _R1, class _R2>
506cb793e1aSLouis Dionneinline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value;
507825a9edbSMarshall Clow
50840a01d53SMarshall Clowtemplate <class _R1, class _R2>
509cb793e1aSLouis Dionneinline constexpr bool ratio_not_equal_v = ratio_not_equal<_R1, _R2>::value;
510825a9edbSMarshall Clow
51140a01d53SMarshall Clowtemplate <class _R1, class _R2>
512cb793e1aSLouis Dionneinline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value;
513825a9edbSMarshall Clow
51440a01d53SMarshall Clowtemplate <class _R1, class _R2>
515cb793e1aSLouis Dionneinline constexpr bool ratio_less_equal_v = ratio_less_equal<_R1, _R2>::value;
516825a9edbSMarshall Clow
51740a01d53SMarshall Clowtemplate <class _R1, class _R2>
518cb793e1aSLouis Dionneinline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value;
519825a9edbSMarshall Clow
52040a01d53SMarshall Clowtemplate <class _R1, class _R2>
521cb793e1aSLouis Dionneinline constexpr bool ratio_greater_equal_v = ratio_greater_equal<_R1, _R2>::value;
522825a9edbSMarshall Clow#endif
523825a9edbSMarshall Clow
5243e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
5253e519524SHoward Hinnant
526a016efb1SEric Fiselier_LIBCPP_POP_MACROS
527a016efb1SEric Fiselier
5283e519524SHoward Hinnant#endif // _LIBCPP_RATIO
529