4848import std;
4949#else
5050#include < compare> // IWYU pragma: export
51+ #include < concepts>
5152#include < limits>
53+ #include < stdexcept>
54+ #include < type_traits>
5255#include < utility>
5356#if MP_UNITS_HOSTED
5457#include < locale>
@@ -60,6 +63,15 @@ namespace mp_units {
6063
6164namespace detail {
6265
66+ struct zero {
67+ template <typename T>
68+ requires std::is_arithmetic_v<T> && (!is_same_v<T, bool >)
69+ consteval explicit (false ) zero(T val)
70+ {
71+ if (val != T{0 }) MP_UNITS_THROW (std::logic_error (" not zero" ));
72+ }
73+ };
74+
6375template <Unit UFrom, Unit UTo>
6476[[nodiscard]] consteval bool integral_conversion_factor (UFrom from, UTo to)
6577{
@@ -467,7 +479,7 @@ class quantity {
467479 }
468480 constexpr quantity& operator %=(const quantity<R2, Rep2>& other) &
469481 {
470- MP_UNITS_EXPECTS_DEBUG (is_neq_zero ( other) );
482+ MP_UNITS_EXPECTS_DEBUG (other != 0 );
471483 if constexpr (equivalent (unit, get_unit (R2)))
472484 numerical_value_is_an_implementation_detail_ %= other.numerical_value_is_an_implementation_detail_ ;
473485 else
@@ -574,7 +586,7 @@ class quantity {
574586 detail::CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>>
575587 [[nodiscard]] friend constexpr Quantity auto operator %(const Q& lhs, const quantity<R2, Rep2>& rhs)
576588 {
577- MP_UNITS_EXPECTS_DEBUG (is_neq_zero ( rhs) );
589+ MP_UNITS_EXPECTS_DEBUG (rhs != 0 );
578590 using ret = detail::common_quantity_for<std::modulus<>, quantity, quantity<R2, Rep2>>;
579591 const ret ret_lhs (lhs);
580592 const ret ret_rhs (rhs);
@@ -625,7 +637,7 @@ class quantity {
625637 requires detail::InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>>
626638 [[nodiscard]] friend constexpr Quantity auto operator /(const Q& lhs, const quantity<R2, Rep2>& rhs)
627639 {
628- MP_UNITS_EXPECTS_DEBUG (is_neq_zero ( rhs) );
640+ MP_UNITS_EXPECTS_DEBUG (rhs != 0 );
629641 return ::mp_units::quantity{lhs.numerical_value_ref_in (unit) / rhs.numerical_value_ref_in (rhs.unit ), R / R2};
630642 }
631643
@@ -643,7 +655,7 @@ class quantity {
643655 (!Reference<Value>) && detail::InvokeResultOf<quantity_spec, std::divides<>, const Value&, rep>
644656 [[nodiscard]] friend constexpr Quantity auto operator /(const Value& val, const Q& q)
645657 {
646- MP_UNITS_EXPECTS_DEBUG (is_neq_zero (q) );
658+ MP_UNITS_EXPECTS_DEBUG (q != 0 );
647659 return ::mp_units::quantity{val / q.numerical_value_ref_in (unit), one / R};
648660 }
649661
@@ -668,6 +680,13 @@ class quantity {
668680 return lhs.numerical_value_ref_in (unit) == rhs;
669681 }
670682
683+ template <std::derived_from<quantity> Q>
684+ requires std::equality_comparable<rep> && requires { representation_values<rep>::zero (); }
685+ [[nodiscard]] friend constexpr bool operator ==(const Q& lhs, detail::zero)
686+ {
687+ return lhs.numerical_value_ref_in (unit) == representation_values<rep>::zero ();
688+ }
689+
671690 template <std::derived_from<quantity> Q, auto R2, typename Rep2>
672691 requires requires { typename std::common_type_t <quantity, quantity<R2, Rep2>>; } &&
673692 std::three_way_comparable<typename std::common_type_t <quantity, quantity<R2, Rep2>>::rep>
@@ -685,6 +704,13 @@ class quantity {
685704 {
686705 return lhs.numerical_value_ref_in (unit) <=> rhs;
687706 }
707+
708+ template <std::derived_from<quantity> Q>
709+ requires std::three_way_comparable<rep> && requires { representation_values<rep>::zero (); }
710+ [[nodiscard]] friend constexpr auto operator <=>(const Q& lhs, detail::zero)
711+ {
712+ return lhs.numerical_value_ref_in (unit) <=> representation_values<rep>::zero ();
713+ }
688714};
689715
690716// CTAD
0 commit comments