| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
 | 
					
						
							|  |  |  | #define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  atomic_shared_ptr.hpp
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  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)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  See http://www.boost.org/libs/smart_ptr/ for documentation.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/smart_ptr/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  | #include <boost/smart_ptr/detail/spinlock.hpp>
 | 
					
						
							|  |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace boost | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class T> class atomic_shared_ptr | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     boost::shared_ptr<T> p_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |     mutable boost::detail::spinlock l_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     atomic_shared_ptr(const atomic_shared_ptr&); | 
					
						
							|  |  |  |     atomic_shared_ptr& operator=(const atomic_shared_ptr&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  | private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         l_.lock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if( p_._internal_equiv( v ) ) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             p_.swap( w ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             l_.unlock(); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             shared_ptr<T> tmp( p_ ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             l_.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             tmp.swap( v ); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 07:56:42 +03:00
										 |  |  | #if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 02:17:28 +03:00
										 |  |  |     atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |         : p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 07:56:42 +03:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     atomic_shared_ptr() BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; | 
					
						
							|  |  |  |         std::memcpy( &l_, &init, sizeof( init ) ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |     atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 20:19:37 +03:00
										 |  |  | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
					
						
							|  |  |  |         : p_( std::move( p ) ) | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         : p_( p ) | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; | 
					
						
							|  |  |  |         std::memcpy( &l_, &init, sizeof( init ) ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 02:17:28 +03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |         p_.swap( r ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     shared_ptr<T> load() const BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |         return p_; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |         return p_; | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     operator shared_ptr<T>() const BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |         return p_; | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |         p_.swap( r ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |         p_.swap( r ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         { | 
					
						
							|  |  |  |             boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |             p_.swap( r ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return std::move( r ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return r; | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             boost::detail::spinlock::scoped_lock lock( l_ ); | 
					
						
							|  |  |  |             p_.swap( r ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return std::move( r ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, w ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, w ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, w ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return compare_exchange( v, w ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return compare_exchange( v, w ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, w ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return compare_exchange( v, std::move( w ) ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return compare_exchange( v, std::move( w ) ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, std::move( w ) ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, std::move( w ) ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, std::move( w ) ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-07 17:45:07 +02:00
										 |  |  |     bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-17 23:37:18 +03:00
										 |  |  |         return compare_exchange( v, std::move( w ) ); | 
					
						
							| 
									
										
										
										
											2017-06-16 18:26:17 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace boost
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif  // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
 |