CMS 3D CMS Logo

MultiVectorManager.h
Go to the documentation of this file.
1 // Author: Felice Pantaleo (CERN), 2023, felice.pantaleo@cern.ch
2 #ifndef MultiVectorManager_h
3 #define MultiVectorManager_h
4 
5 #include <vector>
6 #include <cassert>
7 #include <algorithm>
8 #include <span>
9 
10 template <typename T>
12 public:
13  void addVector(std::span<const T> vec) {
14  vectors.emplace_back(vec);
15  offsets.push_back(totalSize);
16  totalSize += vec.size();
17  }
18 
19  T& operator[](size_t globalIndex) {
20  return const_cast<T&>(static_cast<const MultiVectorManager*>(this)->operator[](globalIndex));
21  }
22 
23  const T& operator[](size_t globalIndex) const {
24  assert(globalIndex < totalSize && "Global index out of range");
25 
26  auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex);
27  size_t vectorIndex = std::distance(offsets.begin(), it) - 1;
28  size_t localIndex = globalIndex - offsets[vectorIndex];
29 
30  return vectors[vectorIndex][localIndex];
31  }
32 
33  size_t getGlobalIndex(size_t vectorIndex, size_t localIndex) const {
34  assert(vectorIndex < vectors.size() && "Vector index out of range");
35 
36  const auto& vec = vectors[vectorIndex];
37  assert(localIndex < vec.size() && "Local index out of range");
38 
39  return offsets[vectorIndex] + localIndex;
40  }
41 
42  std::pair<size_t, size_t> getVectorAndLocalIndex(size_t globalIndex) const {
43  assert(globalIndex < totalSize && "Global index out of range");
44 
45  auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex);
46  size_t vectorIndex = std::distance(offsets.begin(), it) - 1;
47  size_t localIndex = globalIndex - offsets[vectorIndex];
48 
49  return {vectorIndex, localIndex};
50  }
51 
52  size_t size() const { return totalSize; }
53 
54  class Iterator {
55  public:
56  using iterator_category = std::forward_iterator_tag;
57  using difference_type = std::ptrdiff_t;
58  using value_type = T;
59  using pointer = T*;
60  using reference = T&;
61 
63 
64  bool operator!=(const Iterator& other) const { return currentIndex != other.currentIndex; }
65 
66  T& operator*() const { return const_cast<T&>(manager[currentIndex]); }
67 
68  void operator++() { ++currentIndex; }
69 
70  private:
72  size_t currentIndex;
73  };
74 
75  Iterator begin() const { return Iterator(*this, 0); }
76 
77  Iterator end() const { return Iterator(*this, totalSize); }
78 
79 private:
80  std::vector<std::span<const T>> vectors;
81  std::vector<size_t> offsets;
82  size_t totalSize = 0;
83 };
84 
85 #endif
Iterator(const MultiVectorManager &manager, size_t index)
std::pair< size_t, size_t > getVectorAndLocalIndex(size_t globalIndex) const
assert(be >=bs)
Iterator end() const
bool operator!=(const Iterator &other) const
TGeoIterator Iterator
T & operator[](size_t globalIndex)
const T & operator[](size_t globalIndex) const
std::vector< size_t > offsets
std::forward_iterator_tag iterator_category
const MultiVectorManager & manager
void addVector(std::span< const T > vec)
Iterator begin() const
std::vector< std::span< const T > > vectors
long double T
size_t getGlobalIndex(size_t vectorIndex, size_t localIndex) const