Cpp Utilities 1.2.3
|
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... | |
SafeSharedPtr & | operator= (const SafeSharedPtr &other) noexcept |
Shares ownership of the object managed by other . More... | |
SafeSharedPtr & | operator= (SafeSharedPtr &&other) noexcept |
Move-assigns a SafeSharedPtr from other . More... | |
template<typename Y > | |
SafeSharedPtr & | operator= (const SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &other) noexcept |
Shares ownership of the object managed by other . More... | |
template<typename Y > | |
SafeSharedPtr & | operator= (SafeSharedPtr< Y, SharedMutex, SharedLock, UniqueLock > &&other) noexcept |
Move-assigns a SafeSharedPtr from other . More... | |
template<typename Y > | |
SafeSharedPtr & | operator= (const std::shared_ptr< Y > &other) |
Shares ownership of the object managed by other , and provide read-write lock guard for memory safety. More... | |
template<typename Y > | |
SafeSharedPtr & | operator= (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_type * | get () const noexcept |
Returns the stored pointer. More... | |
RefHelper< UniqueLock > | operator* () noexcept |
Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored pointer is null. More... | |
const RefHelper< SharedLock > | operator* () const noexcept |
Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null. More... | |
PtrHelper< UniqueLock > | operator-> () noexcept |
Dereferences the stored pointer, guard it with write lock. The behavior is undefined if the stored pointer is null. More... | |
const PtrHelper< SharedLock > | operator-> () const noexcept |
Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null. More... | |
ArrayHelper< UniqueLock > | operator[] (std::ptrdiff_t idx) |
Provides indexed access to the stored array, guard it with write lock. More... | |
const ArrayHelper< SharedLock > | operator[] (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, UniqueLock > | make_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, UniqueLock > | allocate_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, UniqueLock > | static_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, UniqueLock > | dynamic_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, UniqueLock > | const_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, UniqueLock > | reinterpret_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... | |
Wrapper to std::shared_ptr
to provide thread-safety while operating the underlying pointer.
T | Type of the object managed by SafeSharedPtr. |
mutex_t | Type of the mutex used, default is shared_mutex_t. |
read_lock_t | Type of the read-lock used, default is shared_lock_t. |
write_lock_t | Type 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
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 Type | Threads | Iters | Total t | t/iter | iter/sec |
---|---|---|---|---|---|
MinGW 4.8.2 32bit on C++11 with RWSpinLock | |||||
int* | 1 | 1,000,000 | 1.59 ms | 1.59 ns | 627 M |
SafeSharedPtr | 1 | 1,000,000 | 17.62 ms | 17.62 ns | 56.73 M |
SafeSharedPtr | 4 | 1,000,000 | 251.4 ms | 62.85 ns | 15.91 M |
SafeSharedPtr | 8 | 1,000,000 | 720.57 ms | 90.07 ns | 11.1 M |
MSVC 2017 64bit (cl 19.16.27024.1) on C++17 with std::shared_mutex | |||||
int* | 1 | 1,000,000 | 1.61 ms | 1.6 ns | 620.96 M |
SafeSharedPtr | 1 | 1,000,000 | 17.08 ms | 17.08 ns | 58.57 M |
SafeSharedPtr | 4 | 1,000,000 | 80.81 ms | 20.2 ns | 49.5 M |
SafeSharedPtr | 8 | 1,000,000 | 159.16 ms | 19.9 ns | 50.26 M |
Y*
requires that Y*
must be implicitly convertible to T*
.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).delete[]
if T
is an arry type; operator.
operator->
or operator[]
multiply times in a single line/expression, otherwise a deadlock will happen. Sorry for the inconvenience. using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SharedMutex = mutex_t |
Type alias for template shared_mutex_t.
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::SharedLock = read_lock_t |
Type alias for template read_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.
using Memory::SafeSharedPtr< T, mutex_t, read_lock_t, write_lock_t >::element_type = typename std::remove_extent<T>::type |
Type of element managed.
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.
|
inlineconstexpr |
Default constructor, construct a SafeSharedPtr
with no managed object, i.e. empty SafeSharedPtr.
std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
inlineconstexpr |
Construct a SafeSharedPtr
with no managed object, i.e. empty SafeSharedPtr.
p | nullptr. |
std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
inlineexplicit |
Constructs a SafeSharedPtr
with a managed object.
Y | Type of input pointer. |
p | Pointer to an object to manage. |
std::bad_alloc | If 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. |
|
inlineexplicit |
Constructs a SafeSharedPtr
with a managed object.
Y | Type of input pointer. |
p | Pointer to an object to manage. |
std::bad_alloc | If 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. |
|
inline |
Constructs a SafeSharedPtr
with a managed object of specified deleter.
Y | Type of input pointer. |
Deleter | Type of specified deleter. |
p | Pointer to an object to manage. |
d | Deleter 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. |
std::bad_alloc | If 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. |
|
inline |
Constructs a SafeSharedPtr
with a managed object of specified deleter.
Y | Type of input pointer. |
Deleter | Type of specified deleter. |
p | Pointer to an object to manage. |
d | Deleter 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. |
std::bad_alloc | If 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. |
|
inline |
Constructs a SafeSharedPtr
with with no managed but has specified deleter.
Deleter | Type of specified deleter. |
p | nullptr. |
d | Deleter 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. |
std::bad_alloc | If 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. |
|
inline |
Constructs a SafeSharedPtr
with a managed object of specified deleter and allocator.
Y | Type of input pointer. |
Deleter | Type of specified deleter. |
Alloc | Type of specified allocator. |
p | Pointer to an object to manage. |
d | Deleter 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. |
alloc | Allocator to use for allocations of data for internal use, must satisfy C++ named requirements of Allocator . |
std::bad_alloc | If 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. |
|
inline |
|
inline |
Constructs a SafeSharedPtr
with no managed but has specified deleter and allocator.
Deleter | Type of specified deleter. |
Alloc | Type of specified allocator. |
p | nullptr. |
d | Deleter 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. |
alloc | Allocator to use for allocations of data for internal use, must satisfy C++ named requirements of Allocator . |
std::bad_alloc | If 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. |
|
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
.
Y | Type of input shared pointer. |
U | Type of input object, U must implicitly convertible to T. |
other | Input SafeSharedPtr to share ownership from. |
p | Pointer 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.
|
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
.
Y | Type of input shared pointer. |
other | Input SafeSharedPtr to share ownership from. |
p | Pointer 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.
|
inlinenoexcept |
|
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.
other | Another shared pointer to share the ownership from. |
|
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.
Y | Type of input pointer. |
other | Another shared pointer to share the ownership from. |
|
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.
other | Another shared pointer to acquire the ownership from. |
|
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.
Y | Type of input pointer. |
other | Another shared pointer to acquire the ownership from. |
|
inline |
Constructs a SafeSharedPtr
which shares ownership of the object managed by other
. If other
manages no object, *this
manages no object too.
Y | Type of input pointer. |
other | Another weak pointer to share the ownership to. |
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. std::bad_weak_ptr | Throw if other.expired() == true The constructor has no effect in this case. |
|
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.
Y | Type of input pointer. |
other | Another std::shared pointer to share the ownership to. |
SafeSharedPtr
are gauranteed memory safe, operations with existing std::shared_ptr
are still without gaurantee. std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
inline |
|
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.
Y | Type of input pointer. |
other | Another shared pointer to acquire the ownership from. |
std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
inline |
|
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.
Y | Type of input pointer. |
other | Another weak pointer to share the ownership to. |
SafeSharedPtr
are gauranteed memory safe, operations with existing std::shared_ptr
are still without gaurantee. 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. std::bad_weak_ptr | Throw if other.expired() == true The constructor has no effect in this case. |
std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
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.
|
inlinenoexcept |
Shares ownership of the object managed by other
.
other | Another shared pointer to share the ownership to. |
*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.
|
inlinenoexcept |
Move-assigns a SafeSharedPtr
from other
.
other | Another shared pointer to acquire the ownership from. |
*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.
|
inlinenoexcept |
Shares ownership of the object managed by other
.
Y | Type of input pointer. |
other | Another shared pointer to share the ownership to. |
*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.
|
inlinenoexcept |
Move-assigns a SafeSharedPtr
from other
.
Y | Type of input pointer. |
other | Another shared pointer to acquire the ownership from. |
*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.
|
inline |
Shares ownership of the object managed by other
, and provide read-write lock guard for memory safety.
Y | Type of input pointer. |
other | Another shared pointer to share the ownership to. |
*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.
SafeSharedPtr
are gauranteed memory safe, operations with existing std::shared_ptr
are still without gaurantee. std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
inline |
Move-assigns a SafeSharedPtr
from other
, provide read-write lock guard for memory safety.
Y | Type of input pointer. |
other | Another shared pointer to acquire the ownership from. |
*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.
std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
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.
std::bad_alloc | If read-write lock could not be obtained. May throw implementation-defined exception for other errors. delete mutex is called if an exception occurs. |
|
inline |
Replaces the managed object with an object pointed to by ptr. Uses the delete expression as the deleter.
Y | Type 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. |
ptr | Pointer 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.
std::bad_alloc | If 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. |
|
inline |
Replaces the managed object with an object pointed to by ptr. Uses the specified deleter d
as the deleter.
Y | Type of input pointer. |
Deleter | Type 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. |
ptr | Pointer to an object to acquire ownership of. |
d | Deleter 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.
std::bad_alloc | If 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. |
|
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.
Y | Type of input pointer. |
Deleter | Type 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. |
Alloc | Type of specified allocator. Alloc must satisfy C++ named requirements of Allocator . The copy constructor and destructor must not throw exceptions. |
ptr | Pointer to an object to acquire ownership of. |
d | Deleter to store for deletion of the object. |
alloc | Allocator 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.
std::bad_alloc | If 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. |
|
inlinenoexcept |
Exchanges the contents of *this
and other
.
other | Another shared pointer to exchange the contents with. |
Complexity
Constant.
|
inlinenoexcept |
Returns the stored pointer.
SafeSharedPtr
may share ownership of an object while storing a pointer to another object. get()
returns the stored pointer, not the managed pointer.
|
inlinenoexcept |
|
inlinenoexcept |
Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null.
|
inlinenoexcept |
|
inlinenoexcept |
Dereferences the stored pointer, guard it with read lock. The behavior is undefined if the stored pointer is null.
|
inline |
Provides indexed access to the stored array, guard it with write lock.
idx | The array index. |
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.
|
inline |
Provides indexed access to the stored array, guard it with read lock.
idx | The array index. |
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.
|
inlinenoexcept |
Returns the number of SafeSharedPtr
objects referring to the same managed object.
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)
|
inlineexplicitnoexcept |
Checks if *this stores a non-null pointer, i.e. whether get() != nullptr
.
true
if *this
stores a pointer, false
otherwise. SafeSharedPtr
(where use_count() == 0
) may store a non-null pointer accessible by get(), e.g. if it were created using the aliasing constructor.
|
inline |
Checks whether this SafeSharedPtr
precedes other in implementation defined owner-based (as opposed to value-based) order.
Y | Type of the object managed by input pointer. |
M | Type of the mutex used, default is shared_mutex_t. |
R | Type of the read-lock used, default is shared_lock_t. |
W | Type of the write-lock used, default is unique_lock_t. |
other | The SafeSharedPtr to be compared. |
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.
|
inline |
Checks whether this SafeSharedPtr
precedes other in implementation defined owner-based (as opposed to value-based) order.
Y | Type of the object managed by input pointer. |
M | Type of the mutex used, default is shared_mutex_t. |
R | Type of the read-lock used, default is shared_lock_t. |
W | Type of the write-lock used, default is unique_lock_t. |
other | the SafeWeakPtr to be compared. |
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.
|
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.
NOT
recursive, locking multiply times in same thread will cause block.
|
inline |
Unlocks the read lock.
Attempting to unlock a lock that is not locked is an error, and will result in undefined behaviour.
|
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.
NOT
recursive, locking multiply times in same thread will cause block.
|
inline |
Unlocks the write lock.
Attempting to unlock a lock that is not locked is an error, and will result in undefined behaviour.
|
inline |
Generate a RAII guard for read lock, it will call lock_shared() on construction and unlock_shared() on destruction.
|
inline |
|
friend |
|
friend |
|
related |
Creates a shared pointer that manages a new object.
T | Type of object to be created. |
SharedMutex | Type of the mutex used, default is shared_mutex_t. |
SharedLock | Type of the read-lock used, default is shared_lock_t. |
UniqueLock | Type of the write-lock used, default is unique_lock_t. |
Args | Types of arguments in constructor of T . |
args | List 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.
std::bad_alloc | May throw std::bad_alloc or any exception thrown by the constructor of T . If an exception is thrown, the functions have no effect. |
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: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.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.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)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.SafeSharedPtr
constructors, make_shared does not allow a custom deleter.::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...))
.
|
related |
Creates a shared pointer that manages a new object allocated using an allocator.
T | Type of object to be created. |
Alloc | Type of input allocator. |
SharedMutex | Type of the mutex used, default is shared_mutex_t. |
SharedLock | Type of the read-lock used, default is shared_lock_t. |
UniqueLock | Type of the write-lock used, default is unique_lock_t. |
Args | Types of arguments in constructor of T . |
alloc | The Allocator to use. |
args | List 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.
UserDefined | Can throw the exceptions thrown from Alloc::allocate() or from the constructor of T . If an exception is thrown, this function has no effect. |
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. 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.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: 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.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.
|
related |
Applies static_cast to the stored pointer.
T | Type to cast to. |
U | Type to cast from. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
r | The pointer to convert. |
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.
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!
|
related |
Applies dynamic_cast to the stored pointer.
T | Type to cast to. |
U | Type to cast from. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
r | The pointer to convert. |
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.
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!
|
related |
Applies const_cast to the stored pointer.
T | Type to cast to. |
U | Type to cast from. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
r | The pointer to convert. |
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.
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!
|
related |
Applies reinterpret_cast to the stored pointer.
T | Type to cast to. |
U | Type to cast from. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
r | The pointer to convert. |
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.
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!
|
related |
Returns the deleter of specified type, if owned.
Deleter | Type of deleter returned. |
T | Type of the object managed by SafeSharedPtr. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
p | A shared pointer whose deleter needs to be accessed. |
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.
SafeSharedPtr
if, for example, SafeWeakPtrs remain and the implementation doesn't destroy the deleter until the entire control block is destroyed.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex_L | Type of lhs's mutex, will auto-deduct from input. |
SharedLock_L | Type of lhs's read-lock, will auto-deduct from input. |
UniqueLock_L | Type of lhs's write-lock, will auto-deduct from input. |
U | Type of rhs. |
SharedMutex_R | Type of rhs's mutex, will auto-deduct from input. |
SharedLock_R | Type of rhs's read-lock, will auto-deduct from input. |
UniqueLock_R | Type of rhs's write-lock, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex_L | Type of lhs's mutex, will auto-deduct from input. |
SharedLock_L | Type of lhs's read-lock, will auto-deduct from input. |
UniqueLock_L | Type of lhs's write-lock, will auto-deduct from input. |
U | Type of rhs. |
SharedMutex_R | Type of rhs's mutex, will auto-deduct from input. |
SharedLock_R | Type of rhs's read-lock, will auto-deduct from input. |
UniqueLock_R | Type of rhs's write-lock, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
!(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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex_L | Type of lhs's mutex, will auto-deduct from input. |
SharedLock_L | Type of lhs's read-lock, will auto-deduct from input. |
UniqueLock_L | Type of lhs's write-lock, will auto-deduct from input. |
U | Type of rhs. |
SharedMutex_R | Type of rhs's mutex, will auto-deduct from input. |
SharedLock_R | Type of rhs's read-lock, will auto-deduct from input. |
UniqueLock_R | Type of rhs's write-lock, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex_L | Type of lhs's mutex, will auto-deduct from input. |
SharedLock_L | Type of lhs's read-lock, will auto-deduct from input. |
UniqueLock_L | Type of lhs's write-lock, will auto-deduct from input. |
U | Type of rhs. |
SharedMutex_R | Type of rhs's mutex, will auto-deduct from input. |
SharedLock_R | Type of rhs's read-lock, will auto-deduct from input. |
UniqueLock_R | Type of rhs's write-lock, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex_L | Type of lhs's mutex, will auto-deduct from input. |
SharedLock_L | Type of lhs's read-lock, will auto-deduct from input. |
UniqueLock_L | Type of lhs's write-lock, will auto-deduct from input. |
U | Type of rhs. |
SharedMutex_R | Type of rhs's mutex, will auto-deduct from input. |
SharedLock_R | Type of rhs's read-lock, will auto-deduct from input. |
UniqueLock_R | Type of rhs's write-lock, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
!(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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex_L | Type of lhs's mutex, will auto-deduct from input. |
SharedLock_L | Type of lhs's read-lock, will auto-deduct from input. |
UniqueLock_L | Type of lhs's write-lock, will auto-deduct from input. |
U | Type of rhs. |
SharedMutex_R | Type of rhs's mutex, will auto-deduct from input. |
SharedLock_R | Type of rhs's read-lock, will auto-deduct from input. |
UniqueLock_R | Type of rhs's write-lock, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
!(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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand nullptr to compare. |
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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of rhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand nullptr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand nullptr to compare. |
!(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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of rhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand nullptr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
!(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
.
SafeSharedPtr
created using the aliasing constructor.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand nullptr to compare. |
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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of rhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand nullptr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand nullptr to compare. |
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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of rhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand nullptr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand nullptr to compare. |
!(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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of rhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand nullptr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
!(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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of lhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand SafeSharedPtr to compare. |
rhs | The right-hand nullptr to compare. |
!(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
.
|
related |
Compare SafeSharedPtr
object with another input.
T | Type of rhs. |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
lhs | The left-hand nullptr to compare. |
rhs | The right-hand SafeSharedPtr to compare. |
!(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
.
|
related |
Outputs the value of the stored pointer to an output stream.
T | Type of object managed by SafeSharedPtr |
SharedMutex | Type of the mutex used, will auto-deduct from input. |
SharedLock | Type of the read-lock used, will auto-deduct from input. |
UniqueLock | Type of the write-lock used, will auto-deduct from input. |
OStream | Type of output stream. |
os | An output stream supports output pointer type. |
ptr | The data to be inserted into os. |
Inserts the value of the pointer stored in ptr
into the output stream os
.
Equivalent to os << ptr.get()
.
|
related |
Specializes the std::swap
algorithm.
T | Element type of input shared pointers. |
SharedMutex | Type of the mutex used, default is shared_mutex_t. |
SharedLock | Type of the read-lock used, default is shared_lock_t. |
UniqueLock | Type of the write-lock used, default is unique_lock_t. |
lhs | Shared pointer whose contents to swap. |
rhs | Another 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.