diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/concepts.h | 8 | ||||
| -rw-r--r-- | src/common/fixed_point.h | 120 |
2 files changed, 56 insertions, 72 deletions
diff --git a/src/common/concepts.h b/src/common/concepts.h index a97555f6a..e8ce30dfe 100644 --- a/src/common/concepts.h +++ b/src/common/concepts.h | |||
| @@ -34,4 +34,12 @@ concept DerivedFrom = requires { | |||
| 34 | template <typename From, typename To> | 34 | template <typename From, typename To> |
| 35 | concept ConvertibleTo = std::is_convertible_v<From, To>; | 35 | concept ConvertibleTo = std::is_convertible_v<From, To>; |
| 36 | 36 | ||
| 37 | // No equivalents in the stdlib | ||
| 38 | |||
| 39 | template <typename T> | ||
| 40 | concept IsArithmetic = std::is_arithmetic_v<T>; | ||
| 41 | |||
| 42 | template <typename T> | ||
| 43 | concept IsIntegral = std::is_integral_v<T>; | ||
| 44 | |||
| 37 | } // namespace Common | 45 | } // namespace Common |
diff --git a/src/common/fixed_point.h b/src/common/fixed_point.h index 6eb6afe2f..b2e489841 100644 --- a/src/common/fixed_point.h +++ b/src/common/fixed_point.h | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #include <ostream> | 12 | #include <ostream> |
| 13 | #include <type_traits> | 13 | #include <type_traits> |
| 14 | 14 | ||
| 15 | #include <common/concepts.h> | ||
| 16 | |||
| 15 | namespace Common { | 17 | namespace Common { |
| 16 | 18 | ||
| 17 | template <size_t I, size_t F> | 19 | template <size_t I, size_t F> |
| @@ -50,8 +52,8 @@ struct type_from_size<64> { | |||
| 50 | static constexpr size_t size = 64; | 52 | static constexpr size_t size = 64; |
| 51 | 53 | ||
| 52 | using value_type = int64_t; | 54 | using value_type = int64_t; |
| 53 | using unsigned_type = std::make_unsigned<value_type>::type; | 55 | using unsigned_type = std::make_unsigned_t<value_type>; |
| 54 | using signed_type = std::make_signed<value_type>::type; | 56 | using signed_type = std::make_signed_t<value_type>; |
| 55 | using next_size = type_from_size<128>; | 57 | using next_size = type_from_size<128>; |
| 56 | }; | 58 | }; |
| 57 | 59 | ||
| @@ -61,8 +63,8 @@ struct type_from_size<32> { | |||
| 61 | static constexpr size_t size = 32; | 63 | static constexpr size_t size = 32; |
| 62 | 64 | ||
| 63 | using value_type = int32_t; | 65 | using value_type = int32_t; |
| 64 | using unsigned_type = std::make_unsigned<value_type>::type; | 66 | using unsigned_type = std::make_unsigned_t<value_type>; |
| 65 | using signed_type = std::make_signed<value_type>::type; | 67 | using signed_type = std::make_signed_t<value_type>; |
| 66 | using next_size = type_from_size<64>; | 68 | using next_size = type_from_size<64>; |
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| @@ -72,8 +74,8 @@ struct type_from_size<16> { | |||
| 72 | static constexpr size_t size = 16; | 74 | static constexpr size_t size = 16; |
| 73 | 75 | ||
| 74 | using value_type = int16_t; | 76 | using value_type = int16_t; |
| 75 | using unsigned_type = std::make_unsigned<value_type>::type; | 77 | using unsigned_type = std::make_unsigned_t<value_type>; |
| 76 | using signed_type = std::make_signed<value_type>::type; | 78 | using signed_type = std::make_signed_t<value_type>; |
| 77 | using next_size = type_from_size<32>; | 79 | using next_size = type_from_size<32>; |
| 78 | }; | 80 | }; |
| 79 | 81 | ||
| @@ -83,8 +85,8 @@ struct type_from_size<8> { | |||
| 83 | static constexpr size_t size = 8; | 85 | static constexpr size_t size = 8; |
| 84 | 86 | ||
| 85 | using value_type = int8_t; | 87 | using value_type = int8_t; |
| 86 | using unsigned_type = std::make_unsigned<value_type>::type; | 88 | using unsigned_type = std::make_unsigned_t<value_type>; |
| 87 | using signed_type = std::make_signed<value_type>::type; | 89 | using signed_type = std::make_signed_t<value_type>; |
| 88 | using next_size = type_from_size<16>; | 90 | using next_size = type_from_size<16>; |
| 89 | }; | 91 | }; |
| 90 | 92 | ||
| @@ -101,7 +103,7 @@ struct divide_by_zero : std::exception {}; | |||
| 101 | template <size_t I, size_t F> | 103 | template <size_t I, size_t F> |
| 102 | constexpr FixedPoint<I, F> divide( | 104 | constexpr FixedPoint<I, F> divide( |
| 103 | FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, | 105 | FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, |
| 104 | typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { | 106 | std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) { |
| 105 | 107 | ||
| 106 | using next_type = typename FixedPoint<I, F>::next_type; | 108 | using next_type = typename FixedPoint<I, F>::next_type; |
| 107 | using base_type = typename FixedPoint<I, F>::base_type; | 109 | using base_type = typename FixedPoint<I, F>::base_type; |
| @@ -121,7 +123,7 @@ constexpr FixedPoint<I, F> divide( | |||
| 121 | template <size_t I, size_t F> | 123 | template <size_t I, size_t F> |
| 122 | constexpr FixedPoint<I, F> divide( | 124 | constexpr FixedPoint<I, F> divide( |
| 123 | FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, | 125 | FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, |
| 124 | typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { | 126 | std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) { |
| 125 | 127 | ||
| 126 | using unsigned_type = typename FixedPoint<I, F>::unsigned_type; | 128 | using unsigned_type = typename FixedPoint<I, F>::unsigned_type; |
| 127 | 129 | ||
| @@ -191,7 +193,7 @@ constexpr FixedPoint<I, F> divide( | |||
| 191 | template <size_t I, size_t F> | 193 | template <size_t I, size_t F> |
| 192 | constexpr FixedPoint<I, F> multiply( | 194 | constexpr FixedPoint<I, F> multiply( |
| 193 | FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, | 195 | FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, |
| 194 | typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { | 196 | std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) { |
| 195 | 197 | ||
| 196 | using next_type = typename FixedPoint<I, F>::next_type; | 198 | using next_type = typename FixedPoint<I, F>::next_type; |
| 197 | using base_type = typename FixedPoint<I, F>::base_type; | 199 | using base_type = typename FixedPoint<I, F>::base_type; |
| @@ -210,7 +212,7 @@ constexpr FixedPoint<I, F> multiply( | |||
| 210 | template <size_t I, size_t F> | 212 | template <size_t I, size_t F> |
| 211 | constexpr FixedPoint<I, F> multiply( | 213 | constexpr FixedPoint<I, F> multiply( |
| 212 | FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, | 214 | FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, |
| 213 | typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { | 215 | std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) { |
| 214 | 216 | ||
| 215 | using base_type = typename FixedPoint<I, F>::base_type; | 217 | using base_type = typename FixedPoint<I, F>::base_type; |
| 216 | 218 | ||
| @@ -270,10 +272,8 @@ public: // constructors | |||
| 270 | FixedPoint(FixedPoint&&) = default; | 272 | FixedPoint(FixedPoint&&) = default; |
| 271 | FixedPoint& operator=(const FixedPoint&) = default; | 273 | FixedPoint& operator=(const FixedPoint&) = default; |
| 272 | 274 | ||
| 273 | template <class Number> | 275 | template <IsArithmetic Number> |
| 274 | constexpr FixedPoint( | 276 | constexpr FixedPoint(Number n) : data_(static_cast<base_type>(n * one)) {} |
| 275 | Number n, typename std::enable_if<std::is_arithmetic<Number>::value>::type* = nullptr) | ||
| 276 | : data_(static_cast<base_type>(n * one)) {} | ||
| 277 | 277 | ||
| 278 | public: // conversion | 278 | public: // conversion |
| 279 | template <size_t I2, size_t F2> | 279 | template <size_t I2, size_t F2> |
| @@ -411,15 +411,13 @@ public: // binary math operators, effects underlying bit pattern since these | |||
| 411 | return *this; | 411 | return *this; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | template <class Integer, | 414 | template <IsIntegral Integer> |
| 415 | class = typename std::enable_if<std::is_integral<Integer>::value>::type> | ||
| 416 | constexpr FixedPoint& operator>>=(Integer n) { | 415 | constexpr FixedPoint& operator>>=(Integer n) { |
| 417 | data_ >>= n; | 416 | data_ >>= n; |
| 418 | return *this; | 417 | return *this; |
| 419 | } | 418 | } |
| 420 | 419 | ||
| 421 | template <class Integer, | 420 | template <IsIntegral Integer> |
| 422 | class = typename std::enable_if<std::is_integral<Integer>::value>::type> | ||
| 423 | constexpr FixedPoint& operator<<=(Integer n) { | 421 | constexpr FixedPoint& operator<<=(Integer n) { |
| 424 | data_ <<= n; | 422 | data_ <<= n; |
| 425 | return *this; | 423 | return *this; |
| @@ -490,10 +488,10 @@ public: | |||
| 490 | // if we have the same fractional portion, but differing integer portions, we trivially upgrade the | 488 | // if we have the same fractional portion, but differing integer portions, we trivially upgrade the |
| 491 | // smaller type | 489 | // smaller type |
| 492 | template <size_t I1, size_t I2, size_t F> | 490 | template <size_t I1, size_t I2, size_t F> |
| 493 | constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator+( | 491 | constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator+( |
| 494 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { | 492 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { |
| 495 | 493 | ||
| 496 | using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; | 494 | using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>; |
| 497 | 495 | ||
| 498 | const T l = T::from_base(lhs.to_raw()); | 496 | const T l = T::from_base(lhs.to_raw()); |
| 499 | const T r = T::from_base(rhs.to_raw()); | 497 | const T r = T::from_base(rhs.to_raw()); |
| @@ -501,10 +499,10 @@ constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, | |||
| 501 | } | 499 | } |
| 502 | 500 | ||
| 503 | template <size_t I1, size_t I2, size_t F> | 501 | template <size_t I1, size_t I2, size_t F> |
| 504 | constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator-( | 502 | constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator-( |
| 505 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { | 503 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { |
| 506 | 504 | ||
| 507 | using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; | 505 | using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>; |
| 508 | 506 | ||
| 509 | const T l = T::from_base(lhs.to_raw()); | 507 | const T l = T::from_base(lhs.to_raw()); |
| 510 | const T r = T::from_base(rhs.to_raw()); | 508 | const T r = T::from_base(rhs.to_raw()); |
| @@ -512,10 +510,10 @@ constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, | |||
| 512 | } | 510 | } |
| 513 | 511 | ||
| 514 | template <size_t I1, size_t I2, size_t F> | 512 | template <size_t I1, size_t I2, size_t F> |
| 515 | constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator*( | 513 | constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator*( |
| 516 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { | 514 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { |
| 517 | 515 | ||
| 518 | using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; | 516 | using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>; |
| 519 | 517 | ||
| 520 | const T l = T::from_base(lhs.to_raw()); | 518 | const T l = T::from_base(lhs.to_raw()); |
| 521 | const T r = T::from_base(rhs.to_raw()); | 519 | const T r = T::from_base(rhs.to_raw()); |
| @@ -523,10 +521,10 @@ constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, | |||
| 523 | } | 521 | } |
| 524 | 522 | ||
| 525 | template <size_t I1, size_t I2, size_t F> | 523 | template <size_t I1, size_t I2, size_t F> |
| 526 | constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator/( | 524 | constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator/( |
| 527 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { | 525 | FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { |
| 528 | 526 | ||
| 529 | using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; | 527 | using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>; |
| 530 | 528 | ||
| 531 | const T l = T::from_base(lhs.to_raw()); | 529 | const T l = T::from_base(lhs.to_raw()); |
| 532 | const T r = T::from_base(rhs.to_raw()); | 530 | const T r = T::from_base(rhs.to_raw()); |
| @@ -561,54 +559,46 @@ constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) | |||
| 561 | return lhs; | 559 | return lhs; |
| 562 | } | 560 | } |
| 563 | 561 | ||
| 564 | template <size_t I, size_t F, class Number, | 562 | template <size_t I, size_t F, IsArithmetic Number> |
| 565 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 566 | constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) { | 563 | constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) { |
| 567 | lhs += FixedPoint<I, F>(rhs); | 564 | lhs += FixedPoint<I, F>(rhs); |
| 568 | return lhs; | 565 | return lhs; |
| 569 | } | 566 | } |
| 570 | template <size_t I, size_t F, class Number, | 567 | template <size_t I, size_t F, IsArithmetic Number> |
| 571 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 572 | constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) { | 568 | constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) { |
| 573 | lhs -= FixedPoint<I, F>(rhs); | 569 | lhs -= FixedPoint<I, F>(rhs); |
| 574 | return lhs; | 570 | return lhs; |
| 575 | } | 571 | } |
| 576 | template <size_t I, size_t F, class Number, | 572 | template <size_t I, size_t F, IsArithmetic Number> |
| 577 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 578 | constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) { | 573 | constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) { |
| 579 | lhs *= FixedPoint<I, F>(rhs); | 574 | lhs *= FixedPoint<I, F>(rhs); |
| 580 | return lhs; | 575 | return lhs; |
| 581 | } | 576 | } |
| 582 | template <size_t I, size_t F, class Number, | 577 | template <size_t I, size_t F, IsArithmetic Number> |
| 583 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 584 | constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) { | 578 | constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) { |
| 585 | lhs /= FixedPoint<I, F>(rhs); | 579 | lhs /= FixedPoint<I, F>(rhs); |
| 586 | return lhs; | 580 | return lhs; |
| 587 | } | 581 | } |
| 588 | 582 | ||
| 589 | template <size_t I, size_t F, class Number, | 583 | template <size_t I, size_t F, IsArithmetic Number> |
| 590 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 591 | constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) { | 584 | constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) { |
| 592 | FixedPoint<I, F> tmp(lhs); | 585 | FixedPoint<I, F> tmp(lhs); |
| 593 | tmp += rhs; | 586 | tmp += rhs; |
| 594 | return tmp; | 587 | return tmp; |
| 595 | } | 588 | } |
| 596 | template <size_t I, size_t F, class Number, | 589 | template <size_t I, size_t F, IsArithmetic Number> |
| 597 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 598 | constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) { | 590 | constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) { |
| 599 | FixedPoint<I, F> tmp(lhs); | 591 | FixedPoint<I, F> tmp(lhs); |
| 600 | tmp -= rhs; | 592 | tmp -= rhs; |
| 601 | return tmp; | 593 | return tmp; |
| 602 | } | 594 | } |
| 603 | template <size_t I, size_t F, class Number, | 595 | template <size_t I, size_t F, IsArithmetic Number> |
| 604 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 605 | constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) { | 596 | constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) { |
| 606 | FixedPoint<I, F> tmp(lhs); | 597 | FixedPoint<I, F> tmp(lhs); |
| 607 | tmp *= rhs; | 598 | tmp *= rhs; |
| 608 | return tmp; | 599 | return tmp; |
| 609 | } | 600 | } |
| 610 | template <size_t I, size_t F, class Number, | 601 | template <size_t I, size_t F, IsArithmetic Number> |
| 611 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 612 | constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) { | 602 | constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) { |
| 613 | FixedPoint<I, F> tmp(lhs); | 603 | FixedPoint<I, F> tmp(lhs); |
| 614 | tmp /= rhs; | 604 | tmp /= rhs; |
| @@ -616,78 +606,64 @@ constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) { | |||
| 616 | } | 606 | } |
| 617 | 607 | ||
| 618 | // shift operators | 608 | // shift operators |
| 619 | template <size_t I, size_t F, class Integer, | 609 | template <size_t I, size_t F, IsIntegral Integer> |
| 620 | class = typename std::enable_if<std::is_integral<Integer>::value>::type> | ||
| 621 | constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) { | 610 | constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) { |
| 622 | lhs <<= rhs; | 611 | lhs <<= rhs; |
| 623 | return lhs; | 612 | return lhs; |
| 624 | } | 613 | } |
| 625 | template <size_t I, size_t F, class Integer, | 614 | template <size_t I, size_t F, IsIntegral Integer> |
| 626 | class = typename std::enable_if<std::is_integral<Integer>::value>::type> | ||
| 627 | constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) { | 615 | constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) { |
| 628 | lhs >>= rhs; | 616 | lhs >>= rhs; |
| 629 | return lhs; | 617 | return lhs; |
| 630 | } | 618 | } |
| 631 | 619 | ||
| 632 | // comparison operators | 620 | // comparison operators |
| 633 | template <size_t I, size_t F, class Number, | 621 | template <size_t I, size_t F, IsArithmetic Number> |
| 634 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 635 | constexpr bool operator>(FixedPoint<I, F> lhs, Number rhs) { | 622 | constexpr bool operator>(FixedPoint<I, F> lhs, Number rhs) { |
| 636 | return lhs > FixedPoint<I, F>(rhs); | 623 | return lhs > FixedPoint<I, F>(rhs); |
| 637 | } | 624 | } |
| 638 | template <size_t I, size_t F, class Number, | 625 | template <size_t I, size_t F, IsArithmetic Number> |
| 639 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 640 | constexpr bool operator<(FixedPoint<I, F> lhs, Number rhs) { | 626 | constexpr bool operator<(FixedPoint<I, F> lhs, Number rhs) { |
| 641 | return lhs < FixedPoint<I, F>(rhs); | 627 | return lhs < FixedPoint<I, F>(rhs); |
| 642 | } | 628 | } |
| 643 | template <size_t I, size_t F, class Number, | 629 | template <size_t I, size_t F, IsArithmetic Number> |
| 644 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 645 | constexpr bool operator>=(FixedPoint<I, F> lhs, Number rhs) { | 630 | constexpr bool operator>=(FixedPoint<I, F> lhs, Number rhs) { |
| 646 | return lhs >= FixedPoint<I, F>(rhs); | 631 | return lhs >= FixedPoint<I, F>(rhs); |
| 647 | } | 632 | } |
| 648 | template <size_t I, size_t F, class Number, | 633 | template <size_t I, size_t F, IsArithmetic Number> |
| 649 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 650 | constexpr bool operator<=(FixedPoint<I, F> lhs, Number rhs) { | 634 | constexpr bool operator<=(FixedPoint<I, F> lhs, Number rhs) { |
| 651 | return lhs <= FixedPoint<I, F>(rhs); | 635 | return lhs <= FixedPoint<I, F>(rhs); |
| 652 | } | 636 | } |
| 653 | template <size_t I, size_t F, class Number, | 637 | template <size_t I, size_t F, IsArithmetic Number> |
| 654 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 655 | constexpr bool operator==(FixedPoint<I, F> lhs, Number rhs) { | 638 | constexpr bool operator==(FixedPoint<I, F> lhs, Number rhs) { |
| 656 | return lhs == FixedPoint<I, F>(rhs); | 639 | return lhs == FixedPoint<I, F>(rhs); |
| 657 | } | 640 | } |
| 658 | template <size_t I, size_t F, class Number, | 641 | template <size_t I, size_t F, IsArithmetic Number> |
| 659 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 660 | constexpr bool operator!=(FixedPoint<I, F> lhs, Number rhs) { | 642 | constexpr bool operator!=(FixedPoint<I, F> lhs, Number rhs) { |
| 661 | return lhs != FixedPoint<I, F>(rhs); | 643 | return lhs != FixedPoint<I, F>(rhs); |
| 662 | } | 644 | } |
| 663 | 645 | ||
| 664 | template <size_t I, size_t F, class Number, | 646 | template <size_t I, size_t F, IsArithmetic Number> |
| 665 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 666 | constexpr bool operator>(Number lhs, FixedPoint<I, F> rhs) { | 647 | constexpr bool operator>(Number lhs, FixedPoint<I, F> rhs) { |
| 667 | return FixedPoint<I, F>(lhs) > rhs; | 648 | return FixedPoint<I, F>(lhs) > rhs; |
| 668 | } | 649 | } |
| 669 | template <size_t I, size_t F, class Number, | 650 | template <size_t I, size_t F, IsArithmetic Number> |
| 670 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 671 | constexpr bool operator<(Number lhs, FixedPoint<I, F> rhs) { | 651 | constexpr bool operator<(Number lhs, FixedPoint<I, F> rhs) { |
| 672 | return FixedPoint<I, F>(lhs) < rhs; | 652 | return FixedPoint<I, F>(lhs) < rhs; |
| 673 | } | 653 | } |
| 674 | template <size_t I, size_t F, class Number, | 654 | template <size_t I, size_t F, IsArithmetic Number> |
| 675 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 676 | constexpr bool operator>=(Number lhs, FixedPoint<I, F> rhs) { | 655 | constexpr bool operator>=(Number lhs, FixedPoint<I, F> rhs) { |
| 677 | return FixedPoint<I, F>(lhs) >= rhs; | 656 | return FixedPoint<I, F>(lhs) >= rhs; |
| 678 | } | 657 | } |
| 679 | template <size_t I, size_t F, class Number, | 658 | template <size_t I, size_t F, IsArithmetic Number> |
| 680 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 681 | constexpr bool operator<=(Number lhs, FixedPoint<I, F> rhs) { | 659 | constexpr bool operator<=(Number lhs, FixedPoint<I, F> rhs) { |
| 682 | return FixedPoint<I, F>(lhs) <= rhs; | 660 | return FixedPoint<I, F>(lhs) <= rhs; |
| 683 | } | 661 | } |
| 684 | template <size_t I, size_t F, class Number, | 662 | template <size_t I, size_t F, IsArithmetic Number> |
| 685 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 686 | constexpr bool operator==(Number lhs, FixedPoint<I, F> rhs) { | 663 | constexpr bool operator==(Number lhs, FixedPoint<I, F> rhs) { |
| 687 | return FixedPoint<I, F>(lhs) == rhs; | 664 | return FixedPoint<I, F>(lhs) == rhs; |
| 688 | } | 665 | } |
| 689 | template <size_t I, size_t F, class Number, | 666 | template <size_t I, size_t F, IsArithmetic Number> |
| 690 | class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> | ||
| 691 | constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) { | 667 | constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) { |
| 692 | return FixedPoint<I, F>(lhs) != rhs; | 668 | return FixedPoint<I, F>(lhs) != rhs; |
| 693 | } | 669 | } |