From d3cedd0be4dd54deeb846bd5f48f509b4540b416 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Tue, 10 Dec 2024 16:49:45 +0100 Subject: [PATCH] feat: Make TransformRange fulfill range concept (#3971) This allows using it with range algorithms --- .../include/Acts/Utilities/TransformRange.hpp | 16 +++++++++++++ .../Core/Utilities/TransformRangeTests.cpp | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Core/include/Acts/Utilities/TransformRange.hpp b/Core/include/Acts/Utilities/TransformRange.hpp index 4c7653c49e2..58e30b4f8c4 100644 --- a/Core/include/Acts/Utilities/TransformRange.hpp +++ b/Core/include/Acts/Utilities/TransformRange.hpp @@ -169,6 +169,8 @@ struct TransformRangeIterator { /// Construct an iterator from an underlying iterator explicit TransformRangeIterator(iterator_t iterator) : m_iterator(iterator) {} + TransformRangeIterator() = default; + /// Return a reference to the value that is transformed by the callable /// @return Reference to the transformed value reference operator*() { return Callable::apply(*m_iterator); } @@ -184,6 +186,14 @@ struct TransformRangeIterator { return *this; } + /// Advance the iterator + /// @return Reference to the iterator + TransformRangeIterator operator++(int) { + auto tmp = *this; + ++m_iterator; + return tmp; + } + /// Compare two iterators for equality /// @param other The other iterator to compare to bool operator==(const TransformRangeIterator& other) const { @@ -219,3 +229,9 @@ struct DotGet { }; } // namespace Acts::detail + +/// @cond +template +constexpr bool std::ranges::enable_borrowed_range< + Acts::detail::TransformRange> = true; +/// @endcond diff --git a/Tests/UnitTests/Core/Utilities/TransformRangeTests.cpp b/Tests/UnitTests/Core/Utilities/TransformRangeTests.cpp index d7ce6b56877..3b369d56307 100644 --- a/Tests/UnitTests/Core/Utilities/TransformRangeTests.cpp +++ b/Tests/UnitTests/Core/Utilities/TransformRangeTests.cpp @@ -6,10 +6,13 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. +#include #include #include "Acts/Utilities/TransformRange.hpp" +#include + using namespace Acts; BOOST_AUTO_TEST_SUITE(TransformRangeTests) @@ -99,6 +102,14 @@ BOOST_AUTO_TEST_CASE(TransformRangeDeref) { static_assert(std::is_same_v); checkSameAddresses(v, r); + std::vector unpacked; + std::ranges::transform(r, std::back_inserter(unpacked), + [](auto val) { return val; }); + std::vector exp = {1, 2, 4}; + + BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), unpacked.begin(), + unpacked.end()); + auto cr = detail::TransformRange{detail::ConstDereference{}, raw_v}; static_assert(std::is_same_v); static_assert(std::is_same_v); @@ -108,6 +119,13 @@ BOOST_AUTO_TEST_CASE(TransformRangeDeref) { static_assert(std::is_same_v); static_assert(std::is_same_v); checkSameAddresses(v, r); + + unpacked.clear(); + std::ranges::transform(cr, std::back_inserter(unpacked), + [](auto val) { return val; }); + + BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), unpacked.begin(), + unpacked.end()); } } @@ -127,6 +145,12 @@ BOOST_AUTO_TEST_CASE(TransformRangeDeref) { static_assert(std::is_same_v); static_assert(std::is_same_v); checkSameAddresses(v, r); + + std::vector unpacked; + std::ranges::transform(r, std::back_inserter(unpacked), + [](auto val) { return val; }); + + BOOST_CHECK(unpacked == std::vector({1, 2, 3})); } std::vector raw_v;