From cdcbe5143509de509e5f6c4d8ce37befb58d9463 Mon Sep 17 00:00:00 2001 From: Yury Kudryashov Date: Thu, 28 Aug 2025 19:14:08 +0000 Subject: [PATCH 1/2] fix: make `boost::rational>` work --- include/boost/rational.hpp | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/include/boost/rational.hpp b/include/boost/rational.hpp index 89d2fb4..51a6b12 100644 --- a/include/boost/rational.hpp +++ b/include/boost/rational.hpp @@ -21,6 +21,7 @@ // Nickolay Mladenov, for the implementation of operator+= // Revision History +// 10 Aug 25 Don't use `-` on unsigned types (Yury Kudryashov) // 12 Nov 20 Fix operators to work with C++20 rules (Glen Joseph Fernandes) // 02 Sep 13 Remove unneeded forward declarations; tweak private helper // function (Daryle Walker) @@ -324,9 +325,11 @@ class rational num /= gcd; den *= i / gcd; - if(den < zero) { - num = -num; - den = -den; + if constexpr (std::numeric_limits::is_signed) { + if(den < zero) { + num = -num; + den = -den; + } } return *this; @@ -604,9 +607,11 @@ BOOST_CXX14_CONSTEXPR rational& rational::operator/= (const ra num = (num/gcd1) * (r_den/gcd2); den = (den/gcd2) * (r_num/gcd1); - if (den < zero) { - num = -num; - den = -den; + if constexpr (std::numeric_limits::is_signed) { + if (den < zero) { + num = -num; + den = -den; + } } return *this; } @@ -902,14 +907,16 @@ BOOST_CXX14_CONSTEXPR void rational::normalize() num /= g; den /= g; - if (std::numeric_limits::is_bounded && den < -(std::numeric_limits::max)()) { - BOOST_THROW_EXCEPTION(bad_rational("bad rational: non-zero singular denominator")); - } + if constexpr (std::numeric_limits::is_signed && std::numeric_limits::is_bounded) { + if (den < -(std::numeric_limits::max)()) { + BOOST_THROW_EXCEPTION(bad_rational("bad rational: non-zero singular denominator")); + } - // Ensure that the denominator is positive - if (den < zero) { - num = -num; - den = -den; + // Ensure that the denominator is positive + if (den < zero) { + num = -num; + den = -den; + } } BOOST_ASSERT( this->test_invariant() ); From 2837644764e8c6b53c13d3804807a501d824dc15 Mon Sep 17 00:00:00 2001 From: Yury Kudryashov Date: Thu, 28 Aug 2025 19:55:43 +0000 Subject: [PATCH 2/2] Try `BOOST_CONSTEXPR` --- include/boost/rational.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/rational.hpp b/include/boost/rational.hpp index 51a6b12..0e4ffea 100644 --- a/include/boost/rational.hpp +++ b/include/boost/rational.hpp @@ -325,7 +325,7 @@ class rational num /= gcd; den *= i / gcd; - if constexpr (std::numeric_limits::is_signed) { + if BOOST_CONSTEXPR (std::numeric_limits::is_signed) { if(den < zero) { num = -num; den = -den; @@ -607,7 +607,7 @@ BOOST_CXX14_CONSTEXPR rational& rational::operator/= (const ra num = (num/gcd1) * (r_den/gcd2); den = (den/gcd2) * (r_num/gcd1); - if constexpr (std::numeric_limits::is_signed) { + if BOOST_CONSTEXPR (std::numeric_limits::is_signed) { if (den < zero) { num = -num; den = -den; @@ -907,7 +907,7 @@ BOOST_CXX14_CONSTEXPR void rational::normalize() num /= g; den /= g; - if constexpr (std::numeric_limits::is_signed && std::numeric_limits::is_bounded) { + if BOOST_CONSTEXPR (std::numeric_limits::is_signed && std::numeric_limits::is_bounded) { if (den < -(std::numeric_limits::max)()) { BOOST_THROW_EXCEPTION(bad_rational("bad rational: non-zero singular denominator")); }