xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/ratio (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
14fee23f9Smrg// ratio -*- C++ -*-
24fee23f9Smrg
3b1e83836Smrg// Copyright (C) 2008-2022 Free Software Foundation, Inc.
44fee23f9Smrg//
54fee23f9Smrg// This file is part of the GNU ISO C++ Library.  This library is free
64fee23f9Smrg// software; you can redistribute it and/or modify it under the
74fee23f9Smrg// terms of the GNU General Public License as published by the
84fee23f9Smrg// Free Software Foundation; either version 3, or (at your option)
94fee23f9Smrg// any later version.
104fee23f9Smrg
114fee23f9Smrg// This library is distributed in the hope that it will be useful,
124fee23f9Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144fee23f9Smrg// GNU General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg// Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg// permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg// 3.1, as published by the Free Software Foundation.
194fee23f9Smrg
204fee23f9Smrg// You should have received a copy of the GNU General Public License and
214fee23f9Smrg// a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
234fee23f9Smrg// <http://www.gnu.org/licenses/>.
244fee23f9Smrg
2548fb7bfaSmrg/** @file include/ratio
264fee23f9Smrg *  This is a Standard C++ Library header.
27fb8a8121Smrg *  @ingroup ratio
284fee23f9Smrg */
294fee23f9Smrg
304fee23f9Smrg#ifndef _GLIBCXX_RATIO
314fee23f9Smrg#define _GLIBCXX_RATIO 1
324fee23f9Smrg
334fee23f9Smrg#pragma GCC system_header
344fee23f9Smrg
3548fb7bfaSmrg#if __cplusplus < 201103L
364fee23f9Smrg# include <bits/c++0x_warning.h>
374fee23f9Smrg#else
384fee23f9Smrg
394fee23f9Smrg#include <type_traits>
40181254a7Smrg#include <cstdint>		// intmax_t, uintmax_t
414fee23f9Smrg
4248fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default)
434fee23f9Smrg{
4448fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
4548fb7bfaSmrg
464fee23f9Smrg  /**
474fee23f9Smrg   * @defgroup ratio Rational Arithmetic
484fee23f9Smrg   * @ingroup utilities
494fee23f9Smrg   *
504fee23f9Smrg   * Compile time representation of finite rational numbers.
514fee23f9Smrg   * @{
524fee23f9Smrg   */
534fee23f9Smrg
54fb8a8121Smrg  /// @cond undocumented
55fb8a8121Smrg
564fee23f9Smrg  template<intmax_t _Pn>
574fee23f9Smrg    struct __static_sign
584fee23f9Smrg    : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1>
594fee23f9Smrg    { };
604fee23f9Smrg
614fee23f9Smrg  template<intmax_t _Pn>
624fee23f9Smrg    struct __static_abs
634fee23f9Smrg    : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value>
644fee23f9Smrg    { };
654fee23f9Smrg
664fee23f9Smrg  template<intmax_t _Pn, intmax_t _Qn>
674fee23f9Smrg    struct __static_gcd
684fee23f9Smrg    : __static_gcd<_Qn, (_Pn % _Qn)>
694fee23f9Smrg    { };
704fee23f9Smrg
714fee23f9Smrg  template<intmax_t _Pn>
724fee23f9Smrg    struct __static_gcd<_Pn, 0>
734fee23f9Smrg    : integral_constant<intmax_t, __static_abs<_Pn>::value>
744fee23f9Smrg    { };
754fee23f9Smrg
764fee23f9Smrg  template<intmax_t _Qn>
774fee23f9Smrg    struct __static_gcd<0, _Qn>
784fee23f9Smrg    : integral_constant<intmax_t, __static_abs<_Qn>::value>
794fee23f9Smrg    { };
804fee23f9Smrg
814fee23f9Smrg  // Let c = 2^(half # of bits in an intmax_t)
824fee23f9Smrg  // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
834fee23f9Smrg  // The multiplication of N and M becomes,
844fee23f9Smrg  // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
854fee23f9Smrg  // Multiplication is safe if each term and the sum of the terms
864fee23f9Smrg  // is representable by intmax_t.
874fee23f9Smrg  template<intmax_t _Pn, intmax_t _Qn>
884fee23f9Smrg    struct __safe_multiply
894fee23f9Smrg    {
904fee23f9Smrg    private:
914fee23f9Smrg      static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
924fee23f9Smrg
934fee23f9Smrg      static const uintmax_t __a0 = __static_abs<_Pn>::value % __c;
944fee23f9Smrg      static const uintmax_t __a1 = __static_abs<_Pn>::value / __c;
954fee23f9Smrg      static const uintmax_t __b0 = __static_abs<_Qn>::value % __c;
964fee23f9Smrg      static const uintmax_t __b1 = __static_abs<_Qn>::value / __c;
974fee23f9Smrg
984fee23f9Smrg      static_assert(__a1 == 0 || __b1 == 0,
994fee23f9Smrg		    "overflow in multiplication");
1004fee23f9Smrg      static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1),
1014fee23f9Smrg		    "overflow in multiplication");
1024fee23f9Smrg      static_assert(__b0 * __a0 <= __INTMAX_MAX__,
1034fee23f9Smrg		    "overflow in multiplication");
10448fb7bfaSmrg      static_assert((__a0 * __b1 + __b0 * __a1) * __c
10548fb7bfaSmrg		    <= __INTMAX_MAX__ -  __b0 * __a0,
10648fb7bfaSmrg		    "overflow in multiplication");
1074fee23f9Smrg
1084fee23f9Smrg    public:
1094fee23f9Smrg      static const intmax_t value = _Pn * _Qn;
1104fee23f9Smrg    };
1114fee23f9Smrg
11248fb7bfaSmrg  // Some double-precision utilities, where numbers are represented as
11348fb7bfaSmrg  // __hi*2^(8*sizeof(uintmax_t)) + __lo.
11448fb7bfaSmrg  template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2>
11548fb7bfaSmrg    struct __big_less
11648fb7bfaSmrg    : integral_constant<bool, (__hi1 < __hi2
11748fb7bfaSmrg			       || (__hi1 == __hi2 && __lo1 < __lo2))>
1184fee23f9Smrg    { };
1194fee23f9Smrg
12048fb7bfaSmrg  template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2>
12148fb7bfaSmrg    struct __big_add
1224fee23f9Smrg    {
12348fb7bfaSmrg      static constexpr uintmax_t __lo = __lo1 + __lo2;
12448fb7bfaSmrg      static constexpr uintmax_t __hi = (__hi1 + __hi2 +
12548fb7bfaSmrg					 (__lo1 + __lo2 < __lo1)); // carry
12648fb7bfaSmrg    };
1274fee23f9Smrg
12848fb7bfaSmrg  // Subtract a number from a bigger one.
12948fb7bfaSmrg  template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2>
13048fb7bfaSmrg    struct __big_sub
13148fb7bfaSmrg    {
13248fb7bfaSmrg      static_assert(!__big_less<__hi1, __lo1, __hi2, __lo2>::value,
13348fb7bfaSmrg		    "Internal library error");
13448fb7bfaSmrg      static constexpr uintmax_t __lo = __lo1 - __lo2;
13548fb7bfaSmrg      static constexpr uintmax_t __hi = (__hi1 - __hi2 -
13648fb7bfaSmrg					 (__lo1 < __lo2)); // carry
13748fb7bfaSmrg    };
13848fb7bfaSmrg
13948fb7bfaSmrg  // Same principle as __safe_multiply.
14048fb7bfaSmrg  template<uintmax_t __x, uintmax_t __y>
14148fb7bfaSmrg    struct __big_mul
14248fb7bfaSmrg    {
14348fb7bfaSmrg    private:
14448fb7bfaSmrg      static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
14548fb7bfaSmrg      static constexpr uintmax_t __x0 = __x % __c;
14648fb7bfaSmrg      static constexpr uintmax_t __x1 = __x / __c;
14748fb7bfaSmrg      static constexpr uintmax_t __y0 = __y % __c;
14848fb7bfaSmrg      static constexpr uintmax_t __y1 = __y / __c;
14948fb7bfaSmrg      static constexpr uintmax_t __x0y0 = __x0 * __y0;
15048fb7bfaSmrg      static constexpr uintmax_t __x0y1 = __x0 * __y1;
15148fb7bfaSmrg      static constexpr uintmax_t __x1y0 = __x1 * __y0;
15248fb7bfaSmrg      static constexpr uintmax_t __x1y1 = __x1 * __y1;
15348fb7bfaSmrg      static constexpr uintmax_t __mix = __x0y1 + __x1y0; // possible carry...
15448fb7bfaSmrg      static constexpr uintmax_t __mix_lo = __mix * __c;
15548fb7bfaSmrg      static constexpr uintmax_t __mix_hi
15648fb7bfaSmrg      = __mix / __c + ((__mix < __x0y1) ? __c : 0); // ... added here
15748fb7bfaSmrg      typedef __big_add<__mix_hi, __mix_lo, __x1y1, __x0y0> _Res;
15848fb7bfaSmrg    public:
15948fb7bfaSmrg      static constexpr uintmax_t __hi = _Res::__hi;
16048fb7bfaSmrg      static constexpr uintmax_t __lo = _Res::__lo;
16148fb7bfaSmrg    };
16248fb7bfaSmrg
16348fb7bfaSmrg  // Adapted from __udiv_qrnnd_c in longlong.h
16448fb7bfaSmrg  // This version assumes that the high bit of __d is 1.
16548fb7bfaSmrg  template<uintmax_t __n1, uintmax_t __n0, uintmax_t __d>
16648fb7bfaSmrg    struct __big_div_impl
16748fb7bfaSmrg    {
16848fb7bfaSmrg    private:
16948fb7bfaSmrg      static_assert(__d >= (uintmax_t(1) << (sizeof(intmax_t) * 8 - 1)),
17048fb7bfaSmrg		    "Internal library error");
17148fb7bfaSmrg      static_assert(__n1 < __d, "Internal library error");
17248fb7bfaSmrg      static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
17348fb7bfaSmrg      static constexpr uintmax_t __d1 = __d / __c;
17448fb7bfaSmrg      static constexpr uintmax_t __d0 = __d % __c;
17548fb7bfaSmrg
17648fb7bfaSmrg      static constexpr uintmax_t __q1x = __n1 / __d1;
17748fb7bfaSmrg      static constexpr uintmax_t __r1x = __n1 % __d1;
17848fb7bfaSmrg      static constexpr uintmax_t __m = __q1x * __d0;
17948fb7bfaSmrg      static constexpr uintmax_t __r1y = __r1x * __c + __n0 / __c;
18048fb7bfaSmrg      static constexpr uintmax_t __r1z = __r1y + __d;
18148fb7bfaSmrg      static constexpr uintmax_t __r1
18248fb7bfaSmrg      = ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m))
18348fb7bfaSmrg	 ? (__r1z + __d) : __r1z : __r1y) - __m;
18448fb7bfaSmrg      static constexpr uintmax_t __q1
18548fb7bfaSmrg      = __q1x - ((__r1y < __m)
18648fb7bfaSmrg		 ? ((__r1z >= __d) && (__r1z < __m)) ? 2 : 1 : 0);
18748fb7bfaSmrg      static constexpr uintmax_t __q0x = __r1 / __d1;
18848fb7bfaSmrg      static constexpr uintmax_t __r0x = __r1 % __d1;
18948fb7bfaSmrg      static constexpr uintmax_t __n = __q0x * __d0;
19048fb7bfaSmrg      static constexpr uintmax_t __r0y = __r0x * __c + __n0 % __c;
19148fb7bfaSmrg      static constexpr uintmax_t __r0z = __r0y + __d;
19248fb7bfaSmrg      static constexpr uintmax_t __r0
19348fb7bfaSmrg      = ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n))
19448fb7bfaSmrg	 ? (__r0z + __d) : __r0z : __r0y) - __n;
19548fb7bfaSmrg      static constexpr uintmax_t __q0
19648fb7bfaSmrg      = __q0x - ((__r0y < __n) ? ((__r0z >= __d)
19748fb7bfaSmrg				  && (__r0z < __n)) ? 2 : 1 : 0);
19848fb7bfaSmrg
19948fb7bfaSmrg    public:
20048fb7bfaSmrg      static constexpr uintmax_t __quot = __q1 * __c + __q0;
20148fb7bfaSmrg      static constexpr uintmax_t __rem = __r0;
20248fb7bfaSmrg
20348fb7bfaSmrg    private:
20448fb7bfaSmrg      typedef __big_mul<__quot, __d> _Prod;
20548fb7bfaSmrg      typedef __big_add<_Prod::__hi, _Prod::__lo, 0, __rem> _Sum;
20648fb7bfaSmrg      static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0,
20748fb7bfaSmrg		    "Internal library error");
20848fb7bfaSmrg  };
20948fb7bfaSmrg
21048fb7bfaSmrg  template<uintmax_t __n1, uintmax_t __n0, uintmax_t __d>
21148fb7bfaSmrg    struct __big_div
21248fb7bfaSmrg    {
21348fb7bfaSmrg    private:
21448fb7bfaSmrg      static_assert(__d != 0, "Internal library error");
21548fb7bfaSmrg      static_assert(sizeof (uintmax_t) == sizeof (unsigned long long),
21648fb7bfaSmrg		    "This library calls __builtin_clzll on uintmax_t, which "
21748fb7bfaSmrg		    "is unsafe on your platform. Please complain to "
21848fb7bfaSmrg		    "http://gcc.gnu.org/bugzilla/");
21948fb7bfaSmrg      static constexpr int __shift = __builtin_clzll(__d);
22048fb7bfaSmrg      static constexpr int __coshift_ = sizeof(uintmax_t) * 8 - __shift;
22148fb7bfaSmrg      static constexpr int __coshift = (__shift != 0) ? __coshift_ : 0;
22248fb7bfaSmrg      static constexpr uintmax_t __c1 = uintmax_t(1) << __shift;
22348fb7bfaSmrg      static constexpr uintmax_t __c2 = uintmax_t(1) << __coshift;
22448fb7bfaSmrg      static constexpr uintmax_t __new_d = __d * __c1;
22548fb7bfaSmrg      static constexpr uintmax_t __new_n0 = __n0 * __c1;
22648fb7bfaSmrg      static constexpr uintmax_t __n1_shifted = (__n1 % __d) * __c1;
22748fb7bfaSmrg      static constexpr uintmax_t __n0_top = (__shift != 0) ? (__n0 / __c2) : 0;
22848fb7bfaSmrg      static constexpr uintmax_t __new_n1 = __n1_shifted + __n0_top;
22948fb7bfaSmrg      typedef __big_div_impl<__new_n1, __new_n0, __new_d> _Res;
23048fb7bfaSmrg
23148fb7bfaSmrg    public:
23248fb7bfaSmrg      static constexpr uintmax_t __quot_hi = __n1 / __d;
23348fb7bfaSmrg      static constexpr uintmax_t __quot_lo = _Res::__quot;
23448fb7bfaSmrg      static constexpr uintmax_t __rem = _Res::__rem / __c1;
23548fb7bfaSmrg
23648fb7bfaSmrg    private:
23748fb7bfaSmrg      typedef __big_mul<__quot_lo, __d> _P0;
23848fb7bfaSmrg      typedef __big_mul<__quot_hi, __d> _P1;
23948fb7bfaSmrg      typedef __big_add<_P0::__hi, _P0::__lo, _P1::__lo, __rem> _Sum;
24048fb7bfaSmrg      // No overflow.
24148fb7bfaSmrg      static_assert(_P1::__hi == 0, "Internal library error");
24248fb7bfaSmrg      static_assert(_Sum::__hi >= _P0::__hi, "Internal library error");
24348fb7bfaSmrg      // Matches the input data.
24448fb7bfaSmrg      static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0,
24548fb7bfaSmrg		    "Internal library error");
24648fb7bfaSmrg      static_assert(__rem < __d, "Internal library error");
2474fee23f9Smrg    };
2484fee23f9Smrg
249fb8a8121Smrg  /// @endcond
250fb8a8121Smrg
2514fee23f9Smrg  /**
2524fee23f9Smrg   *  @brief Provides compile-time rational arithmetic.
2534fee23f9Smrg   *
2544fee23f9Smrg   *  This class template represents any finite rational number with a
2554fee23f9Smrg   *  numerator and denominator representable by compile-time constants of
2564fee23f9Smrg   *  type intmax_t. The ratio is simplified when instantiated.
2574fee23f9Smrg   *
2584fee23f9Smrg   *  For example:
2594fee23f9Smrg   *  @code
2604fee23f9Smrg   *    std::ratio<7,-21>::num == -1;
2614fee23f9Smrg   *    std::ratio<7,-21>::den == 3;
2624fee23f9Smrg   *  @endcode
2634fee23f9Smrg   *
2644fee23f9Smrg  */
2654fee23f9Smrg  template<intmax_t _Num, intmax_t _Den = 1>
2664fee23f9Smrg    struct ratio
2674fee23f9Smrg    {
2684fee23f9Smrg      static_assert(_Den != 0, "denominator cannot be zero");
2694fee23f9Smrg      static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__,
2704fee23f9Smrg		    "out of range");
2714fee23f9Smrg
2724fee23f9Smrg      // Note: sign(N) * abs(N) == N
27348fb7bfaSmrg      static constexpr intmax_t num =
2744fee23f9Smrg        _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value;
2754fee23f9Smrg
27648fb7bfaSmrg      static constexpr intmax_t den =
2774fee23f9Smrg        __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value;
27848fb7bfaSmrg
27948fb7bfaSmrg      typedef ratio<num, den> type;
2804fee23f9Smrg    };
2814fee23f9Smrg
282b1e83836Smrg#if ! __cpp_inline_variables
2834fee23f9Smrg  template<intmax_t _Num, intmax_t _Den>
28448fb7bfaSmrg    constexpr intmax_t ratio<_Num, _Den>::num;
2854fee23f9Smrg
2864fee23f9Smrg  template<intmax_t _Num, intmax_t _Den>
28748fb7bfaSmrg    constexpr intmax_t ratio<_Num, _Den>::den;
288b1e83836Smrg#endif
2894fee23f9Smrg
290fb8a8121Smrg  /// @cond undocumented
291fb8a8121Smrg
292*0a307195Smrg  template<typename _Tp>
293*0a307195Smrg    struct __is_ratio
294*0a307195Smrg    : std::false_type
295*0a307195Smrg    { };
296*0a307195Smrg
297*0a307195Smrg  template<intmax_t _Num, intmax_t _Den>
298*0a307195Smrg    struct __is_ratio<ratio<_Num, _Den>>
299*0a307195Smrg    : std::true_type
300*0a307195Smrg    { };
301*0a307195Smrg
302*0a307195Smrg#if __cpp_variable_templates
303*0a307195Smrg  template<typename _Tp>
304*0a307195Smrg    constexpr bool __is_ratio_v = false;
305*0a307195Smrg  template<intmax_t _Num, intmax_t _Den>
306*0a307195Smrg    constexpr bool __is_ratio_v<ratio<_Num, _Den>> = true;
307*0a307195Smrg#endif
308*0a307195Smrg
309*0a307195Smrg  template<typename _R1, typename _R2>
310*0a307195Smrg    constexpr bool
311*0a307195Smrg    __are_both_ratios() noexcept
312*0a307195Smrg    {
313*0a307195Smrg#if __cpp_variable_templates && __cpp_if_constexpr
314*0a307195Smrg      if constexpr (__is_ratio_v<_R1>)
315*0a307195Smrg	if constexpr (__is_ratio_v<_R2>)
316*0a307195Smrg	  return true;
317*0a307195Smrg      return false;
318*0a307195Smrg#else
319*0a307195Smrg      return __and_<__is_ratio<_R1>, __is_ratio<_R2>>::value;
320*0a307195Smrg#endif
321*0a307195Smrg    }
322*0a307195Smrg
3234fee23f9Smrg  template<typename _R1, typename _R2>
32448fb7bfaSmrg    struct __ratio_multiply
3254fee23f9Smrg    {
326*0a307195Smrg      static_assert(std::__are_both_ratios<_R1, _R2>(),
327*0a307195Smrg		    "both template arguments must be a std::ratio");
328*0a307195Smrg
3294fee23f9Smrg    private:
3304fee23f9Smrg      static const intmax_t __gcd1 =
3314fee23f9Smrg        __static_gcd<_R1::num, _R2::den>::value;
3324fee23f9Smrg      static const intmax_t __gcd2 =
3334fee23f9Smrg        __static_gcd<_R2::num, _R1::den>::value;
3344fee23f9Smrg
3354fee23f9Smrg    public:
3364fee23f9Smrg      typedef ratio<
3374fee23f9Smrg        __safe_multiply<(_R1::num / __gcd1),
3384fee23f9Smrg                        (_R2::num / __gcd2)>::value,
3394fee23f9Smrg        __safe_multiply<(_R1::den / __gcd2),
3404fee23f9Smrg                        (_R2::den / __gcd1)>::value> type;
34148fb7bfaSmrg
34248fb7bfaSmrg      static constexpr intmax_t num = type::num;
34348fb7bfaSmrg      static constexpr intmax_t den = type::den;
3444fee23f9Smrg    };
3454fee23f9Smrg
346b1e83836Smrg#if ! __cpp_inline_variables
3474fee23f9Smrg  template<typename _R1, typename _R2>
34848fb7bfaSmrg    constexpr intmax_t __ratio_multiply<_R1, _R2>::num;
34948fb7bfaSmrg
35048fb7bfaSmrg  template<typename _R1, typename _R2>
35148fb7bfaSmrg    constexpr intmax_t __ratio_multiply<_R1, _R2>::den;
352b1e83836Smrg#endif
35348fb7bfaSmrg
354fb8a8121Smrg  /// @endcond
355fb8a8121Smrg
35648fb7bfaSmrg  /// ratio_multiply
35748fb7bfaSmrg  template<typename _R1, typename _R2>
35848fb7bfaSmrg    using ratio_multiply = typename __ratio_multiply<_R1, _R2>::type;
35948fb7bfaSmrg
360fb8a8121Smrg  /// @cond undocumented
361fb8a8121Smrg
36248fb7bfaSmrg  template<typename _R1, typename _R2>
36348fb7bfaSmrg    struct __ratio_divide
3644fee23f9Smrg    {
3654fee23f9Smrg      static_assert(_R2::num != 0, "division by 0");
3664fee23f9Smrg
36748fb7bfaSmrg      typedef typename __ratio_multiply<
3684fee23f9Smrg        _R1,
3694fee23f9Smrg        ratio<_R2::den, _R2::num>>::type type;
37048fb7bfaSmrg
37148fb7bfaSmrg      static constexpr intmax_t num = type::num;
37248fb7bfaSmrg      static constexpr intmax_t den = type::den;
3734fee23f9Smrg    };
3744fee23f9Smrg
375b1e83836Smrg#if ! __cpp_inline_variables
37648fb7bfaSmrg  template<typename _R1, typename _R2>
37748fb7bfaSmrg    constexpr intmax_t __ratio_divide<_R1, _R2>::num;
37848fb7bfaSmrg
37948fb7bfaSmrg  template<typename _R1, typename _R2>
38048fb7bfaSmrg    constexpr intmax_t __ratio_divide<_R1, _R2>::den;
381b1e83836Smrg#endif
38248fb7bfaSmrg
383fb8a8121Smrg  /// @endcond
384fb8a8121Smrg
38548fb7bfaSmrg  /// ratio_divide
38648fb7bfaSmrg  template<typename _R1, typename _R2>
38748fb7bfaSmrg    using ratio_divide = typename __ratio_divide<_R1, _R2>::type;
38848fb7bfaSmrg
3894fee23f9Smrg  /// ratio_equal
3904fee23f9Smrg  template<typename _R1, typename _R2>
3914fee23f9Smrg    struct ratio_equal
3924fee23f9Smrg    : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den>
393*0a307195Smrg    {
394*0a307195Smrg      static_assert(std::__are_both_ratios<_R1, _R2>(),
395*0a307195Smrg		    "both template arguments must be a std::ratio");
396*0a307195Smrg    };
3974fee23f9Smrg
3984fee23f9Smrg  /// ratio_not_equal
3994fee23f9Smrg  template<typename _R1, typename _R2>
4004fee23f9Smrg    struct ratio_not_equal
4014fee23f9Smrg    : integral_constant<bool, !ratio_equal<_R1, _R2>::value>
4024fee23f9Smrg    { };
4034fee23f9Smrg
404fb8a8121Smrg  /// @cond undocumented
405fb8a8121Smrg
40648fb7bfaSmrg  // Both numbers are positive.
40748fb7bfaSmrg  template<typename _R1, typename _R2,
40848fb7bfaSmrg           typename _Left = __big_mul<_R1::num,_R2::den>,
40948fb7bfaSmrg           typename _Right = __big_mul<_R2::num,_R1::den> >
41048fb7bfaSmrg    struct __ratio_less_impl_1
41148fb7bfaSmrg    : integral_constant<bool, __big_less<_Left::__hi, _Left::__lo,
41248fb7bfaSmrg           _Right::__hi, _Right::__lo>::value>
4134fee23f9Smrg    { };
4144fee23f9Smrg
41548fb7bfaSmrg  template<typename _R1, typename _R2,
41648fb7bfaSmrg	   bool = (_R1::num == 0 || _R2::num == 0
4174fee23f9Smrg		   || (__static_sign<_R1::num>::value
4184fee23f9Smrg		       != __static_sign<_R2::num>::value)),
41948fb7bfaSmrg	   bool = (__static_sign<_R1::num>::value == -1
42048fb7bfaSmrg		   && __static_sign<_R2::num>::value == -1)>
42148fb7bfaSmrg    struct __ratio_less_impl
42248fb7bfaSmrg    : __ratio_less_impl_1<_R1, _R2>::type
42348fb7bfaSmrg    { };
42448fb7bfaSmrg
42548fb7bfaSmrg  template<typename _R1, typename _R2>
42648fb7bfaSmrg    struct __ratio_less_impl<_R1, _R2, true, false>
42748fb7bfaSmrg    : integral_constant<bool, _R1::num < _R2::num>
42848fb7bfaSmrg    { };
42948fb7bfaSmrg
43048fb7bfaSmrg  template<typename _R1, typename _R2>
43148fb7bfaSmrg    struct __ratio_less_impl<_R1, _R2, false, true>
43248fb7bfaSmrg    : __ratio_less_impl_1<ratio<-_R2::num, _R2::den>,
43348fb7bfaSmrg           ratio<-_R1::num, _R1::den> >::type
4344fee23f9Smrg    { };
4354fee23f9Smrg
436fb8a8121Smrg  /// @endcond
437fb8a8121Smrg
4384fee23f9Smrg  /// ratio_less
4394fee23f9Smrg  template<typename _R1, typename _R2>
4404fee23f9Smrg    struct ratio_less
4414fee23f9Smrg    : __ratio_less_impl<_R1, _R2>::type
442*0a307195Smrg    {
443*0a307195Smrg      static_assert(std::__are_both_ratios<_R1, _R2>(),
444*0a307195Smrg		    "both template arguments must be a std::ratio");
445*0a307195Smrg    };
4464fee23f9Smrg
4474fee23f9Smrg  /// ratio_less_equal
4484fee23f9Smrg  template<typename _R1, typename _R2>
4494fee23f9Smrg    struct ratio_less_equal
4504fee23f9Smrg    : integral_constant<bool, !ratio_less<_R2, _R1>::value>
4514fee23f9Smrg    { };
4524fee23f9Smrg
4534fee23f9Smrg  /// ratio_greater
4544fee23f9Smrg  template<typename _R1, typename _R2>
4554fee23f9Smrg    struct ratio_greater
4564fee23f9Smrg    : integral_constant<bool, ratio_less<_R2, _R1>::value>
4574fee23f9Smrg    { };
4584fee23f9Smrg
4594fee23f9Smrg  /// ratio_greater_equal
4604fee23f9Smrg  template<typename _R1, typename _R2>
4614fee23f9Smrg    struct ratio_greater_equal
4624fee23f9Smrg    : integral_constant<bool, !ratio_less<_R1, _R2>::value>
4634fee23f9Smrg    { };
4644fee23f9Smrg
465b17d1066Smrg#if __cplusplus > 201402L
466b17d1066Smrg  template <typename _R1, typename _R2>
467b17d1066Smrg    inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value;
468b17d1066Smrg  template <typename _R1, typename _R2>
469b17d1066Smrg    inline constexpr bool ratio_not_equal_v = ratio_not_equal<_R1, _R2>::value;
470b17d1066Smrg  template <typename _R1, typename _R2>
471b17d1066Smrg    inline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value;
472b17d1066Smrg  template <typename _R1, typename _R2>
473*0a307195Smrg    inline constexpr bool ratio_less_equal_v
474*0a307195Smrg      = ratio_less_equal<_R1, _R2>::value;
475b17d1066Smrg  template <typename _R1, typename _R2>
476b17d1066Smrg    inline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value;
477b17d1066Smrg  template <typename _R1, typename _R2>
478b17d1066Smrg    inline constexpr bool ratio_greater_equal_v
479b17d1066Smrg      = ratio_greater_equal<_R1, _R2>::value;
480b17d1066Smrg#endif // C++17
481b17d1066Smrg
482fb8a8121Smrg  /// @cond undocumented
483fb8a8121Smrg
48448fb7bfaSmrg  template<typename _R1, typename _R2,
48548fb7bfaSmrg      bool = (_R1::num >= 0),
48648fb7bfaSmrg      bool = (_R2::num >= 0),
48748fb7bfaSmrg      bool = ratio_less<ratio<__static_abs<_R1::num>::value, _R1::den>,
48848fb7bfaSmrg        ratio<__static_abs<_R2::num>::value, _R2::den> >::value>
48948fb7bfaSmrg    struct __ratio_add_impl
49048fb7bfaSmrg    {
49148fb7bfaSmrg    private:
49248fb7bfaSmrg      typedef typename __ratio_add_impl<
49348fb7bfaSmrg        ratio<-_R1::num, _R1::den>,
49448fb7bfaSmrg        ratio<-_R2::num, _R2::den> >::type __t;
49548fb7bfaSmrg    public:
49648fb7bfaSmrg      typedef ratio<-__t::num, __t::den> type;
49748fb7bfaSmrg    };
49848fb7bfaSmrg
49948fb7bfaSmrg  // True addition of nonnegative numbers.
50048fb7bfaSmrg  template<typename _R1, typename _R2, bool __b>
50148fb7bfaSmrg    struct __ratio_add_impl<_R1, _R2, true, true, __b>
50248fb7bfaSmrg    {
50348fb7bfaSmrg    private:
50448fb7bfaSmrg      static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value;
50548fb7bfaSmrg      static constexpr uintmax_t __d2 = _R2::den / __g;
50648fb7bfaSmrg      typedef __big_mul<_R1::den, __d2> __d;
50748fb7bfaSmrg      typedef __big_mul<_R1::num, _R2::den / __g> __x;
50848fb7bfaSmrg      typedef __big_mul<_R2::num, _R1::den / __g> __y;
50948fb7bfaSmrg      typedef __big_add<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n;
51048fb7bfaSmrg      static_assert(__n::__hi >= __x::__hi, "Internal library error");
51148fb7bfaSmrg      typedef __big_div<__n::__hi, __n::__lo, __g> __ng;
51248fb7bfaSmrg      static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value;
51348fb7bfaSmrg      typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final;
51448fb7bfaSmrg      static_assert(__n_final::__rem == 0, "Internal library error");
51548fb7bfaSmrg      static_assert(__n_final::__quot_hi == 0 &&
51648fb7bfaSmrg        __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition");
51748fb7bfaSmrg      typedef __big_mul<_R1::den / __g2, __d2> __d_final;
51848fb7bfaSmrg      static_assert(__d_final::__hi == 0 &&
51948fb7bfaSmrg        __d_final::__lo <= __INTMAX_MAX__, "overflow in addition");
52048fb7bfaSmrg    public:
52148fb7bfaSmrg      typedef ratio<__n_final::__quot_lo, __d_final::__lo> type;
52248fb7bfaSmrg    };
52348fb7bfaSmrg
52448fb7bfaSmrg  template<typename _R1, typename _R2>
52548fb7bfaSmrg    struct __ratio_add_impl<_R1, _R2, false, true, true>
52648fb7bfaSmrg    : __ratio_add_impl<_R2, _R1>
52748fb7bfaSmrg    { };
52848fb7bfaSmrg
52948fb7bfaSmrg  // True subtraction of nonnegative numbers yielding a nonnegative result.
53048fb7bfaSmrg  template<typename _R1, typename _R2>
53148fb7bfaSmrg    struct __ratio_add_impl<_R1, _R2, true, false, false>
53248fb7bfaSmrg    {
53348fb7bfaSmrg    private:
53448fb7bfaSmrg      static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value;
53548fb7bfaSmrg      static constexpr uintmax_t __d2 = _R2::den / __g;
53648fb7bfaSmrg      typedef __big_mul<_R1::den, __d2> __d;
53748fb7bfaSmrg      typedef __big_mul<_R1::num, _R2::den / __g> __x;
53848fb7bfaSmrg      typedef __big_mul<-_R2::num, _R1::den / __g> __y;
53948fb7bfaSmrg      typedef __big_sub<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n;
54048fb7bfaSmrg      typedef __big_div<__n::__hi, __n::__lo, __g> __ng;
54148fb7bfaSmrg      static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value;
54248fb7bfaSmrg      typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final;
54348fb7bfaSmrg      static_assert(__n_final::__rem == 0, "Internal library error");
54448fb7bfaSmrg      static_assert(__n_final::__quot_hi == 0 &&
54548fb7bfaSmrg        __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition");
54648fb7bfaSmrg      typedef __big_mul<_R1::den / __g2, __d2> __d_final;
54748fb7bfaSmrg      static_assert(__d_final::__hi == 0 &&
54848fb7bfaSmrg        __d_final::__lo <= __INTMAX_MAX__, "overflow in addition");
54948fb7bfaSmrg    public:
55048fb7bfaSmrg      typedef ratio<__n_final::__quot_lo, __d_final::__lo> type;
55148fb7bfaSmrg    };
55248fb7bfaSmrg
55348fb7bfaSmrg  template<typename _R1, typename _R2>
55448fb7bfaSmrg    struct __ratio_add
55548fb7bfaSmrg    {
556*0a307195Smrg      static_assert(std::__are_both_ratios<_R1, _R2>(),
557*0a307195Smrg		    "both template arguments must be a std::ratio");
558*0a307195Smrg
55948fb7bfaSmrg      typedef typename __ratio_add_impl<_R1, _R2>::type type;
56048fb7bfaSmrg      static constexpr intmax_t num = type::num;
56148fb7bfaSmrg      static constexpr intmax_t den = type::den;
56248fb7bfaSmrg    };
56348fb7bfaSmrg
564b1e83836Smrg#if ! __cpp_inline_variables
56548fb7bfaSmrg  template<typename _R1, typename _R2>
56648fb7bfaSmrg    constexpr intmax_t __ratio_add<_R1, _R2>::num;
56748fb7bfaSmrg
56848fb7bfaSmrg  template<typename _R1, typename _R2>
56948fb7bfaSmrg    constexpr intmax_t __ratio_add<_R1, _R2>::den;
570b1e83836Smrg#endif
57148fb7bfaSmrg
572fb8a8121Smrg  /// @endcond
573fb8a8121Smrg
57448fb7bfaSmrg  /// ratio_add
57548fb7bfaSmrg  template<typename _R1, typename _R2>
57648fb7bfaSmrg    using ratio_add = typename __ratio_add<_R1, _R2>::type;
57748fb7bfaSmrg
578fb8a8121Smrg  /// @cond undocumented
579fb8a8121Smrg
58048fb7bfaSmrg  template<typename _R1, typename _R2>
58148fb7bfaSmrg    struct __ratio_subtract
58248fb7bfaSmrg    {
58348fb7bfaSmrg      typedef typename __ratio_add<
58448fb7bfaSmrg        _R1,
58548fb7bfaSmrg        ratio<-_R2::num, _R2::den>>::type type;
58648fb7bfaSmrg
58748fb7bfaSmrg      static constexpr intmax_t num = type::num;
58848fb7bfaSmrg      static constexpr intmax_t den = type::den;
58948fb7bfaSmrg    };
59048fb7bfaSmrg
591b1e83836Smrg#if ! __cpp_inline_variables
59248fb7bfaSmrg  template<typename _R1, typename _R2>
59348fb7bfaSmrg    constexpr intmax_t __ratio_subtract<_R1, _R2>::num;
59448fb7bfaSmrg
59548fb7bfaSmrg  template<typename _R1, typename _R2>
59648fb7bfaSmrg    constexpr intmax_t __ratio_subtract<_R1, _R2>::den;
597b1e83836Smrg#endif
59848fb7bfaSmrg
599fb8a8121Smrg  /// @endcond
600fb8a8121Smrg
60148fb7bfaSmrg  /// ratio_subtract
60248fb7bfaSmrg  template<typename _R1, typename _R2>
60348fb7bfaSmrg    using ratio_subtract = typename __ratio_subtract<_R1, _R2>::type;
60448fb7bfaSmrg
60548fb7bfaSmrg
6064fee23f9Smrg  typedef ratio<1,       1000000000000000000> atto;
6074fee23f9Smrg  typedef ratio<1,          1000000000000000> femto;
6084fee23f9Smrg  typedef ratio<1,             1000000000000> pico;
6094fee23f9Smrg  typedef ratio<1,                1000000000> nano;
6104fee23f9Smrg  typedef ratio<1,                   1000000> micro;
6114fee23f9Smrg  typedef ratio<1,                      1000> milli;
6124fee23f9Smrg  typedef ratio<1,                       100> centi;
6134fee23f9Smrg  typedef ratio<1,                        10> deci;
6144fee23f9Smrg  typedef ratio<                       10, 1> deca;
6154fee23f9Smrg  typedef ratio<                      100, 1> hecto;
6164fee23f9Smrg  typedef ratio<                     1000, 1> kilo;
6174fee23f9Smrg  typedef ratio<                  1000000, 1> mega;
6184fee23f9Smrg  typedef ratio<               1000000000, 1> giga;
6194fee23f9Smrg  typedef ratio<            1000000000000, 1> tera;
6204fee23f9Smrg  typedef ratio<         1000000000000000, 1> peta;
6214fee23f9Smrg  typedef ratio<      1000000000000000000, 1> exa;
6224fee23f9Smrg
623a448f87cSmrg  /// @} group ratio
62448fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION
62548fb7bfaSmrg} // namespace
6264fee23f9Smrg
62748fb7bfaSmrg#endif // C++11
6284fee23f9Smrg
6294fee23f9Smrg#endif //_GLIBCXX_RATIO
630