Truncating conversions disalowed for *=, /=, +=, amd -= operators (resolves #137)

This commit is contained in:
Mateusz Pusz
2020-08-16 13:29:40 +02:00
parent 69dddaf1f6
commit deb1ee6efa
2 changed files with 20 additions and 16 deletions

View File

@ -164,37 +164,33 @@ public:
return quantity(value_--);
}
template<typename T = Rep>
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<T&>; } // TODO gated by gcc-9 (fixed in gcc-10)
template<typename Rep2>
requires detail::safe_convertible<Rep2, rep>
constexpr quantity& operator+=(const quantity<D, U, Rep2>& q)
{
value_ += q.count();
return *this;
}
template<typename T = Rep>
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<T&>; } // TODO gated by gcc-9 (fixed in gcc-10)
template<typename Rep2>
requires detail::safe_convertible<Rep2, rep>
constexpr quantity& operator-=(const quantity<D, U, Rep2>& q)
{
value_ -= q.count();
return *this;
}
template<typename T = Rep>
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<T&>; } // TODO gated by gcc-9 (fixed in gcc-10)
template<typename Rep2>
requires detail::safe_convertible<Rep2, rep>
constexpr quantity& operator*=(const Rep2& rhs)
{
value_ *= rhs;
return *this;
}
template<typename T = Rep>
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<rep&>; } // TODO gated by gcc-9 (fixed in gcc-10)
template<typename Rep2>
requires detail::safe_convertible<Rep2, rep>
constexpr quantity& operator/=(const Rep2& rhs)
{
value_ /= rhs;
return *this;

View File

@ -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<decltype(length<metre, int>() + length<metre, double>()), length<metre, double>>);