diff --git a/doc/smart_ptr/shared_ptr.adoc b/doc/smart_ptr/shared_ptr.adoc index 594c740..0e0ef82 100644 --- a/doc/smart_ptr/shared_ptr.adoc +++ b/doc/smart_ptr/shared_ptr.adoc @@ -220,6 +220,30 @@ namespace boost { operator<< (std::basic_ostream & os, shared_ptr const & p); template D * get_deleter(shared_ptr const & p) noexcept; + + template bool atomic_is_lock_free( shared_ptr const * p ) noexcept; + + template shared_ptr atomic_load( shared_ptr const * p ) noexcept; + template + shared_ptr atomic_load_explicit( shared_ptr const * p, int ) noexcept; + + template + void atomic_store( shared_ptr * p, shared_ptr r ) noexcept; + template + void atomic_store_explicit( shared_ptr * p, shared_ptr r, int ) noexcept; + + template + shared_ptr atomic_exchange( shared_ptr * p, shared_ptr r ) noexcept; + template + shared_ptr atomic_exchange_explicit( + shared_ptr * p, shared_ptr r, int ) noexcept; + + template + bool atomic_compare_exchange( + shared_ptr * p, shared_ptr * v, shared_ptr w ) noexcept; + template + bool atomic_compare_exchange_explicit( + shared_ptr * p, shared_ptr * v, shared_ptr w, int, int ) noexcept; } ``` @@ -783,6 +807,82 @@ template + Returns:: If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0. +### Atomic Access + +NOTE: The function in this section are atomic with respect to the first `shared_ptr` argument, + identified by `*p`. Concurrent access to the same `shared_ptr` instance is not a data race, if + done exclusively by the functions in this section. + +``` +template bool atomic_is_lock_free( shared_ptr const * p ) noexcept; +``` +[none] +* {blank} ++ +Returns:: `false`. + +NOTE: This implementation is not lock-free. + +``` +template shared_ptr atomic_load( shared_ptr const * p ) noexcept; +``` +``` +template shared_ptr atomic_load_explicit( shared_ptr const * p, int ) noexcept; +``` +[none] +* {blank} ++ +Returns:: `*p`. + +NOTE: The `int` argument is the `memory_order`, but this implementation does not use it, as it's lock-based + and therefore always sequentially consistent. + +``` +template + void atomic_store( shared_ptr * p, shared_ptr r ) noexcept; +``` +``` +template + void atomic_store_explicit( shared_ptr * p, shared_ptr r, int ) noexcept; +``` +[none] +* {blank} ++ +Effects:: `p\->swap(r)`. + +``` +template + shared_ptr atomic_exchange( shared_ptr * p, shared_ptr r ) noexcept; +``` +``` +template + shared_ptr atomic_exchange_explicit( + shared_ptr * p, shared_ptr r, int ) noexcept; +``` +[none] +* {blank} ++ +Effects:: `p\->swap(r)`. +Returns:: The old value of `*p`. + +``` +template + bool atomic_compare_exchange( + shared_ptr * p, shared_ptr * v, shared_ptr w ) noexcept; +``` +``` +template + bool atomic_compare_exchange_explicit( + shared_ptr * p, shared_ptr * v, shared_ptr w, int, int ) 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_. + + ## Example See link:../../example/shared_ptr_example.cpp[shared_ptr_example.cpp] for a complete example program. The program builds a diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 47d8339..c87901a 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -1090,7 +1090,7 @@ template shared_ptr atomic_exchange( shared_ptr * p, shared_ptr shared_ptr atomic_exchange_explicit( shared_ptr * p, shared_ptr r, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT +template shared_ptr inline atomic_exchange_explicit( shared_ptr * p, shared_ptr r, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT { return atomic_exchange( p, r ); // std::move( r ) }