Blender V5.0
BLI_implicit_sharing_ptr.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
10
11#include <memory>
12#include <utility>
13
16
17namespace blender {
18
24template<typename T = ImplicitSharingInfo, bool IsStrong = true> class ImplicitSharingPtr {
25 private:
26 const T *data_ = nullptr;
27
28 public:
29 using element_type = T;
30
31 ImplicitSharingPtr() = default;
32
33 explicit ImplicitSharingPtr(const T *data) : data_(data) {}
34
35 /* Implicit conversion from nullptr. */
36 ImplicitSharingPtr(std::nullptr_t) : data_(nullptr) {}
37
38 ImplicitSharingPtr(const ImplicitSharingPtr &other) : data_(other.data_)
39 {
40 this->add_user(data_);
41 }
42
43 ImplicitSharingPtr(ImplicitSharingPtr &&other) : data_(other.data_)
44 {
45 other.data_ = nullptr;
46 }
47
49 {
50 this->remove_user_and_delete_if_last(data_);
51 }
52
54 {
55 if (this == &other) {
56 return *this;
57 }
58
59 this->remove_user_and_delete_if_last(data_);
60 data_ = other.data_;
61 this->add_user(data_);
62 return *this;
63 }
64
66 {
67 if (this == &other) {
68 return *this;
69 }
70
71 this->remove_user_and_delete_if_last(data_);
72 data_ = other.data_;
73 other.data_ = nullptr;
74 return *this;
75 }
76
77 const T *operator->() const
78 {
79 BLI_assert(data_ != nullptr);
80 return data_;
81 }
82
83 const T &operator*() const
84 {
85 BLI_assert(data_ != nullptr);
86 return *data_;
87 }
88
89 operator bool() const
90 {
91 return data_ != nullptr;
92 }
93
94 const T *get() const
95 {
96 return data_;
97 }
98
99 const T *release()
100 {
101 const T *data = data_;
102 data_ = nullptr;
103 return data;
104 }
105
106 void reset()
107 {
108 this->remove_user_and_delete_if_last(data_);
109 data_ = nullptr;
110 }
111
112 bool has_value() const
113 {
114 return data_ != nullptr;
115 }
116
118 {
119 return get_default_hash(data_);
120 }
121
122 static uint64_t hash_as(const T *data)
123 {
124 return get_default_hash(data);
125 }
126
128
129 friend bool operator==(const T *a, const ImplicitSharingPtr &b)
130 {
131 return a == b.data_;
132 }
133
134 friend bool operator==(const ImplicitSharingPtr &a, const T *b)
135 {
136 return a.data_ == b;
137 }
138
139 private:
140 static void add_user(const T *data)
141 {
142 if (data != nullptr) {
143 if constexpr (IsStrong) {
144 data->add_user();
145 }
146 else {
147 data->add_weak_user();
148 }
149 }
150 }
151
152 static void remove_user_and_delete_if_last(const T *data)
153 {
154 if (data != nullptr) {
155 if constexpr (IsStrong) {
156 data->remove_user_and_delete_if_last();
157 }
158 else {
159 data->remove_weak_user_and_delete_if_last();
160 }
161 }
162 }
163};
164
166
176 public:
178 const void *data = nullptr;
179
185
187
189 : sharing_info(std::move(other.sharing_info)), data(std::exchange(other.data, nullptr))
190 {
191 }
192
194 {
195 if (this == &other) {
196 return *this;
197 }
198 std::destroy_at(this);
199 new (this) ImplicitSharingPtrAndData(other);
200 return *this;
201 }
202
204 {
205 if (this == &other) {
206 return *this;
207 }
208 std::destroy_at(this);
209 new (this) ImplicitSharingPtrAndData(std::move(other));
210 return *this;
211 }
212
214 {
215 this->data = nullptr;
216 }
217
218 bool has_value() const
219 {
220 return this->sharing_info.has_value();
221 }
222};
223
224template<typename T> static constexpr bool is_ImplicitSharingPtr_strong_v = false;
225template<typename T>
227
228} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_STRUCT_EQUALITY_OPERATORS_1(Type, m)
BMesh const char void * data
unsigned long long int uint64_t
ImplicitSharingPtrAndData & operator=(const ImplicitSharingPtrAndData &other)
ImplicitSharingPtrAndData & operator=(ImplicitSharingPtrAndData &&other)
ImplicitSharingPtrAndData(ImplicitSharingPtr<> sharing_info, const void *data)
ImplicitSharingPtrAndData(const ImplicitSharingPtrAndData &other)=default
ImplicitSharingPtrAndData(ImplicitSharingPtrAndData &&other)
friend bool operator==(const ImplicitSharingPtr &a, const T *b)
ImplicitSharingPtr & operator=(ImplicitSharingPtr &&other)
ImplicitSharingPtr(ImplicitSharingPtr &&other)
static uint64_t hash_as(const T *data)
ImplicitSharingPtr & operator=(const ImplicitSharingPtr &other)
ImplicitSharingPtr(const ImplicitSharingPtr &other)
#define T
ImplicitSharingPtr< ImplicitSharingInfo, false > WeakImplicitSharingPtr
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
static constexpr bool is_ImplicitSharingPtr_strong_v