Annex D (normative) Compatibility features [depr]

D.18 Deprecated shared_­ptr atomic access [depr.util.smartptr.shared.atomic]

The header <memory> ([memory.syn]) has the following additions:
namespace std {
  template<class T>
    bool atomic_is_lock_free(const shared_ptr<T>* p);

  template<class T>
    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
  template<class T>
    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);

  template<class T>
    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
  template<class T>
    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

  template<class T>
    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
  template<class T>
    shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

  template<class T>
    bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
  template<class T>
    bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
  template<class T>
    bool atomic_compare_exchange_weak_explicit(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
      memory_order success, memory_order failure);
  template<class T>
    bool atomic_compare_exchange_strong_explicit(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
      memory_order success, memory_order failure);
}
Concurrent access to a shared_­ptr object from multiple threads does not introduce a data race if the access is done exclusively via the functions in this subclause and the instance is passed as their first argument.
The meaning of the arguments of type memory_­order is explained in [atomics.order].
template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p);
Requires: p shall not be null.
Returns: true if atomic access to *p is lock-free, false otherwise.
Throws: Nothing.
template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p);
Requires: p shall not be null.
Returns: atomic_­load_­explicit(p, memory_­order​::​seq_­cst).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
Requires: p shall not be null.
Requires: mo shall not be memory_­order​::​release or memory_­order​::​acq_­rel.
Returns: *p.
Throws: Nothing.
template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
Requires: p shall not be null.
Effects: As if by atomic_­store_­explicit(p, r, memory_­order​::​seq_­cst).
Throws: Nothing.
template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
Requires: p shall not be null.
Requires: mo shall not be memory_­order​::​acquire or memory_­order​::​acq_­rel.
Effects: As if by p->swap(r).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
Requires: p shall not be null.
Returns: atomic_­exchange_­explicit(p, r, memory_­order​::​seq_­cst).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
Requires: p shall not be null.
Effects: As if by p->swap(r).
Returns: The previous value of *p.
Throws: Nothing.
template<class T> bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
Requires: p shall not be null and v shall not be null.
Returns:
atomic_compare_exchange_weak_explicit(p, v, w, memory_order::seq_cst, memory_order::seq_cst)
Throws: Nothing.
template<class T> bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
Returns:
atomic_compare_exchange_strong_explicit(p, v, w, memory_order::seq_cst,
                                        memory_order::seq_cst)
template<class T> bool atomic_compare_exchange_weak_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure); template<class T> bool atomic_compare_exchange_strong_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure);
Requires: p shall not be null and v shall not be null.
The failure argument shall not be memory_­order​::​release nor memory_­order​::​acq_­rel.
Effects: If *p is equivalent to *v, assigns w to *p and has synchronization semantics corresponding to the value of success, otherwise assigns *p to *v and has synchronization semantics corresponding to the value of failure.
Returns: true if *p was equivalent to *v, false otherwise.
Throws: Nothing.
Remarks: Two shared_­ptr objects are equivalent if they store the same pointer value and share ownership.
The weak form may fail spuriously.