diff --git a/src/libxrpl/protocol/ErrorCodes.cpp b/src/libxrpl/protocol/ErrorCodes.cpp index e81f975844..802bae100d 100644 --- a/src/libxrpl/protocol/ErrorCodes.cpp +++ b/src/libxrpl/protocol/ErrorCodes.cpp @@ -105,10 +105,9 @@ static constexpr ErrorInfo kUnorderedErrorInfos[]{ }; // clang-format on -// Sort and validate unorderedErrorInfos at compile time. Should be -// converted to consteval when get to C++20. +// Sort and validate unorderedErrorInfos at compile time. template -constexpr auto +consteval auto sortErrorInfos(ErrorInfo const (&unordered)[N]) -> std::array { std::array ret = {}; diff --git a/src/test/app/Invariants_test.cpp b/src/test/app/Invariants_test.cpp index ffdfe6bc83..ed09b7b660 100644 --- a/src/test/app/Invariants_test.cpp +++ b/src/test/app/Invariants_test.cpp @@ -437,16 +437,10 @@ class Invariants_test : public beast::unit_test::Suite XRPAmount{}, STTx{ttACCOUNT_DELETE, [](STObject& tx) {}}); - for (auto const& keyletInfo : kDirectAccountKeylets) + for (auto const& [keyletfunc, type, includeInTests] : kDirectAccountKeylets) { - // TODO: Use structured binding once LLVM 16 is the minimum - // supported version. See also: - // https://github.com/llvm/llvm-project/issues/48582 - // https://github.com/llvm/llvm-project/commit/127bf44385424891eb04cff8e52d3f157fc2cb7c - if (!keyletInfo.includeInTests) + if (!includeInTests) continue; - auto const& keyletfunc = keyletInfo.function; - auto const& type = keyletInfo.expectedLEName; using namespace std::string_literals; diff --git a/src/test/jtx/TestHelpers.h b/src/test/jtx/TestHelpers.h index 5c8486e6c5..801c3627b8 100644 --- a/src/test/jtx/TestHelpers.h +++ b/src/test/jtx/TestHelpers.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -315,19 +316,11 @@ auto const kData = JTxFieldWrapper(sfData); auto const kAmount = JTxFieldWrapper(sfAmount); -// TODO We only need this long "requires" clause as polyfill, for C++20 -// implementations which are missing header. Replace with -// `std::ranges::range`, and accordingly use std::ranges::begin/end -// when we have moved to better compilers. -template +template auto makeVector(Input const& input) - requires requires(Input& v) { - std::begin(v); - std::end(v); - } { - return std::vector(std::begin(input), std::end(input)); + return std::vector(std::ranges::begin(input), std::ranges::end(input)); } // Functions used in debugging diff --git a/src/xrpld/app/misc/FeeVoteImpl.cpp b/src/xrpld/app/misc/FeeVoteImpl.cpp index 76a4d8f186..f1cb944a52 100644 --- a/src/xrpld/app/misc/FeeVoteImpl.cpp +++ b/src/xrpld/app/misc/FeeVoteImpl.cpp @@ -260,39 +260,35 @@ FeeVoteImpl::doVoting( } // choose our positions - // TODO: Use structured binding once LLVM 16 is the minimum supported - // version. See also: https://github.com/llvm/llvm-project/issues/48582 - // https://github.com/llvm/llvm-project/commit/127bf44385424891eb04cff8e52d3f157fc2cb7c - auto const baseFee = baseFeeVote.getVotes(); - auto const baseReserve = baseReserveVote.getVotes(); - auto const incReserve = incReserveVote.getVotes(); + auto const [baseFee, baseFeeChanged] = baseFeeVote.getVotes(); + auto const [baseReserve, baseReserveChanged] = baseReserveVote.getVotes(); + auto const [incReserve, incReserveChanged] = incReserveVote.getVotes(); auto const seq = lastClosedLedger->header().seq + 1; // add transactions to our position - if (baseFee.second || baseReserve.second || incReserve.second) + if (baseFeeChanged || baseReserveChanged || incReserveChanged) { - JLOG(journal_.warn()) << "We are voting for a fee change: " << baseFee.first << "/" - << baseReserve.first << "/" << incReserve.first; + JLOG(journal_.warn()) << "We are voting for a fee change: " << baseFee << "/" << baseReserve + << "/" << incReserve; STTx const feeTx(ttFEE, [=, &rules](auto& obj) { obj[sfAccount] = AccountID(); obj[sfLedgerSequence] = seq; if (rules.enabled(featureXRPFees)) { - obj[sfBaseFeeDrops] = baseFee.first; - obj[sfReserveBaseDrops] = baseReserve.first; - obj[sfReserveIncrementDrops] = incReserve.first; + obj[sfBaseFeeDrops] = baseFee; + obj[sfReserveBaseDrops] = baseReserve; + obj[sfReserveIncrementDrops] = incReserve; } else { // Without the featureXRPFees amendment, these fields are // required. - obj[sfBaseFee] = baseFee.first.dropsAs(baseFeeVote.current()); - obj[sfReserveBase] = - baseReserve.first.dropsAs(baseReserveVote.current()); + obj[sfBaseFee] = baseFee.dropsAs(baseFeeVote.current()); + obj[sfReserveBase] = baseReserve.dropsAs(baseReserveVote.current()); obj[sfReserveIncrement] = - incReserve.first.dropsAs(incReserveVote.current()); + incReserve.dropsAs(incReserveVote.current()); obj[sfReferenceFeeUnits] = kFeeUnitsDeprecated; } }); diff --git a/src/xrpld/overlay/detail/ProtocolVersion.cpp b/src/xrpld/overlay/detail/ProtocolVersion.cpp index 2d5d0a56f7..93d4fae156 100644 --- a/src/xrpld/overlay/detail/ProtocolVersion.cpp +++ b/src/xrpld/overlay/detail/ProtocolVersion.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -32,31 +33,17 @@ constexpr ProtocolVersion const kSupportedProtocolList[]{ {2, 3}, }; -// This ugly construct ensures that supportedProtocolList is sorted in strictly -// ascending order and doesn't contain any duplicates. -// FIXME: With C++20 we can use std::is_sorted with an appropriate comparator +// There should be at least one protocol we're willing to speak. static_assert( - []() constexpr -> bool { - auto const len = - std::distance(std::begin(kSupportedProtocolList), std::end(kSupportedProtocolList)); + !std::ranges::empty(kSupportedProtocolList), + "There must be at least one supported protocol."); - // There should be at least one protocol we're willing to speak. - if (len == 0) - return false; - - // A list with only one entry is, by definition, sorted so we don't - // need to check it. - if (len != 1) - { - for (auto i = 0; i != len - 1; ++i) - { - if (kSupportedProtocolList[i] >= kSupportedProtocolList[i + 1]) - return false; - } - } - - return true; - }(), +// Searching for an adjacent pair where the first element is not less than the +// second one proves the list is sorted in strictly ascending order, which in +// turn means it holds no duplicates. +static_assert( + std::ranges::adjacent_find(kSupportedProtocolList, std::ranges::greater_equal{}) == + std::ranges::end(kSupportedProtocolList), "The list of supported protocols isn't properly sorted."); std::string diff --git a/src/xrpld/rpc/handlers/server_info/ServerDefinitions.cpp b/src/xrpld/rpc/handlers/server_info/ServerDefinitions.cpp index b561ce6d38..32a084a833 100644 --- a/src/xrpld/rpc/handlers/server_info/ServerDefinitions.cpp +++ b/src/xrpld/rpc/handlers/server_info/ServerDefinitions.cpp @@ -64,7 +64,6 @@ ServerDefinitions::translate(std::string const& inp) return out; }; - // TODO: use string::contains with C++23 auto contains = [&](std::string_view s) -> bool { return inp.contains(s); }; if (contains("UINT"))