1227825Stheraven// -*- C++ -*- 2227825Stheraven//===---------------------------- ratio -----------------------------------===// 3227825Stheraven// 4227825Stheraven// The LLVM Compiler Infrastructure 5227825Stheraven// 6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 7227825Stheraven// Source Licenses. See LICENSE.TXT for details. 8227825Stheraven// 9227825Stheraven//===----------------------------------------------------------------------===// 10227825Stheraven 11227825Stheraven#ifndef _LIBCPP_RATIO 12227825Stheraven#define _LIBCPP_RATIO 13227825Stheraven 14227825Stheraven/* 15227825Stheraven ratio synopsis 16227825Stheraven 17227825Stheravennamespace std 18227825Stheraven{ 19227825Stheraven 20227825Stheraventemplate <intmax_t N, intmax_t D = 1> 21227825Stheravenclass ratio 22227825Stheraven{ 23227825Stheravenpublic: 24288943Sdim static constexpr intmax_t num; 25288943Sdim static constexpr intmax_t den; 26227825Stheraven typedef ratio<num, den> type; 27227825Stheraven}; 28227825Stheraven 29227825Stheraven// ratio arithmetic 30227825Stheraventemplate <class R1, class R2> using ratio_add = ...; 31227825Stheraventemplate <class R1, class R2> using ratio_subtract = ...; 32227825Stheraventemplate <class R1, class R2> using ratio_multiply = ...; 33227825Stheraventemplate <class R1, class R2> using ratio_divide = ...; 34227825Stheraven 35227825Stheraven// ratio comparison 36227825Stheraventemplate <class R1, class R2> struct ratio_equal; 37227825Stheraventemplate <class R1, class R2> struct ratio_not_equal; 38227825Stheraventemplate <class R1, class R2> struct ratio_less; 39227825Stheraventemplate <class R1, class R2> struct ratio_less_equal; 40227825Stheraventemplate <class R1, class R2> struct ratio_greater; 41227825Stheraventemplate <class R1, class R2> struct ratio_greater_equal; 42227825Stheraven 43227825Stheraven// convenience SI typedefs 44227825Stheraventypedef ratio<1, 1000000000000000000000000> yocto; // not supported 45227825Stheraventypedef ratio<1, 1000000000000000000000> zepto; // not supported 46227825Stheraventypedef ratio<1, 1000000000000000000> atto; 47227825Stheraventypedef ratio<1, 1000000000000000> femto; 48227825Stheraventypedef ratio<1, 1000000000000> pico; 49227825Stheraventypedef ratio<1, 1000000000> nano; 50227825Stheraventypedef ratio<1, 1000000> micro; 51227825Stheraventypedef ratio<1, 1000> milli; 52227825Stheraventypedef ratio<1, 100> centi; 53227825Stheraventypedef ratio<1, 10> deci; 54227825Stheraventypedef ratio< 10, 1> deca; 55227825Stheraventypedef ratio< 100, 1> hecto; 56227825Stheraventypedef ratio< 1000, 1> kilo; 57227825Stheraventypedef ratio< 1000000, 1> mega; 58227825Stheraventypedef ratio< 1000000000, 1> giga; 59227825Stheraventypedef ratio< 1000000000000, 1> tera; 60227825Stheraventypedef ratio< 1000000000000000, 1> peta; 61227825Stheraventypedef ratio< 1000000000000000000, 1> exa; 62227825Stheraventypedef ratio< 1000000000000000000000, 1> zetta; // not supported 63227825Stheraventypedef ratio<1000000000000000000000000, 1> yotta; // not supported 64227825Stheraven 65300770Sdim // 20.11.5, ratio comparison 66300770Sdim template <class R1, class R2> constexpr bool ratio_equal_v 67300770Sdim = ratio_equal<R1, R2>::value; // C++17 68300770Sdim template <class R1, class R2> constexpr bool ratio_not_equal_v 69300770Sdim = ratio_not_equal<R1, R2>::value; // C++17 70300770Sdim template <class R1, class R2> constexpr bool ratio_less_v 71300770Sdim = ratio_less<R1, R2>::value; // C++17 72300770Sdim template <class R1, class R2> constexpr bool ratio_less_equal_v 73300770Sdim = ratio_less_equal<R1, R2>::value; // C++17 74300770Sdim template <class R1, class R2> constexpr bool ratio_greater_v 75300770Sdim = ratio_greater<R1, R2>::value; // C++17 76300770Sdim template <class R1, class R2> constexpr bool ratio_greater_equal_v 77300770Sdim = ratio_greater_equal<R1, R2>::value; // C++17 78227825Stheraven} 79227825Stheraven*/ 80227825Stheraven 81227825Stheraven#include <__config> 82227825Stheraven#include <cstdint> 83227825Stheraven#include <climits> 84227825Stheraven#include <type_traits> 85227825Stheraven 86232924Stheraven#include <__undef_min_max> 87232924Stheraven 88227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 89227825Stheraven#pragma GCC system_header 90227825Stheraven#endif 91227825Stheraven 92227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 93227825Stheraven 94227825Stheraven// __static_gcd 95227825Stheraven 96227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 97227825Stheravenstruct __static_gcd 98227825Stheraven{ 99227825Stheraven static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value; 100227825Stheraven}; 101227825Stheraven 102227825Stheraventemplate <intmax_t _Xp> 103227825Stheravenstruct __static_gcd<_Xp, 0> 104227825Stheraven{ 105227825Stheraven static const intmax_t value = _Xp; 106227825Stheraven}; 107227825Stheraven 108227825Stheraventemplate <> 109227825Stheravenstruct __static_gcd<0, 0> 110227825Stheraven{ 111227825Stheraven static const intmax_t value = 1; 112227825Stheraven}; 113227825Stheraven 114227825Stheraven// __static_lcm 115227825Stheraven 116227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 117227825Stheravenstruct __static_lcm 118227825Stheraven{ 119227825Stheraven static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp; 120227825Stheraven}; 121227825Stheraven 122227825Stheraventemplate <intmax_t _Xp> 123227825Stheravenstruct __static_abs 124227825Stheraven{ 125227825Stheraven static const intmax_t value = _Xp < 0 ? -_Xp : _Xp; 126227825Stheraven}; 127227825Stheraven 128227825Stheraventemplate <intmax_t _Xp> 129227825Stheravenstruct __static_sign 130227825Stheraven{ 131227825Stheraven static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1); 132227825Stheraven}; 133227825Stheraven 134227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value> 135227825Stheravenclass __ll_add; 136227825Stheraven 137227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 138227825Stheravenclass __ll_add<_Xp, _Yp, 1> 139227825Stheraven{ 140227825Stheraven static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 141227825Stheraven static const intmax_t max = -min; 142227825Stheraven 143227825Stheraven static_assert(_Xp <= max - _Yp, "overflow in __ll_add"); 144227825Stheravenpublic: 145227825Stheraven static const intmax_t value = _Xp + _Yp; 146227825Stheraven}; 147227825Stheraven 148227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 149227825Stheravenclass __ll_add<_Xp, _Yp, 0> 150227825Stheraven{ 151227825Stheravenpublic: 152227825Stheraven static const intmax_t value = _Xp; 153227825Stheraven}; 154227825Stheraven 155227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 156227825Stheravenclass __ll_add<_Xp, _Yp, -1> 157227825Stheraven{ 158227825Stheraven static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 159227825Stheraven static const intmax_t max = -min; 160227825Stheraven 161227825Stheraven static_assert(min - _Yp <= _Xp, "overflow in __ll_add"); 162227825Stheravenpublic: 163227825Stheraven static const intmax_t value = _Xp + _Yp; 164227825Stheraven}; 165227825Stheraven 166227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value> 167227825Stheravenclass __ll_sub; 168227825Stheraven 169227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 170227825Stheravenclass __ll_sub<_Xp, _Yp, 1> 171227825Stheraven{ 172227825Stheraven static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 173227825Stheraven static const intmax_t max = -min; 174227825Stheraven 175227825Stheraven static_assert(min + _Yp <= _Xp, "overflow in __ll_sub"); 176227825Stheravenpublic: 177227825Stheraven static const intmax_t value = _Xp - _Yp; 178227825Stheraven}; 179227825Stheraven 180227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 181227825Stheravenclass __ll_sub<_Xp, _Yp, 0> 182227825Stheraven{ 183227825Stheravenpublic: 184227825Stheraven static const intmax_t value = _Xp; 185227825Stheraven}; 186227825Stheraven 187227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 188227825Stheravenclass __ll_sub<_Xp, _Yp, -1> 189227825Stheraven{ 190227825Stheraven static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1; 191227825Stheraven static const intmax_t max = -min; 192227825Stheraven 193227825Stheraven static_assert(_Xp <= max + _Yp, "overflow in __ll_sub"); 194227825Stheravenpublic: 195227825Stheraven static const intmax_t value = _Xp - _Yp; 196227825Stheraven}; 197227825Stheraven 198227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 199227825Stheravenclass __ll_mul 200227825Stheraven{ 201227825Stheraven static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)); 202227825Stheraven static const intmax_t min = nan + 1; 203227825Stheraven static const intmax_t max = -min; 204227825Stheraven static const intmax_t __a_x = __static_abs<_Xp>::value; 205227825Stheraven static const intmax_t __a_y = __static_abs<_Yp>::value; 206227825Stheraven 207227825Stheraven static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul"); 208227825Stheravenpublic: 209227825Stheraven static const intmax_t value = _Xp * _Yp; 210227825Stheraven}; 211227825Stheraven 212227825Stheraventemplate <intmax_t _Yp> 213227825Stheravenclass __ll_mul<0, _Yp> 214227825Stheraven{ 215227825Stheravenpublic: 216227825Stheraven static const intmax_t value = 0; 217227825Stheraven}; 218227825Stheraven 219227825Stheraventemplate <intmax_t _Xp> 220227825Stheravenclass __ll_mul<_Xp, 0> 221227825Stheraven{ 222227825Stheravenpublic: 223227825Stheraven static const intmax_t value = 0; 224227825Stheraven}; 225227825Stheraven 226227825Stheraventemplate <> 227227825Stheravenclass __ll_mul<0, 0> 228227825Stheraven{ 229227825Stheravenpublic: 230227825Stheraven static const intmax_t value = 0; 231227825Stheraven}; 232227825Stheraven 233227825Stheraven// Not actually used but left here in case needed in future maintenance 234227825Stheraventemplate <intmax_t _Xp, intmax_t _Yp> 235227825Stheravenclass __ll_div 236227825Stheraven{ 237227825Stheraven static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)); 238227825Stheraven static const intmax_t min = nan + 1; 239227825Stheraven static const intmax_t max = -min; 240227825Stheraven 241227825Stheraven static_assert(_Xp != nan && _Yp != nan && _Yp != 0, "overflow in __ll_div"); 242227825Stheravenpublic: 243227825Stheraven static const intmax_t value = _Xp / _Yp; 244227825Stheraven}; 245227825Stheraven 246227825Stheraventemplate <intmax_t _Num, intmax_t _Den = 1> 247261272Sdimclass _LIBCPP_TYPE_VIS_ONLY ratio 248227825Stheraven{ 249227825Stheraven static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range"); 250227825Stheraven static_assert(_Den != 0, "ratio divide by 0"); 251227825Stheraven static_assert(__static_abs<_Den>::value > 0, "ratio denominator is out of range"); 252288943Sdim static _LIBCPP_CONSTEXPR const intmax_t __na = __static_abs<_Num>::value; 253288943Sdim static _LIBCPP_CONSTEXPR const intmax_t __da = __static_abs<_Den>::value; 254288943Sdim static _LIBCPP_CONSTEXPR const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value; 255288943Sdim static _LIBCPP_CONSTEXPR const intmax_t __gcd = __static_gcd<__na, __da>::value; 256227825Stheravenpublic: 257288943Sdim static _LIBCPP_CONSTEXPR const intmax_t num = __s * __na / __gcd; 258288943Sdim static _LIBCPP_CONSTEXPR const intmax_t den = __da / __gcd; 259227825Stheraven 260227825Stheraven typedef ratio<num, den> type; 261227825Stheraven}; 262227825Stheraven 263288943Sdimtemplate <intmax_t _Num, intmax_t _Den> 264288943Sdim_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::num; 265227825Stheraven 266288943Sdimtemplate <intmax_t _Num, intmax_t _Den> 267288943Sdim_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::den; 268288943Sdim 269227825Stheraventemplate <class _Tp> struct __is_ratio : false_type {}; 270227825Stheraventemplate <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type {}; 271227825Stheraven 272227825Stheraventypedef ratio<1LL, 1000000000000000000LL> atto; 273227825Stheraventypedef ratio<1LL, 1000000000000000LL> femto; 274227825Stheraventypedef ratio<1LL, 1000000000000LL> pico; 275227825Stheraventypedef ratio<1LL, 1000000000LL> nano; 276227825Stheraventypedef ratio<1LL, 1000000LL> micro; 277227825Stheraventypedef ratio<1LL, 1000LL> milli; 278227825Stheraventypedef ratio<1LL, 100LL> centi; 279227825Stheraventypedef ratio<1LL, 10LL> deci; 280227825Stheraventypedef ratio< 10LL, 1LL> deca; 281227825Stheraventypedef ratio< 100LL, 1LL> hecto; 282227825Stheraventypedef ratio< 1000LL, 1LL> kilo; 283227825Stheraventypedef ratio< 1000000LL, 1LL> mega; 284227825Stheraventypedef ratio< 1000000000LL, 1LL> giga; 285227825Stheraventypedef ratio< 1000000000000LL, 1LL> tera; 286227825Stheraventypedef ratio< 1000000000000000LL, 1LL> peta; 287227825Stheraventypedef ratio<1000000000000000000LL, 1LL> exa; 288227825Stheraven 289227825Stheraventemplate <class _R1, class _R2> 290227825Stheravenstruct __ratio_multiply 291227825Stheraven{ 292227825Stheravenprivate: 293227825Stheraven static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value; 294227825Stheraven static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value; 295227825Stheravenpublic: 296227825Stheraven typedef typename ratio 297227825Stheraven < 298227825Stheraven __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value, 299227825Stheraven __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value 300227825Stheraven >::type type; 301227825Stheraven}; 302227825Stheraven 303227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES 304227825Stheraven 305227825Stheraventemplate <class _R1, class _R2> using ratio_multiply 306227825Stheraven = typename __ratio_multiply<_R1, _R2>::type; 307227825Stheraven 308227825Stheraven#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 309227825Stheraven 310227825Stheraventemplate <class _R1, class _R2> 311261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_multiply 312227825Stheraven : public __ratio_multiply<_R1, _R2>::type {}; 313227825Stheraven 314227825Stheraven#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 315227825Stheraven 316227825Stheraventemplate <class _R1, class _R2> 317227825Stheravenstruct __ratio_divide 318227825Stheraven{ 319227825Stheravenprivate: 320227825Stheraven static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 321227825Stheraven static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 322227825Stheravenpublic: 323227825Stheraven typedef typename ratio 324227825Stheraven < 325227825Stheraven __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value, 326227825Stheraven __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value 327227825Stheraven >::type type; 328227825Stheraven}; 329227825Stheraven 330227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES 331227825Stheraven 332227825Stheraventemplate <class _R1, class _R2> using ratio_divide 333227825Stheraven = typename __ratio_divide<_R1, _R2>::type; 334227825Stheraven 335227825Stheraven#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 336227825Stheraven 337227825Stheraventemplate <class _R1, class _R2> 338261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_divide 339227825Stheraven : public __ratio_divide<_R1, _R2>::type {}; 340227825Stheraven 341227825Stheraven#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 342227825Stheraven 343227825Stheraventemplate <class _R1, class _R2> 344227825Stheravenstruct __ratio_add 345227825Stheraven{ 346227825Stheravenprivate: 347227825Stheraven static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 348227825Stheraven static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 349227825Stheravenpublic: 350227825Stheraven typedef typename ratio_multiply 351227825Stheraven < 352227825Stheraven ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>, 353227825Stheraven ratio 354227825Stheraven < 355227825Stheraven __ll_add 356227825Stheraven < 357227825Stheraven __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value, 358227825Stheraven __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value 359227825Stheraven >::value, 360227825Stheraven _R2::den 361227825Stheraven > 362227825Stheraven >::type type; 363227825Stheraven}; 364227825Stheraven 365227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES 366227825Stheraven 367227825Stheraventemplate <class _R1, class _R2> using ratio_add 368227825Stheraven = typename __ratio_add<_R1, _R2>::type; 369227825Stheraven 370227825Stheraven#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 371227825Stheraven 372227825Stheraventemplate <class _R1, class _R2> 373261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_add 374227825Stheraven : public __ratio_add<_R1, _R2>::type {}; 375227825Stheraven 376227825Stheraven#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 377227825Stheraven 378227825Stheraventemplate <class _R1, class _R2> 379227825Stheravenstruct __ratio_subtract 380227825Stheraven{ 381227825Stheravenprivate: 382227825Stheraven static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 383227825Stheraven static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 384227825Stheravenpublic: 385227825Stheraven typedef typename ratio_multiply 386227825Stheraven < 387227825Stheraven ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>, 388227825Stheraven ratio 389227825Stheraven < 390227825Stheraven __ll_sub 391227825Stheraven < 392227825Stheraven __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value, 393227825Stheraven __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value 394227825Stheraven >::value, 395227825Stheraven _R2::den 396227825Stheraven > 397227825Stheraven >::type type; 398227825Stheraven}; 399227825Stheraven 400227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES 401227825Stheraven 402227825Stheraventemplate <class _R1, class _R2> using ratio_subtract 403227825Stheraven = typename __ratio_subtract<_R1, _R2>::type; 404227825Stheraven 405227825Stheraven#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 406227825Stheraven 407227825Stheraventemplate <class _R1, class _R2> 408261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_subtract 409227825Stheraven : public __ratio_subtract<_R1, _R2>::type {}; 410227825Stheraven 411227825Stheraven#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES 412227825Stheraven 413227825Stheraven// ratio_equal 414227825Stheraven 415227825Stheraventemplate <class _R1, class _R2> 416261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_equal 417288943Sdim : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {}; 418227825Stheraven 419227825Stheraventemplate <class _R1, class _R2> 420261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_not_equal 421288943Sdim : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {}; 422227825Stheraven 423227825Stheraven// ratio_less 424227825Stheraven 425227825Stheraventemplate <class _R1, class _R2, bool _Odd = false, 426227825Stheraven intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den, 427227825Stheraven intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den> 428227825Stheravenstruct __ratio_less1 429227825Stheraven{ 430227825Stheraven static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2; 431227825Stheraven}; 432227825Stheraven 433232924Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp> 434232924Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, 0> 435227825Stheraven{ 436227825Stheraven static const bool value = false; 437227825Stheraven}; 438227825Stheraven 439232924Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M2> 440232924Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, _M2> 441227825Stheraven{ 442227825Stheraven static const bool value = !_Odd; 443227825Stheraven}; 444227825Stheraven 445232924Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1> 446232924Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, 0> 447227825Stheraven{ 448227825Stheraven static const bool value = _Odd; 449227825Stheraven}; 450227825Stheraven 451232924Stheraventemplate <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1, 452227825Stheraven intmax_t _M2> 453232924Stheravenstruct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, _M2> 454227825Stheraven{ 455227825Stheraven static const bool value = __ratio_less1<ratio<_R1::den, _M1>, 456227825Stheraven ratio<_R2::den, _M2>, !_Odd>::value; 457227825Stheraven}; 458227825Stheraven 459227825Stheraventemplate <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value, 460227825Stheraven intmax_t _S2 = __static_sign<_R2::num>::value> 461227825Stheravenstruct __ratio_less 462227825Stheraven{ 463227825Stheraven static const bool value = _S1 < _S2; 464227825Stheraven}; 465227825Stheraven 466227825Stheraventemplate <class _R1, class _R2> 467227825Stheravenstruct __ratio_less<_R1, _R2, 1LL, 1LL> 468227825Stheraven{ 469227825Stheraven static const bool value = __ratio_less1<_R1, _R2>::value; 470227825Stheraven}; 471227825Stheraven 472227825Stheraventemplate <class _R1, class _R2> 473227825Stheravenstruct __ratio_less<_R1, _R2, -1LL, -1LL> 474227825Stheraven{ 475227825Stheraven static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value; 476227825Stheraven}; 477227825Stheraven 478227825Stheraventemplate <class _R1, class _R2> 479261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_less 480288943Sdim : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {}; 481227825Stheraven 482227825Stheraventemplate <class _R1, class _R2> 483261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_less_equal 484288943Sdim : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {}; 485227825Stheraven 486227825Stheraventemplate <class _R1, class _R2> 487261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_greater 488288943Sdim : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {}; 489227825Stheraven 490227825Stheraventemplate <class _R1, class _R2> 491261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY ratio_greater_equal 492288943Sdim : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {}; 493227825Stheraven 494227825Stheraventemplate <class _R1, class _R2> 495227825Stheravenstruct __ratio_gcd 496227825Stheraven{ 497227825Stheraven typedef ratio<__static_gcd<_R1::num, _R2::num>::value, 498227825Stheraven __static_lcm<_R1::den, _R2::den>::value> type; 499227825Stheraven}; 500227825Stheraven 501300770Sdim#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) 502300770Sdimtemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_equal_v 503300770Sdim = ratio_equal<_R1, _R2>::value; 504300770Sdim 505300770Sdimtemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_not_equal_v 506300770Sdim = ratio_not_equal<_R1, _R2>::value; 507300770Sdim 508300770Sdimtemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_v 509300770Sdim = ratio_less<_R1, _R2>::value; 510300770Sdim 511300770Sdimtemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_equal_v 512300770Sdim = ratio_less_equal<_R1, _R2>::value; 513300770Sdim 514300770Sdimtemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_v 515300770Sdim = ratio_greater<_R1, _R2>::value; 516300770Sdim 517300770Sdimtemplate <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_equal_v 518300770Sdim = ratio_greater_equal<_R1, _R2>::value; 519300770Sdim#endif 520300770Sdim 521227825Stheraven_LIBCPP_END_NAMESPACE_STD 522227825Stheraven 523227825Stheraven#endif // _LIBCPP_RATIO 524