Cpp Utilities 1.2.3
Classes | Public Types | Public Member Functions | Friends | Related Functions | List of all members
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t > Class Template Reference

Wrapper to std::shared_ptr to provide thread-safety while operating the underlying pointer. More...

#include <SafeSharedPtr.hpp>

Classes

class  ArrayHelper
 Proxy class for operator[] in SafeSharedPtr, behave like array element of underlying array object, and provide RAII read-write lock for thread safety. More...
 
class  PtrHelper
 Proxy class for operator-> in SafeSharedPtr, behave like underlying object, and provide RAII read-write lock for thread safety. More...
 
class  RefHelper
 Proxy class for operator* in SafeSharedPtr, behave like underlying object, and provide RAII read-write lock for thread safety. More...
 

Public Types

using SharedMutex = mutex_t
 Type alias for template shared_mutex_t. More...
 
using SharedLock = read_lock_t
 Type alias for template read_lock_t. More...
 
using UniqueLock = write_lock_t
 Type alias for template write_lock_t. More...
 
using element_type = typename std::remove_extent< T >::type
 Type of element managed. More...
 
using weak_type = SafeWeakPtr< T, SharedMutex, SharedLock, UniqueLock >
 Type of weak pointer from this shared pointer. More...
 

Public Member Functions

constexpr SafeSharedPtr ()
 Default constructor, construct a SafeSharedPtr with no managed object, i.e. empty SafeSharedPtr. More...
 
constexpr SafeSharedPtr (std::nullptr_t p)
 Construct a SafeSharedPtr with no managed object, i.e. empty SafeSharedPtr. More...
 
template<typename Y >
 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. More...
 
template<typename Y >
 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. More...
 
template<typename Y , typename Deleter >
 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. More...
 
template<typename Y , typename Deleter >
 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. More...
 
template<typename Deleter >
 SafeSharedPtr (std::nullptr_t p, Deleter d)
 Constructs a SafeSharedPtr with with no managed but has specified deleter. More...
 
template<typename Y , typename Deleter , typename Alloc >
 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. More...
 
template<typename Y , typename Deleter , typename Alloc >
 SafeSharedPtr (Y *p, Deleter d, Alloc alloc, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
 
template<typename Deleter , typename Alloc >
 SafeSharedPtr (std::nullptr_t p, Deleter d, Alloc alloc)
 Constructs a SafeSharedPtr with no managed but has specified deleter and allocator. More...
 
template<typename Y , typename U >
 SafeSharedPtr (const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other, U *p) noexcept
 The aliasing constructor: constructs a SafeSharedPtr which shares ownership information with the initial value of other, but holds an unrelated and unmanaged pointer p. More...
 
template<typename Y >
 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 initial value of other, but holds an unrelated and unmanaged pointer p. More...
 
template<typename Y >
 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
 
 SafeSharedPtr (const SafeSharedPtr &other) noexcept
 Copy constructor, constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no object, *this manages no object too. More...
 
template<typename Y >
 SafeSharedPtr (const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other) noexcept
 Copy constructor, constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no object, *this manages no object too. More...
 
 SafeSharedPtr (SafeSharedPtr &&other) noexcept
 Move constructor, move-constructs a SafeSharedPtr from other. After the construction, *this contains a copy of the previous state of other, other is empty and its stored pointer is null. More...
 
template<typename Y >
 SafeSharedPtr (SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&other) noexcept
 Move constructor, move-constructs a SafeSharedPtr from other. After the construction, *this contains a copy of the previous state of other, other is empty and its stored pointer is null. More...
 
template<typename Y >
 SafeSharedPtr (const SafeWeakPtr< Y, SharedMutex, SharedLock, UniqueLock > &other)
 Constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no object, *this manages no object too. More...
 
template<typename Y >
 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-write lock guard for memory safety. If other manages no object, *this manages no object too. More...
 
template<typename Y >
 SafeSharedPtr (const std::shared_ptr< Y > &other, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
 
template<typename Y >
 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 previous state of other, other is empty and its stored pointer is null. More...
 
template<typename Y >
 SafeSharedPtr (std::shared_ptr< Y > &&other, typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *=nullptr)
 
template<typename Y >
 SafeSharedPtr (const std::weak_ptr< Y > &other)
 Constructs a SafeSharedPtr which shares ownership of the object managed by other. and provide read-write lock guard for memory safety. If other manages no object, *this manages no object too. More...
 
 ~SafeSharedPtr ()=default
 Destructor, destructs the owned object if no more SafeSharedPtr link to it. More...
 
SafeSharedPtroperator= (const SafeSharedPtr &other) noexcept
 Shares ownership of the object managed by other. More...
 
SafeSharedPtroperator= (SafeSharedPtr &&other) noexcept
 Move-assigns a SafeSharedPtr from other. More...
 
template<typename Y >
SafeSharedPtroperator= (const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other) noexcept
 Shares ownership of the object managed by other. More...
 
template<typename Y >
SafeSharedPtroperator= (SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&other) noexcept
 Move-assigns a SafeSharedPtr from other. More...
 
template<typename Y >
SafeSharedPtroperator= (const std::shared_ptr< Y > &other)
 Shares ownership of the object managed by other, and provide read-write lock guard for memory safety. More...
 
template<typename Y >
SafeSharedPtroperator= (std::shared_ptr< Y > &&other)
 Move-assigns a SafeSharedPtr from other, provide read-write lock guard for memory safety. More...
 
void reset ()
 Releases the ownership of the managed object, if any. After the call, *this manages no object. More...
 
template<typename Y >
void reset (Y *ptr)
 Replaces the managed object with an object pointed to by ptr. Uses the delete expression as the deleter. More...
 
template<typename Y , typename Deleter >
void reset (Y *ptr, Deleter d)
 Replaces the managed object with an object pointed to by ptr. Uses the specified deleter d as the deleter. More...
 
template<typename Y , typename Deleter , typename Alloc >
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 deleter. Uses a copy of alloc for allocation of data for internal use. More...
 
void swap (SafeSharedPtr &other) noexcept
 Exchanges the contents of *this and other. More...
 
element_typeget () const noexcept
 Returns the stored pointer. More...
 
RefHelper< UniqueLockoperator* () noexcept
 Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored pointer is null. More...
 
const RefHelper< SharedLockoperator* () const noexcept
 Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null. More...
 
PtrHelper< UniqueLockoperator-> () noexcept
 Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored pointer is null. More...
 
const PtrHelper< SharedLockoperator-> () const noexcept
 Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null. More...
 
ArrayHelper< UniqueLockoperator[] (std::ptrdiff_t idx)
 Provides indexed access to the stored array, guard it with write lock. More...
 
const ArrayHelper< SharedLockoperator[] (std::ptrdiff_t idx) const
 Provides indexed access to the stored array, guard it with read lock. More...
 
long use_count () const noexcept
 Returns the number of SafeSharedPtr objects referring to the same managed object. More...
 
 operator bool () const noexcept
 Checks if *this stores a non-null pointer, i.e. whether get() != nullptr. More...
 
template<typename Y , typename M , typename R , typename W >
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 value-based) order. More...
 
template<typename Y , typename M , typename R , typename W >
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 value-based) order. More...
 
void lock_shared () const
 Locks the lock for reading. This function will block the current thread if another thread has locked for writing. More...
 
void unlock_shared () const
 Unlocks the read lock. More...
 
void lock ()
 Locks the lock for writing. This function will block the current thread if another thread (including the current) has locked for reading or writing. More...
 
void unlock () const
 Unlocks the write lock. More...
 
SharedLock shared_lock () const
 Generate a RAII guard for read lock, it will call lock_shared() on construction and unlock_shared() on destruction. More...
 
UniqueLock unique_lock () const
 Generate a RAII guard for write lock, it will call lock() on construction and unlock() on destruction. More...
 

Friends

template<typename Y , typename M , typename R , typename W >
class SafeSharedPtr
 
template<typename Y , typename M , typename R , typename W >
class SafeWeakPtr
 

Related Functions

(Note that these are not member functions.)

template<typename T , typename SharedMutex = shared_mutex_t, typename SharedLock = shared_lock_t, typename UniqueLock = unique_lock_t, typename... Args>
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLockmake_shared (Args &&... args)
 Creates a shared pointer that manages a new object. More...
 
template<typename T , typename Alloc , typename SharedMutex = shared_mutex_t, typename SharedLock = shared_lock_t, typename UniqueLock = unique_lock_t, typename... Args>
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLockallocate_shared (const Alloc &alloc, Args &&... args)
 Creates a shared pointer that manages a new object allocated using an allocator. More...
 
template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLockstatic_pointer_cast (const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
 Applies static_cast to the stored pointer. More...
 
template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLockdynamic_pointer_cast (const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
 Applies dynamic_cast to the stored pointer. More...
 
template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLockconst_pointer_cast (const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
 Applies const_cast to the stored pointer. More...
 
template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLockreinterpret_pointer_cast (const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &r) noexcept
 Applies reinterpret_cast to the stored pointer. More...
 
template<typename Deleter , typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
Deleter * get_deleter (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &p) noexcept
 Returns the deleter of specified type, if owned. More...
 
template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
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. More...
 
template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
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. More...
 
template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
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. More...
 
template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
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. More...
 
template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
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. More...
 
template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
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. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator== (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator== (std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator!= (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator!= (std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator< (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator< (std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator> (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator> (std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator<= (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator<= (std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator>= (const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, std::nullptr_t rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator>= (std::nullptr_t lhs, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Compare SafeSharedPtr object with another input. More...
 
template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock , typename OStream >
OStream & operator<< (OStream &os, const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &ptr)
 Outputs the value of the stored pointer to an output stream. More...
 
template<typename T , typename SharedMutex = Memory::shared_mutex_t, typename SharedLock = Memory::shared_lock_t, typename UniqueLock = Memory::unique_lock_t>
void swap (Memory::SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &lhs, Memory::SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &rhs) noexcept
 Specializes the std::swap algorithm. More...
 

Detailed Description

template<typename T, typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
class Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >

Wrapper to std::shared_ptr to provide thread-safety while operating the underlying pointer.

Template Parameters
TType of the object managed by SafeSharedPtr.
mutex_tType of the mutex used, default is shared_mutex_t.
read_lock_tType of the read-lock used, default is shared_lock_t.
write_lock_tType of the write-lock used, default is unique_lock_t.

Same API as std::shared_ptr, but operator* and operator() are guarded by read-write lock to guarantee thread-safety.
When SafeSharedPtr is a constant object, operations with underlying pointer will be guarded by read lock.
When SafeSharedPtr is a mutable object, operations with underlying pointer will be guarded by write lock.

Sample Code

Memory::SafeSharedPtr<int> ptr = Memory::make_shared<int>(0);
std::thread thread([](Memory::SafeSharedPtr<int> ptr){
for (int i = 0; i < 1000 * 1000; ++i)
*ptr += 1;
}, ptr);
for (int i = 0; i < 1000 * 1000; ++i)
*ptr += 1;
thread.join();
std::cout << *ptr << std::endl; // 2000000
Wrapper to std::shared_ptr to provide thread-safety while operating the underlying pointer.
Definition: SafeSharedPtr.hpp:194

To prevent lock/unlock too often, call lock_shared() / lock(), then use get() for raw pointer directly, call unlock_shared() / unlock() when finished.

See https://en.cppreference.com/w/cpp/memory/shared_ptr for more details of functionalities with std::shared_ptr.


Benchmark on (Intel(R) Core(R) CPU i5-6300U @ 2.4GHz Turbo 2.9GHz) 2 cores(4 HTs)

Contention Benchmark on integer plus, 90% read, 10% write.

Data TypeThreadsIters Total tt/iteriter/sec
MinGW 4.8.2 32bit on C++11 with RWSpinLock
int*11,000,000 1.59 ms1.59 ns627 M
SafeSharedPtr11,000,000 17.62 ms17.62 ns56.73 M
SafeSharedPtr41,000,000 251.4 ms62.85 ns15.91 M
SafeSharedPtr81,000,000 720.57 ms90.07 ns11.1 M
MSVC 2017 64bit (cl 19.16.27024.1) on C++17 with std::shared_mutex
int*11,000,000 1.61 ms1.6 ns620.96 M
SafeSharedPtr11,000,000 17.08 ms17.08 ns58.57 M
SafeSharedPtr41,000,000 80.81 ms20.2 ns49.5 M
SafeSharedPtr81,000,000 159.16 ms19.9 ns50.26 M
Note
Before C++17, for the purposes of the description below, a pointer type Y* requires that Y* must be implicitly convertible to T*.
Since C++17, for the purposes of the description below, a pointer type Y* is said to be compatible with a pointer type T* if either Y* is convertible to T* or Y is the array type U[N] and T is U cv [] (where cv is some set of cv-qualifiers).
Since C++17, default deleter called on destructor will use delete[] if T is an arry type;
Warning
Read-write lock used in this class is NOT recursive, so DO NOT call operator. operator-> or operator[] multiply times in a single line/expression, otherwise a deadlock will happen. Sorry for the inconvenience.
// deadlock happens
std::cout << point->x() << " " << point->y() << std::endl;
See also
SafeWeakPtr, EnableSafeSharedFromThis

Member Typedef Documentation

◆ SharedMutex

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SharedMutex = mutex_t

Type alias for template shared_mutex_t.

◆ SharedLock

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SharedLock = read_lock_t

Type alias for template read_lock_t.

◆ UniqueLock

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::UniqueLock = write_lock_t

Type alias for template write_lock_t.

◆ element_type

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::element_type = typename std::remove_extent<T>::type

Type of element managed.

◆ weak_type

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::weak_type = SafeWeakPtr<T, SharedMutex, SharedLock, UniqueLock>

Type of weak pointer from this shared pointer.

Constructor & Destructor Documentation

◆ SafeSharedPtr() [1/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
constexpr Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( )
inlineconstexpr

Default constructor, construct a SafeSharedPtr with no managed object, i.e. empty SafeSharedPtr.

Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.

◆ SafeSharedPtr() [2/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
constexpr Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( std::nullptr_t  p)
inlineconstexpr

Construct a SafeSharedPtr with no managed object, i.e. empty SafeSharedPtr.

Parameters
pnullptr.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.

◆ SafeSharedPtr() [3/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( Y *  p,
typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inlineexplicit

Constructs a SafeSharedPtr with a managed object.

Template Parameters
YType of input pointer.
Parameters
pPointer to an object to manage.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. delete p (if T is not an array type, delete[] p otherwise) (since C++17) is called if an exception occurs.

◆ SafeSharedPtr() [4/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( Y *  p,
typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inlineexplicit

Constructs a SafeSharedPtr with a managed object.

Template Parameters
YType of input pointer.
Parameters
pPointer to an object to manage.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. delete p (if T is not an array type, delete[] p otherwise) (since C++17) is called if an exception occurs.

◆ SafeSharedPtr() [5/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename Deleter >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( Y *  p,
Deleter  d,
typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

Constructs a SafeSharedPtr with a managed object of specified deleter.

Template Parameters
YType of input pointer.
DeleterType of specified deleter.
Parameters
pPointer to an object to manage.
dDeleter to use to destroy the object, must be CopyConstructible, and expression d(ptr) must be well formed, have well-defined behavior and not throw any exceptions.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(p) is called if an exception occurs.

◆ SafeSharedPtr() [6/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename Deleter >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( Y *  p,
Deleter  d,
typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

Constructs a SafeSharedPtr with a managed object of specified deleter.

Template Parameters
YType of input pointer.
DeleterType of specified deleter.
Parameters
pPointer to an object to manage.
dDeleter to use to destroy the object, must be CopyConstructible, and expression d(ptr) must be well formed, have well-defined behavior and not throw any exceptions.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(p) is called if an exception occurs.

◆ SafeSharedPtr() [7/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Deleter >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( std::nullptr_t  p,
Deleter  d 
)
inline

Constructs a SafeSharedPtr with with no managed but has specified deleter.

Template Parameters
DeleterType of specified deleter.
Parameters
pnullptr.
dDeleter to use to destroy the object, must be CopyConstructible, and expression d(ptr) must be well formed, have well-defined behavior and not throw any exceptions.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(p) is called if an exception occurs.

◆ SafeSharedPtr() [8/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename Deleter , typename Alloc >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( Y *  p,
Deleter  d,
Alloc  alloc,
typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

Constructs a SafeSharedPtr with a managed object of specified deleter and allocator.

Template Parameters
YType of input pointer.
DeleterType of specified deleter.
AllocType of specified allocator.
Parameters
pPointer to an object to manage.
dDeleter to use to destroy the object, must be CopyConstructible, and expression d(ptr) must be well formed, have well-defined behavior and not throw any exceptions.
allocAllocator to use for allocations of data for internal use, must satisfy C++ named requirements of Allocator.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(p) is called if an exception occurs.

◆ SafeSharedPtr() [9/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename Deleter , typename Alloc >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( Y *  p,
Deleter  d,
Alloc  alloc,
typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

◆ SafeSharedPtr() [10/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Deleter , typename Alloc >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( std::nullptr_t  p,
Deleter  d,
Alloc  alloc 
)
inline

Constructs a SafeSharedPtr with no managed but has specified deleter and allocator.

Template Parameters
DeleterType of specified deleter.
AllocType of specified allocator.
Parameters
pnullptr.
dDeleter to use to destroy the object, must be CopyConstructible, and expression d(ptr) must be well formed, have well-defined behavior and not throw any exceptions.
allocAllocator to use for allocations of data for internal use, must satisfy C++ named requirements of Allocator.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(p) is called if an exception occurs.

◆ SafeSharedPtr() [11/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename U >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &  other,
U *  p 
)
inlinenoexcept

The aliasing constructor: constructs a SafeSharedPtr which shares ownership information with the initial value of other, but holds an unrelated and unmanaged pointer p.

Template Parameters
YType of input shared pointer.
UType of input object, U must implicitly convertible to T.
Parameters
otherInput SafeSharedPtr to share ownership from.
pPointer to an object to manage.

If this SafeSharedPtr is the last of the group to go out of scope, it will call the stored deleter for the object originally managed by other. However, calling get() on this SafeSharedPtr will always return a copy of p. It is the responsibility of the programmer to make sure that this pointer remains valid as long as this SafeSharedPtr exists, such as in the typical use cases where 'p' is a member of the object managed by other or is an alias (e.g., downcast) of other.get() after the call.

◆ SafeSharedPtr() [12/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::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 
)
inlinenoexcept

The aliasing constructor: constructs a SafeSharedPtr which shares ownership information with the initial value of other, but holds an unrelated and unmanaged pointer p.

Template Parameters
YType of input shared pointer.
Parameters
otherInput SafeSharedPtr to share ownership from.
pPointer to an object to manage.

If this SafeSharedPtr is the last of the group to go out of scope, it will call the stored deleter for the object originally managed by other. However, calling get() on this SafeSharedPtr will always return a copy of p. It is the responsibility of the programmer to make sure that this pointer remains valid as long as this SafeSharedPtr exists, such as in the typical use cases where 'p' is a member of the object managed by other or is an alias (e.g., downcast) of other.get() after the call.

◆ SafeSharedPtr() [13/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::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 
)
inlinenoexcept

◆ SafeSharedPtr() [14/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t > &  other)
inlinenoexcept

Copy constructor, constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no object, *this manages no object too.

Parameters
otherAnother shared pointer to share the ownership from.

◆ SafeSharedPtr() [15/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &  other)
inlinenoexcept

Copy constructor, constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no object, *this manages no object too.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to share the ownership from.

◆ SafeSharedPtr() [16/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t > &&  other)
inlinenoexcept

Move constructor, move-constructs a SafeSharedPtr from other. After the construction, *this contains a copy of the previous state of other, other is empty and its stored pointer is null.

Parameters
otherAnother shared pointer to acquire the ownership from.

◆ SafeSharedPtr() [17/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&  other)
inlinenoexcept

Move constructor, move-constructs a SafeSharedPtr from other. After the construction, *this contains a copy of the previous state of other, other is empty and its stored pointer is null.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to acquire the ownership from.

◆ SafeSharedPtr() [18/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const SafeWeakPtr< Y, SharedMutex, SharedLock, UniqueLock > &  other)
inline

Constructs a SafeSharedPtr which shares ownership of the object managed by other. If other manages no object, *this manages no object too.

Template Parameters
YType of input pointer.
Parameters
otherAnother weak pointer to share the ownership to.
Note
other.lock() may be used for the same purpose: the difference is that this constructor throws an exception if the argument is empty, while SafeWeakPtr<T>::lock() constructs an empty SafeSharedPtr in that case.
Exceptions
std::bad_weak_ptrThrow if other.expired() == true The constructor has no effect in this case.

◆ SafeSharedPtr() [19/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const std::shared_ptr< Y > &  other,
typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

Constructs a SafeSharedPtr which shares ownership of the object managed by other, and provide read-write lock guard for memory safety. If other manages no object, *this manages no object too.

Template Parameters
YType of input pointer.
Parameters
otherAnother std::shared pointer to share the ownership to.
Warning
Only pointer operations with SafeSharedPtr are gauranteed memory safe, operations with existing std::shared_ptr are still without gaurantee.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.

◆ SafeSharedPtr() [20/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const std::shared_ptr< Y > &  other,
typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

◆ SafeSharedPtr() [21/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( std::shared_ptr< Y > &&  other,
typename std::enable_if<!std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

Move-constructs a SafeSharedPtr from other. After the construction, *this contains a copy of the previous state of other, other is empty and its stored pointer is null.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to acquire the ownership from.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.

◆ SafeSharedPtr() [22/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( std::shared_ptr< Y > &&  other,
typename std::enable_if< std::is_base_of< EnableSafeSharedFromThis< Y, SharedMutex, SharedLock, UniqueLock >, Y >::value >::type *  = nullptr 
)
inline

◆ SafeSharedPtr() [23/23]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SafeSharedPtr ( const std::weak_ptr< Y > &  other)
inline

Constructs a SafeSharedPtr which shares ownership of the object managed by other. and provide read-write lock guard for memory safety. If other manages no object, *this manages no object too.

Template Parameters
YType of input pointer.
Parameters
otherAnother weak pointer to share the ownership to.
Warning
Only pointer operations with SafeSharedPtr are gauranteed memory safe, operations with existing std::shared_ptr are still without gaurantee.
Note
other.lock() may be used for the same purpose: the difference is that this constructor throws an exception if the argument is empty, while std::weak_ptr<T>::lock() constructs an empty SafeSharedPtr in that case.
Exceptions
std::bad_weak_ptrThrow if other.expired() == true The constructor has no effect in this case.
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.

◆ ~SafeSharedPtr()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::~SafeSharedPtr ( )
default

Destructor, destructs the owned object if no more SafeSharedPtr link to it.

If *this owns an object and it is the last SafeSharedPtr owning it, the object is destroyed through the owned deleter. After the destruction, the shared pointers that shared ownership with *this, if any, will report a use_count() that is one less than its previous value.

Member Function Documentation

◆ operator=() [1/6]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
SafeSharedPtr & Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator= ( const SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t > &  other)
inlinenoexcept

Shares ownership of the object managed by other.

Parameters
otherAnother shared pointer to share the ownership to.
Returns
*this with same object managed by other.

Equivalent to SafeSharedPtr<T>(other).swap(*this).
If other manages no object, *this manages no object too.
Replaces the managed object with the one managed by other. If *this already owns an object and it is the last SafeSharedPtr owning it, and other is not the same as *this, the object is destroyed through the owned deleter.

See also
reset

◆ operator=() [2/6]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
SafeSharedPtr & Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator= ( SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t > &&  other)
inlinenoexcept

Move-assigns a SafeSharedPtr from other.

Parameters
otherAnother shared pointer to acquire the ownership from.
Returns
*this with same object managed by other.

Equivalent to SafeSharedPtr<T>(std::move(other)).swap(*this).
After the assignment, *this contains a copy of the previous state of other, and other is empty.
Replaces the managed object with the one managed by other. If *this already owns an object and it is the last SafeSharedPtr owning it, and other is not the same as *this, the object is destroyed through the owned deleter.

See also
reset

◆ operator=() [3/6]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
SafeSharedPtr & Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator= ( const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &  other)
inlinenoexcept

Shares ownership of the object managed by other.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to share the ownership to.
Returns
*this with same object managed by other.

Equivalent to SafeSharedPtr<T>(other).swap(*this).
If other manages no object, *this manages no object too.
Replaces the managed object with the one managed by other. If *this already owns an object and it is the last SafeSharedPtr owning it, and other is not the same as *this, the object is destroyed through the owned deleter.

See also
reset

◆ operator=() [4/6]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
SafeSharedPtr & Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator= ( SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&  other)
inlinenoexcept

Move-assigns a SafeSharedPtr from other.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to acquire the ownership from.
Returns
*this with same object managed by other.

Equivalent to SafeSharedPtr<T>(std::move(other)).swap(*this).
After the assignment, *this contains a copy of the previous state of other, and other is empty.
Replaces the managed object with the one managed by other. If *this already owns an object and it is the last SafeSharedPtr owning it, and other is not the same as *this, the object is destroyed through the owned deleter.

See also
reset

◆ operator=() [5/6]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
SafeSharedPtr & Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator= ( const std::shared_ptr< Y > &  other)
inline

Shares ownership of the object managed by other, and provide read-write lock guard for memory safety.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to share the ownership to.
Returns
*this with same object managed by other.

If other manages no object, *this manages no object too.
Replaces the managed object with the one managed by other. If *this already owns an object and it is the last SafeSharedPtr owning it, and other is not the same as *this, the object is destroyed through the owned deleter.

Warning
Only pointer operations with SafeSharedPtr are gauranteed memory safe, operations with existing std::shared_ptr are still without gaurantee.
Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
See also
reset

◆ operator=() [6/6]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
SafeSharedPtr & Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator= ( std::shared_ptr< Y > &&  other)
inline

Move-assigns a SafeSharedPtr from other, provide read-write lock guard for memory safety.

Template Parameters
YType of input pointer.
Parameters
otherAnother shared pointer to acquire the ownership from.
Returns
*this with same object managed by other.

After the assignment, *this contains a copy of the previous state of other, and other is empty.
Replaces the managed object with the one managed by other. If *this already owns an object and it is the last SafeSharedPtr owning it, and other is not the same as *this, the object is destroyed through the owned deleter.

Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
See also
reset

◆ reset() [1/4]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::reset ( )
inline

Releases the ownership of the managed object, if any. After the call, *this manages no object.

Equivalent to SafeSharedPtr().swap(*this).
If *this already owns an object and it is the last SafeSharedPtr owning it, the object is destroyed through the owned deleter.

Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
See also
operator=

◆ reset() [2/4]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y >
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::reset ( Y *  ptr)
inline

Replaces the managed object with an object pointed to by ptr. Uses the delete expression as the deleter.

Template Parameters
YType of input pointer. A valid delete expression must be available, i.e. delete ptr must be well formed, have well-defined behavior and not throw any exceptions.
Parameters
ptrPointer to an object to acquire ownership of.

Equivalent to SafeSharedPtr<T>(ptr).swap(*this).
Replaces the managed object with an object pointed to by ptr. By default, delete expression is used as deleter. Proper delete expression corresponding to the supplied type is always selected, this is the reason why the function is implemented as template using a separate parameter Y.
If *this already owns an object and it is the last SafeSharedPtr owning it, the object is destroyed through the owned deleter.
If the object pointed to by ptr is already owned, the function results in undefined behavior.

Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. delete ptr is called if an exception occurs.
See also
operator=

◆ reset() [3/4]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename Deleter >
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::reset ( Y *  ptr,
Deleter  d 
)
inline

Replaces the managed object with an object pointed to by ptr. Uses the specified deleter d as the deleter.

Template Parameters
YType of input pointer.
DeleterType of specified deleter. Deleter must be callable for the type T, i.e. d(ptr) must be well formed, have well-defined behavior and not throw any exceptions. Deleter must be CopyConstructible, and its copy constructor and destructor must not throw exceptions.
Parameters
ptrPointer to an object to acquire ownership of.
dDeleter to store for deletion of the object.

Equivalent to SafeSharedPtr<T>(ptr, d).swap(*this).
Replaces the managed object with an object pointed to by ptr. Optional deleter d is supplied, which is later used to destroy the new object when no SafeSharedPtr objects own it.
If *this already owns an object and it is the last SafeSharedPtr owning it, the object is destroyed through the owned deleter.
If the object pointed to by ptr is already owned, the function results in undefined behavior.

Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(ptr) is called if an exception occurs.
See also
operator=

◆ reset() [4/4]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename Deleter , typename Alloc >
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::reset ( Y *  ptr,
Deleter  d,
Alloc  alloc 
)
inline

Replaces the managed object with an object pointed to by ptr. Uses the specified deleter d as the deleter. Uses a copy of alloc for allocation of data for internal use.

Template Parameters
YType of input pointer.
DeleterType of specified deleter. Deleter must be callable for the type T, i.e. d(ptr) must be well formed, have well-defined behavior and not throw any exceptions. Deleter must be CopyConstructible, and its copy constructor and destructor must not throw exceptions.
AllocType of specified allocator. Alloc must satisfy C++ named requirements of Allocator. The copy constructor and destructor must not throw exceptions.
Parameters
ptrPointer to an object to acquire ownership of.
dDeleter to store for deletion of the object.
allocAllocator to use for allocations of data for internal use, must satisfy C++ named requirements of Allocator.

Equivalent to SafeSharedPtr<T>(ptr, d, alloc).swap(*this).
Replaces the managed object with an object pointed to by ptr. Optional deleter d is supplied, which is later used to destroy the new object when no SafeSharedPtr objects own it.
If *this already owns an object and it is the last SafeSharedPtr owning it, the object is destroyed through the owned deleter.
If the object pointed to by ptr is already owned, the function results in undefined behavior.

Exceptions
std::bad_allocIf read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs.
If required additional memory could not be obtained. May throw implementation-defined exception for other errors. d(ptr) is called if an exception occurs.
See also
operator=

◆ swap()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::swap ( SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t > &  other)
inlinenoexcept

Exchanges the contents of *this and other.

Parameters
otherAnother shared pointer to exchange the contents with.

Complexity
Constant.

◆ get()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
element_type * Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::get ( ) const
inlinenoexcept

Returns the stored pointer.

Returns
The stored pointer.
Note
A SafeSharedPtr may share ownership of an object while storing a pointer to another object. get() returns the stored pointer, not the managed pointer.
Warning
Thread safety is not gauranteed with this method, call lock_shared() / lock() before get(), and call unlock_shared() / unlock() when finished.
See also
operator*, operator->

◆ operator*() [1/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
RefHelper< UniqueLock > Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator* ( )
inlinenoexcept

Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored pointer is null.

Returns
A temporary object provides proxy to dereferencing the stored pointer, with lock() on construction and unlock() on destruction.
Note
This method is thread-safe.
See also
get

◆ operator*() [2/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
const RefHelper< SharedLock > Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator* ( ) const
inlinenoexcept

Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null.

Returns
A temporary object provides proxy to dereferencing the stored pointer, with lock_shared() on construction and unlock_shared() on destruction.
Note
This method is thread-safe.
See also
get

◆ operator->() [1/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
PtrHelper< UniqueLock > Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator-> ( )
inlinenoexcept

Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored pointer is null.

Returns
A temporary object provides proxy to the stored pointer, with lock() on construction and unlock() on destruction.
Note
This method is thread-safe.
See also
get

◆ operator->() [2/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
const PtrHelper< SharedLock > Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator-> ( ) const
inlinenoexcept

Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null.

Returns
A temporary object provides proxy to the stored pointer, with lock_shared() on construction and unlock_shared() on destruction.
Note
This method is thread-safe.
See also
get

◆ operator[]() [1/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
ArrayHelper< UniqueLock > Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator[] ( std::ptrdiff_t  idx)
inline

Provides indexed access to the stored array, guard it with write lock.

Parameters
idxThe array index.
Returns
A temporary object provides proxy to the idx-th element of the array, with lock() on construction and unlock() on destruction.

The behavior is undefined if the stored pointer is null or if idx is negative.
If T (the template parameter of SafeSharedPtr) is an array type U[N], idx must be less than N, otherwise the behavior is undefined.
When T is not an array type, it is unspecified whether this function is declared. If the function is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function is guaranteed to be legal.

Note
This method is thread-safe.
See also
get

◆ operator[]() [2/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
const ArrayHelper< SharedLock > Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator[] ( std::ptrdiff_t  idx) const
inline

Provides indexed access to the stored array, guard it with read lock.

Parameters
idxThe array index.
Returns
A temporary object provides proxy to the idx-th element of the array, with lock_shared() on construction and unlock_shared() on destruction.

The behavior is undefined if the stored pointer is null or if idx is negative.
If T (the template parameter of SafeSharedPtr) is an array type U[N], idx must be less than N, otherwise the behavior is undefined.
When T is not an array type, it is unspecified whether this function is declared. If the function is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function is guaranteed to be legal.

See also
get

◆ use_count()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
long Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::use_count ( ) const
inlinenoexcept

Returns the number of SafeSharedPtr objects referring to the same managed object.

Returns
The number of SafeSharedPtr instances managing the current object or 0 if there is no managed object.

Returns the number of different SafeSharedPtr instances (this included) managing the current object. If there is no managed object, 0 is returned.
In multithreaded environment, the value returned by use_count is approximate (typical implementations use a memory_order_relaxed load)

Note
Common use cases include:
  • Comparison with 0. If use_count returns zero, the shared pointer is empty and manages no objects (whether or not its stored pointer is null). In multithreaded environment, this does not imply that the destructor of the managed object has completed.
  • Comparison with 1. If use_count returns 1, there are no other owners. In multithreaded environment, this does not imply that the object is safe to modify because accesses to the managed object by former shared owners may not have completed, and because new shared owners may be introduced concurrently, such as by SafeWeakPtr::lock.

◆ operator bool()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::operator bool ( ) const
inlineexplicitnoexcept

Checks if *this stores a non-null pointer, i.e. whether get() != nullptr.

Returns
true if *this stores a pointer, false otherwise.
Note
An empty SafeSharedPtr (where use_count() == 0) may store a non-null pointer accessible by get(), e.g. if it were created using the aliasing constructor.
See also
get

◆ owner_before() [1/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename M , typename R , typename W >
bool Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::owner_before ( const SafeSharedPtr< Y, M, R, W > &  other) const
inline

Checks whether this SafeSharedPtr precedes other in implementation defined owner-based (as opposed to value-based) order.

Template Parameters
YType of the object managed by input pointer.
MType of the mutex used, default is shared_mutex_t.
RType of the read-lock used, default is shared_lock_t.
WType of the write-lock used, default is unique_lock_t.
Parameters
otherThe SafeSharedPtr to be compared.
Returns
true if *this precedes other, false otherwise. Common implementations compare the addresses of the control blocks.

The order is such that two shared pointers compare equivalent only if they are both empty or if they both own the same object, even if the values of the pointers obtained by get() are different (e.g. because they point at different subobjects within the same object)
This ordering is used to make shared and weak pointers usable as keys in associative containers, typically through std::owner_less.

◆ owner_before() [2/2]

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename M , typename R , typename W >
bool Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::owner_before ( const SafeWeakPtr< Y, M, R, W > &  other) const
inline

Checks whether this SafeSharedPtr precedes other in implementation defined owner-based (as opposed to value-based) order.

Template Parameters
YType of the object managed by input pointer.
MType of the mutex used, default is shared_mutex_t.
RType of the read-lock used, default is shared_lock_t.
WType of the write-lock used, default is unique_lock_t.
Parameters
otherthe SafeWeakPtr to be compared.
Returns
true if *this precedes other, false otherwise. Common implementations compare the addresses of the control blocks.

The order is such that two shared pointers compare equivalent only if they are both empty or if they both own the same object, even if the values of the pointers obtained by get() are different (e.g. because they point at different subobjects within the same object)
This ordering is used to make shared and weak pointers usable as keys in associative containers, typically through std::owner_less.

◆ lock_shared()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::lock_shared ( ) const
inline

Locks the lock for reading. This function will block the current thread if another thread has locked for writing.

Multiply readers in different thread can lock_shared at same time.
It is not possible to lock for read if the thread already has locked for write.

Note
This method is thread-safe.
Warning
Read-write lock is NOT recursive, locking multiply times in same thread will cause block.
See also
unlock_shared

◆ unlock_shared()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::unlock_shared ( ) const
inline

Unlocks the read lock.

Attempting to unlock a lock that is not locked is an error, and will result in undefined behaviour.

Note
This method is thread-safe.
See also
lock_shared

◆ lock()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::lock ( )
inline

Locks the lock for writing. This function will block the current thread if another thread (including the current) has locked for reading or writing.

Only one write can lock at same time.
It is not possible to lock for read if the thread already has locked for write.

Note
This method is thread-safe.
Warning
Read-write lock is NOT recursive, locking multiply times in same thread will cause block.
See also
unlock

◆ unlock()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
void Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::unlock ( ) const
inline

Unlocks the write lock.

Attempting to unlock a lock that is not locked is an error, and will result in undefined behaviour.

Note
This method is thread-safe.
See also
lock

◆ shared_lock()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
SharedLock Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::shared_lock ( ) const
inline

Generate a RAII guard for read lock, it will call lock_shared() on construction and unlock_shared() on destruction.

Returns
RAII guard for read lock
Note
This method is thread-safe.
See also
lock_shared, unlock_shared

◆ unique_lock()

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
UniqueLock Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::unique_lock ( ) const
inline

Generate a RAII guard for write lock, it will call lock() on construction and unlock() on destruction.

Returns
RAII write for read lock
Note
This method is thread-safe.
See also
lock, unlock

Friends And Related Function Documentation

◆ SafeSharedPtr

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename M , typename R , typename W >
friend class SafeSharedPtr
friend

◆ SafeWeakPtr

template<typename T , typename mutex_t = shared_mutex_t, typename read_lock_t = shared_lock_t, typename write_lock_t = unique_lock_t>
template<typename Y , typename M , typename R , typename W >
friend class SafeWeakPtr
friend

◆ make_shared()

template<typename T , typename SharedMutex = shared_mutex_t, typename SharedLock = shared_lock_t, typename UniqueLock = unique_lock_t, typename... Args>
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > make_shared ( Args &&...  args)
related

Creates a shared pointer that manages a new object.

Template Parameters
TType of object to be created.
SharedMutexType of the mutex used, default is shared_mutex_t.
SharedLockType of the read-lock used, default is shared_lock_t.
UniqueLockType of the write-lock used, default is unique_lock_t.
ArgsTypes of arguments in constructor of T.
Parameters
argsList of arguments with which an instance of T will be constructed.

Constructs an object of type T and wraps it in a SafeSharedPtr using args as the parameter list for the constructor of T. The object is constructed as if by the expression ::new (pv) T(std::forward<Args>(args)...), where pv is an internal void* pointer to storage suitable to hold an object of type T. The storage is typically larger than sizeof(T) in order to use one allocation for both the control block of the shared pointer and the T object. The SafeSharedPtr constructor called by this function enables `shared_from_this with a pointer to the newly constructed object of type T.
The object will be destroyed by p->~X(), where p is a pointer to the object and X is its type.

Exceptions
std::bad_allocMay throw std::bad_alloc or any exception thrown by the constructor of T. If an exception is thrown, the functions have no effect.
Note
A constructor enables std::enable_shared_from_this with a pointer ptr of type U* means that it determines if U has a base class that is a specialization of std::enable_shared_from_this, and if so, the constructor evaluates the statement:
if (ptr != nullptr && ptr->weak_this.expired())
ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(*this,
const_cast<std::remove_cv_t<U>*>(ptr));
Where weak_this is the hidden mutable std::weak_ptr member of std::shared_from_this. The assignment to the weak_this member is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls to shared_from_this() would share ownership with the shared_ptr created by this raw pointer constructor.
The test ptr->weak_this.expired() in the exposition code above makes sure that weak_this is not reassigned if it already indicates an owner. This test is required as of C++17.

This function may be used as an alternative to SafeSharedPtr<T>(new T(args...)). The trade-offs are:
  • SafeSharedPtr<T>(new T(args...)) performs at least two allocations (one for the object T and one for the control block of the shared pointer), while make_shared<T> typically performs only one allocation (the standard recommends, but does not require this, all known implementations do this)
  • If any SafeWeakPtr references the control block created by make_shared after the lifetime of all shared owners ended, the memory occupied by T persists until all weak owners get destroyed as well, which may be undesirable if sizeof(T) is large.
  • SafeSharedPtr<T>(new T(args...)) may call a non-public constructor of T if executed in context where it is accessible, while make_shared requires public access to the selected constructor.
  • Unlike the SafeSharedPtr constructors, make_shared does not allow a custom deleter.
  • make_shared uses ::new, so if any special behavior has been set up using a class-specific operator new, it will differ from SafeSharedPtr<T>(new T(args...)).
See also
allocate_shared

◆ allocate_shared()

template<typename T , typename Alloc , typename SharedMutex = shared_mutex_t, typename SharedLock = shared_lock_t, typename UniqueLock = unique_lock_t, typename... Args>
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > allocate_shared ( const Alloc &  alloc,
Args &&...  args 
)
related

Creates a shared pointer that manages a new object allocated using an allocator.

Template Parameters
TType of object to be created.
AllocType of input allocator.
SharedMutexType of the mutex used, default is shared_mutex_t.
SharedLockType of the read-lock used, default is shared_lock_t.
UniqueLockType of the write-lock used, default is unique_lock_t.
ArgsTypes of arguments in constructor of T.
Parameters
allocThe Allocator to use.
argsList of arguments with which an instance of T will be constructed.

Constructs an object of type T and wraps it in a SafeSharedPtr using args as the parameter list for the constructor of T. The object is constructed as if by the expression std::allocator_traits<A2>::construct(a, pv, v), where pv is an internal void* pointer to storage suitable to hold an object of type T and a is a copy of the allocator rebound to std::remove_cv_t<T>. The storage is typically larger than sizeof(T) in order to use one allocation for both the control block of the shared pointer and the T object. The SafeSharedPtr constructor called by this function enables shared_from_this with a pointer to the newly constructed object of type T. All memory allocation is done using a copy of alloc, which must satisfy the Allocator requirements.
For allocate_shared, the object are destroyed via the expression std::allocator_traits<A2>::destroy(a, p), where p is a pointer to the object and a is a copy of the allocator passed to allocate_shared, rebound to the type of the object being destroyed.

Exceptions
UserDefinedCan throw the exceptions thrown from Alloc::allocate() or from the constructor of T. If an exception is thrown, this function has no effect.
Note
Like make_shared, this function typically performs only one allocation, and places both the T object and the control block in the allocated memory block (the standard recommends but does not require this, all known implementations do this). A copy of alloc is stored as part of the control block so that it can be used to deallocate it once both shared and weak reference counts reach zero.
Unlike the SafeSharedPtr constructors, allocate_shared does not accept a separate custom deleter: the supplied allocator is used for destruction of the control block and the T object, and for deallocation of their shared memory block.
A constructor enables shared_from_this with a pointer ptr of type U* means that it determines if U has a base class that is a specialization of std::enable_shared_from_this, and if so, the constructor evaluates the statement:
if (ptr != nullptr && ptr->weak_this.expired())
ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(*this,
const_cast<std::remove_cv_t<U>*>(ptr));
Where weak_this is the hidden mutable std::weak_ptr member of std::shared_from_this. The assignment to the weak_this member is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls to shared_from_this() would share ownership with the SafeSharedPtr created by this raw pointer constructor.
The test ptr->weak_this.expired() in the exposition code above makes sure that weak_this is not reassigned if it already indicates an owner. This test is required as of C++17.
See also
make_shared

◆ static_pointer_cast()

template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > static_pointer_cast ( const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &  r)
related

Applies static_cast to the stored pointer.

Template Parameters
TType to cast to.
UType to cast from.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
rThe pointer to convert.
Returns
SafeSharedPtr<T> casted from type U.

Creates a new instance of SafeSharedPtr whose stored pointer is obtained from r's stored pointer using a cast expression.
If r is empty, so is the new SafeSharedPtr (but its stored pointer is not necessarily null). Otherwise, the new SafeSharedPtr will share ownership with the initial value of r.
Let Y be typename std::shared_ptr<T>::element_type, then the resulting SafeSharedPtr's stored pointer will be obtained by evaluating, respectively: static_cast<Y*>(r.get()).
The behavior is undefined unless static_cast<T*>((U*)nullptr) is well formed.

Note
The expression SafeSharedPtr<T>(static_cast<T*>(r.get())) might seem to have the same effect, but they all will likely result in undefined behavior, attempting to delete the same object twice!

◆ dynamic_pointer_cast()

template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > dynamic_pointer_cast ( const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &  r)
related

Applies dynamic_cast to the stored pointer.

Template Parameters
TType to cast to.
UType to cast from.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
rThe pointer to convert.
Returns
SafeSharedPtr<T> casted from type U.

Creates a new instance of SafeSharedPtr whose stored pointer is obtained from r's stored pointer using a cast expression.
If r is empty, so is the new SafeSharedPtr (but its stored pointer is not necessarily null). Otherwise, the new SafeSharedPtr will share ownership with the initial value of r, except that it is empty if the dynamic_cast performed by dynamic_pointer_cast returns a null pointer.
Let Y be typename std::shared_ptr<T>::element_type, then the resulting SafeSharedPtr's stored pointer will be obtained by evaluating, respectively: dynamic_cast<Y*>(r.get()) (If the result of the dynamic_cast is a null pointer value, the returned SafeSharedPtr will be empty). The behavior is undefined unless dynamic_cast<T*>((U*)nullptr) is well formed.

Note
The expression SafeSharedPtr<T>(dynamic_cast<T*>(r.get())) might seem to have the same effect, but they all will likely result in undefined behavior, attempting to delete the same object twice!

◆ const_pointer_cast()

template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > const_pointer_cast ( const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &  r)
related

Applies const_cast to the stored pointer.

Template Parameters
TType to cast to.
UType to cast from.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
rThe pointer to convert.
Returns
SafeSharedPtr<T> casted from type U.

Creates a new instance of SafeSharedPtr whose stored pointer is obtained from r's stored pointer using a cast expression.
If r is empty, so is the new SafeSharedPtr (but its stored pointer is not necessarily null). Otherwise, the new SafeSharedPtr will share ownership with the initial value of r.
Let Y be typename std::shared_ptr<T>::element_type, then the resulting SafeSharedPtr's stored pointer will be obtained by evaluating, respectively: const_cast<Y*>(r.get()). The behavior is undefined unless const_cast<T*>((U*)nullptr) is well formed.

Note
The expression SafeSharedPtr<T>(const_cast<T*>(r.get())) might seem to have the same effect, but they all will likely result in undefined behavior, attempting to delete the same object twice!

◆ reinterpret_pointer_cast()

template<typename T , typename U , typename SharedMutex , typename SharedLock , typename UniqueLock >
SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > reinterpret_pointer_cast ( const SafeSharedPtr< U, SharedMutex, SharedLock, UniqueLock > &  r)
related

Applies reinterpret_cast to the stored pointer.

Template Parameters
TType to cast to.
UType to cast from.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
rThe pointer to convert.
Returns
SafeSharedPtr<T> casted from type U.

Creates a new instance of SafeSharedPtr whose stored pointer is obtained from r's stored pointer using a cast expression.
If r is empty, so is the new SafeSharedPtr (but its stored pointer is not necessarily null). Otherwise, the new SafeSharedPtr will share ownership with the initial value of r.
Let Y be typename std::shared_ptr<T>::element_type, then the resulting SafeSharedPtr's stored pointer will be obtained by evaluating, respectively: reinterpret_cast<Y*>(r.get()). The behavior is undefined unless reinterpret_cast<T*>((U*)nullptr) is well formed.

Note
The expression SafeSharedPtr<T>(reinterpret_cast<T*>(r.get())) might seem to have the same effect, but they all will likely result in undefined behavior, attempting to delete the same object twice!

◆ get_deleter()

template<typename Deleter , typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
Deleter * get_deleter ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  p)
related

Returns the deleter of specified type, if owned.

Template Parameters
DeleterType of deleter returned.
TType of the object managed by SafeSharedPtr.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
pA shared pointer whose deleter needs to be accessed.
Returns
A pointer to the owned deleter or nullptr. The returned pointer is valid at least as long as there remains at least one SafeSharedPtr instance that owns it.

Access to the p's deleter. If the shared pointer p owns a deleter of type cv-unqualified Deleter (e.g. if it was created with one of the constructors that take a deleter as a parameter), then returns a pointer to the deleter. Otherwise, returns a null pointer.

Note
The returned pointer may outlive the last SafeSharedPtr if, for example, SafeWeakPtrs remain and the implementation doesn't destroy the deleter until the entire control block is destroyed.

◆ operator==() [1/3]

template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
bool operator== ( const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &  lhs,
const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutex_LType of lhs's mutex, will auto-deduct from input.
SharedLock_LType of lhs's read-lock, will auto-deduct from input.
UniqueLock_LType of lhs's write-lock, will auto-deduct from input.
UType of rhs.
SharedMutex_RType of rhs's mutex, will auto-deduct from input.
SharedLock_RType of rhs's read-lock, will auto-deduct from input.
UniqueLock_RType of rhs's write-lock, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
lhs == rhs.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator!=() [1/3]

template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
bool operator!= ( const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &  lhs,
const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutex_LType of lhs's mutex, will auto-deduct from input.
SharedLock_LType of lhs's read-lock, will auto-deduct from input.
UniqueLock_LType of lhs's write-lock, will auto-deduct from input.
UType of rhs.
SharedMutex_RType of rhs's mutex, will auto-deduct from input.
SharedLock_RType of rhs's read-lock, will auto-deduct from input.
UniqueLock_RType of rhs's write-lock, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
!(lhs == rhs).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator<() [1/3]

template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
bool operator< ( const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &  lhs,
const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutex_LType of lhs's mutex, will auto-deduct from input.
SharedLock_LType of lhs's read-lock, will auto-deduct from input.
UniqueLock_LType of lhs's write-lock, will auto-deduct from input.
UType of rhs.
SharedMutex_RType of rhs's mutex, will auto-deduct from input.
SharedLock_RType of rhs's read-lock, will auto-deduct from input.
UniqueLock_RType of rhs's write-lock, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
lhs < rhs.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator>() [1/3]

template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
bool operator> ( const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &  lhs,
const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutex_LType of lhs's mutex, will auto-deduct from input.
SharedLock_LType of lhs's read-lock, will auto-deduct from input.
UniqueLock_LType of lhs's write-lock, will auto-deduct from input.
UType of rhs.
SharedMutex_RType of rhs's mutex, will auto-deduct from input.
SharedLock_RType of rhs's read-lock, will auto-deduct from input.
UniqueLock_RType of rhs's write-lock, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
lhs > rhs.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator<=() [1/3]

template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
bool operator<= ( const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &  lhs,
const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutex_LType of lhs's mutex, will auto-deduct from input.
SharedLock_LType of lhs's read-lock, will auto-deduct from input.
UniqueLock_LType of lhs's write-lock, will auto-deduct from input.
UType of rhs.
SharedMutex_RType of rhs's mutex, will auto-deduct from input.
SharedLock_RType of rhs's read-lock, will auto-deduct from input.
UniqueLock_RType of rhs's write-lock, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
!(lhs > rhs).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator>=() [1/3]

template<typename L , typename SharedMutex_L , typename SharedLock_L , typename UniqueLock_L , typename R , typename SharedMutex_R , typename SharedLock_R , typename UniqueLock_R >
bool operator>= ( const SafeSharedPtr< L, SharedMutex_L, SharedLock_L, UniqueLock_L > &  lhs,
const SafeSharedPtr< R, SharedMutex_R, SharedLock_R, UniqueLock_R > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutex_LType of lhs's mutex, will auto-deduct from input.
SharedLock_LType of lhs's read-lock, will auto-deduct from input.
UniqueLock_LType of lhs's write-lock, will auto-deduct from input.
UType of rhs.
SharedMutex_RType of rhs's mutex, will auto-deduct from input.
SharedLock_RType of rhs's read-lock, will auto-deduct from input.
UniqueLock_RType of rhs's write-lock, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
!(lhs < rhs).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator==() [2/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator== ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
std::nullptr_t  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand nullptr to compare.
Returns
lhs == nullptr.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator==() [3/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator== ( std::nullptr_t  lhs,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of rhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand nullptr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
nullptr == rhs.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator!=() [2/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator!= ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
std::nullptr_t  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand nullptr to compare.
Returns
!(lhs == nullptr).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator!=() [3/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator!= ( std::nullptr_t  lhs,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of rhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand nullptr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
!(nullptr == rhs).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtr created using the aliasing constructor.

◆ operator<() [2/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator< ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
std::nullptr_t  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand nullptr to compare.
Returns
lhs < nullptr.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator<() [3/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator< ( std::nullptr_t  lhs,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of rhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand nullptr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
nullptr < rhs.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator>() [2/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator> ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
std::nullptr_t  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand nullptr to compare.
Returns
lhs > nullptr.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator>() [3/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator> ( std::nullptr_t  lhs,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of rhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand nullptr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
nullptr > rhs.

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator<=() [2/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator<= ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
std::nullptr_t  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand nullptr to compare.
Returns
!(lhs > nullptr).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator<=() [3/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator<= ( std::nullptr_t  lhs,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of rhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand nullptr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
!(nullptr > rhs).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator>=() [2/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator>= ( const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
std::nullptr_t  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of lhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand SafeSharedPtr to compare.
rhsThe right-hand nullptr to compare.
Returns
!(lhs < nullptr).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.

◆ operator>=() [3/3]

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock >
bool operator>= ( std::nullptr_t  lhs,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Compare SafeSharedPtr object with another input.

Template Parameters
TType of rhs.
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
Parameters
lhsThe left-hand nullptr to compare.
rhsThe right-hand SafeSharedPtr to compare.
Returns
!(nullptr < rhs).

The comparison operators for SafeSharedPtr simply compare pointer values; the actual objects pointed to are not compared. Having operator< defined for SafeSharedPtr allows SafeSharedPtr to be used as keys in associative containers, like std::map and std::set.

Note
In all cases, it is the stored pointer (the one returned by get()) that is compared, rather than the managed pointer (the one passed to the deleter when use_count goes to zero). The two pointers may differ in a SafeSharedPtrcreated using the aliasing constructor.
See also
get

◆ operator<<()

template<typename T , typename SharedMutex , typename SharedLock , typename UniqueLock , typename OStream >
OStream & operator<< ( OStream &  os,
const SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  ptr 
)
related

Outputs the value of the stored pointer to an output stream.

Template Parameters
TType of object managed by SafeSharedPtr
SharedMutexType of the mutex used, will auto-deduct from input.
SharedLockType of the read-lock used, will auto-deduct from input.
UniqueLockType of the write-lock used, will auto-deduct from input.
OStreamType of output stream.
Parameters
osAn output stream supports output pointer type.
ptrThe data to be inserted into os.
Returns
os

Inserts the value of the pointer stored in ptr into the output stream os.
Equivalent to os << ptr.get().

◆ swap()

template<typename T , typename SharedMutex = Memory::shared_mutex_t, typename SharedLock = Memory::shared_lock_t, typename UniqueLock = Memory::unique_lock_t>
void swap ( Memory::SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  lhs,
Memory::SafeSharedPtr< T, SharedMutex, SharedLock, UniqueLock > &  rhs 
)
related

Specializes the std::swap algorithm.

Template Parameters
TElement type of input shared pointers.
SharedMutexType of the mutex used, default is shared_mutex_t.
SharedLockType of the read-lock used, default is shared_lock_t.
UniqueLockType of the write-lock used, default is unique_lock_t.
Parameters
lhsShared pointer whose contents to swap.
rhsAnother shared pointer whose contents to swap.

Specializes the std::swap algorithm for Memory::SafeSharedPtr. Swaps the pointers of lhs and rhs. Calls lhs.swap(rhs).

Complexity
Constant.


The documentation for this class was generated from the following file: