Blender V4.5
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 typename vector<unique_ptr<T>>::const_iterator it;
108
109 const T *operator*() const
110 {
111 return it->get();
112 }
113 bool operator!=(const ConstIterator &other) const
114 {
115 return it != other.it;
116 }
118 {
119 ++it;
120 }
121 };
122
124 {
125 return ConstIterator{data.begin()};
126 }
128 {
129 return ConstIterator{data.end()};
130 }
131
132 struct Iterator {
133 typename vector<unique_ptr<T>>::const_iterator it;
134
135 T *operator*() const
136 {
137 return it->get();
138 }
139 bool operator!=(const Iterator &other) const
140 {
141 return it != other.it;
142 }
144 {
145 ++it;
146 }
147 };
149 {
150 return Iterator{data.begin()};
151 }
153 {
154 return Iterator{data.end()};
155 }
156
157 /* Cast to read-only regular vector for easier interop.
158 * Assumes unique_ptr is zero overhead. */
159 operator const vector<T *> &()
160 {
161 static_assert(sizeof(unique_ptr<T>) == sizeof(T *));
162 return reinterpret_cast<vector<T *> &>(*this);
163 }
164
165 /* For sorting unique_ptr instead of pointer. */
166 template<typename Compare> void stable_sort(Compare compare)
167 {
168 auto compare_unique_ptr = [compare](const unique_ptr<T> &a, const unique_ptr<T> &b) {
169 return compare(a.get(), b.get());
170 };
171
172 std::stable_sort(data.begin(), data.end(), compare_unique_ptr);
173 }
174};
175
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
vector< unique_ptr< T > >::const_iterator it
vector< unique_ptr< T > >::const_iterator it
bool operator!=(const Iterator &other) const
i
Definition text_draw.cc:230