17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===---------------------------- ratio -----------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_RATIO 127a984708SDavid Chisnall#define _LIBCPP_RATIO 137a984708SDavid Chisnall 147a984708SDavid Chisnall/* 157a984708SDavid Chisnall ratio synopsis 167a984708SDavid Chisnall 177a984708SDavid Chisnallnamespace std 187a984708SDavid Chisnall{ 197a984708SDavid Chisnall 207a984708SDavid Chisnalltemplate <intmax_t N, intmax_t D = 1> 217a984708SDavid Chisnallclass ratio 227a984708SDavid Chisnall{ 237a984708SDavid Chisnallpublic: 24854fa44bSDimitry Andric static constexpr intmax_t num; 25854fa44bSDimitry Andric static constexpr intmax_t den; 267a984708SDavid Chisnall typedef ratio<num, den> type; 277a984708SDavid Chisnall}; 287a984708SDavid Chisnall 297a984708SDavid Chisnall// ratio arithmetic 307a984708SDavid Chisnalltemplate <class R1, class R2> using ratio_add = ...; 317a984708SDavid Chisnalltemplate <class R1, class R2> using ratio_subtract = ...; 327a984708SDavid Chisnalltemplate <class R1, class R2> using ratio_multiply = ...; 337a984708SDavid Chisnalltemplate <class R1, class R2> using ratio_divide = ...; 347a984708SDavid Chisnall 357a984708SDavid Chisnall// ratio comparison 367a984708SDavid Chisnalltemplate <class R1, class R2> struct ratio_equal; 377a984708SDavid Chisnalltemplate <class R1, class R2> struct ratio_not_equal; 387a984708SDavid Chisnalltemplate <class R1, class R2> struct ratio_less; 397a984708SDavid Chisnalltemplate <class R1, class R2> struct ratio_less_equal; 407a984708SDavid Chisnalltemplate <class R1, class R2> struct ratio_greater; 417a984708SDavid Chisnalltemplate <class R1, class R2> struct ratio_greater_equal; 427a984708SDavid Chisnall 437a984708SDavid Chisnall// convenience SI typedefs 447a984708SDavid Chisnalltypedef ratio<1, 1000000000000000000000000> yocto; // not supported 457a984708SDavid Chisnalltypedef ratio<1, 1000000000000000000000> zepto; // not supported 467a984708SDavid Chisnalltypedef ratio<1, 1000000000000000000> atto; 477a984708SDavid Chisnalltypedef ratio<1, 1000000000000000> femto; 487a984708SDavid Chisnalltypedef ratio<1, 1000000000000> pico; 497a984708SDavid Chisnalltypedef ratio<1, 1000000000> nano; 507a984708SDavid Chisnalltypedef ratio<1, 1000000> micro; 517a984708SDavid Chisnalltypedef ratio<1, 1000> milli; 527a984708SDavid Chisnalltypedef ratio<1, 100> centi; 537a984708SDavid Chisnalltypedef ratio<1, 10> deci; 547a984708SDavid Chisnalltypedef ratio< 10, 1> deca; 557a984708SDavid Chisnalltypedef ratio< 100, 1> hecto; 567a984708SDavid Chisnalltypedef ratio< 1000, 1> kilo; 577a984708SDavid Chisnalltypedef ratio< 1000000, 1> mega; 587a984708SDavid Chisnalltypedef ratio< 1000000000, 1> giga; 597a984708SDavid Chisnalltypedef ratio< 1000000000000, 1> tera; 607a984708SDavid Chisnalltypedef ratio< 1000000000000000, 1> peta; 617a984708SDavid Chisnalltypedef ratio< 1000000000000000000, 1> exa; 627a984708SDavid Chisnalltypedef ratio< 1000000000000000000000, 1> zetta; // not supported 637a984708SDavid Chisnalltypedef ratio<1000000000000000000000000, 1> yotta; // not supported 647a984708SDavid Chisnall 659729cf09SDimitry Andric // 20.11.5, ratio comparison 66*30785c0eSDimitry Andric template <class R1, class R2> inline constexpr bool ratio_equal_v 679729cf09SDimitry Andric = ratio_equal<R1, R2>::value; // C++17 68*30785c0eSDimitry Andric template <class R1, class R2> inline constexpr bool ratio_not_equal_v 699729cf09SDimitry Andric = ratio_not_equal<R1, R2>::value; // C++17 70*30785c0eSDimitry Andric template <class R1, class R2> inline constexpr bool ratio_less_v 719729cf09SDimitry Andric = ratio_less<R1, R2>::value; // C++17 72*30785c0eSDimitry Andric template <class R1, class R2> inline constexpr bool ratio_less_equal_v 739729cf09SDimitry Andric = ratio_less_equal<R1, R2>::value; // C++17 74*30785c0eSDimitry Andric template <class R1, class R2> inline constexpr bool ratio_greater_v 759729cf09SDimitry Andric = ratio_greater<R1, R2>::value; // C++17 76*30785c0eSDimitry Andric template <class R1, class R2> inline constexpr bool ratio_greater_equal_v 779729cf09SDimitry Andric = ratio_greater_equal<R1, R2>::value; // C++17 787a984708SDavid Chisnall} 797a984708SDavid Chisnall*/ 807a984708SDavid Chisnall 817a984708SDavid Chisnall#include <__config> 827a984708SDavid Chisnall#include <cstdint> 837a984708SDavid Chisnall#include <climits> 847a984708SDavid Chisnall#include <type_traits> 857a984708SDavid Chisnall 867a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 877a984708SDavid Chisnall#pragma GCC system_header 887a984708SDavid Chisnall#endif 897a984708SDavid Chisnall 90f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS 91f9448bf3SDimitry Andric#include <__undef_macros> 92f9448bf3SDimitry Andric 93f9448bf3SDimitry Andric 947a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 957a984708SDavid Chisnall 967a984708SDavid Chisnall// __static_gcd 977a984708SDavid Chisnall 987a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 997a984708SDavid Chisnallstruct __static_gcd 1007a984708SDavid Chisnall{ 1017a984708SDavid Chisnall static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value; 1027a984708SDavid Chisnall}; 1037a984708SDavid Chisnall 1047a984708SDavid Chisnalltemplate <intmax_t _Xp> 1057a984708SDavid Chisnallstruct __static_gcd<_Xp, 0> 1067a984708SDavid Chisnall{ 1077a984708SDavid Chisnall static const intmax_t value = _Xp; 1087a984708SDavid Chisnall}; 1097a984708SDavid Chisnall 1107a984708SDavid Chisnalltemplate <> 1117a984708SDavid Chisnallstruct __static_gcd<0, 0> 1127a984708SDavid Chisnall{ 1137a984708SDavid Chisnall static const intmax_t value = 1; 1147a984708SDavid Chisnall}; 1157a984708SDavid Chisnall 1167a984708SDavid Chisnall// __static_lcm 1177a984708SDavid Chisnall 1187a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1197a984708SDavid Chisnallstruct __static_lcm 1207a984708SDavid Chisnall{ 1217a984708SDavid Chisnall static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp; 1227a984708SDavid Chisnall}; 1237a984708SDavid Chisnall 1247a984708SDavid Chisnalltemplate <intmax_t _Xp> 1257a984708SDavid Chisnallstruct __static_abs 1267a984708SDavid Chisnall{ 1277a984708SDavid Chisnall static const intmax_t value = _Xp < 0 ? -_Xp : _Xp; 1287a984708SDavid Chisnall}; 1297a984708SDavid Chisnall 1307a984708SDavid Chisnalltemplate <intmax_t _Xp> 1317a984708SDavid Chisnallstruct __static_sign 1327a984708SDavid Chisnall{ 1337a984708SDavid Chisnall static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1); 1347a984708SDavid Chisnall}; 1357a984708SDavid Chisnall 1367a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value> 1377a984708SDavid Chisnallclass __ll_add; 1387a984708SDavid Chisnall 1397a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1407a984708SDavid Chisnallclass __ll_add<_Xp, _Yp, 1> 1417a984708SDavid Chisnall{ 1427a984708SDavid Chisnall static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1437a984708SDavid Chisnall static const intmax_t max = -min; 1447a984708SDavid Chisnall 1457a984708SDavid Chisnall static_assert(_Xp <= max - _Yp, "overflow in __ll_add"); 1467a984708SDavid Chisnallpublic: 1477a984708SDavid Chisnall static const intmax_t value = _Xp + _Yp; 1487a984708SDavid Chisnall}; 1497a984708SDavid Chisnall 1507a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1517a984708SDavid Chisnallclass __ll_add<_Xp, _Yp, 0> 1527a984708SDavid Chisnall{ 1537a984708SDavid Chisnallpublic: 1547a984708SDavid Chisnall static const intmax_t value = _Xp; 1557a984708SDavid Chisnall}; 1567a984708SDavid Chisnall 1577a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1587a984708SDavid Chisnallclass __ll_add<_Xp, _Yp, -1> 1597a984708SDavid Chisnall{ 1607a984708SDavid Chisnall static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1617a984708SDavid Chisnall static const intmax_t max = -min; 1627a984708SDavid Chisnall 1637a984708SDavid Chisnall static_assert(min - _Yp <= _Xp, "overflow in __ll_add"); 1647a984708SDavid Chisnallpublic: 1657a984708SDavid Chisnall static const intmax_t value = _Xp + _Yp; 1667a984708SDavid Chisnall}; 1677a984708SDavid Chisnall 1687a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value> 1697a984708SDavid Chisnallclass __ll_sub; 1707a984708SDavid Chisnall 1717a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1727a984708SDavid Chisnallclass __ll_sub<_Xp, _Yp, 1> 1737a984708SDavid Chisnall{ 1747a984708SDavid Chisnall static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1757a984708SDavid Chisnall static const intmax_t max = -min; 1767a984708SDavid Chisnall 1777a984708SDavid Chisnall static_assert(min + _Yp <= _Xp, "overflow in __ll_sub"); 1787a984708SDavid Chisnallpublic: 1797a984708SDavid Chisnall static const intmax_t value = _Xp - _Yp; 1807a984708SDavid Chisnall}; 1817a984708SDavid Chisnall 1827a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1837a984708SDavid Chisnallclass __ll_sub<_Xp, _Yp, 0> 1847a984708SDavid Chisnall{ 1857a984708SDavid Chisnallpublic: 1867a984708SDavid Chisnall static const intmax_t value = _Xp; 1877a984708SDavid Chisnall}; 1887a984708SDavid Chisnall 1897a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 1907a984708SDavid Chisnallclass __ll_sub<_Xp, _Yp, -1> 1917a984708SDavid Chisnall{ 1927a984708SDavid Chisnall static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 1937a984708SDavid Chisnall static const intmax_t max = -min; 1947a984708SDavid Chisnall 1957a984708SDavid Chisnall static_assert(_Xp <= max + _Yp, "overflow in __ll_sub"); 1967a984708SDavid Chisnallpublic: 1977a984708SDavid Chisnall static const intmax_t value = _Xp - _Yp; 1987a984708SDavid Chisnall}; 1997a984708SDavid Chisnall 2007a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 2017a984708SDavid Chisnallclass __ll_mul 2027a984708SDavid Chisnall{ 2037a984708SDavid Chisnall static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)); 2047a984708SDavid Chisnall static const intmax_t min = nan + 1; 2057a984708SDavid Chisnall static const intmax_t max = -min; 2067a984708SDavid Chisnall static const intmax_t __a_x = __static_abs<_Xp>::value; 2077a984708SDavid Chisnall static const intmax_t __a_y = __static_abs<_Yp>::value; 2087a984708SDavid Chisnall 2097a984708SDavid Chisnall static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul"); 2107a984708SDavid Chisnallpublic: 2117a984708SDavid Chisnall static const intmax_t value = _Xp * _Yp; 2127a984708SDavid Chisnall}; 2137a984708SDavid Chisnall 2147a984708SDavid Chisnalltemplate <intmax_t _Yp> 2157a984708SDavid Chisnallclass __ll_mul<0, _Yp> 2167a984708SDavid Chisnall{ 2177a984708SDavid Chisnallpublic: 2187a984708SDavid Chisnall static const intmax_t value = 0; 2197a984708SDavid Chisnall}; 2207a984708SDavid Chisnall 2217a984708SDavid Chisnalltemplate <intmax_t _Xp> 2227a984708SDavid Chisnallclass __ll_mul<_Xp, 0> 2237a984708SDavid Chisnall{ 2247a984708SDavid Chisnallpublic: 2257a984708SDavid Chisnall static const intmax_t value = 0; 2267a984708SDavid Chisnall}; 2277a984708SDavid Chisnall 2287a984708SDavid Chisnalltemplate <> 2297a984708SDavid Chisnallclass __ll_mul<0, 0> 2307a984708SDavid Chisnall{ 2317a984708SDavid Chisnallpublic: 2327a984708SDavid Chisnall static const intmax_t value = 0; 2337a984708SDavid Chisnall}; 2347a984708SDavid Chisnall 2357a984708SDavid Chisnall// Not actually used but left here in case needed in future maintenance 2367a984708SDavid Chisnalltemplate <intmax_t _Xp, intmax_t _Yp> 2377a984708SDavid Chisnallclass __ll_div 2387a984708SDavid Chisnall{ 2397a984708SDavid Chisnall static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)); 2407a984708SDavid Chisnall static const intmax_t min = nan + 1; 2417a984708SDavid Chisnall static const intmax_t max = -min; 2427a984708SDavid Chisnall 2437a984708SDavid Chisnall static_assert(_Xp != nan && _Yp != nan && _Yp != 0, "overflow in __ll_div"); 2447a984708SDavid Chisnallpublic: 2457a984708SDavid Chisnall static const intmax_t value = _Xp / _Yp; 2467a984708SDavid Chisnall}; 2477a984708SDavid Chisnall 2487a984708SDavid Chisnalltemplate <intmax_t _Num, intmax_t _Den = 1> 249aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS ratio 2507a984708SDavid Chisnall{ 2517a984708SDavid Chisnall static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range"); 2527a984708SDavid Chisnall static_assert(_Den != 0, "ratio divide by 0"); 2537a984708SDavid Chisnall static_assert(__static_abs<_Den>::value > 0, "ratio denominator is out of range"); 254854fa44bSDimitry Andric static _LIBCPP_CONSTEXPR const intmax_t __na = __static_abs<_Num>::value; 255854fa44bSDimitry Andric static _LIBCPP_CONSTEXPR const intmax_t __da = __static_abs<_Den>::value; 256854fa44bSDimitry Andric static _LIBCPP_CONSTEXPR const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value; 257854fa44bSDimitry Andric static _LIBCPP_CONSTEXPR const intmax_t __gcd = __static_gcd<__na, __da>::value; 2587a984708SDavid Chisnallpublic: 259854fa44bSDimitry Andric static _LIBCPP_CONSTEXPR const intmax_t num = __s * __na / __gcd; 260854fa44bSDimitry Andric static _LIBCPP_CONSTEXPR const intmax_t den = __da / __gcd; 2617a984708SDavid Chisnall 2627a984708SDavid Chisnall typedef ratio<num, den> type; 2637a984708SDavid Chisnall}; 2647a984708SDavid Chisnall 265854fa44bSDimitry Andrictemplate <intmax_t _Num, intmax_t _Den> 266854fa44bSDimitry Andric_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::num; 267854fa44bSDimitry Andric 268854fa44bSDimitry Andrictemplate <intmax_t _Num, intmax_t _Den> 269854fa44bSDimitry Andric_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::den; 2707a984708SDavid Chisnall 2717a984708SDavid Chisnalltemplate <class _Tp> struct __is_ratio : false_type {}; 2727a984708SDavid Chisnalltemplate <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type {}; 2737a984708SDavid Chisnall 2747a984708SDavid Chisnalltypedef ratio<1LL, 1000000000000000000LL> atto; 2757a984708SDavid Chisnalltypedef ratio<1LL, 1000000000000000LL> femto; 2767a984708SDavid Chisnalltypedef ratio<1LL, 1000000000000LL> pico; 2777a984708SDavid Chisnalltypedef ratio<1LL, 1000000000LL> nano; 2787a984708SDavid Chisnalltypedef ratio<1LL, 1000000LL> micro; 2797a984708SDavid Chisnalltypedef ratio<1LL, 1000LL> milli; 2807a984708SDavid Chisnalltypedef ratio<1LL, 100LL> centi; 2817a984708SDavid Chisnalltypedef ratio<1LL, 10LL> deci; 2827a984708SDavid Chisnalltypedef ratio< 10LL, 1LL> deca; 2837a984708SDavid Chisnalltypedef ratio< 100LL, 1LL> hecto; 2847a984708SDavid Chisnalltypedef ratio< 1000LL, 1LL> kilo; 2857a984708SDavid Chisnalltypedef ratio< 1000000LL, 1LL> mega; 2867a984708SDavid Chisnalltypedef ratio< 1000000000LL, 1LL> giga; 2877a984708SDavid Chisnalltypedef ratio< 1000000000000LL, 1LL> tera; 2887a984708SDavid Chisnalltypedef ratio< 1000000000000000LL, 1LL> peta; 2897a984708SDavid Chisnalltypedef ratio<1000000000000000000LL, 1LL> exa; 2907a984708SDavid Chisnall 2917a984708SDavid Chisnalltemplate <class _R1, class _R2> 2927a984708SDavid Chisnallstruct __ratio_multiply 2937a984708SDavid Chisnall{ 2947a984708SDavid Chisnallprivate: 2957a984708SDavid Chisnall static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value; 2967a984708SDavid Chisnall static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value; 2977a984708SDavid Chisnallpublic: 2987a984708SDavid Chisnall typedef typename ratio 2997a984708SDavid Chisnall < 3007a984708SDavid Chisnall __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value, 3017a984708SDavid Chisnall __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value 3027a984708SDavid Chisnall >::type type; 3037a984708SDavid Chisnall}; 3047a984708SDavid Chisnall 305aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3067a984708SDavid Chisnall 3077a984708SDavid Chisnalltemplate <class _R1, class _R2> using ratio_multiply 3087a984708SDavid Chisnall = typename __ratio_multiply<_R1, _R2>::type; 3097a984708SDavid Chisnall 310aed8d94eSDimitry Andric#else // _LIBCPP_CXX03_LANG 3117a984708SDavid Chisnall 3127a984708SDavid Chisnalltemplate <class _R1, class _R2> 313aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_multiply 3147a984708SDavid Chisnall : public __ratio_multiply<_R1, _R2>::type {}; 3157a984708SDavid Chisnall 316aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG 3177a984708SDavid Chisnall 3187a984708SDavid Chisnalltemplate <class _R1, class _R2> 3197a984708SDavid Chisnallstruct __ratio_divide 3207a984708SDavid Chisnall{ 3217a984708SDavid Chisnallprivate: 3227a984708SDavid Chisnall static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 3237a984708SDavid Chisnall static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 3247a984708SDavid Chisnallpublic: 3257a984708SDavid Chisnall typedef typename ratio 3267a984708SDavid Chisnall < 3277a984708SDavid Chisnall __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value, 3287a984708SDavid Chisnall __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value 3297a984708SDavid Chisnall >::type type; 3307a984708SDavid Chisnall}; 3317a984708SDavid Chisnall 332aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3337a984708SDavid Chisnall 3347a984708SDavid Chisnalltemplate <class _R1, class _R2> using ratio_divide 3357a984708SDavid Chisnall = typename __ratio_divide<_R1, _R2>::type; 3367a984708SDavid Chisnall 337aed8d94eSDimitry Andric#else // _LIBCPP_CXX03_LANG 3387a984708SDavid Chisnall 3397a984708SDavid Chisnalltemplate <class _R1, class _R2> 340aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_divide 3417a984708SDavid Chisnall : public __ratio_divide<_R1, _R2>::type {}; 3427a984708SDavid Chisnall 343aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG 3447a984708SDavid Chisnall 3457a984708SDavid Chisnalltemplate <class _R1, class _R2> 3467a984708SDavid Chisnallstruct __ratio_add 3477a984708SDavid Chisnall{ 3487a984708SDavid Chisnallprivate: 3497a984708SDavid Chisnall static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 3507a984708SDavid Chisnall static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 3517a984708SDavid Chisnallpublic: 3527a984708SDavid Chisnall typedef typename ratio_multiply 3537a984708SDavid Chisnall < 3547a984708SDavid Chisnall ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>, 3557a984708SDavid Chisnall ratio 3567a984708SDavid Chisnall < 3577a984708SDavid Chisnall __ll_add 3587a984708SDavid Chisnall < 3597a984708SDavid Chisnall __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value, 3607a984708SDavid Chisnall __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value 3617a984708SDavid Chisnall >::value, 3627a984708SDavid Chisnall _R2::den 3637a984708SDavid Chisnall > 3647a984708SDavid Chisnall >::type type; 3657a984708SDavid Chisnall}; 3667a984708SDavid Chisnall 367aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3687a984708SDavid Chisnall 3697a984708SDavid Chisnalltemplate <class _R1, class _R2> using ratio_add 3707a984708SDavid Chisnall = typename __ratio_add<_R1, _R2>::type; 3717a984708SDavid Chisnall 372aed8d94eSDimitry Andric#else // _LIBCPP_CXX03_LANG 3737a984708SDavid Chisnall 3747a984708SDavid Chisnalltemplate <class _R1, class _R2> 375aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_add 3767a984708SDavid Chisnall : public __ratio_add<_R1, _R2>::type {}; 3777a984708SDavid Chisnall 378aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG 3797a984708SDavid Chisnall 3807a984708SDavid Chisnalltemplate <class _R1, class _R2> 3817a984708SDavid Chisnallstruct __ratio_subtract 3827a984708SDavid Chisnall{ 3837a984708SDavid Chisnallprivate: 3847a984708SDavid Chisnall static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 3857a984708SDavid Chisnall static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 3867a984708SDavid Chisnallpublic: 3877a984708SDavid Chisnall typedef typename ratio_multiply 3887a984708SDavid Chisnall < 3897a984708SDavid Chisnall ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>, 3907a984708SDavid Chisnall ratio 3917a984708SDavid Chisnall < 3927a984708SDavid Chisnall __ll_sub 3937a984708SDavid Chisnall < 3947a984708SDavid Chisnall __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value, 3957a984708SDavid Chisnall __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value 3967a984708SDavid Chisnall >::value, 3977a984708SDavid Chisnall _R2::den 3987a984708SDavid Chisnall > 3997a984708SDavid Chisnall >::type type; 4007a984708SDavid Chisnall}; 4017a984708SDavid Chisnall 402aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 4037a984708SDavid Chisnall 4047a984708SDavid Chisnalltemplate <class _R1, class _R2> using ratio_subtract 4057a984708SDavid Chisnall = typename __ratio_subtract<_R1, _R2>::type; 4067a984708SDavid Chisnall 407aed8d94eSDimitry Andric#else // _LIBCPP_CXX03_LANG 4087a984708SDavid Chisnall 4097a984708SDavid Chisnalltemplate <class _R1, class _R2> 410aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_subtract 4117a984708SDavid Chisnall : public __ratio_subtract<_R1, _R2>::type {}; 4127a984708SDavid Chisnall 413aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG 4147a984708SDavid Chisnall 4157a984708SDavid Chisnall// ratio_equal 4167a984708SDavid Chisnall 4177a984708SDavid Chisnalltemplate <class _R1, class _R2> 418aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_equal 419854fa44bSDimitry Andric : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {}; 4207a984708SDavid Chisnall 4217a984708SDavid Chisnalltemplate <class _R1, class _R2> 422aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_not_equal 423854fa44bSDimitry Andric : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {}; 4247a984708SDavid Chisnall 4257a984708SDavid Chisnall// ratio_less 4267a984708SDavid Chisnall 4277a984708SDavid Chisnalltemplate <class _R1, class _R2, bool _Odd = false, 4287a984708SDavid Chisnall intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den, 4297a984708SDavid Chisnall intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den> 4307a984708SDavid Chisnallstruct __ratio_less1 4317a984708SDavid Chisnall{ 4327a984708SDavid Chisnall static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2; 4337a984708SDavid Chisnall}; 4347a984708SDavid Chisnall 43594e3ee44SDavid Chisnalltemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp> 43694e3ee44SDavid Chisnallstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, 0> 4377a984708SDavid Chisnall{ 4387a984708SDavid Chisnall static const bool value = false; 4397a984708SDavid Chisnall}; 4407a984708SDavid Chisnall 44194e3ee44SDavid Chisnalltemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M2> 44294e3ee44SDavid Chisnallstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, _M2> 4437a984708SDavid Chisnall{ 4447a984708SDavid Chisnall static const bool value = !_Odd; 4457a984708SDavid Chisnall}; 4467a984708SDavid Chisnall 44794e3ee44SDavid Chisnalltemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1> 44894e3ee44SDavid Chisnallstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, 0> 4497a984708SDavid Chisnall{ 4507a984708SDavid Chisnall static const bool value = _Odd; 4517a984708SDavid Chisnall}; 4527a984708SDavid Chisnall 45394e3ee44SDavid Chisnalltemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1, 4547a984708SDavid Chisnall intmax_t _M2> 45594e3ee44SDavid Chisnallstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, _M2> 4567a984708SDavid Chisnall{ 4577a984708SDavid Chisnall static const bool value = __ratio_less1<ratio<_R1::den, _M1>, 4587a984708SDavid Chisnall ratio<_R2::den, _M2>, !_Odd>::value; 4597a984708SDavid Chisnall}; 4607a984708SDavid Chisnall 4617a984708SDavid Chisnalltemplate <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value, 4627a984708SDavid Chisnall intmax_t _S2 = __static_sign<_R2::num>::value> 4637a984708SDavid Chisnallstruct __ratio_less 4647a984708SDavid Chisnall{ 4657a984708SDavid Chisnall static const bool value = _S1 < _S2; 4667a984708SDavid Chisnall}; 4677a984708SDavid Chisnall 4687a984708SDavid Chisnalltemplate <class _R1, class _R2> 4697a984708SDavid Chisnallstruct __ratio_less<_R1, _R2, 1LL, 1LL> 4707a984708SDavid Chisnall{ 4717a984708SDavid Chisnall static const bool value = __ratio_less1<_R1, _R2>::value; 4727a984708SDavid Chisnall}; 4737a984708SDavid Chisnall 4747a984708SDavid Chisnalltemplate <class _R1, class _R2> 4757a984708SDavid Chisnallstruct __ratio_less<_R1, _R2, -1LL, -1LL> 4767a984708SDavid Chisnall{ 4777a984708SDavid Chisnall static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value; 4787a984708SDavid Chisnall}; 4797a984708SDavid Chisnall 4807a984708SDavid Chisnalltemplate <class _R1, class _R2> 481aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_less 482854fa44bSDimitry Andric : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {}; 4837a984708SDavid Chisnall 4847a984708SDavid Chisnalltemplate <class _R1, class _R2> 485aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_less_equal 486854fa44bSDimitry Andric : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {}; 4877a984708SDavid Chisnall 4887a984708SDavid Chisnalltemplate <class _R1, class _R2> 489aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_greater 490854fa44bSDimitry Andric : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {}; 4917a984708SDavid Chisnall 4927a984708SDavid Chisnalltemplate <class _R1, class _R2> 493aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS ratio_greater_equal 494854fa44bSDimitry Andric : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {}; 4957a984708SDavid Chisnall 4967a984708SDavid Chisnalltemplate <class _R1, class _R2> 4977a984708SDavid Chisnallstruct __ratio_gcd 4987a984708SDavid Chisnall{ 4997a984708SDavid Chisnall typedef ratio<__static_gcd<_R1::num, _R2::num>::value, 5007a984708SDavid Chisnall __static_lcm<_R1::den, _R2::den>::value> type; 5017a984708SDavid Chisnall}; 5027a984708SDavid Chisnall 5039729cf09SDimitry Andric#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) 504*30785c0eSDimitry Andrictemplate <class _R1, class _R2> 505*30785c0eSDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_equal_v 5069729cf09SDimitry Andric = ratio_equal<_R1, _R2>::value; 5079729cf09SDimitry Andric 508*30785c0eSDimitry Andrictemplate <class _R1, class _R2> 509*30785c0eSDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_not_equal_v 5109729cf09SDimitry Andric = ratio_not_equal<_R1, _R2>::value; 5119729cf09SDimitry Andric 512*30785c0eSDimitry Andrictemplate <class _R1, class _R2> 513*30785c0eSDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_less_v 5149729cf09SDimitry Andric = ratio_less<_R1, _R2>::value; 5159729cf09SDimitry Andric 516*30785c0eSDimitry Andrictemplate <class _R1, class _R2> 517*30785c0eSDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_less_equal_v 5189729cf09SDimitry Andric = ratio_less_equal<_R1, _R2>::value; 5199729cf09SDimitry Andric 520*30785c0eSDimitry Andrictemplate <class _R1, class _R2> 521*30785c0eSDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_greater_v 5229729cf09SDimitry Andric = ratio_greater<_R1, _R2>::value; 5239729cf09SDimitry Andric 524*30785c0eSDimitry Andrictemplate <class _R1, class _R2> 525*30785c0eSDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool ratio_greater_equal_v 5269729cf09SDimitry Andric = ratio_greater_equal<_R1, _R2>::value; 5279729cf09SDimitry Andric#endif 5289729cf09SDimitry Andric 5297a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 5307a984708SDavid Chisnall 531f9448bf3SDimitry Andric_LIBCPP_POP_MACROS 532f9448bf3SDimitry Andric 5337a984708SDavid Chisnall#endif // _LIBCPP_RATIO 534