File indexing completed on 2025-08-05 08:08:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Utilities/ContainerConcepts.hpp"
0012 #include "Acts/Utilities/TypeTraits.hpp"
0013
0014 #include <span>
0015
0016 namespace Acts {
0017
0018 template <typename Container, typename Value, typename Index, bool ReadOnly>
0019 class ContainerSubset {
0020 public:
0021 using container_type = const_if_t<ReadOnly, Container>;
0022 using value_type = Value;
0023 using index_type = Index;
0024 static constexpr bool read_only = ReadOnly;
0025 using index_subset_type = std::span<const index_type>;
0026
0027 class Iterator {
0028 public:
0029 using subset_iterator = index_subset_type::iterator;
0030
0031 using value_type = Value;
0032 using difference_type = std::ptrdiff_t;
0033 using pointer = void;
0034 using reference = void;
0035
0036 using iterator_category = std::random_access_iterator_tag;
0037 using iterator_concept = std::random_access_iterator_tag;
0038
0039 constexpr Iterator() noexcept = default;
0040 constexpr Iterator(container_type &container,
0041 subset_iterator iterator) noexcept
0042 : m_container(&container), m_iterator(iterator) {}
0043
0044 constexpr value_type operator*() const {
0045 static_assert(
0046 ContainerHasAt<Container> || ContainerHasArrayAccess<Container>,
0047 "Container must support at() or operator[] for indexing");
0048 constexpr bool HasArrayAccess = ContainerHasArrayAccess<Container>;
0049
0050 if constexpr (HasArrayAccess) {
0051 return (*m_container)[*m_iterator];
0052 } else {
0053 return m_container->at(*m_iterator);
0054 }
0055 }
0056 constexpr value_type operator[](difference_type n) const {
0057 static_assert(
0058 ContainerHasAt<Container> || ContainerHasArrayAccess<Container>,
0059 "Container must support at() or operator[] for indexing");
0060 constexpr bool HasArrayAccess = ContainerHasArrayAccess<Container>;
0061
0062 if constexpr (HasArrayAccess) {
0063 return (*m_container)[m_iterator[n]];
0064 } else {
0065 return m_container->at(m_iterator[n]);
0066 }
0067 }
0068
0069 constexpr Iterator &operator++() noexcept {
0070 ++m_iterator;
0071 return *this;
0072 }
0073 constexpr Iterator operator++(int) noexcept {
0074 auto tmp = *this;
0075 ++(*this);
0076 return tmp;
0077 }
0078 constexpr Iterator &operator--() noexcept {
0079 --m_iterator;
0080 return *this;
0081 }
0082 constexpr Iterator operator--(int) noexcept {
0083 auto tmp = *this;
0084 --(*this);
0085 return tmp;
0086 }
0087
0088 constexpr Iterator &operator+=(difference_type n) noexcept {
0089 m_iterator += n;
0090 return *this;
0091 }
0092 constexpr Iterator &operator-=(difference_type n) noexcept {
0093 m_iterator -= n;
0094 return *this;
0095 }
0096
0097 private:
0098 container_type *m_container{};
0099 subset_iterator m_iterator{};
0100
0101 friend constexpr Iterator operator+(Iterator it,
0102 difference_type n) noexcept {
0103 return it += n;
0104 }
0105
0106 friend constexpr Iterator operator+(difference_type n,
0107 Iterator it) noexcept {
0108 return it += n;
0109 }
0110
0111 friend constexpr Iterator operator-(Iterator it,
0112 difference_type n) noexcept {
0113 return it -= n;
0114 }
0115
0116 friend constexpr difference_type operator-(const Iterator &lhs,
0117 const Iterator &rhs) noexcept {
0118 return lhs.m_iterator - rhs.m_iterator;
0119 }
0120
0121 friend constexpr auto operator<=>(const Iterator &a,
0122 const Iterator &b) noexcept {
0123 if (a.m_iterator < b.m_iterator) {
0124 return std::strong_ordering::less;
0125 }
0126 if (a.m_iterator > b.m_iterator) {
0127 return std::strong_ordering::greater;
0128 }
0129 return std::strong_ordering::equal;
0130 }
0131 friend constexpr bool operator==(const Iterator &a,
0132 const Iterator &b) noexcept {
0133 return a.m_iterator == b.m_iterator;
0134 }
0135 };
0136 using iterator = Iterator;
0137
0138 constexpr ContainerSubset(container_type &container,
0139 const index_subset_type &subset) noexcept
0140 : m_container(&container), m_subset(subset) {}
0141 template <bool OtherReadOnly>
0142 explicit constexpr ContainerSubset(
0143 const ContainerSubset<Container, Value, Index, OtherReadOnly>
0144 &other) noexcept
0145 requires(ReadOnly && !OtherReadOnly)
0146 : m_container(&other.container()), m_subset(other.subset()) {}
0147
0148 constexpr ContainerSubset<Container, Value, Index, true> asConst()
0149 const noexcept
0150 requires(!ReadOnly)
0151 {
0152 return {*m_container, m_subset};
0153 }
0154
0155 constexpr container_type &container() const noexcept { return *m_container; }
0156 constexpr const index_subset_type &subset() const noexcept {
0157 return m_subset;
0158 }
0159
0160 constexpr std::size_t size() const noexcept { return m_subset.size(); }
0161 constexpr bool empty() const noexcept { return size() == 0; }
0162
0163 constexpr auto front() const noexcept {
0164 return container()[m_subset.front()];
0165 }
0166 constexpr auto back() const noexcept { return container()[m_subset.back()]; }
0167
0168 constexpr iterator begin() const noexcept {
0169 return iterator(*m_container, m_subset.begin());
0170 }
0171 constexpr iterator end() const noexcept {
0172 return iterator(*m_container, m_subset.end());
0173 }
0174
0175 private:
0176 container_type *m_container{};
0177 index_subset_type m_subset{};
0178 };
0179
0180 }