1#include <boost/config.hpp>
2
3// atomic_sp_test.cpp
4//
5// Copyright 2008, 2017 Peter Dimov
6//
7// Distributed under the Boost Software License, Version 1.0.
8// See accompanying file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt
10
11
12#include <boost/smart_ptr/atomic_shared_ptr.hpp>
13#include <boost/core/lightweight_test.hpp>
14#include <boost/memory_order.hpp>
15
16//
17
18struct X
19{
20};
21
22#define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) )
23
24int main()
25{
26 // default constructor
27
28 {
29 boost::atomic_shared_ptr<X> apx;
30
31 boost::shared_ptr<X> p2 = apx.load();
32
33 BOOST_TEST_EQ( p2.get(), (X*)0 );
34 BOOST_TEST_EQ( p2.use_count(), 0 );
35 }
36
37 // shared_ptr constructor
38
39 {
40 boost::shared_ptr<X> px( new X );
41 boost::atomic_shared_ptr<X> apx( px );
42
43 boost::shared_ptr<X> p2 = apx.load();
44
45 BOOST_TEST_EQ( px, p2 );
46 BOOST_TEST_EQ( px.use_count(), 3 );
47 BOOST_TEST_EQ( p2.use_count(), 3 );
48 }
49
50 // shared_ptr assignment
51
52 {
53 boost::shared_ptr<X> px0( new X );
54 boost::atomic_shared_ptr<X> apx( px0 );
55
56 boost::shared_ptr<X> px( new X );
57 apx = px;
58
59 boost::shared_ptr<X> p2 = apx.load();
60
61 BOOST_TEST_EQ( px, p2 );
62 BOOST_TEST_EQ( px.use_count(), 3 );
63 BOOST_TEST_EQ( p2.use_count(), 3 );
64 }
65
66 // load, w/ mo
67
68 {
69 boost::shared_ptr<X> px( new X );
70 boost::atomic_shared_ptr<X> apx( px );
71
72 boost::shared_ptr<X> p2 = apx.load( boost::memory_order_acquire );
73
74 BOOST_TEST_EQ( px, p2 );
75 BOOST_TEST_EQ( px.use_count(), 3 );
76 BOOST_TEST_EQ( p2.use_count(), 3 );
77 }
78
79 // operator shared_ptr
80
81 {
82 boost::shared_ptr<X> px( new X );
83 boost::atomic_shared_ptr<X> apx( px );
84
85 boost::shared_ptr<X> p2 = apx;
86
87 BOOST_TEST_EQ( px, p2 );
88 BOOST_TEST_EQ( px.use_count(), 3 );
89 BOOST_TEST_EQ( p2.use_count(), 3 );
90 }
91
92 // store
93
94 {
95 boost::shared_ptr<X> px0( new X );
96 boost::atomic_shared_ptr<X> apx( px0 );
97
98 boost::shared_ptr<X> px( new X );
99 apx.store( r: px );
100
101 boost::shared_ptr<X> p2 = apx.load();
102
103 BOOST_TEST_EQ( px, p2 );
104 BOOST_TEST_EQ( px.use_count(), 3 );
105 BOOST_TEST_EQ( p2.use_count(), 3 );
106 }
107
108 // store, w/ mo
109
110 {
111 boost::shared_ptr<X> px0( new X );
112 boost::atomic_shared_ptr<X> apx( px0 );
113
114 boost::shared_ptr<X> px( new X );
115 apx.store( r: px, boost::memory_order_release );
116
117 boost::shared_ptr<X> p2 = apx.load();
118
119 BOOST_TEST_EQ( px, p2 );
120 BOOST_TEST_EQ( px.use_count(), 3 );
121 BOOST_TEST_EQ( p2.use_count(), 3 );
122 }
123
124 // exchange
125
126 {
127 boost::shared_ptr<X> px0( new X );
128 boost::atomic_shared_ptr<X> apx( px0 );
129
130 boost::shared_ptr<X> px( new X );
131 boost::shared_ptr<X> p1 = apx.exchange( r: px );
132
133 BOOST_TEST_EQ( px0, p1 );
134 BOOST_TEST_EQ( px0.use_count(), 2 );
135 BOOST_TEST_EQ( p1.use_count(), 2 );
136
137 boost::shared_ptr<X> p2 = apx.load();
138
139 BOOST_TEST_EQ( px, p2 );
140 BOOST_TEST_EQ( px.use_count(), 3 );
141 BOOST_TEST_EQ( p2.use_count(), 3 );
142 }
143
144 // exchange, w/ mo
145
146 {
147 boost::shared_ptr<X> px0( new X );
148 boost::atomic_shared_ptr<X> apx( px0 );
149
150 boost::shared_ptr<X> px( new X );
151 boost::shared_ptr<X> p1 = apx.exchange( r: px, boost::memory_order_acq_rel );
152
153 BOOST_TEST_EQ( px0, p1 );
154 BOOST_TEST_EQ( px0.use_count(), 2 );
155 BOOST_TEST_EQ( p1.use_count(), 2 );
156
157 boost::shared_ptr<X> p2 = apx.load();
158
159 BOOST_TEST_EQ( px, p2 );
160 BOOST_TEST_EQ( px.use_count(), 3 );
161 BOOST_TEST_EQ( p2.use_count(), 3 );
162 }
163
164 // compare_exchange_weak
165
166 {
167 boost::shared_ptr<X> px( new X );
168 boost::atomic_shared_ptr<X> apx( px );
169
170 boost::shared_ptr<X> px2( new X );
171 boost::shared_ptr<X> cmp;
172
173 bool r = apx.compare_exchange_weak( v&: cmp, w: px2 );
174 BOOST_TEST( !r );
175 BOOST_TEST_SP_EQ( apx.load(), px );
176 BOOST_TEST_SP_EQ( cmp, px );
177
178 r = apx.compare_exchange_weak( v&: cmp, w: px2 );
179 BOOST_TEST( r );
180 BOOST_TEST_SP_EQ( apx.load(), px2 );
181 }
182
183 // compare_exchange_weak, w/ mo
184
185 {
186 boost::shared_ptr<X> px( new X );
187 boost::atomic_shared_ptr<X> apx( px );
188
189 boost::shared_ptr<X> px2( new X );
190 boost::shared_ptr<X> cmp;
191
192 bool r = apx.compare_exchange_weak( v&: cmp, w: px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
193 BOOST_TEST( !r );
194 BOOST_TEST_SP_EQ( apx.load(), px );
195 BOOST_TEST_SP_EQ( cmp, px );
196
197 r = apx.compare_exchange_weak( v&: cmp, w: px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
198 BOOST_TEST( r );
199 BOOST_TEST_SP_EQ( apx.load(), px2 );
200 }
201
202 // compare_exchange_weak, rv
203
204 {
205 boost::shared_ptr<X> px( new X );
206 boost::atomic_shared_ptr<X> apx( px );
207
208 boost::shared_ptr<X> cmp;
209
210 bool r = apx.compare_exchange_weak( v&: cmp, w: boost::shared_ptr<X>() );
211
212 BOOST_TEST( !r );
213 BOOST_TEST_SP_EQ( apx.load(), px );
214 BOOST_TEST_SP_EQ( cmp, px );
215
216 r = apx.compare_exchange_weak( v&: cmp, w: boost::shared_ptr<X>() );
217
218 BOOST_TEST( r );
219 BOOST_TEST( apx.load().get() == 0 );
220 BOOST_TEST( apx.load().use_count() == 0 );
221 }
222
223 // compare_exchange_weak, rv, w/ mo
224
225 {
226 boost::shared_ptr<X> px( new X );
227 boost::atomic_shared_ptr<X> apx( px );
228
229 boost::shared_ptr<X> cmp;
230
231 bool r = apx.compare_exchange_weak( v&: cmp, w: boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
232
233 BOOST_TEST( !r );
234 BOOST_TEST_SP_EQ( apx.load(), px );
235 BOOST_TEST_SP_EQ( cmp, px );
236
237 r = apx.compare_exchange_weak( v&: cmp, w: boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
238
239 BOOST_TEST( r );
240 BOOST_TEST( apx.load().get() == 0 );
241 BOOST_TEST( apx.load().use_count() == 0 );
242 }
243
244 // compare_exchange_strong
245
246 {
247 boost::shared_ptr<X> px( new X );
248 boost::atomic_shared_ptr<X> apx( px );
249
250 boost::shared_ptr<X> px2( new X );
251 boost::shared_ptr<X> cmp;
252
253 bool r = apx.compare_exchange_strong( v&: cmp, w: px2 );
254 BOOST_TEST( !r );
255 BOOST_TEST_SP_EQ( apx.load(), px );
256 BOOST_TEST_SP_EQ( cmp, px );
257
258 r = apx.compare_exchange_strong( v&: cmp, w: px2 );
259 BOOST_TEST( r );
260 BOOST_TEST_SP_EQ( apx.load(), px2 );
261 }
262
263 // compare_exchange_strong, w/ mo
264
265 {
266 boost::shared_ptr<X> px( new X );
267 boost::atomic_shared_ptr<X> apx( px );
268
269 boost::shared_ptr<X> px2( new X );
270 boost::shared_ptr<X> cmp;
271
272 bool r = apx.compare_exchange_strong( v&: cmp, w: px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
273 BOOST_TEST( !r );
274 BOOST_TEST_SP_EQ( apx.load(), px );
275 BOOST_TEST_SP_EQ( cmp, px );
276
277 r = apx.compare_exchange_strong( v&: cmp, w: px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
278 BOOST_TEST( r );
279 BOOST_TEST_SP_EQ( apx.load(), px2 );
280 }
281
282 // compare_exchange_strong, rv
283
284 {
285 boost::shared_ptr<X> px( new X );
286 boost::atomic_shared_ptr<X> apx( px );
287
288 boost::shared_ptr<X> cmp;
289
290 bool r = apx.compare_exchange_strong( v&: cmp, w: boost::shared_ptr<X>() );
291
292 BOOST_TEST( !r );
293 BOOST_TEST_SP_EQ( apx.load(), px );
294 BOOST_TEST_SP_EQ( cmp, px );
295
296 r = apx.compare_exchange_strong( v&: cmp, w: boost::shared_ptr<X>() );
297
298 BOOST_TEST( r );
299 BOOST_TEST( apx.load().get() == 0 );
300 BOOST_TEST( apx.load().use_count() == 0 );
301 }
302
303 // compare_exchange_strong, rv, w/ mo
304
305 {
306 boost::shared_ptr<X> px( new X );
307 boost::atomic_shared_ptr<X> apx( px );
308
309 boost::shared_ptr<X> cmp;
310
311 bool r = apx.compare_exchange_strong( v&: cmp, w: boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
312
313 BOOST_TEST( !r );
314 BOOST_TEST_SP_EQ( apx.load(), px );
315 BOOST_TEST_SP_EQ( cmp, px );
316
317 r = apx.compare_exchange_strong( v&: cmp, w: boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
318
319 BOOST_TEST( r );
320 BOOST_TEST( apx.load().get() == 0 );
321 BOOST_TEST( apx.load().use_count() == 0 );
322 }
323
324 return boost::report_errors();
325}
326

source code of boost/libs/smart_ptr/test/atomic_sp_test.cpp