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 <cstddef>
0015 #include <iterator>
0016
0017 namespace Acts {
0018
0019 template <typename Container, typename Value, typename Index, bool ReadOnly>
0020 class ContainerIterator {
0021 public:
0022 using container_type = const_if_t<ReadOnly, Container>;
0023 using index_type = Index;
0024 static constexpr bool read_only = ReadOnly;
0025
0026 using value_type = Value;
0027 using difference_type = std::ptrdiff_t;
0028 using pointer = void;
0029 using reference = void;
0030
0031 using iterator_category = std::random_access_iterator_tag;
0032 using iterator_concept = std::random_access_iterator_tag;
0033
0034 constexpr ContainerIterator() noexcept = default;
0035 constexpr ContainerIterator(container_type &container,
0036 index_type index) noexcept
0037 : m_container(&container), m_index(index) {}
0038 template <bool OtherReadOnly>
0039 explicit constexpr ContainerIterator(
0040 const ContainerIterator<Container, Value, Index, OtherReadOnly>
0041 &other) noexcept
0042 requires(ReadOnly && !OtherReadOnly)
0043 : m_container(&other.container()), m_index(other.index()) {}
0044
0045 constexpr ContainerIterator<Container, Value, Index, true> asConst()
0046 const noexcept
0047 requires(!ReadOnly)
0048 {
0049 return {*m_container, m_index};
0050 }
0051
0052 constexpr container_type &container() const noexcept { return *m_container; }
0053 constexpr index_type index() const noexcept { return m_index; }
0054
0055 constexpr value_type operator*() const {
0056 static_assert(
0057 ContainerHasAt<Container> || ContainerHasArrayAccess<Container>,
0058 "Container must support at() or operator[] for indexing");
0059 constexpr bool HasArrayAccess = ContainerHasArrayAccess<Container>;
0060
0061 if constexpr (HasArrayAccess) {
0062 return (*m_container)[m_index];
0063 } else {
0064 return m_container->at(m_index);
0065 }
0066 }
0067 constexpr value_type operator[](difference_type n) const {
0068 static_assert(
0069 ContainerHasAt<Container> || ContainerHasArrayAccess<Container>,
0070 "Container must support at() or operator[] for indexing");
0071 constexpr bool HasArrayAccess = ContainerHasArrayAccess<Container>;
0072
0073 if constexpr (HasArrayAccess) {
0074 return (*m_container)[m_index + n];
0075 } else {
0076 return m_container->at(m_index + n);
0077 }
0078 }
0079
0080 constexpr ContainerIterator &operator++() noexcept {
0081 ++m_index;
0082 return *this;
0083 }
0084 constexpr ContainerIterator operator++(int) noexcept {
0085 auto tmp = *this;
0086 ++(*this);
0087 return tmp;
0088 }
0089 constexpr ContainerIterator &operator--() noexcept {
0090 --m_index;
0091 return *this;
0092 }
0093 constexpr ContainerIterator operator--(int) noexcept {
0094 auto tmp = *this;
0095 --(*this);
0096 return tmp;
0097 }
0098
0099 constexpr ContainerIterator &operator+=(difference_type n) noexcept {
0100 m_index += n;
0101 return *this;
0102 }
0103 constexpr ContainerIterator &operator-=(difference_type n) noexcept {
0104 m_index -= n;
0105 return *this;
0106 }
0107
0108 private:
0109 container_type *m_container{};
0110 index_type m_index{};
0111
0112 friend constexpr ContainerIterator operator+(ContainerIterator it,
0113 difference_type n) noexcept {
0114 return it += n;
0115 }
0116
0117 friend constexpr ContainerIterator operator+(difference_type n,
0118 ContainerIterator it) noexcept {
0119 return it += n;
0120 }
0121
0122 friend constexpr ContainerIterator operator-(ContainerIterator it,
0123 difference_type n) noexcept {
0124 return it -= n;
0125 }
0126
0127 friend constexpr difference_type operator-(
0128 const ContainerIterator &lhs, const ContainerIterator &rhs) noexcept {
0129 return lhs.m_index - rhs.m_index;
0130 }
0131
0132 friend constexpr auto operator<=>(const ContainerIterator &a,
0133 const ContainerIterator &b) noexcept {
0134 return a.m_index <=> b.m_index;
0135 }
0136 friend constexpr bool operator==(const ContainerIterator &a,
0137 const ContainerIterator &b) noexcept {
0138 return a.m_index == b.m_index;
0139 }
0140 };
0141
0142 }