Atomic Smart Pointers

General

This section provides alternatives to raw pointers for thread-safe atomic pointer operations, and defines the atomic_shared_ptr and atomic_weak_ptr class templates.

The class templates atomic_shared_ptr<T> and atomic_weak_ptr<T> have the corresponding non-atomic types shared_ptr<T> and weak_ptr<T>. The template parameter T of these class templates may be an incomplete type.

The behavior of all operations is as specified in , unless stated otherwise.

Header <experimental/atomic> synopsis


#include <atomic>


namespace std {
namespace experimental {
inline namespace concurrency_v1 {

  template <class T> struct atomic_shared_ptr;
  template <class T> struct atomic_weak_ptr;

} // namespace concurrency_v1
} // namespace experimental
} // namespace st


Class template atomic_shared_ptr


namespace std {
  namespace experimental {
  inline namespace concurrency_v1 {

  template <class T> struct atomic_shared_ptr {
    bool is_lock_free() const noexcept;
    void store(shared_ptr<T>, memory_order = memory_order_seq_cst) noexcept;
    shared_ptr<T> load(memory_order = memory_order_seq_cst) const noexcept;
    operator shared_ptr<T>() const noexcept;
    
    shared_ptr<T> exchange(shared_ptr<T>, 
      memory_order = memory_order_seq_cst) noexcept;
    
    bool compare_exchange_weak(shared_ptr<T>&, const shared_ptr<T>&,
      memory_order, memory_order) noexcept;
    bool compare_exchange_weak(shared_ptr<T>&, shared_ptr<T>&&, 
      memory_order,  memory_order) noexcept;
    bool compare_exchange_weak(shared_ptr<T>&, const shared_ptr<T>&,
      memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(shared_ptr<T>&, shared_ptr<T>&&, 
      memory_order = memory_order_seq_cst) noexcept;

    bool compare_exchange_strong(shared_ptr<T>&, const shared_ptr<T>&,
      memory_order, memory_order) noexcept;
    bool compare_exchange_strong(shared_ptr<T>&, shared_ptr<T>&&,
      memory_order, memory_order) noexcept;
    bool compare_exchange_strong(shared_ptr<T>&, const shared_ptr<T>&,
      memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(shared_ptr<T>&, shared_ptr<T>&&, 
      memory_order = memory_order_seq_cst) noexcept;

    constexpr atomic_shared_ptr() noexcept = default;
    atomic_shared_ptr(shared_ptr<T>) noexcept;
    atomic_shared_ptr(const atomic_shared_ptr&) = delete;
    atomic_shared_ptr& operator=(const atomic_shared_ptr&) = delete;
    atomic_shared_ptr& operator=(shared_ptr<T>) noexcept;
  };
  } // namespace concurrency_v1
  } // namespace experimental
} // namespace std

constexpr atomic_shared_ptr() noexcept = default; Initializes the atomic object to an empty value.

Class template atomic_weak_ptr


namespace std {
  namespace experimental {
  inline namespace concurrency_v1 {

  template <class T> struct atomic_weak_ptr {
    bool is_lock_free() const noexcept;
    void store(weak_ptr<T>, memory_order = memory_order_seq_cst) noexcept;
    weak_ptr<T> load(memory_order = memory_order_seq_cst) const noexcept;
    operator weak_ptr<T>() const noexcept;

    weak_ptr<T> exchange(weak_ptr<T>,
      memory_order = memory_order_seq_cst) noexcept;

    bool compare_exchange_weak(weak_ptr<T>&, const weak_ptr<T>&,
      memory_order, memory_order) noexcept;
    bool compare_exchange_weak(weak_ptr<T>&, weak_ptr<T>&&,
      memory_order, memory_order) noexcept;
    bool compare_exchange_weak(weak_ptr<T>&, const weak_ptr<T>&, 
      memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(weak_ptr<T>&, weak_ptr<T>&&, 
      memory_order = memory_order_seq_cst) noexcept;

    bool compare_exchange_strong(weak_ptr<T>&, const weak_ptr<T>&, 
      memory_order, memory_order) noexcept;
    bool compare_exchange_strong(weak_ptr<T>&, weak_ptr<T>&&, 
      memory_order, memory_order) noexcept;
    bool compare_exchange_strong(weak_ptr<T>&, const weak_ptr<T>&, 
      memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(weak_ptr<T>&, weak_ptr<T>&&, 
      memory_order = memory_order_seq_cst) noexcept;

    constexpr atomic_weak_ptr() noexcept = default;
    atomic_weak_ptr(weak_ptr<T>) noexcept;
    atomic_weak_ptr(const atomic_weak_ptr&) = delete;
    atomic_weak_ptr& operator=(const atomic_weak_ptr&) = delete;
    atomic_weak_ptr& operator=(weak_ptr<T>) noexcept;
  };
  } // namespace concurrency_v1
  } // namespace experimental
} // namespace std

constexpr atomic_weak_ptr() noexcept = default; Initializes the atomic object to an empty value.

When any operation on an atomic_shared_ptr or atomic_weak_ptr causes an object to be destroyed or memory to be deallocated, that destruction or deallocation shall be sequenced after the changes to the atomic object's state.

This prevents potential deadlock if the atomic smart pointer operation is not lock-free, such as by including a spinlock as part of the atomic object's state, and the destruction or the deallocation may attempt to acquire a lock.

These types replace all known uses of the functions in .