forked from mpusz/mp-units
fix: operators to behave like the underlying type's
This commit is contained in:
committed by
Mateusz Pusz
parent
58903e46e6
commit
00d182e133
@@ -150,10 +150,11 @@ public:
|
||||
[[nodiscard]] constexpr rep count() const noexcept { return value_; }
|
||||
|
||||
// member unary operators
|
||||
[[nodiscard]] constexpr quantity operator+() const
|
||||
requires requires(rep v) { { +v } -> std::same_as<rep>; }
|
||||
[[nodiscard]] constexpr Quantity auto operator+() const
|
||||
requires requires(rep v) { { +v } -> std::common_with<rep>; }
|
||||
{
|
||||
return *this;
|
||||
using ret = quantity<D, U, decltype(+count())>;
|
||||
return ret(+count());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr Quantity auto operator-() const
|
||||
@@ -233,9 +234,10 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr quantity& operator%=(const rep& rhs)
|
||||
requires (!floating_point_<rep>) &&
|
||||
requires(rep a, const rep b) { { a %= b } -> std::same_as<rep&>; }
|
||||
template<typename Rep2>
|
||||
constexpr quantity& operator%=(const Rep2& rhs)
|
||||
requires (!floating_point_<rep>) && (!floating_point_<Rep2>) &&
|
||||
requires(rep a, const Rep2 b) { { a %= b } -> std::same_as<rep&>; }
|
||||
{
|
||||
value_ %= rhs;
|
||||
return *this;
|
||||
@@ -251,16 +253,34 @@ public:
|
||||
|
||||
// Hidden Friends
|
||||
// Below friend functions are to be found via argument-dependent lookup only
|
||||
[[nodiscard]] friend constexpr quantity operator+(const quantity& lhs, const quantity& rhs)
|
||||
requires invoke_result_convertible_to_<rep, std::plus<>, rep, rep>
|
||||
template<typename Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const Value& rhs)
|
||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
||||
invoke_result_convertible_to_<rep, std::plus<>, rep, Value>
|
||||
{
|
||||
return quantity(lhs.count() + rhs.count());
|
||||
return units::quantity(lhs.count() + rhs);
|
||||
}
|
||||
template<typename Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator+(const Value& lhs, const quantity& rhs)
|
||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
||||
invoke_result_convertible_to_<rep, std::plus<>, Value, rep>
|
||||
{
|
||||
return units::quantity(lhs + rhs.count());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr quantity operator-(const quantity& lhs, const quantity& rhs)
|
||||
requires invoke_result_convertible_to_<rep, std::minus<>, rep, rep>
|
||||
template<typename Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const Value& rhs)
|
||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
||||
invoke_result_convertible_to_<rep, std::minus<>, rep, Value>
|
||||
{
|
||||
return quantity(lhs.count() - rhs.count());
|
||||
return units::quantity(lhs.count() - rhs);
|
||||
}
|
||||
template<typename Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const Value& lhs, const quantity& rhs)
|
||||
requires (!Quantity<Value>) && is_same_v<unit, units::one> &&
|
||||
invoke_result_convertible_to_<rep, std::minus<>, Value, rep>
|
||||
{
|
||||
return units::quantity(lhs - rhs.count());
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
@@ -312,11 +332,11 @@ public:
|
||||
return ret(q.count() % v);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr quantity operator%(const quantity& lhs, const quantity& rhs)
|
||||
requires (!floating_point_<rep>) &&
|
||||
[[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs)
|
||||
requires (!floating_point_<rep>) && is_same_v<unit, units::one> &&
|
||||
invoke_result_convertible_to_<rep, std::modulus<>, rep, rep>
|
||||
{
|
||||
return quantity(lhs.count() % rhs.count());
|
||||
return units::quantity(lhs.count() % rhs.count());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity& rhs)
|
||||
|
||||
@@ -189,8 +189,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr quantity_kind& operator%=(const rep& rhs)
|
||||
requires requires(quantity_type q) { q %= rhs; }
|
||||
template<typename Rep2>
|
||||
constexpr quantity_kind& operator%=(const Rep2& rhs)
|
||||
requires (!Quantity<Rep2>) && requires(quantity_type q, const Rep2 r) { q %= r; }
|
||||
{
|
||||
q_ %= rhs;
|
||||
return *this;
|
||||
@@ -205,18 +206,6 @@ public:
|
||||
|
||||
// Hidden Friends
|
||||
// Below friend functions are to be found via argument-dependent lookup only
|
||||
[[nodiscard]] friend constexpr quantity_kind operator+(const quantity_kind& lhs, const quantity_kind& rhs)
|
||||
requires requires { lhs.common() + rhs.common(); }
|
||||
{
|
||||
return quantity_kind(lhs.common() + rhs.common());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr quantity_kind operator-(const quantity_kind& lhs, const quantity_kind& rhs)
|
||||
requires requires { lhs.common() - rhs.common(); }
|
||||
{
|
||||
return quantity_kind(lhs.common() - rhs.common());
|
||||
}
|
||||
|
||||
template<QuantityValue Value>
|
||||
[[nodiscard]] friend constexpr QuantityKind auto operator*(const quantity_kind& qk, const Value& v)
|
||||
requires requires { { qk.common() * v } -> Quantity; }
|
||||
@@ -252,12 +241,6 @@ public:
|
||||
return detail::make_quantity_kind<quantity_kind>(qk.common() % v);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr quantity_kind operator%(const quantity_kind& lhs, const quantity_kind& rhs)
|
||||
requires requires { lhs.common() % rhs.common(); }
|
||||
{
|
||||
return quantity_kind(lhs.common() % rhs.common());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity_kind& lhs, const quantity_kind& rhs)
|
||||
requires std::three_way_comparable<quantity_type>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user