From deb1ee6efa376934f43b295b400d5436342a72db Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sun, 16 Aug 2020 13:29:40 +0200 Subject: [PATCH] Truncating conversions disalowed for `*=`, `/=`, `+=`, amd `-=` operators (resolves #137) --- src/include/units/quantity.h | 28 +++++++++++-------------- test/unit_test/static/quantity_test.cpp | 8 +++++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index c055e8ef..bc3c3bdf 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -164,37 +164,33 @@ public: return quantity(value_--); } - template - requires requires(T v1, T v2) { { v1 += v2 } -> SAME_AS(T&); } - constexpr quantity& operator+=(const quantity& q) - // requires requires(rep v1, rep v2) { { v1 += v2 } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + template + requires detail::safe_convertible + constexpr quantity& operator+=(const quantity& q) { value_ += q.count(); return *this; } - template - requires requires(T v1, T v2) { { v1 -= v2 } -> SAME_AS(T&); } - constexpr quantity& operator-=(const quantity& q) - // requires requires(rep v1, rep v2) { { v1 -= v2 } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + template + requires detail::safe_convertible + constexpr quantity& operator-=(const quantity& q) { value_ -= q.count(); return *this; } - template - requires requires(T v1, T v2) { { v1 *= v2 } -> SAME_AS(T&); } - constexpr quantity& operator*=(const rep& rhs) - // requires requires(rep v1, rep v2) { { v1 *= v2 } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + template + requires detail::safe_convertible + constexpr quantity& operator*=(const Rep2& rhs) { value_ *= rhs; return *this; } - template - requires requires(T v1, T v2) { { v1 /= v2 } -> SAME_AS(T&); } - constexpr quantity& operator/=(const rep& rhs) - // requires requires(rep v1, rep v2) { { v1 /= v2 } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + template + requires detail::safe_convertible + constexpr quantity& operator/=(const Rep2& rhs) { value_ /= rhs; return *this; diff --git a/test/unit_test/static/quantity_test.cpp b/test/unit_test/static/quantity_test.cpp index 8d0bd693..3e4b20f4 100644 --- a/test/unit_test/static/quantity_test.cpp +++ b/test/unit_test/static/quantity_test.cpp @@ -124,6 +124,14 @@ static_assert((7q_m %= 2q_m).count() == 1); // static_assert((7.m %= 2q_m).count() == 1); // should not compile (operation not allowed for floating-point types) // static_assert((7q_m %= 2.m).count() == 1); // should not compile (operation not allowed for floating-point types) +// static_assert(2q_m += 3.5q_m); // should not compile +static_assert((2.5q_m += 3q_m).count() == 5.5); +static_assert((2.5q_m += 3.5q_m).count() == 6); + +// static_assert(2q_m *= 3.5); // should not compile +static_assert((2.5q_m *= 3).count() == 7.5); +static_assert((2.5q_m *= 3.5).count() == 8.75); + // non-member arithmetic operators static_assert(is_same_v() + length()), length>);