diff --git a/include/xrpl/protocol/STObject.h b/include/xrpl/protocol/STObject.h index 14f276ce90..2f44e36990 100644 --- a/include/xrpl/protocol/STObject.h +++ b/include/xrpl/protocol/STObject.h @@ -518,8 +518,26 @@ protected: // Constraint += and -= ValueProxy operators // to value types that support arithmetic operations template -concept IsArithmetic = std::is_arithmetic_v || std::is_same_v || - std::is_same_v || std::is_same_v; +concept IsArithmeticNumber = std::is_arithmetic_v || + std::is_same_v || std::is_same_v; +template < + typename U, + typename Value = U::value_type, + typename Unit = U::unit_type> +concept IsArithmeticValueUnit = + std::is_same_v> && + IsArithmeticNumber && std::is_class_v; +template +concept IsArithmeticST = !IsArithmeticValueUnit && IsArithmeticNumber; +template +concept IsArithmetic = + IsArithmeticNumber || IsArithmeticST || IsArithmeticValueUnit; + +template +concept Addable = requires(T t, U u) { t = t + u; }; +template +concept IsArithmeticCompatible = + IsArithmetic && Addable; template class STObject::ValueProxy : public Proxy @@ -539,10 +557,12 @@ public: // Convenience operators for value types supporting // arithmetic operations template + requires IsArithmeticCompatible ValueProxy& operator+=(U const& u); template + requires IsArithmeticCompatible ValueProxy& operator-=(U const& u); @@ -778,6 +798,7 @@ STObject::ValueProxy::operator=(U&& u) template template + requires IsArithmeticCompatible STObject::ValueProxy& STObject::ValueProxy::operator+=(U const& u) { @@ -787,6 +808,7 @@ STObject::ValueProxy::operator+=(U const& u) template template + requires IsArithmeticCompatible STObject::ValueProxy& STObject::ValueProxy::operator-=(U const& u) { diff --git a/src/test/ledger/Invariants_test.cpp b/src/test/ledger/Invariants_test.cpp index ac8adf5a77..0927c8fcb3 100644 --- a/src/test/ledger/Invariants_test.cpp +++ b/src/test/ledger/Invariants_test.cpp @@ -1382,11 +1382,7 @@ class Invariants_test : public beast::unit_test::suite sle->at(sfOwner) = sle->at(sfAccount); }, [](SLE::pointer& sle) { - // The operator overloads aren't playing nice with the - // custom class, so just do it the hard way for now. - auto value = sle->at(sfManagementFeeRate).value(); - ++value; - sle->at(sfManagementFeeRate) = value; + sle->at(sfManagementFeeRate) += TenthBips16(1); }, [](SLE::pointer& sle) { sle->at(sfCoverRateMinimum) += 1; }, [](SLE::pointer& sle) {