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 <iterator>
9 
10 template <typename T>
12 public:
13  void addVector(const std::vector<T>& vec) {
14  vectors.emplace_back(vec.begin(), vec.end());
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  size_t size() const { return totalSize; }
43 
44  std::pair<size_t, size_t> getVectorAndLocalIndex(size_t globalIndex) const {
45  assert(globalIndex < totalSize && "Global index out of range");
46 
47  auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex);
48  size_t vectorIndex = std::distance(offsets.begin(), it) - 1;
49  size_t localIndex = globalIndex - offsets[vectorIndex];
50 
51  return {vectorIndex, localIndex};
52  }
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::vector<T>> vectors;
81  std::vector<size_t> offsets;
82  size_t totalSize = 0;
83 };
84 
85 #endif
std::vector< std::vector< T > > vectors
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
void addVector(const std::vector< T > &vec)
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
Iterator begin() const
long double T
size_t getGlobalIndex(size_t vectorIndex, size_t localIndex) const