| //// |
| Copyright 2017 Peter Dimov |
| |
| Distributed under the Boost Software License, Version 1.0. |
| |
| See accompanying file LICENSE_1_0.txt or copy at |
| http://www.boost.org/LICENSE_1_0.txt |
| //// |
| |
| [#atomic_shared_ptr] |
| # atomic_shared_ptr |
| :toc: |
| :toc-title: |
| :idprefix: atomic_shared_ptr_ |
| |
| ## Description |
| |
| The class template `atomic_shared_ptr<T>` implements the interface of `std::atomic` |
| for a contained value of type `shared_ptr<T>`. Concurrent access to `atomic_shared_ptr` |
| is not a data race. |
| |
| ## Synopsis |
| |
| `atomic_shared_ptr` is defined in `<boost/smart_ptr/atomic_shared_ptr.hpp>`. |
| |
| ``` |
| namespace boost { |
| |
| template<class T> class atomic_shared_ptr { |
| private: |
| |
| shared_ptr<T> p_; // exposition only |
| |
| atomic_shared_ptr(const atomic_shared_ptr&) = delete; |
| atomic_shared_ptr& operator=(const atomic_shared_ptr&) = delete; |
| |
| public: |
| |
| constexpr atomic_shared_ptr() noexcept; |
| atomic_shared_ptr( shared_ptr<T> p ) noexcept; |
| |
| atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept; |
| |
| bool is_lock_free() const noexcept; |
| |
| shared_ptr<T> load( int = 0 ) const noexcept; |
| operator shared_ptr<T>() const noexcept; |
| |
| void store( shared_ptr<T> r, int = 0 ) noexcept; |
| |
| shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept; |
| |
| bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept; |
| bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept; |
| bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept; |
| bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept; |
| |
| bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept; |
| bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept; |
| bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept; |
| bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept; |
| }; |
| } |
| ``` |
| |
| ## Members |
| |
| ``` |
| constexpr atomic_shared_ptr() noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: Default-initializes `p_`. |
| |
| ``` |
| atomic_shared_ptr( shared_ptr<T> p ) noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: Initializes `p_` to `p`. |
| |
| ``` |
| atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: `p_.swap(r)`. |
| Returns:: `*this`. |
| |
| ``` |
| bool is_lock_free() const noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Returns:: `false`. |
| |
| NOTE: This implementation is not lock-free. |
| |
| ``` |
| shared_ptr<T> load( int = 0 ) const noexcept; |
| ``` |
| ``` |
| operator shared_ptr<T>() const noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Returns:: `p_`. |
| |
| NOTE: The `int` argument is intended to be of type `memory_order`, but is ignored. |
| This implementation is lock-based and therefore always sequentially consistent. |
| |
| ``` |
| void store( shared_ptr<T> r, int = 0 ) noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: `p_.swap(r)`. |
| |
| ``` |
| shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: `p_.swap(r)`. |
| Returns:: The old value of `p_`. |
| |
| ``` |
| bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept; |
| ``` |
| ``` |
| bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept; |
| ``` |
| ``` |
| bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept; |
| ``` |
| ``` |
| bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: If `p_` is equivalent to `v`, assigns `w` to `p_`, otherwise assigns `p_` to `v`. |
| Returns:: `true` if `p_` was equivalent to `v`, `false` otherwise. |
| Remarks:: Two `shared_ptr` instances are equivalent if they store the same pointer value and _share ownership_. |
| |
| ``` |
| bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept; |
| ``` |
| ``` |
| bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept; |
| ``` |
| ``` |
| bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept; |
| ``` |
| ``` |
| bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept; |
| ``` |
| [none] |
| * {blank} |
| + |
| Effects:: If `p_` is equivalent to `v`, assigns `std::move(w)` to `p_`, otherwise assigns `p_` to `v`. |
| Returns:: `true` if `p_` was equivalent to `v`, `false` otherwise. |
| Remarks:: The old value of `w` is not preserved in either case. |