From d6353e593f9f60c7007c8bd4ea1b288d91e701b8 Mon Sep 17 00:00:00 2001 From: Ed Hennis Date: Thu, 24 Apr 2025 16:36:26 -0400 Subject: [PATCH] Get arithmetic operators working for typed-values --- include/xrpl/protocol/STObject.h | 26 ++++++++++++++++++++++++-- src/test/ledger/Invariants_test.cpp | 6 +----- 2 files changed, 25 insertions(+), 7 deletions(-) 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) {