File indexing completed on 2024-10-16 05:03:39
0001
0002 #ifndef MultiVectorManager_h
0003 #define MultiVectorManager_h
0004
0005 #include <vector>
0006 #include <cassert>
0007 #include <algorithm>
0008 #include <span>
0009
0010 template <typename T>
0011 class MultiVectorManager {
0012 public:
0013 void addVector(std::span<const T> vec) {
0014 vectors.emplace_back(vec);
0015 offsets.push_back(totalSize);
0016 totalSize += vec.size();
0017 }
0018
0019 T& operator[](size_t globalIndex) {
0020 return const_cast<T&>(static_cast<const MultiVectorManager*>(this)->operator[](globalIndex));
0021 }
0022
0023 const T& operator[](size_t globalIndex) const {
0024 assert(globalIndex < totalSize && "Global index out of range");
0025
0026 auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex);
0027 size_t vectorIndex = std::distance(offsets.begin(), it) - 1;
0028 size_t localIndex = globalIndex - offsets[vectorIndex];
0029
0030 return vectors[vectorIndex][localIndex];
0031 }
0032
0033 size_t getGlobalIndex(size_t vectorIndex, size_t localIndex) const {
0034 assert(vectorIndex < vectors.size() && "Vector index out of range");
0035
0036 const auto& vec = vectors[vectorIndex];
0037 assert(localIndex < vec.size() && "Local index out of range");
0038
0039 return offsets[vectorIndex] + localIndex;
0040 }
0041
0042 std::pair<size_t, size_t> getVectorAndLocalIndex(size_t globalIndex) const {
0043 assert(globalIndex < totalSize && "Global index out of range");
0044
0045 auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex);
0046 size_t vectorIndex = std::distance(offsets.begin(), it) - 1;
0047 size_t localIndex = globalIndex - offsets[vectorIndex];
0048
0049 return {vectorIndex, localIndex};
0050 }
0051
0052 size_t size() const { return totalSize; }
0053
0054 class Iterator {
0055 public:
0056 using iterator_category = std::forward_iterator_tag;
0057 using difference_type = std::ptrdiff_t;
0058 using value_type = T;
0059 using pointer = T*;
0060 using reference = T&;
0061
0062 Iterator(const MultiVectorManager& manager, size_t index) : manager(manager), currentIndex(index) {}
0063
0064 bool operator!=(const Iterator& other) const { return currentIndex != other.currentIndex; }
0065
0066 T& operator*() const { return const_cast<T&>(manager[currentIndex]); }
0067
0068 void operator++() { ++currentIndex; }
0069
0070 private:
0071 const MultiVectorManager& manager;
0072 size_t currentIndex;
0073 };
0074
0075 Iterator begin() const { return Iterator(*this, 0); }
0076
0077 Iterator end() const { return Iterator(*this, totalSize); }
0078
0079 private:
0080 std::vector<std::span<const T>> vectors;
0081 std::vector<size_t> offsets;
0082 size_t totalSize = 0;
0083 };
0084
0085 #endif