Cpp Utilities 1.2.3
SafeSharedPtr.hpp
Go to the documentation of this file.
1#ifndef CPP_UTILITIES_MEMORYSAFETY_SAFESHAREDPTR_HPP
2#define CPP_UTILITIES_MEMORYSAFETY_SAFESHAREDPTR_HPP
3
4#include <memory>
5#include <utility>
6#include <type_traits>
7#include "../Common.h"
8#if __cplusplus >= 201703L
9#include <shared_mutex>
10#else
11#include "RWSpinLock.hpp"
12#endif
13
30
37namespace Memory {
38// Forward declaration
39template<typename T,
40 typename mutex_t,
41 typename read_lock_t,
42 typename write_lock_t>
43class SafeWeakPtr;
44template<typename T,
45 typename mutex_t,
46 typename read_lock_t,
47 typename write_lock_t>
48class EnableSafeSharedFromThis;
49
50#if __cplusplus >= 201703L
55 using shared_mutex_t = std::shared_mutex;
60 using shared_lock_t = std::shared_lock<shared_mutex_t>;
65 using unique_lock_t = std::unique_lock<shared_mutex_t>;
66#else
82#endif
83
189template<typename T,
190 typename mutex_t = shared_mutex_t,
191 typename read_lock_t = shared_lock_t,
192 typename write_lock_t = unique_lock_t>
194{
195 template<typename Y, typename M, typename R, typename W>
196 friend class SafeSharedPtr;
197
198public:
199 template<typename Lock> class PtrHelper;
200 template<typename Lock> class RefHelper;
201 template<typename Lock> class ArrayHelper;
202
204 using SharedMutex = mutex_t;
205
207 using SharedLock = read_lock_t;
208
210 using UniqueLock = write_lock_t;
211
215 using element_type = typename std::remove_extent<T>::type;
216
219
228 constexpr SafeSharedPtr()
229 : mutex(std::make_shared<SharedMutex>())
230 {}
231
241 constexpr SafeSharedPtr(std::nullptr_t p)
242 : mutex(std::make_shared<SharedMutex>()),
243 ptr(p)
244 {}
245
259 template<typename Y>
260 explicit SafeSharedPtr(Y* p,
261 typename std::enable_if<!std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
262 : mutex(std::make_shared<SharedMutex>()),
263 ptr(p)
264 {
265 }
266
280 template<typename Y>
281 explicit SafeSharedPtr(Y* p,
282 typename std::enable_if<std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
283 : ptr(p)
284 { mutex = ptr->__safeSharedLock; }
285
304 template<typename Y, typename Deleter>
305 SafeSharedPtr(Y* p, Deleter d,
306 typename std::enable_if<!std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
307 : mutex(std::make_shared<SharedMutex>()),
308 ptr(p, d)
309 {
310 }
311
330 template<typename Y, typename Deleter>
331 SafeSharedPtr(Y* p, Deleter d,
332 typename std::enable_if<std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
333 : ptr(p, d)
334 { mutex = ptr->__safeSharedLock; }
335
353 template<typename Deleter>
354 SafeSharedPtr(std::nullptr_t p, Deleter d)
355 : mutex(std::make_shared<SharedMutex>()),
356 ptr(p, d)
357 {}
358
380 template<typename Y, typename Deleter, typename Alloc>
381 SafeSharedPtr(Y* p, Deleter d, Alloc alloc,
382 typename std::enable_if<!std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
383 : mutex(std::make_shared<SharedMutex>()),
384 ptr(p, d, alloc)
385 {}
386 template<typename Y, typename Deleter, typename Alloc>
387 SafeSharedPtr(Y* p, Deleter d, Alloc alloc,
388 typename std::enable_if<std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
389 : ptr(p, d, alloc)
390 { mutex = ptr->__safeSharedLock; }
391
412 template<typename Deleter, typename Alloc>
413 SafeSharedPtr(std::nullptr_t p, Deleter d, Alloc alloc)
414 : mutex(std::make_shared<SharedMutex>()),
415 ptr(p, d, alloc)
416 {}
417
436 template<typename Y, typename U>
438 : mutex(other.mutex), ptr(other.ptr, p)
439 {}
440
458 template<typename Y>
459 SafeSharedPtr(const std::shared_ptr<Y>& other, T* p,
460 typename std::enable_if<!std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr) noexcept
461 : mutex(std::make_shared<SharedMutex>()), ptr(other, p)
462 {}
463 template<typename Y>
464 SafeSharedPtr(const std::shared_ptr<Y>& other, T* p,
465 typename std::enable_if<std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr) noexcept
466 : mutex(other->__safeSharedLock), ptr(other, p)
467 {
468 }
469
476 SafeSharedPtr(const SafeSharedPtr& other) noexcept
477 : mutex(other.mutex), ptr(other.ptr)
478 {}
479
487 template<typename Y>
489 : mutex(other.mutex), ptr(other.ptr)
490 {}
491
498 SafeSharedPtr(SafeSharedPtr&& other) noexcept
499 : mutex(std::forward<std::shared_ptr<SharedMutex>>(other.mutex)),
500 ptr(std::forward<std::shared_ptr<T>>(other.ptr))
501 {}
502
510 template<typename Y>
512 : mutex(std::forward<std::shared_ptr<SharedMutex>>(other.mutex)),
513 ptr(std::forward<std::shared_ptr<Y>>(other.ptr))
514 {}
515
530 template<typename Y>
532 : mutex(other.mutex), ptr(other.ptr)
533 {}
534
549 template<typename Y>
550 SafeSharedPtr(const std::shared_ptr<Y>& other,
551 typename std::enable_if<!std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
552 : mutex(std::make_shared<SharedMutex>()), ptr(other)
553 {}
554 template<typename Y>
555 SafeSharedPtr(const std::shared_ptr<Y>& other,
556 typename std::enable_if<std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
557 : ptr(other)
558 { mutex = ptr->__safeSharedLock; }
559
571 template<typename Y>
572 SafeSharedPtr(std::shared_ptr<Y>&& other,
573 typename std::enable_if<!std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
574 : mutex(std::make_shared<SharedMutex>()),
575 ptr(std::forward<std::shared_ptr<Y>>(other))
576 {}
577 template<typename Y>
578 SafeSharedPtr(std::shared_ptr<Y>&& other,
579 typename std::enable_if<std::is_base_of<EnableSafeSharedFromThis<Y, SharedMutex, SharedLock, UniqueLock>, Y>::value>::type* = nullptr)
580 : ptr(std::forward<std::shared_ptr<Y>>(other))
581 { mutex = ptr->__safeSharedLock; }
582
604 template<typename Y>
605 SafeSharedPtr(const std::weak_ptr<Y>& other)
606 : SafeSharedPtr(other.lock())
607 {}
608
619 ~SafeSharedPtr() = default;
620
634 SafeSharedPtr& operator=(const SafeSharedPtr& other) noexcept
635 {
636 SafeSharedPtr(other).swap(*this);
637 return *this;
638 }
639
655 {
656 SafeSharedPtr(std::move(other)).swap(*this);
657 return *this;
658 }
659
674 template<typename Y>
676 {
677 SafeSharedPtr(other).swap(*this);
678 return *this;
679 }
680
696 template<typename Y>
698 {
700 return *this;
701 }
702
724 template<typename Y>
725 SafeSharedPtr& operator=(const std::shared_ptr<Y>& other)
726 {
727 SafeSharedPtr(other).swap(*this);
728 return *this;
729 }
730
750 template<typename Y>
751 SafeSharedPtr& operator=(std::shared_ptr<Y>&& other)
752 {
753 SafeSharedPtr(std::forward<std::shared_ptr<Y>>(other)).swap(*this);
754 return *this;
755 }
756
770 void reset()
771 { SafeSharedPtr().swap(*this); }
772
800 template<typename Y>
801 void reset(Y* ptr)
802 { SafeSharedPtr(ptr).swap(*this); }
803
833 template<typename Y, typename Deleter>
834 void reset(Y* ptr, Deleter d)
835 { SafeSharedPtr(ptr, d).swap(*this); }
836
872 template<typename Y, typename Deleter, typename Alloc>
873 void reset(Y* ptr, Deleter d, Alloc alloc)
874 { SafeSharedPtr(ptr, d, alloc).swap(*this); }
875
883 void swap(SafeSharedPtr& other) noexcept
884 {
885 mutex.swap(other.mutex);
886 ptr.swap(other.ptr);
887 }
888
900 element_type* get() const noexcept
901 { return ptr.get(); }
902
913 { return RefHelper<UniqueLock>(*this); }
914
924 const RefHelper<SharedLock> operator*() const noexcept
925 { return RefHelper<SharedLock>(*this); }
926
936 { return PtrHelper<UniqueLock>(*this); }
937
946 const PtrHelper<SharedLock> operator->() const noexcept
947 { return PtrHelper<SharedLock>(*this); }
948
949#if __cplusplus >= 201703L
970 { return ArrayHelper<UniqueLock>(*this, idx); }
971
990 const ArrayHelper<SharedLock> operator[](std::ptrdiff_t idx) const
991 { return ArrayHelper<SharedLock>(*this, idx); }
992#endif
993
1018 long use_count() const noexcept
1019 { return ptr.use_count(); }
1020
1030 explicit operator bool() const noexcept
1031 { return get() != nullptr; }
1032
1051 template<typename Y, typename M, typename R, typename W>
1053 { return ptr.owner_before(other.ptr); }
1054
1073 template<typename Y, typename M, typename R, typename W>
1074 bool owner_before(const SafeWeakPtr<Y, M, R, W>& other) const
1075 { return ptr.owner_before(other.ptr); }
1076
1089 void lock_shared() const
1090 { mutex->lock_shared(); }
1091
1100 void unlock_shared() const
1101 { mutex->unlock_shared(); }
1102
1116 void lock()
1117 { mutex->lock(); }
1118
1127 void unlock() const
1128 { mutex->unlock(); }
1129
1138 { return SharedLock(*mutex); }
1139
1148 { return std::move(UniqueLock(*mutex)); }
1149
1161 template<typename Lock>
1163 {
1164 public:
1166 using pointer = T*;
1168 using const_pointer = const T*;
1170 using reference = T&;
1172 using const_reference = const T&;
1173
1180 explicit PtrHelper(const SafeSharedPtr& p)
1181 : ptr(p.get()),
1182 lock(*(p.mutex))
1183 {
1184 }
1185
1191 PtrHelper(PtrHelper&& other) noexcept
1192 : ptr(std::move(other.ptr)),
1193 lock(std::move(other.lock))
1194 {
1195 }
1196
1201 {
1202 }
1203
1211 {
1212 ptr = std::move(other.ptr);
1213 lock = std::move(other.lock);
1214 return *this;
1215 }
1216
1221 operator pointer()
1222 { return ptr; }
1223
1228 operator const_pointer() const
1229 { return ptr; }
1230
1236 { return ptr; }
1237
1243 { return ptr; }
1244
1245 private:
1246 T* const ptr = nullptr;
1247 Lock lock;
1248
1249 PtrHelper(const PtrHelper&) = delete;
1250 PtrHelper& operator=(const PtrHelper&) = delete;
1251 };
1252
1266 template<typename Lock>
1268 {
1269 public:
1271 using reference = T&;
1273 using const_reference = const T&;
1274
1281 explicit RefHelper(const SafeSharedPtr& p)
1282 : ptr(p.get()),
1283 lock(*(p.mutex))
1284 {
1285 }
1286
1292 RefHelper(RefHelper&& other) noexcept
1293 : ptr(std::move(other.ptr)),
1294 lock(std::move(other.lock))
1295 {
1296 }
1297
1302 {
1303 }
1304
1312 {
1313 ptr = std::move(other.ptr);
1314 lock = std::move(other.lock);
1315 return *this;
1316 }
1317
1322 operator reference()
1323 { return *ptr; }
1324
1329 operator const_reference() const
1330 { return *ptr; }
1331
1344 template<typename X>
1345 RefHelper& operator=(const X& other)
1346 {
1347 operator reference() = other;
1348 return *this;
1349 }
1350
1351 private:
1352 T* const ptr = nullptr;
1353 Lock lock;
1354
1355 RefHelper(const RefHelper&) = delete;
1356 RefHelper& operator=(const RefHelper&) = delete;
1357 };
1358
1359 #if __cplusplus >= 201703L
1375 template<typename Lock>
1377 {
1378 public:
1380 using element_type = std::remove_extent_t<T>;
1389
1397 ArrayHelper(const SafeSharedPtr& p, std::ptrdiff_t idx)
1398 : ptr(p.get()),
1399 index(idx),
1400 lock(*(p.mutex))
1401 {
1402 }
1403
1409 ArrayHelper(ArrayHelper&& other) noexcept
1410 : ptr(std::move(other.ptr)),
1411 index(std::move(other.index)),
1412 lock(std::move(other.lock))
1413 {
1414 }
1415
1420 {
1421 }
1422
1430 {
1431 ptr = std::move(other.ptr);
1432 index = std::move(other.index);
1433 lock = std::move(other.lock);
1434 return *this;
1435 }
1436
1441 operator reference()
1442 { return ptr[index]; }
1443
1448 operator const_reference() const
1449 { return ptr[index]; }
1450
1463 template<typename X>
1464 ArrayHelper& operator=(const X& other)
1465 {
1466 operator reference() = other;
1467 return *this;
1468 }
1469
1470 private:
1471 element_type* const ptr = nullptr;
1472 std::ptrdiff_t index = 0;
1473 Lock lock;
1474
1475 ArrayHelper(const ArrayHelper&) = delete;
1476 ArrayHelper& operator=(const ArrayHelper&) = delete;
1477 };
1478#endif
1479
1480private:
1481 SafeSharedPtr(std::shared_ptr<SharedMutex> l, std::shared_ptr<T> p)
1482 : mutex(l), ptr(p)
1483 {}
1484
1485 template<typename Y, typename M, typename R, typename W>
1486 friend class SafeWeakPtr;
1487 mutable std::shared_ptr<SharedMutex> mutex;
1488 std::shared_ptr<T> ptr;
1489};
1490
1556template<typename T,
1557 typename SharedMutex = shared_mutex_t,
1558 typename SharedLock = shared_lock_t,
1559 typename UniqueLock = unique_lock_t,
1560 typename... Args>
1562{
1563 std::shared_ptr<T> p = std::make_shared<T>(std::forward<Args>(args)...);
1565}
1566
1629template<typename T,
1630 typename Alloc,
1631 typename SharedMutex = shared_mutex_t,
1632 typename SharedLock = shared_lock_t,
1633 typename UniqueLock = unique_lock_t,
1634 typename... Args>
1636 Args&&... args)
1637{
1638 std::shared_ptr<T> p = std::allocate_shared<T>(alloc, std::forward<Args>(args)...);
1640}
1641
1668template<typename T,
1669 typename U,
1670 typename SharedMutex,
1671 typename SharedLock,
1672 typename UniqueLock>
1674{
1675 auto p = static_cast<typename std::shared_ptr<T>::element_type*>(r.get());
1677}
1678
1708template<typename T,
1709 typename U,
1710 typename SharedMutex,
1711 typename SharedLock,
1712 typename UniqueLock>
1714{
1715 auto p = dynamic_cast<typename std::shared_ptr<T>::element_type*>(r.get());
1717}
1718
1745template<typename T,
1746 typename U,
1747 typename SharedMutex,
1748 typename SharedLock,
1749 typename UniqueLock>
1751{
1752 auto p = const_cast<typename std::shared_ptr<T>::element_type*>(r.get());
1754}
1755
1782template<typename T,
1783 typename U,
1784 typename SharedMutex,
1785 typename SharedLock,
1786 typename UniqueLock>
1788{
1789 auto p = reinterpret_cast<typename std::shared_ptr<T>::element_type*>(r.get());
1791}
1792
1815template<typename Deleter,
1816 typename T,
1817 typename SharedMutex,
1818 typename SharedLock,
1819 typename UniqueLock>
1821{ return std::get_deleter<Deleter>(p.ptr); }
1822
1848template<typename L,
1849 typename SharedMutex_L,
1850 typename SharedLock_L,
1851 typename UniqueLock_L,
1852 typename R,
1853 typename SharedMutex_R,
1854 typename SharedLock_R,
1855 typename UniqueLock_R>
1858{ return lhs.ptr == rhs.ptr; }
1859
1885template<typename L,
1886 typename SharedMutex_L,
1887 typename SharedLock_L,
1888 typename UniqueLock_L,
1889 typename R,
1890 typename SharedMutex_R,
1891 typename SharedLock_R,
1892 typename UniqueLock_R>
1895{ return !(lhs == rhs); }
1896
1922template<typename L,
1923 typename SharedMutex_L,
1924 typename SharedLock_L,
1925 typename UniqueLock_L,
1926 typename R,
1927 typename SharedMutex_R,
1928 typename SharedLock_R,
1929 typename UniqueLock_R>
1932{ return lhs.ptr < rhs.ptr; }
1933
1959template<typename L,
1960 typename SharedMutex_L,
1961 typename SharedLock_L,
1962 typename UniqueLock_L,
1963 typename R,
1964 typename SharedMutex_R,
1965 typename SharedLock_R,
1966 typename UniqueLock_R>
1969{ return lhs.ptr > rhs.ptr; }
1970
1996template<typename L,
1997 typename SharedMutex_L,
1998 typename SharedLock_L,
1999 typename UniqueLock_L,
2000 typename R,
2001 typename SharedMutex_R,
2002 typename SharedLock_R,
2003 typename UniqueLock_R>
2006{ return !(lhs > rhs); }
2007
2033template<typename L,
2034 typename SharedMutex_L,
2035 typename SharedLock_L,
2036 typename UniqueLock_L,
2037 typename R,
2038 typename SharedMutex_R,
2039 typename SharedLock_R,
2040 typename UniqueLock_R>
2043{ return !(lhs < rhs); }
2044
2066template<typename T,
2067 typename SharedMutex,
2068 typename SharedLock,
2069 typename UniqueLock>
2071 std::nullptr_t rhs) noexcept
2072{ return lhs.ptr == rhs; }
2073
2095template<typename T,
2096 typename SharedMutex,
2097 typename SharedLock,
2098 typename UniqueLock>
2099inline bool operator==(std::nullptr_t lhs,
2101{ return lhs == rhs.ptr; }
2102
2124template<typename T,
2125 typename SharedMutex,
2126 typename SharedLock,
2127 typename UniqueLock>
2129 std::nullptr_t rhs) noexcept
2130{ return !(lhs.ptr == rhs); }
2131
2153template<typename T,
2154 typename SharedMutex,
2155 typename SharedLock,
2156 typename UniqueLock>
2157inline bool operator!=(std::nullptr_t lhs,
2159{ return !(lhs == rhs.ptr); }
2160
2182template<typename T,
2183 typename SharedMutex,
2184 typename SharedLock,
2185 typename UniqueLock>
2187 std::nullptr_t rhs) noexcept
2188{ return lhs.ptr < rhs; }
2189
2211template<typename T,
2212 typename SharedMutex,
2213 typename SharedLock,
2214 typename UniqueLock>
2215inline bool operator<(std::nullptr_t lhs,
2217{ return lhs < rhs.ptr; }
2218
2240template<typename T,
2241 typename SharedMutex,
2242 typename SharedLock,
2243 typename UniqueLock>
2245 std::nullptr_t rhs) noexcept
2246{ return lhs.ptr > rhs; }
2247
2269template<typename T,
2270 typename SharedMutex,
2271 typename SharedLock,
2272 typename UniqueLock>
2273inline bool operator>(std::nullptr_t lhs,
2275{ return lhs > rhs.ptr; }
2276
2298template<typename T,
2299 typename SharedMutex,
2300 typename SharedLock,
2301 typename UniqueLock>
2303 std::nullptr_t rhs) noexcept
2304{ return !(lhs > rhs); }
2305
2327template<typename T,
2328 typename SharedMutex,
2329 typename SharedLock,
2330 typename UniqueLock>
2331inline bool operator<=(std::nullptr_t lhs,
2333{ return !(lhs > rhs); }
2334
2356template<typename T,
2357 typename SharedMutex,
2358 typename SharedLock,
2359 typename UniqueLock>
2361 std::nullptr_t rhs) noexcept
2362{ return !(lhs < rhs); }
2363
2386template<typename T,
2387 typename SharedMutex,
2388 typename SharedLock,
2389 typename UniqueLock>
2390inline bool operator>=(std::nullptr_t lhs,
2392{ return !(lhs < rhs); }
2393
2410template<typename T,
2411 typename SharedMutex,
2412 typename SharedLock,
2413 typename UniqueLock,
2414 typename OStream>
2415inline OStream& operator<<(OStream& os,
2417{
2418 os << ptr.get();
2419 return os;
2420}
2421
2443template<typename T,
2444 typename mutex_t = shared_mutex_t,
2445 typename read_lock_t = shared_lock_t,
2446 typename write_lock_t = unique_lock_t>
2448{
2449public:
2451 using SharedMutex = mutex_t;
2452
2454 using SharedLock = read_lock_t;
2455
2457 using UniqueLock = write_lock_t;
2458
2461
2465 constexpr SafeWeakPtr() noexcept = default;
2466
2475 template<typename Y>
2477 : mutex(other.mutex), ptr(other.ptr)
2478 {}
2479
2488 template<typename Y>
2490 : mutex(other.mutex), ptr(other.ptr)
2491 {}
2492
2497 ~SafeWeakPtr() = default;
2498
2512 {
2513 SafeWeakPtr<T>(other).swap(*this);
2514 return *this;
2515 }
2516
2530 template<typename Y>
2532 {
2533 SafeWeakPtr<T>(other).swap(*this);
2534 return *this;
2535 }
2536
2541 void reset() noexcept
2542 { SafeWeakPtr<T>().swap(*this); }
2543
2551 void swap(SafeWeakPtr<T>& other) noexcept
2552 {
2553 mutex.swap(other.mutex);
2554 ptr.swap(other.ptr);
2555 }
2556
2572 long use_count() const noexcept
2573 { return ptr.use_count(); }
2574
2589 bool expired() const noexcept
2590 { return ptr.expired(); }
2591
2611 SafeSharedPtr<T> lock() const noexcept
2612 {
2613 return expired() ? SafeSharedPtr<T>() : SafeSharedPtr<T>(*this);
2614 }
2615
2635 template<typename Y, typename M, typename R, typename W>
2636 bool owner_before(const SafeWeakPtr<Y, M, R, W>& other) const
2637 { return ptr.owner_before(other.ptr); }
2638
2658 template<typename Y, typename M, typename R, typename W>
2660 { return ptr.owner_before(other); }
2661
2662private:
2663 template<typename Y, typename M, typename R, typename W>
2664 friend class SafeSharedPtr;
2665 std::weak_ptr<SharedMutex> mutex;
2666 std::weak_ptr<T> ptr;
2667};
2668
2683template<typename T,
2684 typename mutex_t = shared_mutex_t,
2685 typename read_lock_t = shared_lock_t,
2686 typename write_lock_t = unique_lock_t>
2687class EnableSafeSharedFromThis : public std::enable_shared_from_this<T>
2688{
2689public:
2691 using SharedMutex = mutex_t;
2692
2694 using SharedLock = read_lock_t;
2695
2697 using UniqueLock = write_lock_t;
2698
2704 constexpr EnableSafeSharedFromThis() noexcept
2705 : __safeSharedLock(std::make_shared<SharedMutex>())
2706 {}
2707
2718 : std::enable_shared_from_this<T>(other),
2719 __safeSharedLock(other.__safeSharedLock)
2720 {}
2721
2731 EnableSafeSharedFromThis(const std::enable_shared_from_this<T>& other) noexcept
2732 : std::enable_shared_from_this<T>(other),
2733 __safeSharedLock(std::make_shared<SharedMutex>())
2734 {}
2735
2741
2752 {
2753 static_cast<std::enable_shared_from_this<T>&>(*this)
2754 = static_cast<std::enable_shared_from_this<T>&>(other);
2755 __safeSharedLock = other.__safeSharedLock;
2756 return *this;
2757 }
2758
2768 EnableSafeSharedFromThis<T>& operator=(const std::enable_shared_from_this<T>& other) noexcept
2769 {
2770 static_cast<std::enable_shared_from_this<T>&>(*this) = other;
2771 __safeSharedLock = std::make_shared<SharedMutex>();
2772 return *this;
2773 }
2774
2799 {
2801 __safeSharedLock,
2802 std::enable_shared_from_this<T>::shared_from_this());
2803 }
2804
2829 {
2830 return SafeSharedPtr<T const>(__safeSharedLock,
2831 std::enable_shared_from_this<T>::shared_from_this());
2832 }
2833
2845 { return shared_from_this(); }
2846
2858 { return shared_from_this(); }
2859
2860private:
2861 template<typename Y, typename M, typename R, typename W>
2862 friend class SafeSharedPtr;
2863 std::shared_ptr<typename SafeSharedPtr<T, SharedMutex, SharedLock, UniqueLock>::SharedMutex> __safeSharedLock;
2864};
2865} // namespace Memory
2869
2870namespace std {
2887template<typename T,
2888 typename SharedMutex = Memory::shared_mutex_t,
2889 typename SharedLock = Memory::shared_lock_t,
2890 typename UniqueLock = Memory::unique_lock_t>
2893{ lhs.swap(rhs); }
2910template<typename T,
2911 typename SharedMutex = Memory::shared_mutex_t,
2912 typename SharedLock = Memory::shared_lock_t,
2913 typename UniqueLock = Memory::unique_lock_t>
2916{ lhs.swap(rhs); }
2917} // namespace std
2918
2921#endif // CPP_UTILITIES_MEMORYSAFETY_SAFESHAREDPTR_HPP
#define UTILITIES_NAMESPACE_END
Define for end namespace declaration, nothing will be generated if UTILITIES_NAMESPACE isn't defined.
Definition: Common.h:92
#define UTILITIES_NAMESPACE_BEGIN
Define for begin namespace declaration, nothing will be generated if UTILITIES_NAMESPACE isn't define...
Definition: Common.h:91
ReadWrite lock using spin_lock, copied from Folly library under Apache-2.0 license,...
A proxy class from std::enable_shared_from_this to provide same functionality for SafeSharedPtr.
Definition: SafeSharedPtr.hpp:2688
mutex_t SharedMutex
Type alias for template shared_mutex_t.
Definition: SafeSharedPtr.hpp:2691
write_lock_t UniqueLock
Type alias for template write_lock_t.
Definition: SafeSharedPtr.hpp:2697
SafeWeakPtr< T > weak_from_this()
Returns a SafeWeakPtr<T> that tracks ownership of *this by all existing SafeSharedPtr that refer to *...
Definition: SafeSharedPtr.hpp:2844
~EnableSafeSharedFromThis()=default
Destroys *this.
constexpr EnableSafeSharedFromThis() noexcept
Constructs a new EnableSafeSharedFromThis object. The private std::weak_ptr<T> member is empty-initia...
Definition: SafeSharedPtr.hpp:2704
read_lock_t SharedLock
Type alias for template read_lock_t.
Definition: SafeSharedPtr.hpp:2694
SafeWeakPtr< T const > weak_from_this() const
Returns a SafeWeakPtr<T const> that tracks ownership of *this by all existing SafeSharedPtr that refe...
Definition: SafeSharedPtr.hpp:2857
EnableSafeSharedFromThis(const EnableSafeSharedFromThis &other) noexcept
Constructs a new EnableSafeSharedFromThis object. The private std::weak_ptr<T> member is value-initia...
Definition: SafeSharedPtr.hpp:2717
EnableSafeSharedFromThis(const std::enable_shared_from_this< T > &other) noexcept
Constructs a new EnableSafeSharedFromThis object. The private std::weak_ptr<T> member is value-initia...
Definition: SafeSharedPtr.hpp:2731
EnableSafeSharedFromThis & operator=(const EnableSafeSharedFromThis &other) noexcept
Does nothing; returns *this.
Definition: SafeSharedPtr.hpp:2751
EnableSafeSharedFromThis< T > & operator=(const std::enable_shared_from_this< T > &other) noexcept
Does nothing; returns *this.
Definition: SafeSharedPtr.hpp:2768
SafeSharedPtr< T const > shared_from_this() const
Returns a SafeSharedPtr<T const> that shares ownership of *this with all existing SafeSharedPtr that ...
Definition: SafeSharedPtr.hpp:2828
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > shared_from_this()
Returns a SafeSharedPtr<T> that shares ownership of *this with all existing SafeSharedPtr that refer ...
Definition: SafeSharedPtr.hpp:2798
RAII guard for read lock with RWSpinLock::lock_shared() on construction and RWSpinLock::unlock_shared...
Definition: RWSpinLock.hpp:307
RAII guard for write lock with RWSpinLock::lock() on construction and RWSpinLock::unlock() on destruc...
Definition: RWSpinLock.hpp:447
High-performance read-write-spinlock, see RWSpinLock.hpp for details.
Definition: RWSpinLock.hpp:164
Proxy class for operator[] in SafeSharedPtr, behave like array element of underlying array object,...
Definition: SafeSharedPtr.hpp:1377
element_type & reference
Reference type of element.
Definition: SafeSharedPtr.hpp:1386
element_type * pointer
Pointer type of element.
Definition: SafeSharedPtr.hpp:1382
const element_type & const_reference
Const eference type of element.
Definition: SafeSharedPtr.hpp:1388
ArrayHelper(const SafeSharedPtr &p, std::ptrdiff_t idx)
Constructor a constant ArrayHelper to gain access to element of object managed by SafeSharedPtr.
Definition: SafeSharedPtr.hpp:1397
const element_type * const_pointer
Const pointer type of element.
Definition: SafeSharedPtr.hpp:1384
~ArrayHelper()
Destructor, release Lock if exists.
Definition: SafeSharedPtr.hpp:1419
ArrayHelper(ArrayHelper &&other) noexcept
Move constructor, transport ownership to another ArrayHelper, keep existing lock state.
Definition: SafeSharedPtr.hpp:1409
ArrayHelper & operator=(ArrayHelper &&other)
Move assigment, transport ownership to another ArrayHelper, keep existing lock state.
Definition: SafeSharedPtr.hpp:1429
std::remove_extent_t< T > element_type
Element type of array T.
Definition: SafeSharedPtr.hpp:1380
ArrayHelper & operator=(const X &other)
Assign operator to assign from another value.
Definition: SafeSharedPtr.hpp:1464
Proxy class for operator-> in SafeSharedPtr, behave like underlying object, and provide RAII read-wri...
Definition: SafeSharedPtr.hpp:1163
pointer operator->()
Operator overload to act as T*.
Definition: SafeSharedPtr.hpp:1235
const T * const_pointer
Const pointer type of element.
Definition: SafeSharedPtr.hpp:1168
~PtrHelper()
Destructor, release Lock if exists.
Definition: SafeSharedPtr.hpp:1200
const_pointer operator->() const
Operator overload to act as const T*.
Definition: SafeSharedPtr.hpp:1242
PtrHelper(PtrHelper &&other) noexcept
Move constructor, transport ownership to another PtrHelper, keep existing lock state.
Definition: SafeSharedPtr.hpp:1191
PtrHelper & operator=(PtrHelper &&other)
Move assigment, transport ownership to another PtrHelper, keep existing lock state.
Definition: SafeSharedPtr.hpp:1210
PtrHelper(const SafeSharedPtr &p)
Constructor a constant PtrHelper to gain access to underlying object of SafeSharedPtr.
Definition: SafeSharedPtr.hpp:1180
const T & const_reference
Const eference type of element.
Definition: SafeSharedPtr.hpp:1172
T * pointer
Pointer type of element.
Definition: SafeSharedPtr.hpp:1166
T & reference
Reference type of element.
Definition: SafeSharedPtr.hpp:1170
Proxy class for operator* in SafeSharedPtr, behave like underlying object, and provide RAII read-writ...
Definition: SafeSharedPtr.hpp:1268
T & reference
Reference type of element.
Definition: SafeSharedPtr.hpp:1271
const T & const_reference
Const eference type of element.
Definition: SafeSharedPtr.hpp:1273
RefHelper(RefHelper &&other) noexcept
Move constructor, transport ownership to another RefHelper, keep existing lock state.
Definition: SafeSharedPtr.hpp:1292
RefHelper & operator=(RefHelper &&other)
Move assigment, transport ownership to another RefHelper, keep existing lock state.
Definition: SafeSharedPtr.hpp:1311
RefHelper & operator=(const X &other)
Assign operator to assign from another value.
Definition: SafeSharedPtr.hpp:1345
RefHelper(const SafeSharedPtr &p)
Constructor a constant RefHelper to gain access to underlying object of SafeSharedPtr.
Definition: SafeSharedPtr.hpp:1281
~RefHelper()
Destructor, release Lock if exists.
Definition: SafeSharedPtr.hpp:1301
Wrapper to std::shared_ptr to provide thread-safety while operating the underlying pointer.
Definition: SafeSharedPtr.hpp:194
Deleter * get_deleter(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &p) noexcept
Returns the deleter of specified type, if owned.
Definition: SafeSharedPtr.hpp:1820
bool operator<=(const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &lhs, const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2004
typename std::remove_extent< T >::type element_type
Type of element managed.
Definition: SafeSharedPtr.hpp:215
bool operator<=(std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2331
bool operator>(std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2273
SafeSharedPtr(const std::weak_ptr< Y > &other)
Constructs a SafeSharedPtr which shares ownership of the object managed by other. and provide read-wr...
Definition: SafeSharedPtr.hpp:605
bool operator!=(const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &lhs, const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:1893
bool operator>=(std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2390
bool operator<=(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2302
void reset()
Releases the ownership of the managed object, if any. After the call, *this manages no object.
Definition: SafeSharedPtr.hpp:770
SafeSharedPtr(const std::shared_ptr< Y > &other, T *p, typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr) noexcept
The aliasing constructor: constructs a SafeSharedPtr which shares ownership information with the init...
Definition: SafeSharedPtr.hpp:459
bool operator>(const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &lhs, const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:1967
write_lock_t UniqueLock
Type alias for template write_lock_t.
Definition: SafeSharedPtr.hpp:210
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > const_pointer_cast(const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
Applies const_cast to the stored pointer.
Definition: SafeSharedPtr.hpp:1750
bool operator>=(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2360
void lock_shared() const
Locks the lock for reading. This function will block the current thread if another thread has locked ...
Definition: SafeSharedPtr.hpp:1089
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > reinterpret_pointer_cast(const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
Applies reinterpret_cast to the stored pointer.
Definition: SafeSharedPtr.hpp:1787
SharedLock shared_lock() const
Generate a RAII guard for read lock, it will call lock_shared() on construction and unlock_shared() o...
Definition: SafeSharedPtr.hpp:1137
const PtrHelper< SharedLock > operator->() const noexcept
Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored poi...
Definition: SafeSharedPtr.hpp:946
UniqueLock unique_lock() const
Generate a RAII guard for write lock, it will call lock() on construction and unlock() on destruction...
Definition: SafeSharedPtr.hpp:1147
SafeSharedPtr(Y *p, Deleter d, typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Constructs a SafeSharedPtr with a managed object of specified deleter.
Definition: SafeSharedPtr.hpp:305
element_type * get() const noexcept
Returns the stored pointer.
Definition: SafeSharedPtr.hpp:900
constexpr SafeSharedPtr(std::nullptr_t p)
Construct a SafeSharedPtr with no managed object, i.e. empty SafeSharedPtr.
Definition: SafeSharedPtr.hpp:241
SafeSharedPtr(std::shared_ptr< Y > &&other, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Definition: SafeSharedPtr.hpp:578
void swap(SafeSharedPtr &other) noexcept
Exchanges the contents of *this and other.
Definition: SafeSharedPtr.hpp:883
void lock()
Locks the lock for writing. This function will block the current thread if another thread (including ...
Definition: SafeSharedPtr.hpp:1116
SafeSharedPtr & operator=(SafeSharedPtr &&other) noexcept
Move-assigns a SafeSharedPtr from other.
Definition: SafeSharedPtr.hpp:654
bool operator<(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2186
bool operator>=(const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &lhs, const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2041
SafeSharedPtr(Y *p, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Constructs a SafeSharedPtr with a managed object.
Definition: SafeSharedPtr.hpp:281
const ArrayHelper< SharedLock > operator[](std::ptrdiff_t idx) const
Provides indexed access to the stored array, guard it with read lock.
Definition: SafeSharedPtr.hpp:990
SafeSharedPtr & operator=(const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other) noexcept
Shares ownership of the object managed by other.
Definition: SafeSharedPtr.hpp:675
SafeSharedPtr(std::nullptr_t p, Deleter d)
Constructs a SafeSharedPtr with with no managed but has specified deleter.
Definition: SafeSharedPtr.hpp:354
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > allocate_shared(const Alloc &alloc, Args &&... args)
Creates a shared pointer that manages a new object allocated using an allocator.
Definition: SafeSharedPtr.hpp:1635
bool operator!=(std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2157
void swap(Memory::SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, Memory::SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Specializes the std::swap algorithm.
Definition: SafeSharedPtr.hpp:2891
bool operator<(const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &lhs, const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:1930
bool operator==(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2070
SafeSharedPtr(Y *p, typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Constructs a SafeSharedPtr with a managed object.
Definition: SafeSharedPtr.hpp:260
bool owner_before(const SafeWeakPtr< Y, M, R, W > &other) const
Checks whether this SafeSharedPtr precedes other in implementation defined owner-based (as opposed to...
Definition: SafeSharedPtr.hpp:1074
friend class SafeSharedPtr
Definition: SafeSharedPtr.hpp:196
SafeSharedPtr(const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other) noexcept
Copy constructor, constructs a SafeSharedPtr which shares ownership of the object managed by other....
Definition: SafeSharedPtr.hpp:488
void unlock_shared() const
Unlocks the read lock.
Definition: SafeSharedPtr.hpp:1100
SafeSharedPtr(const SafeSharedPtr &other) noexcept
Copy constructor, constructs a SafeSharedPtr which shares ownership of the object managed by other....
Definition: SafeSharedPtr.hpp:476
bool operator==(std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2099
SafeSharedPtr(std::shared_ptr< Y > &&other, typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Move-constructs a SafeSharedPtr from other. After the construction, *this contains a copy of the prev...
Definition: SafeSharedPtr.hpp:572
SafeSharedPtr & operator=(const SafeSharedPtr &other) noexcept
Shares ownership of the object managed by other.
Definition: SafeSharedPtr.hpp:634
SafeSharedPtr & operator=(std::shared_ptr< Y > &&other)
Move-assigns a SafeSharedPtr from other, provide read-write lock guard for memory safety.
Definition: SafeSharedPtr.hpp:751
OStream & operator<<(OStream &os, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &ptr)
Outputs the value of the stored pointer to an output stream.
Definition: SafeSharedPtr.hpp:2415
SafeSharedPtr & operator=(SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&other) noexcept
Move-assigns a SafeSharedPtr from other.
Definition: SafeSharedPtr.hpp:697
SafeSharedPtr(const std::shared_ptr< Y > &other, typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Constructs a SafeSharedPtr which shares ownership of the object managed by other, and provide read-wr...
Definition: SafeSharedPtr.hpp:550
SafeSharedPtr(std::nullptr_t p, Deleter d, Alloc alloc)
Constructs a SafeSharedPtr with no managed but has specified deleter and allocator.
Definition: SafeSharedPtr.hpp:413
SafeSharedPtr(Y *p, Deleter d, Alloc alloc, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Definition: SafeSharedPtr.hpp:387
bool owner_before(const SafeSharedPtr< Y, M, R, W > &other) const
Checks whether this SafeSharedPtr precedes other in implementation defined owner-based (as opposed to...
Definition: SafeSharedPtr.hpp:1052
PtrHelper< UniqueLock > operator->() noexcept
Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored po...
Definition: SafeSharedPtr.hpp:935
~SafeSharedPtr()=default
Destructor, destructs the owned object if no more SafeSharedPtr link to it.
bool operator<(std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2215
SafeSharedPtr(SafeSharedPtr &&other) noexcept
Move constructor, move-constructs a SafeSharedPtr from other. After the construction,...
Definition: SafeSharedPtr.hpp:498
bool operator>(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2244
void reset(Y *ptr)
Replaces the managed object with an object pointed to by ptr. Uses the delete expression as the delet...
Definition: SafeSharedPtr.hpp:801
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > make_shared(Args &&... args)
Creates a shared pointer that manages a new object.
Definition: SafeSharedPtr.hpp:1561
SafeSharedPtr(Y *p, Deleter d, Alloc alloc, typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Constructs a SafeSharedPtr with a managed object of specified deleter and allocator.
Definition: SafeSharedPtr.hpp:381
RefHelper< UniqueLock > operator*() noexcept
Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored po...
Definition: SafeSharedPtr.hpp:912
SafeSharedPtr(const SafeWeakPtr< Y, SharedMutex, SharedLock, UniqueLock > &other)
Constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no...
Definition: SafeSharedPtr.hpp:531
ArrayHelper< UniqueLock > operator[](std::ptrdiff_t idx)
Provides indexed access to the stored array, guard it with write lock.
Definition: SafeSharedPtr.hpp:969
void reset(Y *ptr, Deleter d)
Replaces the managed object with an object pointed to by ptr. Uses the specified deleter d as the del...
Definition: SafeSharedPtr.hpp:834
const RefHelper< SharedLock > operator*() const noexcept
Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored poi...
Definition: SafeSharedPtr.hpp:924
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > static_pointer_cast(const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
Applies static_cast to the stored pointer.
Definition: SafeSharedPtr.hpp:1673
bool operator!=(const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:2128
mutex_t SharedMutex
Type alias for template shared_mutex_t.
Definition: SafeSharedPtr.hpp:204
void reset(Y *ptr, Deleter d, Alloc alloc)
Replaces the managed object with an object pointed to by ptr. Uses the specified deleter d as the del...
Definition: SafeSharedPtr.hpp:873
SafeSharedPtr & operator=(const std::shared_ptr< Y > &other)
Shares ownership of the object managed by other, and provide read-write lock guard for memory safety.
Definition: SafeSharedPtr.hpp:725
void unlock() const
Unlocks the write lock.
Definition: SafeSharedPtr.hpp:1127
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > dynamic_pointer_cast(const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
Applies dynamic_cast to the stored pointer.
Definition: SafeSharedPtr.hpp:1713
bool operator==(const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &lhs, const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &rhs) noexcept
Compare SafeSharedPtr object with another input.
Definition: SafeSharedPtr.hpp:1856
constexpr SafeSharedPtr()
Default constructor, construct a SafeSharedPtr with no managed object, i.e. empty SafeSharedPtr.
Definition: SafeSharedPtr.hpp:228
read_lock_t SharedLock
Type alias for template read_lock_t.
Definition: SafeSharedPtr.hpp:207
SafeSharedPtr(Y *p, Deleter d, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Constructs a SafeSharedPtr with a managed object of specified deleter.
Definition: SafeSharedPtr.hpp:331
SafeSharedPtr(SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&other) noexcept
Move constructor, move-constructs a SafeSharedPtr from other. After the construction,...
Definition: SafeSharedPtr.hpp:511
SafeSharedPtr(const std::shared_ptr< Y > &other, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
Definition: SafeSharedPtr.hpp:555
SafeSharedPtr(const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other, U *p) noexcept
The aliasing constructor: constructs a SafeSharedPtr which shares ownership information with the init...
Definition: SafeSharedPtr.hpp:437
SafeSharedPtr(const std::shared_ptr< Y > &other, T *p, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr) noexcept
Definition: SafeSharedPtr.hpp:464
long use_count() const noexcept
Returns the number of SafeSharedPtr objects referring to the same managed object.
Definition: SafeSharedPtr.hpp:1018
Wrapper to std::weak_ptr to provide weak reference for SafeSharedPtr.
Definition: SafeSharedPtr.hpp:2448
read_lock_t SharedLock
Type alias for template read_lock_t.
Definition: SafeSharedPtr.hpp:2454
SafeWeakPtr(const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other)
Constructs new SafeWeakPtr that shares an object with other.
Definition: SafeSharedPtr.hpp:2489
bool owner_before(const SafeSharedPtr< Y, M, R, W > &other) const
Provides owner-based ordering of weak pointers.
Definition: SafeSharedPtr.hpp:2659
void swap(Memory::SafeWeakPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, Memory::SafeWeakPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
Specializes the std::swap algorithm.
Definition: SafeSharedPtr.hpp:2914
~SafeWeakPtr()=default
Destroys the weak_ptr object. Results in no effect to the managed object.
typename SafeSharedPtr< T >::element_type element_type
Same element_type of SafeSharedPtr.
Definition: SafeSharedPtr.hpp:2460
constexpr SafeWeakPtr() noexcept=default
Default constructor. Constructs empty weak_ptr.
SafeSharedPtr< T > lock() const noexcept
Creates a SafeSharedPtr that manages the referenced object.
Definition: SafeSharedPtr.hpp:2611
long use_count() const noexcept
Returns the number of SafeSharedPtr instances that share ownership of the managed object,...
Definition: SafeSharedPtr.hpp:2572
void swap(SafeWeakPtr< T > &other) noexcept
Exchanges the contents of *this and other.
Definition: SafeSharedPtr.hpp:2551
mutex_t SharedMutex
Type alias for template shared_mutex_t.
Definition: SafeSharedPtr.hpp:2451
SafeWeakPtr< T > & operator=(const SafeWeakPtr< T > &other) noexcept
Replaces the managed object with the one managed by other.
Definition: SafeSharedPtr.hpp:2511
write_lock_t UniqueLock
Type alias for template write_lock_t.
Definition: SafeSharedPtr.hpp:2457
void reset() noexcept
Releases the ownership of the managed object. After the call *this manages no object.
Definition: SafeSharedPtr.hpp:2541
SafeWeakPtr< T > & operator=(const SafeWeakPtr< Y, SharedMutex, SharedLock, UniqueLock > &other) noexcept
Replaces the managed object with the one managed by other.
Definition: SafeSharedPtr.hpp:2531
bool expired() const noexcept
Checks whether the referenced object was already deleted.
Definition: SafeSharedPtr.hpp:2589
bool owner_before(const SafeWeakPtr< Y, M, R, W > &other) const
Provides owner-based ordering of weak pointers.
Definition: SafeSharedPtr.hpp:2636
Namespace for all classes, typedefs and functions of memory safety. See Memory Safety for more instru...
Definition: RWSpinLock.hpp:159
std::shared_mutex shared_mutex_t
Defined to std::shared_mutex with C++17 or higher, otherwise defined to RWSpinLock.
Definition: SafeSharedPtr.hpp:55
std::shared_lock< shared_mutex_t > shared_lock_t
Defined to std::shared_lock<std::shared_mutex> with C++17 or higher, otherwise defined to RWSpinLock:...
Definition: SafeSharedPtr.hpp:60
std::unique_lock< shared_mutex_t > unique_lock_t
Defined to std::unique_lock<std::shared_mutex> with C++17 or higher, otherwise defined to RWSpinLock:...
Definition: SafeSharedPtr.hpp:65
Contains std functions overload for classes in Utilities, cannot hide in doxygen, just ignore it.