barretenberg
Loading...
Searching...
No Matches
ref_vector.hpp
1#pragma once
2#include "barretenberg/common/assert.hpp"
3#include <cstddef>
4#include <initializer_list>
5#include <iterator>
6#include <stdexcept>
7#include <vector>
8
9// TODO(https://github.com/AztecProtocol/barretenberg/issues/794) namespace this once convenient
20template <typename T> class RefVector {
21 public:
22 RefVector() = default;
23 explicit RefVector(const std::vector<T*>& ptr_vector)
24 : storage(ptr_vector)
25 {}
26
27 explicit RefVector(std::vector<T>& vector)
28 : storage(vector.size())
29 {
30 for (size_t i = 0; i < vector.size(); i++) {
31 storage[i] = &vector[i];
32 }
33 }
34
35 template <typename... Ts> RefVector(T& ref, Ts&... rest)
36 {
37 storage.push_back(&ref);
38 (storage.push_back(&rest), ...);
39 }
40
41 T& operator[](std::size_t idx) const
42 {
43 ASSERT(idx < storage.size());
44 return *storage[idx];
45 }
46
51 class iterator {
52 public:
59 iterator(RefVector const* vector, std::size_t pos)
60 : vector(vector)
61 , pos(pos)
62 {}
63
64 T& operator*() const { return (*vector)[pos]; }
65
66 iterator& operator++()
67 {
68 pos++;
69 return *this;
70 }
71
72 iterator operator++(int)
73 {
74 iterator temp = *this;
75 ++(*this);
76 return temp;
77 }
78
79 bool operator==(iterator const& other) const { return pos == other.pos; }
80 bool operator!=(iterator const& other) const { return pos != other.pos; }
81
82 private:
83 RefVector const* vector;
84 std::size_t pos;
85 };
86
87 std::size_t size() const { return storage.size(); }
88
89 void push_back(T& element) { storage.push_back(element); }
90 iterator begin() const { return iterator(this, 0); }
91 iterator end() const { return iterator(this, storage.size()); }
92
93 template <typename ConvertibleFromT> operator std::vector<ConvertibleFromT>() const
94 {
95 std::vector<ConvertibleFromT> ret;
96 for (T* elem : storage) {
97 ret.push_back(*elem);
98 }
99 return ret;
100 }
101
102 std::vector<T*>& get_storage() { return storage; }
103 const std::vector<T*>& get_storage() const { return storage; }
104
105 private:
106 std::vector<T*> storage;
107};
108
113template <typename T, typename... Ts> RefVector(T&, Ts&...) -> RefVector<T>;
114
125template <typename T> RefVector<T> concatenate(const RefVector<T>& ref_vector, const auto&... ref_vectors)
126{
127 RefVector<T> concatenated;
128 // Reserve our final space
129 concatenated.get_storage().reserve(ref_vector.size() + (ref_vectors.size() + ...));
130
131 auto append = [&](const auto& vec) {
132 std::copy(vec.get_storage().begin(), vec.get_storage().end(), std::back_inserter(concatenated.get_storage()));
133 };
134
135 append(ref_vector);
136 // Unpack and append each RefVector's elements to concatenated
137 (append(ref_vectors), ...);
138
139 return concatenated;
140}
141
142/* @details Ensures a nested vector holds reference objects */
143template <typename T> static std::vector<RefVector<T>> to_vector_of_ref_vectors(std::vector<std::vector<T>>& vec)
144{
145 std::vector<RefVector<T>> result;
146 for (std::vector<T>& inner : vec) {
147 result.push_back(RefVector{ inner });
148 }
149 return result;
150}
Nested iterator class for RefVector, based on indexing into the pointer vector. Provides semantics si...
Definition: ref_vector.hpp:51
iterator(RefVector const *vector, std::size_t pos)
Constructs an iterator for a given RefVector object.
Definition: ref_vector.hpp:59
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
Definition: ref_vector.hpp:20