TrinityCore
Loading...
Searching...
No Matches
UniqueTrackablePtr.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITYCORE_UNIQUE_TRACKABLE_PTR_H
19#define TRINITYCORE_UNIQUE_TRACKABLE_PTR_H
20
21#include <memory>
22
23namespace Trinity
24{
25template <typename T>
26class unique_trackable_ptr;
27
28template <typename T>
29class unique_weak_ptr;
30
31template <typename T>
32class unique_strong_ref_ptr;
33
39template <typename T>
41{
42public:
43 using element_type = T;
44 using pointer = T*;
45
47
49 : _ptr(ptr) { }
50
51 template <typename Deleter, std::enable_if_t<std::conjunction_v<std::is_move_constructible<Deleter>, std::is_invocable<Deleter&, T*&>>, int> = 0>
52 explicit unique_trackable_ptr(pointer ptr, Deleter deleter)
53 : _ptr(ptr, std::move(deleter)) { }
54
56
58 : _ptr(std::move(other._ptr)) { }
59
60 template <typename T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
62 : _ptr(std::move(other)._ptr) { }
63
65
67 {
68 _ptr = std::move(other._ptr);
69 return *this;
70 }
71
72 template <typename T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
74 {
75 _ptr = std::move(other)._ptr;
76 return *this;
77 }
78
80
82 {
83 reset();
84 return *this;
85 }
86
87 void swap(unique_trackable_ptr& other) noexcept
88 {
89 using std::swap;
90 swap(_ptr, other._ptr);
91 }
92
94 {
95 return *_ptr;
96 }
97
99 {
100 return _ptr.operator->();
101 }
102
103 pointer get() const
104 {
105 return _ptr.get();
106 }
107
108 explicit operator bool() const
109 {
110 return static_cast<bool>(_ptr);
111 }
112
113 void reset()
114 {
115 _ptr.reset();
116 }
117
118 void reset(pointer ptr)
119 {
120 _ptr.reset(ptr);
121 }
122
123 template <class Deleter, std::enable_if_t<std::conjunction_v<std::is_move_constructible<Deleter>, std::is_invocable<Deleter&, T*&>>, int> = 0>
124 void reset(pointer ptr, Deleter deleter)
125 {
126 _ptr.reset(ptr, std::move(deleter));
127 }
128
129private:
130 template <typename T0>
132
133 template <typename T0>
134 friend class unique_weak_ptr;
135
136 template <typename T0, typename... Args>
137 friend std::enable_if_t<!std::is_array_v<T0>, unique_trackable_ptr<T0>> make_unique_trackable(Args&&... args);
138
139 template <typename T0>
140 friend std::enable_if_t<std::is_unbounded_array_v<T0>, unique_trackable_ptr<T0>> make_unique_trackable(std::size_t N);
141
142 template <typename T0>
143 friend std::enable_if_t<std::is_unbounded_array_v<T0>, unique_trackable_ptr<T0>> make_unique_trackable(std::size_t N, std::remove_extent_t<T0> const& val);
144
145 template <typename T0>
146 friend std::enable_if_t<std::is_bounded_array_v<T0>, unique_trackable_ptr<T0>> make_unique_trackable();
147
148 template <typename T0>
149 friend std::enable_if_t<std::is_bounded_array_v<T0>, unique_trackable_ptr<T0>> make_unique_trackable(std::remove_extent_t<T0> const& val);
150
151 std::shared_ptr<element_type> _ptr;
152};
153
158template <typename T>
160{
161public:
162 using element_type = T;
163 using pointer = T*;
164
165 unique_weak_ptr() = default;
166
168 : _ptr(trackable._ptr) { }
169
170 unique_weak_ptr(unique_weak_ptr const& other) = default;
171
172 template <typename T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
174 : _ptr(other._ptr) { }
175
176 unique_weak_ptr(unique_weak_ptr&& other) noexcept = default;
177
178 template <typename T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
180 : _ptr(std::move(other)._ptr) { }
181
182 template <typename T2>
183 unique_weak_ptr(unique_trackable_ptr<T2> const& aliased, T* aliasValue)
184 : _ptr(std::shared_ptr<T>(aliased._ptr, aliasValue)) { }
185
186 template <typename T2>
188 : _ptr(std::shared_ptr<T>(std::move(aliased)._ptr, aliasValue)) { }
189
191 {
192 _ptr = trackable._ptr;
193 return *this;
194 }
195
196 unique_weak_ptr& operator=(unique_weak_ptr const& other) = default;
197
198 template <typename T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
200 {
201 _ptr = std::move(other)._ptr;
202 return *this;
203 }
204
205 unique_weak_ptr& operator=(unique_weak_ptr&& other) noexcept = default;
206
207 ~unique_weak_ptr() = default;
208
209 unique_weak_ptr& operator=(std::nullptr_t) noexcept
210 {
211 _ptr.reset();
212 return *this;
213 }
214
215 void swap(unique_weak_ptr& other) noexcept
216 {
217 using std::swap;
218 swap(_ptr, other._ptr);
219 }
220
221 bool expired() const
222 {
223 return _ptr.expired();
224 }
225
230
231private:
232 template <typename T0>
233 friend class unique_weak_ptr;
234
235 template <typename T0>
237
238 template <class To, class From>
240
241 template <class To, class From>
243
244 template <class To, class From>
246
247 template <class To, class From>
249
250 std::weak_ptr<element_type> _ptr;
251};
252
259template <typename T>
261{
262public:
263 using element_type = T;
264 using pointer = T*;
265
270
272
274 {
275 return *_ptr;
276 }
277
279 {
280 return _ptr.operator->();
281 }
282
283 pointer get() const
284 {
285 return _ptr.get();
286 }
287
288 explicit operator bool() const
289 {
290 return static_cast<bool>(_ptr);
291 }
292
293 operator unique_weak_ptr<T>() const
294 {
296 weak._ptr = _ptr;
297 return weak;
298 }
299
300private:
301 template <typename T0>
302 friend class unique_weak_ptr;
303
304 template <class To, class From>
306
307 template <class To, class From>
309
310 template <class To, class From>
312
313 template <class To, class From>
315
316 template <class To, class From>
318
319 template <class To, class From>
321
322 template <class To, class From>
324
325 template <class To, class From>
327
328 unique_strong_ref_ptr(std::shared_ptr<element_type> ptr) : _ptr(std::move(ptr)) { }
329
330 std::shared_ptr<element_type> _ptr;
331};
332
333// unique_trackable_ptr funcions
334
335template <typename T1, typename T2>
337{
338 return left.get() == right.get();
339}
340
341template <typename T1, typename T2>
342std::strong_ordering operator<=>(unique_trackable_ptr<T1> const& left, unique_trackable_ptr<T2> const& right)
343{
344 return left.get() <=> right.get();
345}
346
347template <typename T1>
348bool operator==(unique_trackable_ptr<T1> const& left, std::nullptr_t)
349{
350 return left.get() == nullptr;
351}
352
353template <typename T1>
354std::strong_ordering operator<=>(unique_trackable_ptr<T1> const& left, std::nullptr_t)
355{
356 return left.get() <=> nullptr;
357}
358
359template <typename T, typename... Args>
360std::enable_if_t<!std::is_array_v<T>, unique_trackable_ptr<T>> make_unique_trackable(Args&&... args)
361{
363 ptr._ptr = std::make_shared<T>(std::forward<Args>(args)...);
364 return ptr;
365}
366
367template <typename T>
368std::enable_if_t<std::is_unbounded_array_v<T>, unique_trackable_ptr<T>> make_unique_trackable(std::size_t N)
369{
371 ptr._ptr = std::make_shared<T>(N);
372 return ptr;
373}
374
375template <typename T>
376std::enable_if_t<std::is_unbounded_array_v<T>, unique_trackable_ptr<T>> make_unique_trackable(std::size_t N, std::remove_extent_t<T> const& val)
377{
379 ptr._ptr = std::make_shared<T>(N, val);
380 return ptr;
381}
382
383template <typename T>
384std::enable_if_t<std::is_bounded_array_v<T>, unique_trackable_ptr<T>> make_unique_trackable()
385{
387 ptr._ptr = std::make_shared<T>();
388 return ptr;
389}
390
391template <typename T>
392std::enable_if_t<std::is_bounded_array_v<T>, unique_trackable_ptr<T>> make_unique_trackable(std::remove_extent_t<T> const& val)
393{
395 ptr._ptr = std::make_shared<T>(val);
396 return ptr;
397}
398
399// unique_weak_ptr funcions
400
401template <class To, class From>
403{
405 to._ptr = std::static_pointer_cast<To>(other._ptr.lock());
406 return to;
407}
408
409template <class To, class From>
411{
413 to._ptr = std::const_pointer_cast<To>(other._ptr.lock());
414 return to;
415}
416
417template <class To, class From>
419{
421 to._ptr = std::reinterpret_pointer_cast<To>(other._ptr.lock());
422 return to;
423}
424
425template <class To, class From>
427{
429 to._ptr = std::dynamic_pointer_cast<To>(other._ptr.lock());
430 return to;
431}
432
433// unique_strong_ref_ptr funcions
434
435template <typename T1, typename T2>
437{
438 return left.get() == right.get();
439}
440
441template <typename T1, typename T2>
442std::strong_ordering operator<=>(unique_strong_ref_ptr<T1> const& left, unique_strong_ref_ptr<T2> const& right)
443{
444 return left.get() <=> right.get();
445}
446
447template <typename T1>
448bool operator==(unique_strong_ref_ptr<T1> const& left, std::nullptr_t)
449{
450 return left.get() == nullptr;
451}
452
453template <typename T1>
454std::strong_ordering operator<=>(unique_strong_ref_ptr<T1> const& left, std::nullptr_t)
455{
456 return left.get() <=> nullptr;
457}
458
459template <class To, class From>
461{
462 return unique_strong_ref_ptr<To>(std::static_pointer_cast<To>(other._ptr));
463}
464
465template <class To, class From>
467{
468 return unique_strong_ref_ptr<To>(std::static_pointer_cast<To>(std::move(other._ptr)));
469}
470
471template <class To, class From>
473{
474 return unique_strong_ref_ptr<To>(std::const_pointer_cast<To>(other._ptr));
475}
476
477template <class To, class From>
479{
480 return unique_strong_ref_ptr<To>(std::const_pointer_cast<To>(std::move(other._ptr)));
481}
482
483template <class To, class From>
485{
486 return unique_strong_ref_ptr<To>(std::reinterpret_pointer_cast<To>(other._ptr));
487}
488
489template <class To, class From>
491{
492 return unique_strong_ref_ptr<To>(std::reinterpret_pointer_cast<To>(std::move(other._ptr)));
493}
494
495template <class To, class From>
497{
498 return unique_strong_ref_ptr<To>(std::dynamic_pointer_cast<To>(other._ptr));
499}
500
501template <class To, class From>
503{
504 return unique_strong_ref_ptr<To>(std::dynamic_pointer_cast<To>(std::move(other._ptr)));
505}
506}
507
508#endif // TRINITYCORE_UNIQUE_TRACKABLE_PTR_H
Result of unique_weak_ptr::lock() function, this class holds a temporary strong reference to held obj...
unique_strong_ref_ptr & operator=(unique_strong_ref_ptr &&)=delete
unique_strong_ref_ptr(std::shared_ptr< element_type > ptr)
std::shared_ptr< element_type > _ptr
unique_strong_ref_ptr(unique_strong_ref_ptr const &)=delete
friend unique_strong_ref_ptr< To > dynamic_pointer_cast(unique_strong_ref_ptr< From > const &other)
friend unique_strong_ref_ptr< To > static_pointer_cast(unique_strong_ref_ptr< From > const &other)
unique_strong_ref_ptr & operator=(unique_strong_ref_ptr const &)=delete
friend unique_strong_ref_ptr< To > reinterpret_pointer_cast(unique_strong_ref_ptr< From > const &other)
unique_strong_ref_ptr(unique_strong_ref_ptr &&)=delete
friend unique_strong_ref_ptr< To > const_pointer_cast(unique_strong_ref_ptr< From > const &other)
Specialized variant of std::shared_ptr that enforces unique ownership and/or std::unique_ptr with std...
unique_trackable_ptr(unique_trackable_ptr const &)=delete
friend std::enable_if_t< std::is_bounded_array_v< T0 >, unique_trackable_ptr< T0 > > make_unique_trackable(std::remove_extent_t< T0 > const &val)
unique_trackable_ptr & operator=(unique_trackable_ptr const &)=delete
unique_trackable_ptr(unique_trackable_ptr< T2 > &&other) noexcept
std::shared_ptr< element_type > _ptr
void reset(pointer ptr, Deleter deleter)
friend std::enable_if_t< std::is_unbounded_array_v< T0 >, unique_trackable_ptr< T0 > > make_unique_trackable(std::size_t N, std::remove_extent_t< T0 > const &val)
friend std::enable_if_t<!std::is_array_v< T0 >, unique_trackable_ptr< T0 > > make_unique_trackable(Args &&... args)
unique_trackable_ptr & operator=(unique_trackable_ptr &&other) noexcept
element_type & operator*() const
friend std::enable_if_t< std::is_bounded_array_v< T0 >, unique_trackable_ptr< T0 > > make_unique_trackable()
unique_trackable_ptr(pointer ptr, Deleter deleter)
unique_trackable_ptr & operator=(std::nullptr_t)
unique_trackable_ptr(unique_trackable_ptr &&other) noexcept
friend std::enable_if_t< std::is_unbounded_array_v< T0 >, unique_trackable_ptr< T0 > > make_unique_trackable(std::size_t N)
unique_trackable_ptr & operator=(unique_trackable_ptr< T2 > &&other) noexcept
void swap(unique_trackable_ptr &other) noexcept
Trinity::unique_trackable_ptr companion class, replicating what std::weak_ptr is to std::shared_ptr.
unique_weak_ptr & operator=(unique_weak_ptr &&other) noexcept=default
unique_strong_ref_ptr< element_type > lock() const
unique_weak_ptr & operator=(unique_weak_ptr< T2 > &&other)
friend unique_weak_ptr< To > dynamic_pointer_cast(unique_weak_ptr< From > const &other)
unique_weak_ptr(unique_weak_ptr &&other) noexcept=default
std::weak_ptr< element_type > _ptr
unique_weak_ptr & operator=(unique_weak_ptr const &other)=default
friend unique_weak_ptr< To > static_pointer_cast(unique_weak_ptr< From > const &other)
unique_weak_ptr(unique_trackable_ptr< T > const &trackable)
unique_weak_ptr(unique_weak_ptr< T2 > &&other) noexcept
unique_weak_ptr(unique_trackable_ptr< T2 > const &aliased, T *aliasValue)
friend unique_weak_ptr< To > reinterpret_pointer_cast(unique_weak_ptr< From > const &other)
unique_weak_ptr & operator=(unique_trackable_ptr< T > const &trackable)
unique_weak_ptr(unique_weak_ptr const &other)=default
friend unique_weak_ptr< To > const_pointer_cast(unique_weak_ptr< From > const &other)
void swap(unique_weak_ptr &other) noexcept
unique_weak_ptr & operator=(std::nullptr_t) noexcept
unique_weak_ptr(unique_trackable_ptr< T2 > &&aliased, T *aliasValue)
unique_weak_ptr(unique_weak_ptr< T2 > const &other) noexcept
std::enable_if_t< std::is_bounded_array_v< T >, unique_trackable_ptr< T > > make_unique_trackable()
unique_weak_ptr< To > reinterpret_pointer_cast(unique_weak_ptr< From > const &other)
bool operator==(unique_trackable_ptr< T1 > const &left, unique_trackable_ptr< T2 > const &right)
unique_weak_ptr< To > const_pointer_cast(unique_weak_ptr< From > const &other)
unique_weak_ptr< To > static_pointer_cast(unique_weak_ptr< From > const &other)
unique_weak_ptr< To > dynamic_pointer_cast(unique_weak_ptr< From > const &other)
std::strong_ordering operator<=>(unique_trackable_ptr< T1 > const &left, unique_trackable_ptr< T2 > const &right)
STL namespace.