Blender V4.3
BLI_map_slots.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
25#include "BLI_memory_utils.hh"
26
27namespace blender {
28
29template<typename Src1, typename Src2, typename Dst1, typename Dst2>
30void initialize_pointer_pair(Src1 &&src1, Src2 &&src2, Dst1 *dst1, Dst2 *dst2)
31{
32 new ((void *)dst1) Dst1(std::forward<Src1>(src1));
33 try {
34 new ((void *)dst2) Dst2(std::forward<Src2>(src2));
35 }
36 catch (...) {
37 dst1->~Dst1();
38 throw;
39 }
40}
41
47template<typename Key, typename Value> class SimpleMapSlot {
48 private:
49 enum State : uint8_t {
50 Empty = 0,
51 Occupied = 1,
52 Removed = 2,
53 };
54
55 State state_;
56 TypedBuffer<Key> key_buffer_;
57 TypedBuffer<Value> value_buffer_;
58
59 public:
64 {
65 state_ = Empty;
66 }
67
72 {
73 if (state_ == Occupied) {
74 key_buffer_.ref().~Key();
75 value_buffer_.ref().~Value();
76 }
77 }
78
84 {
85 state_ = other.state_;
86 if (other.state_ == Occupied) {
87 initialize_pointer_pair(other.key_buffer_.ref(),
88 other.value_buffer_.ref(),
89 key_buffer_.ptr(),
90 value_buffer_.ptr());
91 }
92 }
93
99 SimpleMapSlot(SimpleMapSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key> &&
100 std::is_nothrow_move_constructible_v<Value>)
101 {
102 state_ = other.state_;
103 if (other.state_ == Occupied) {
104 initialize_pointer_pair(std::move(other.key_buffer_.ref()),
105 std::move(other.value_buffer_.ref()),
106 key_buffer_.ptr(),
107 value_buffer_.ptr());
108 }
109 }
110
115 {
116 return key_buffer_;
117 }
118
122 const Key *key() const
123 {
124 return key_buffer_;
125 }
126
130 Value *value()
131 {
132 return value_buffer_;
133 }
134
138 const Value *value() const
139 {
140 return value_buffer_;
141 }
142
146 bool is_occupied() const
147 {
148 return state_ == Occupied;
149 }
150
154 bool is_empty() const
155 {
156 return state_ == Empty;
157 }
158
163 template<typename Hash> uint64_t get_hash(const Hash &hash)
164 {
165 BLI_assert(this->is_occupied());
166 return hash(*key_buffer_);
167 }
168
173 template<typename ForwardKey, typename IsEqual>
174 bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
175 {
176 if (state_ == Occupied) {
177 return is_equal(key, *key_buffer_);
178 }
179 return false;
180 }
181
186 template<typename ForwardKey, typename... ForwardValue>
187 void occupy(ForwardKey &&key, uint64_t hash, ForwardValue &&...value)
188 {
189 BLI_assert(!this->is_occupied());
190 new (&value_buffer_) Value(std::forward<ForwardValue>(value)...);
191 this->occupy_no_value(std::forward<ForwardKey>(key), hash);
192 state_ = Occupied;
193 }
194
199 template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t /*hash*/)
200 {
201 BLI_assert(!this->is_occupied());
202 try {
203 new (&key_buffer_) Key(std::forward<ForwardKey>(key));
204 }
205 catch (...) {
206 /* The value is assumed to be constructed already, so it has to be destructed as well. */
207 value_buffer_.ref().~Value();
208 throw;
209 }
210 state_ = Occupied;
211 }
212
217 void remove()
218 {
219 BLI_assert(this->is_occupied());
220 key_buffer_.ref().~Key();
221 value_buffer_.ref().~Value();
222 state_ = Removed;
223 }
224};
225
234template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot {
235 private:
236 Key key_ = KeyInfo::get_empty();
237 TypedBuffer<Value> value_buffer_;
238
239 public:
240 IntrusiveMapSlot() = default;
241
243 {
244 if (KeyInfo::is_not_empty_or_removed(key_)) {
245 value_buffer_.ref().~Value();
246 }
247 }
248
249 IntrusiveMapSlot(const IntrusiveMapSlot &other) : key_(other.key_)
250 {
251 if (KeyInfo::is_not_empty_or_removed(key_)) {
252 new (&value_buffer_) Value(*other.value_buffer_);
253 }
254 }
255
256 IntrusiveMapSlot(IntrusiveMapSlot &&other) noexcept : key_(other.key_)
257 {
258 if (KeyInfo::is_not_empty_or_removed(key_)) {
259 new (&value_buffer_) Value(std::move(*other.value_buffer_));
260 }
261 }
262
264 {
265 return &key_;
266 }
267
268 const Key *key() const
269 {
270 return &key_;
271 }
272
273 Value *value()
274 {
275 return value_buffer_;
276 }
277
278 const Value *value() const
279 {
280 return value_buffer_;
281 }
282
283 bool is_occupied() const
284 {
285 return KeyInfo::is_not_empty_or_removed(key_);
286 }
287
288 bool is_empty() const
289 {
290 return KeyInfo::is_empty(key_);
291 }
292
293 template<typename Hash> uint64_t get_hash(const Hash &hash)
294 {
295 BLI_assert(this->is_occupied());
296 return hash(key_);
297 }
298
299 template<typename ForwardKey, typename IsEqual>
300 bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
301 {
302 BLI_assert(KeyInfo::is_not_empty_or_removed(key));
303 return is_equal(key, key_);
304 }
305
306 template<typename ForwardKey, typename... ForwardValue>
307 void occupy(ForwardKey &&key, uint64_t hash, ForwardValue &&...value)
308 {
309 BLI_assert(!this->is_occupied());
310 BLI_assert(KeyInfo::is_not_empty_or_removed(key));
311 new (&value_buffer_) Value(std::forward<ForwardValue>(value)...);
312 this->occupy_no_value(std::forward<ForwardKey>(key), hash);
313 }
314
315 template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t /*hash*/)
316 {
317 BLI_assert(!this->is_occupied());
318 BLI_assert(KeyInfo::is_not_empty_or_removed(key));
319 try {
320 key_ = std::forward<ForwardKey>(key);
321 }
322 catch (...) {
323 value_buffer_.ref().~Value();
324 throw;
325 }
326 }
327
328 void remove()
329 {
330 BLI_assert(this->is_occupied());
331 value_buffer_.ref().~Value();
332 KeyInfo::remove(key_);
333 }
334};
335
336template<typename Key, typename Value> struct DefaultMapSlot;
337
341template<typename Key, typename Value> struct DefaultMapSlot {
343};
344
349template<typename Key, typename Value> struct DefaultMapSlot<Key *, Value> {
351};
352
353} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
struct Key Key
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue Hue Saturation Value
const Key * key() const
void occupy_no_value(ForwardKey &&key, uint64_t)
const Value * value() const
IntrusiveMapSlot(IntrusiveMapSlot &&other) noexcept
bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t) const
IntrusiveMapSlot(const IntrusiveMapSlot &other)
void occupy(ForwardKey &&key, uint64_t hash, ForwardValue &&...value)
uint64_t get_hash(const Hash &hash)
SimpleMapSlot(const SimpleMapSlot &other)
const Key * key() const
SimpleMapSlot(SimpleMapSlot &&other) noexcept(std::is_nothrow_move_constructible_v< Key > &&std::is_nothrow_move_constructible_v< Value >)
const Value * value() const
uint64_t get_hash(const Hash &hash)
bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t) const
void occupy(ForwardKey &&key, uint64_t hash, ForwardValue &&...value)
void occupy_no_value(ForwardKey &&key, uint64_t)
void initialize_pointer_pair(Src1 &&src1, Src2 &&src2, Dst1 *dst1, Dst2 *dst2)
#define hash
Definition noise.c:154
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90