Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:08:21

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 }  // namespace Acts