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 <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 }  // namespace Acts