Warning, file /acts/Core/include/Acts/Utilities/Enumerate.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cstddef>
0012 #include <iterator>
0013 #include <ranges>
0014 #include <tuple>
0015 #include <type_traits>
0016 #include <utility>
0017
0018 namespace Acts {
0019
0020 namespace detail {
0021
0022
0023
0024
0025 template <typename T, typename = void>
0026 struct EnumerateIndexType {
0027 using type = std::size_t;
0028 };
0029 template <typename T>
0030 struct EnumerateIndexType<T,
0031 std::void_t<decltype(std::size(std::declval<T>()))>> {
0032 using type = decltype(std::size(std::declval<T>()));
0033 };
0034
0035
0036
0037
0038
0039
0040 template <typename index_type, typename iterator_t>
0041 struct EnumerateIterator {
0042 using iterator_category = std::input_iterator_tag;
0043 using value_type = std::tuple<index_type, std::iter_value_t<iterator_t>>;
0044 using reference = std::tuple<index_type, std::iter_reference_t<iterator_t>>;
0045 using pointer = void;
0046 using difference_type = std::iter_difference_t<iterator_t>;
0047
0048 index_type i;
0049 iterator_t iter;
0050
0051 bool operator==(const EnumerateIterator &rhs) const {
0052 return iter == rhs.iter;
0053 }
0054
0055
0056 EnumerateIterator &operator++() {
0057 ++i;
0058 ++iter;
0059 return *this;
0060 }
0061
0062
0063 EnumerateIterator operator++(int) {
0064 EnumerateIterator tmp = *this;
0065 ++*this;
0066 return tmp;
0067 }
0068
0069 reference operator*() const { return reference{i, *iter}; }
0070 };
0071
0072
0073
0074 template <std::ranges::range container_type, typename index_type,
0075 typename iterator_t>
0076 struct EnumerateWrapper {
0077 container_type iterable;
0078 auto begin() {
0079 return EnumerateIterator<index_type, iterator_t>{0, std::begin(iterable)};
0080 }
0081 auto end() {
0082 return EnumerateIterator<index_type, iterator_t>{0, std::end(iterable)};
0083 }
0084 };
0085
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 template <std::ranges::range container_type,
0098 typename index_type =
0099 typename detail::EnumerateIndexType<container_type>::type,
0100 typename container_type_iter =
0101 decltype(std::begin(std::declval<container_type>()))>
0102 constexpr auto enumerate(container_type &&iterable) {
0103 return detail::EnumerateWrapper<container_type, index_type,
0104 container_type_iter>{
0105 std::forward<container_type>(iterable)};
0106 }
0107
0108 }