Blender V5.0
unique_ptr_vector.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include <cassert>
8
9#include "util/algorithm.h"
10#include "util/set.h"
11#include "util/unique_ptr.h"
12#include "util/vector.h"
13
15
16/* Convenient vector of unique_ptr.
17 * - Indexing and iterators return the pointer value directly.
18 * - Utility functions for erase by swapping elements, for nodes.
19 */
20template<typename T> class unique_ptr_vector {
21 protected:
23
24 public:
25 T *operator[](const size_t i) const
26 {
27 return data[i].get();
28 }
29
30 unique_ptr<T> steal(const size_t i)
31 {
32 unique_ptr<T> local;
33 swap(data[i], local);
34 return local;
35 }
36
38 {
39 data.push_back(std::move(value));
40 }
41
42 bool empty() const
43 {
44 return data.empty();
45 }
46
47 size_t size() const
48 {
49 return data.size();
50 }
51
52 void clear()
53 {
54 data.clear();
55 }
56
58 {
59 data.free_memory();
60 }
61
62 void erase(const T *value)
63 {
64 const size_t size = data.size();
65 for (size_t i = 0; i < size; i++) {
66 if (data[i].get() == value) {
67 data.erase(data.begin() + i);
68 return;
69 }
70 }
71
72 assert(0);
73 }
74
75 /* Slightly faster erase swapping with other element instead of moving many,
76 * but will change element order. */
77 void erase_by_swap(const T *value)
78 {
79 const size_t size = data.size();
80 for (size_t i = 0; i < size; i++) {
81 if (data[i].get() == value) {
82 swap(data[i], data[data.size() - 1]);
83 break;
84 }
85 }
86 data.resize(data.size() - 1);
87 }
88
89 void erase_in_set(const set<T *> &values)
90 {
91 size_t new_size = data.size();
92
93 for (size_t i = 0; i < new_size; i++) {
94 T *value = data[i].get();
95 if (values.find(value) != values.end()) {
96 swap(data[i], data[new_size - 1]);
97 i -= 1;
98 new_size -= 1;
99 }
100 }
101
102 data.resize(new_size);
103 }
104
105 /* Basic iterators for range based for loop. */
107 using iterator_category = std::random_access_iterator_tag;
108
111 using pointer = typename vector<unique_ptr<T>>::const_pointer;
113
114 typename vector<unique_ptr<T>>::const_iterator it;
115
116 const T *operator*() const
117 {
118 return it->get();
119 }
120 bool operator==(const ConstIterator &other) const
121 {
122 return it == other.it;
123 }
124 bool operator!=(const ConstIterator &other) const
125 {
126 return it != other.it;
127 }
129 {
130 ++it;
131 }
132 difference_type operator-(const ConstIterator &other) const noexcept
133 {
134 return static_cast<difference_type>(it - other.it);
135 }
136 ConstIterator operator+(const difference_type offset) const noexcept
137 {
138 ConstIterator temp = *this;
139 temp += offset;
140 return temp;
141 }
143 {
144 it += offset;
145 return *this;
146 }
147 };
148
150 {
151 return ConstIterator{data.begin()};
152 }
154 {
155 return ConstIterator{data.end()};
156 }
157
158 struct Iterator {
159 using iterator_category = std::random_access_iterator_tag;
160
163 using pointer = typename vector<unique_ptr<T>>::const_pointer;
165
166 typename vector<unique_ptr<T>>::const_iterator it;
167
168 T *operator*() const
169 {
170 return it->get();
171 }
172 bool operator==(const Iterator &other) const
173 {
174 return it == other.it;
175 }
176 bool operator!=(const Iterator &other) const
177 {
178 return it != other.it;
179 }
181 {
182 ++it;
183 }
184 difference_type operator-(const Iterator &other) const noexcept
185 {
186 return static_cast<difference_type>(it - other.it);
187 }
188 Iterator operator+(const difference_type offset) const noexcept
189 {
190 Iterator temp = *this;
191 temp += offset;
192 return temp;
193 }
194 Iterator &operator+=(const difference_type offset) noexcept
195 {
196 it += offset;
197 return *this;
198 }
199 };
201 {
202 return Iterator{data.begin()};
203 }
205 {
206 return Iterator{data.end()};
207 }
208
209 /* Cast to read-only regular vector for easier interop.
210 * Assumes unique_ptr is zero overhead. */
211 operator const vector<T *> &()
212 {
213 static_assert(sizeof(unique_ptr<T>) == sizeof(T *));
214 return reinterpret_cast<vector<T *> &>(*this);
215 }
216
217 /* For sorting unique_ptr instead of pointer. */
218 template<typename Compare> void stable_sort(Compare compare)
219 {
220 auto compare_unique_ptr = [compare](const unique_ptr<T> &a, const unique_ptr<T> &b) {
221 return compare(a.get(), b.get());
222 };
223
224 std::stable_sort(data.begin(), data.end(), compare_unique_ptr);
225 }
226};
227
ConstIterator begin() const
void push_back(unique_ptr< T > &&value)
vector< unique_ptr< T > > data
void erase(const T *value)
ConstIterator end() const
unique_ptr< T > steal(const size_t i)
T * operator[](const size_t i) const
size_t size() const
void stable_sort(Compare compare)
void erase_in_set(const set< T * > &values)
void erase_by_swap(const T *value)
#define CCL_NAMESPACE_END
#define assert(assertion)
#define T
#define swap(a, b)
Definition sort.cc:59
bool operator!=(const ConstIterator &other) const
ConstIterator & operator+=(const difference_type offset) noexcept
vector< unique_ptr< T > >::const_iterator it
typename vector< unique_ptr< T > >::const_pointer pointer
difference_type operator-(const ConstIterator &other) const noexcept
std::random_access_iterator_tag iterator_category
ConstIterator operator+(const difference_type offset) const noexcept
typename vector< unique_ptr< T > >::difference_type difference_type
typename vector< unique_ptr< T > >::reference reference
typename vector< unique_ptr< T > >::value_type value_type
bool operator==(const ConstIterator &other) const
typename vector< unique_ptr< T > >::const_pointer pointer
bool operator==(const Iterator &other) const
Iterator operator+(const difference_type offset) const noexcept
typename vector< unique_ptr< T > >::reference reference
typename vector< unique_ptr< T > >::value_type value_type
vector< unique_ptr< T > >::const_iterator it
Iterator & operator+=(const difference_type offset) noexcept
typename vector< unique_ptr< T > >::difference_type difference_type
bool operator!=(const Iterator &other) const
difference_type operator-(const Iterator &other) const noexcept
std::random_access_iterator_tag iterator_category
i
Definition text_draw.cc:230