]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/atomic_shared_ptr.hpp
7c485070f832d088f35540f6b62954dd091c3250
[ceph.git] / ceph / src / boost / boost / smart_ptr / atomic_shared_ptr.hpp
1 #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
3
4 //
5 // atomic_shared_ptr.hpp
6 //
7 // Copyright 2017 Peter Dimov
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 //
13 // See http://www.boost.org/libs/smart_ptr/ for documentation.
14 //
15
16 #include <boost/smart_ptr/shared_ptr.hpp>
17 #include <boost/smart_ptr/detail/spinlock.hpp>
18 #include <cstring>
19
20 namespace boost
21 {
22
23 template<class T> class atomic_shared_ptr
24 {
25 private:
26
27 boost::shared_ptr<T> p_;
28
29 mutable boost::detail::spinlock l_;
30
31 atomic_shared_ptr(const atomic_shared_ptr&);
32 atomic_shared_ptr& operator=(const atomic_shared_ptr&);
33
34 private:
35
36 bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
37 {
38 l_.lock();
39
40 if( p_._internal_equiv( v ) )
41 {
42 p_.swap( w );
43
44 l_.unlock();
45 return true;
46 }
47 else
48 {
49 shared_ptr<T> tmp( p_ );
50
51 l_.unlock();
52
53 tmp.swap( v );
54 return false;
55 }
56 }
57
58 public:
59
60 #if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
61
62 constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT
63 {
64 }
65
66 #else
67
68 atomic_shared_ptr() BOOST_SP_NOEXCEPT
69 {
70 boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
71 std::memcpy( &l_, &init, sizeof( init ) );
72 }
73
74 #endif
75
76 atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
77 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
78 : p_( std::move( p ) )
79 #else
80 : p_( p )
81 #endif
82 {
83 boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
84 std::memcpy( &l_, &init, sizeof( init ) );
85 }
86
87 atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
88 {
89 boost::detail::spinlock::scoped_lock lock( l_ );
90 p_.swap( r );
91
92 return *this;
93 }
94
95 BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
96 {
97 return false;
98 }
99
100 shared_ptr<T> load() const BOOST_SP_NOEXCEPT
101 {
102 boost::detail::spinlock::scoped_lock lock( l_ );
103 return p_;
104 }
105
106 template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT
107 {
108 boost::detail::spinlock::scoped_lock lock( l_ );
109 return p_;
110 }
111
112 operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
113 {
114 boost::detail::spinlock::scoped_lock lock( l_ );
115 return p_;
116 }
117
118 void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
119 {
120 boost::detail::spinlock::scoped_lock lock( l_ );
121 p_.swap( r );
122 }
123
124 template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
125 {
126 boost::detail::spinlock::scoped_lock lock( l_ );
127 p_.swap( r );
128 }
129
130 shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
131 {
132 {
133 boost::detail::spinlock::scoped_lock lock( l_ );
134 p_.swap( r );
135 }
136
137 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
138
139 return std::move( r );
140
141 #else
142
143 return r;
144
145 #endif
146 }
147
148 template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
149 {
150 {
151 boost::detail::spinlock::scoped_lock lock( l_ );
152 p_.swap( r );
153 }
154
155 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
156
157 return std::move( r );
158
159 #else
160
161 return r;
162
163 #endif
164 }
165
166 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
167 {
168 return compare_exchange( v, w );
169 }
170
171 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
172 {
173 return compare_exchange( v, w );
174 }
175
176 bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
177 {
178 return compare_exchange( v, w );
179 }
180
181 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
182 {
183 return compare_exchange( v, w );
184 }
185
186 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
187 {
188 return compare_exchange( v, w );
189 }
190
191 bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
192 {
193 return compare_exchange( v, w );
194 }
195
196 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
197
198 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
199 {
200 return compare_exchange( v, std::move( w ) );
201 }
202
203 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
204 {
205 return compare_exchange( v, std::move( w ) );
206 }
207
208 bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
209 {
210 return compare_exchange( v, std::move( w ) );
211 }
212
213 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
214 {
215 return compare_exchange( v, std::move( w ) );
216 }
217
218 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
219 {
220 return compare_exchange( v, std::move( w ) );
221 }
222
223 bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
224 {
225 return compare_exchange( v, std::move( w ) );
226 }
227
228 #endif
229 };
230
231 } // namespace boost
232
233 #endif // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED