MADNESS 0.10.1
madness::atomic_shared_ptr< T > Class Template Reference

#include <atomic_shared_ptr.h>

Public Member Functions

constexpr atomic_shared_ptr () noexcept=default
 atomic_shared_ptr (atomic_shared_ptr &&other) noexcept
 atomic_shared_ptr (const atomic_shared_ptr &other) noexcept
 Copy-constructs by atomically loading the other pointer.
 atomic_shared_ptr (std::shared_ptr< T > p) noexcept
std::shared_ptr< T > exchange (std::shared_ptr< T > p={}, std::memory_order order=std::memory_order_seq_cst) noexcept
 operator bool () const noexcept
 operator std::shared_ptr< T > () const noexcept
bool operator!= (const atomic_shared_ptr &r) const noexcept
const T * operator-> () const noexcept
T * operator-> () noexcept
atomic_shared_ptr & operator= (atomic_shared_ptr &&other) noexcept
atomic_shared_ptr & operator= (const atomic_shared_ptr &other) noexcept
 Copy-assigns by atomically loading from other and storing.
atomic_shared_ptr & operator= (std::shared_ptr< T > p) noexcept
 Assigns a new shared_ptr value atomically.
bool operator== (const atomic_shared_ptr &r) const noexcept
void reset ()
 Replaces the stored pointer with an empty shared pointer.
void reset (T *p)
 Replaces the stored pointer, adopting p (may be null).
long use_count () const noexcept

Private Member Functions

std::shared_ptr< T > do_load () const noexcept
void do_store (std::shared_ptr< T > p) noexcept

Private Attributes

std::shared_ptr< T > ptr_

Detailed Description

template<typename T>
class madness::atomic_shared_ptr< T >

A std::shared_ptr-like handle backed by atomic storage.

Uses std::atomic<std::shared_ptr<T>> when available (C++20), otherwise falls back to the pre-C++20 atomic free functions on std::shared_ptr. The public API mirrors std::shared_ptr (copy construction/assignment, operator->, operator bool, implicit conversion, reset, use_count, equality comparison) plus a single extension, exchange(), needed for the move-optimisation in Future::get()&&.

Note
Move operations are explicitly provided: they atomically take the value from the source (leaving it empty) via a relaxed-order exchange. This is necessary because (a) user-declared copy operations would otherwise suppress the implicit move operations, and (b) std::atomic is non-movable in the C++20 backend, so the implicit move would silently fall back to copy.
All loads/stores and move operations use memory_order_relaxed, relying on the caller to provide necessary ordering guarantees. The exception is exchange(), which defaults to memory_order_seq_cst to match the pre-C++20 std::atomic_exchange behaviour it replaces.

Constructor & Destructor Documentation

◆ atomic_shared_ptr() [1/4]

template<typename T>
madness::atomic_shared_ptr< T >::atomic_shared_ptr ( )
constexprdefaultnoexcept

◆ atomic_shared_ptr() [2/4]

template<typename T>
madness::atomic_shared_ptr< T >::atomic_shared_ptr ( std::shared_ptr< T > p)
inlinenoexcept

References atomic_shared_ptr(), p(), and ptr_.

◆ atomic_shared_ptr() [3/4]

template<typename T>
madness::atomic_shared_ptr< T >::atomic_shared_ptr ( const atomic_shared_ptr< T > & other)
inlinenoexcept

Copy-constructs by atomically loading the other pointer.

References atomic_shared_ptr().

◆ atomic_shared_ptr() [4/4]

template<typename T>
madness::atomic_shared_ptr< T >::atomic_shared_ptr ( atomic_shared_ptr< T > && other)
inlinenoexcept

Move-constructs by atomically taking the value from other, which is left empty. Uses memory_order_relaxed (consistent with do_load / do_store); caller is responsible for any synchronization.

References atomic_shared_ptr().

Member Function Documentation

◆ do_load()

◆ do_store()

template<typename T>
void madness::atomic_shared_ptr< T >::do_store ( std::shared_ptr< T > p)
inlineprivatenoexcept

References p(), and ptr_.

Referenced by operator=(), operator=(), operator=(), reset(), and reset().

◆ exchange()

template<typename T>
std::shared_ptr< T > madness::atomic_shared_ptr< T >::exchange ( std::shared_ptr< T > p = {},
std::memory_order order = std::memory_order_seq_cst )
inlinenoexcept

Atomically replaces the stored pointer with p and returns the old value. This is the only operation that differs from std::shared_ptr. Defaults to memory_order_seq_cst to match the pre-C++20 std::atomic_exchange behaviour this replaces.

References p().

◆ operator bool()

template<typename T>
madness::atomic_shared_ptr< T >::operator bool ( ) const
inlineexplicitnoexcept

References do_load().

◆ operator std::shared_ptr< T >()

template<typename T>
madness::atomic_shared_ptr< T >::operator std::shared_ptr< T > ( ) const
inlinenoexcept

Implicit conversion to shared_ptr, used for lifetime extension and APIs that require a shared_ptr (e.g. RemoteReference).

◆ operator!=()

template<typename T>
bool madness::atomic_shared_ptr< T >::operator!= ( const atomic_shared_ptr< T > & r) const
inlinenoexcept

References atomic_shared_ptr(), and do_load().

◆ operator->() [1/2]

template<typename T>
const T * madness::atomic_shared_ptr< T >::operator-> ( ) const
inlinenoexcept

Dereferences the stored pointer, const overload. Safe because do_load() returns a shared_ptr temporary whose lifetime extends to the end of the full expression containing the -> call, keeping the referent alive across the dereference.

References do_load().

◆ operator->() [2/2]

template<typename T>
T * madness::atomic_shared_ptr< T >::operator-> ( )
inlinenoexcept

Dereferences the stored pointer. Safe because do_load() returns a shared_ptr temporary whose lifetime extends to the end of the full expression containing the -> call, keeping the referent alive across the dereference.

References do_load().

◆ operator=() [1/3]

template<typename T>
atomic_shared_ptr & madness::atomic_shared_ptr< T >::operator= ( atomic_shared_ptr< T > && other)
inlinenoexcept

Move-assigns by atomically taking the value from other, which is left empty. Self-assignment is a no-op.

References atomic_shared_ptr(), and do_store().

◆ operator=() [2/3]

template<typename T>
atomic_shared_ptr & madness::atomic_shared_ptr< T >::operator= ( const atomic_shared_ptr< T > & other)
inlinenoexcept

Copy-assigns by atomically loading from other and storing.

References atomic_shared_ptr(), and do_store().

◆ operator=() [3/3]

template<typename T>
atomic_shared_ptr & madness::atomic_shared_ptr< T >::operator= ( std::shared_ptr< T > p)
inlinenoexcept

Assigns a new shared_ptr value atomically.

References atomic_shared_ptr(), do_store(), and p().

◆ operator==()

template<typename T>
bool madness::atomic_shared_ptr< T >::operator== ( const atomic_shared_ptr< T > & r) const
inlinenoexcept

References atomic_shared_ptr(), and do_load().

◆ reset() [1/2]

template<typename T>
void madness::atomic_shared_ptr< T >::reset ( )
inline

Replaces the stored pointer with an empty shared pointer.

References do_store().

◆ reset() [2/2]

template<typename T>
void madness::atomic_shared_ptr< T >::reset ( T * p)
inline

Replaces the stored pointer, adopting p (may be null).

References do_store(), and p().

◆ use_count()

template<typename T>
long madness::atomic_shared_ptr< T >::use_count ( ) const
inlinenoexcept

References do_load().

Member Data Documentation

◆ ptr_

template<typename T>
std::shared_ptr<T> madness::atomic_shared_ptr< T >::ptr_
private

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