File indexing completed on 2025-11-04 09:21:57
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 #pragma once
0010 
0011 #include "Acts/Utilities/GridIterator.hpp"
0012 
0013 #include <numeric>
0014 #include <stdexcept>
0015 
0016 namespace Acts {
0017 
0018 
0019 template <typename T, class... Axes>
0020 GridGlobalIterator<T, Axes...>::GridGlobalIterator(const Grid<T, Axes...>& grid,
0021                                                    std::size_t idx)
0022     : m_grid(&grid), m_idx(idx) {}
0023 
0024 template <typename T, class... Axes>
0025 GridGlobalIterator<T, Axes...>::GridGlobalIterator(
0026     GridGlobalIterator<T, Axes...>&& other) noexcept
0027     : m_grid(std::exchange(other.m_grid.ptr, nullptr)), m_idx(other.m_idx) {}
0028 
0029 template <typename T, class... Axes>
0030 GridGlobalIterator<T, Axes...>& GridGlobalIterator<T, Axes...>::operator=(
0031     GridGlobalIterator<T, Axes...>&& other) noexcept {
0032   m_grid.ptr = std::exchange(other.m_grid.ptr, nullptr);
0033   m_idx = other.m_idx;
0034   return *this;
0035 }
0036 
0037 template <typename T, class... Axes>
0038 bool GridGlobalIterator<T, Axes...>::operator==(
0039     const GridGlobalIterator<T, Axes...>& other) const {
0040   
0041   
0042   
0043   
0044   return (m_grid.ptr == other.m_grid.ptr) && m_idx == other.m_idx;
0045 }
0046 
0047 template <typename T, class... Axes>
0048 auto GridGlobalIterator<T, Axes...>::operator<=>(
0049     const GridGlobalIterator<T, Axes...>& other) const {
0050   
0051   
0052   assert(m_grid.ptr == other.m_grid.ptr);
0053   return m_idx <=> other.m_idx;
0054 }
0055 
0056 template <typename T, class... Axes>
0057 GridGlobalIterator<T, Axes...>& GridGlobalIterator<T, Axes...>::operator+=(
0058     const std::size_t offset) {
0059   m_idx += offset;
0060   return *this;
0061 }
0062 
0063 template <typename T, class... Axes>
0064 GridGlobalIterator<T, Axes...>& GridGlobalIterator<T, Axes...>::operator-=(
0065     const std::size_t offset) {
0066   m_idx -= offset;
0067   return *this;
0068 }
0069 
0070 template <typename T, class... Axes>
0071 GridGlobalIterator<T, Axes...> GridGlobalIterator<T, Axes...>::operator+(
0072     const std::size_t offset) const {
0073   return GridGlobalIterator<T, Axes...>(*m_grid, m_idx + offset);
0074 }
0075 
0076 template <typename T, class... Axes>
0077 GridGlobalIterator<T, Axes...> GridGlobalIterator<T, Axes...>::operator-(
0078     const std::size_t offset) const {
0079   return GridGlobalIterator<T, Axes...>(*m_grid, m_idx - offset);
0080 }
0081 
0082 template <typename T, class... Axes>
0083 typename GridGlobalIterator<T, Axes...>::difference_type
0084 GridGlobalIterator<T, Axes...>::operator-(
0085     const GridGlobalIterator<T, Axes...>& other) const {
0086   assert(m_grid.ptr == other.m_grid.ptr);
0087   assert(other <= *this);
0088   return m_idx - other.m_idx;
0089 }
0090 
0091 template <typename T, class... Axes>
0092 const typename GridGlobalIterator<T, Axes...>::value_type&
0093 GridGlobalIterator<T, Axes...>::operator*() const {
0094   return m_grid->at(m_idx);
0095 }
0096 
0097 template <typename T, class... Axes>
0098 GridGlobalIterator<T, Axes...>& GridGlobalIterator<T, Axes...>::operator++() {
0099   ++m_idx;
0100   return *this;
0101 }
0102 
0103 template <typename T, class... Axes>
0104 GridGlobalIterator<T, Axes...> GridGlobalIterator<T, Axes...>::operator++(int) {
0105   GridGlobalIterator<T, Axes...> output(*m_grid, m_idx++);
0106   return output;
0107 }
0108 
0109 template <typename T, class... Axes>
0110 std::size_t GridGlobalIterator<T, Axes...>::globalBinIndex() const {
0111   return m_idx;
0112 }
0113 
0114 template <typename T, class... Axes>
0115 std::array<std::size_t, GridGlobalIterator<T, Axes...>::DIM>
0116 GridGlobalIterator<T, Axes...>::localBinsIndices() const {
0117   return m_grid->localBinsFromGlobalBin(m_idx);
0118 }
0119 
0120 
0121 template <typename T, class... Axes>
0122 GridLocalIterator<T, Axes...>::GridLocalIterator(
0123     const Grid<T, Axes...>& grid, const std::array<std::size_t, DIM>& indices)
0124     : m_grid(&grid),
0125       m_numLocalBins(grid.numLocalBins()),
0126       m_currentIndex(indices) {
0127   
0128   
0129   
0130   for (std::size_t i(0); i < DIM; ++i) {
0131     m_navigationIndex[i].resize(m_numLocalBins[i]);
0132     std::iota(m_navigationIndex[i].begin(), m_navigationIndex[i].end(), 1ul);
0133   }
0134 }
0135 
0136 template <typename T, class... Axes>
0137 GridLocalIterator<T, Axes...>::GridLocalIterator(
0138     const Grid<T, Axes...>& grid, const std::array<std::size_t, DIM>& indices,
0139     std::array<std::vector<std::size_t>, DIM> navigation)
0140     : m_grid(&grid),
0141       m_numLocalBins(grid.numLocalBins()),
0142       m_currentIndex(indices),
0143       m_navigationIndex(std::move(navigation)) {
0144   
0145   
0146   
0147   
0148   for (std::size_t i(0ul); i < DIM; ++i) {
0149     
0150     if (m_navigationIndex[i].size() == 0) {
0151       throw std::invalid_argument(
0152           "Invalid navigation sequence in local grid iterator. No bins "
0153           "specified.");
0154     }
0155     
0156     if (m_navigationIndex[i].size() > m_numLocalBins[i]) {
0157       throw std::invalid_argument(
0158           "Invalid navigation sequence in local grid iterator. Too many bins "
0159           "specified.");
0160     }
0161     m_numLocalBins[i] = m_navigationIndex[i].size();
0162   }
0163 }
0164 
0165 template <typename T, class... Axes>
0166 GridLocalIterator<T, Axes...>::GridLocalIterator(
0167     GridLocalIterator<T, Axes...>&& other) noexcept
0168     : m_grid(std::exchange(other.m_grid.ptr, nullptr)),
0169       m_numLocalBins(other.m_numLocalBins),
0170       m_currentIndex(other.m_currentIndex),
0171       m_navigationIndex(std::move(other.m_navigationIndex)) {}
0172 
0173 template <typename T, class... Axes>
0174 GridLocalIterator<T, Axes...>& GridLocalIterator<T, Axes...>::operator=(
0175     GridLocalIterator<T, Axes...>&& other) noexcept {
0176   m_grid.ptr = std::exchange(other.m_grid.ptr, nullptr);
0177   m_numLocalBins = other.m_numLocalBins;
0178   m_currentIndex = other.m_currentIndex;
0179   m_navigationIndex = std::move(other.m_navigationIndex);
0180   return *this;
0181 }
0182 
0183 template <typename T, class... Axes>
0184 bool GridLocalIterator<T, Axes...>::operator==(
0185     const GridLocalIterator<T, Axes...>& other) const {
0186   
0187   
0188   
0189   
0190   if (m_grid.ptr != other.m_grid.ptr) {
0191     return false;
0192   }
0193 
0194   for (std::size_t i(0); i < DIM; ++i) {
0195     if (m_currentIndex[i] != other.m_currentIndex[i]) {
0196       return false;
0197     }
0198   }
0199 
0200   return true;
0201 }
0202 
0203 template <typename T, class... Axes>
0204 const typename GridLocalIterator<T, Axes...>::value_type&
0205 GridLocalIterator<T, Axes...>::operator*() const {
0206   std::array<std::size_t, DIM> localPositionBin{};
0207   for (std::size_t i(0); i < DIM; ++i) {
0208     localPositionBin[i] = m_navigationIndex[i][m_currentIndex[i]];
0209   }
0210   return m_grid->atLocalBins(localPositionBin);
0211 }
0212 
0213 template <typename T, class... Axes>
0214 GridLocalIterator<T, Axes...>& GridLocalIterator<T, Axes...>::operator++() {
0215   increment<DIM - 1>();
0216   return *this;
0217 }
0218 
0219 template <typename T, class... Axes>
0220 GridLocalIterator<T, Axes...> GridLocalIterator<T, Axes...>::operator++(int) {
0221   GridLocalIterator<T, Axes...> output(*this);
0222   this->operator++();
0223   return output;
0224 }
0225 
0226 template <typename T, class... Axes>
0227 template <std::size_t N>
0228 void GridLocalIterator<T, Axes...>::increment() {
0229   
0230   
0231   if (++m_currentIndex[N] < m_numLocalBins[N]) {
0232     return;
0233   }
0234   
0235   
0236   if constexpr (N != 0) {
0237     m_currentIndex[N] = 0;
0238     increment<N - 1>();
0239   } else {
0240     m_currentIndex = m_numLocalBins;
0241   }
0242 }
0243 
0244 template <typename T, class... Axes>
0245 std::size_t GridLocalIterator<T, Axes...>::globalBinIndex() const {
0246   return m_grid->globalBinFromLocalBins(localBinsIndices());
0247 }
0248 
0249 template <typename T, class... Axes>
0250 std::array<std::size_t, GridLocalIterator<T, Axes...>::DIM>
0251 GridLocalIterator<T, Axes...>::localBinsIndices() const {
0252   std::array<std::size_t, DIM> output{};
0253   for (std::size_t i(0); i < DIM; ++i) {
0254     output[i] = m_navigationIndex[i][m_currentIndex[i]];
0255   }
0256   return output;
0257 }
0258 
0259 }