Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Core/include/Acts/Utilities/Ranges.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// 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/.

#pragma once

#include <ranges>

namespace Acts::Ranges {

/// Adaptor for converting a range to a container
/// @tparam Container the container type to convert to
template <template <typename...> class Container>
struct to_adaptor {
/// Convert a range to a container
/// @tparam Range the range type to convert
/// @param range the range to convert
/// @return the converted container
template <typename Range>
auto operator()(Range&& range) const {
using ValueType = std::ranges::range_value_t<Range>;
return Container<ValueType>(std::ranges::begin(range),
std::ranges::end(range));
}
};

/// Overload operator| for piping
/// @tparam Range the range type to convert
/// @tparam Container the container type to convert to
/// @param range the range to convert
/// @param adaptor the adaptor to use
/// @return the converted container
template <typename Range, template <typename...> class Container>
auto operator|(Range&& range, to_adaptor<Container> adaptor) {
return adaptor(std::forward<Range>(range));
}

/// Create the adaptor objects
/// @tparam Container the container type to convert to
/// @return the adaptor object
template <template <typename...> class Container>
inline constexpr to_adaptor<Container> to{};

} // namespace Acts::Ranges
1 change: 1 addition & 0 deletions Tests/UnitTests/Core/Utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ add_unittest(TypeDispatcher TypeDispatcherTests.cpp)
add_unittest(Histogram HistogramTests.cpp)
add_unittest(ProfileEfficiency ProfileEfficiencyTests.cpp)
add_unittest(ContainerHelpers ContainerHelpersTests.cpp)
add_unittest(Ranges RangesTests.cpp)
59 changes: 59 additions & 0 deletions Tests/UnitTests/Core/Utilities/RangesTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// 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 <boost/test/unit_test.hpp>

#include "Acts/Utilities/Ranges.hpp"

#include <array>
#include <ranges>
#include <set>
#include <vector>

namespace ActsTests {

BOOST_AUTO_TEST_SUITE(RangesTests)

BOOST_AUTO_TEST_CASE(ToVectorFromView) {
std::array<int, 6> values = {1, 2, 3, 4, 5, 6};

auto evenTimesTen =
values | std::views::filter([](int value) { return value % 2 == 0; }) |
std::views::transform([](int value) { return value * 10; });

auto result = evenTimesTen | Acts::Ranges::to<std::vector>;

std::vector<int> expected = {20, 40, 60};
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
result.begin(), result.end());
}

BOOST_AUTO_TEST_CASE(ToSetRemovesDuplicatesAndOrders) {
std::vector<int> values = {4, 1, 4, 3, 2, 2};

auto result = values | Acts::Ranges::to<std::set>;

std::set<int> expected = {1, 2, 3, 4};
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
result.begin(), result.end());
}

BOOST_AUTO_TEST_CASE(ToAdaptorCallableSyntax) {
std::vector<int> values = {5, 6, 7};

auto adaptor = Acts::Ranges::to_adaptor<std::vector>{};
auto result = adaptor(values);

std::vector<int> expected = {5, 6, 7};
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
result.begin(), result.end());
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace ActsTests
Loading