1//
2// sp_array_test.cpp
3//
4// Copyright (c) 2012 Peter Dimov
5//
6// Distributed under the Boost Software License, Version 1.0.
7// See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt
9//
10
11#include <boost/shared_ptr.hpp>
12#include <boost/weak_ptr.hpp>
13#include <boost/enable_shared_from_this.hpp>
14#include <boost/core/lightweight_test.hpp>
15#include <memory>
16#include <utility>
17
18class X: public boost::enable_shared_from_this< X >
19{
20public:
21
22 static int allocations;
23 static int instances;
24
25 X()
26 {
27 ++instances;
28 }
29
30 ~X()
31 {
32 --instances;
33 }
34
35 void* operator new[]( std::size_t n )
36 {
37 ++allocations;
38 return ::operator new[]( n );
39 }
40
41 void operator delete[]( void* p )
42 {
43 --allocations;
44 ::operator delete[]( p );
45 }
46
47private:
48
49 X( X const& );
50 X& operator=( X const& );
51};
52
53int X::allocations = 0;
54int X::instances = 0;
55
56template< class T> class array_deleter
57{
58public:
59
60 static int calls;
61
62 void operator()( T * p ) const
63 {
64 ++calls;
65 delete[] p;
66 }
67
68private:
69
70 template< class Y > void operator()( Y * p ) const;
71};
72
73template< class T > int array_deleter< T >::calls = 0;
74
75int main()
76{
77 BOOST_TEST( X::allocations == 0 );
78 BOOST_TEST( X::instances == 0 );
79
80 {
81 boost::shared_ptr<X[]> px;
82 BOOST_TEST( !px );
83
84 BOOST_TEST( X::allocations == 0 );
85 BOOST_TEST( X::instances == 0 );
86
87 boost::shared_ptr<X[]> px2( new X[ 3 ] );
88 BOOST_TEST( px2 );
89
90 try
91 {
92 px2[0].shared_from_this();
93 BOOST_ERROR( "px2[0].shared_from_this() failed to throw" );
94 }
95 catch( boost::bad_weak_ptr const& )
96 {
97 }
98 catch( ... )
99 {
100 BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" );
101 }
102
103 BOOST_TEST( X::allocations == 1 );
104 BOOST_TEST( X::instances == 3 );
105
106 {
107 X & rx = px2[ 0 ];
108 BOOST_TEST( &rx == px2.get() );
109 }
110
111 boost::shared_ptr<X const[]> px3( px2 );
112 BOOST_TEST( px3 == px2 );
113 BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) );
114
115 {
116 X const & rx = px3[ 1 ];
117 BOOST_TEST( &rx == px3.get() + 1 );
118 }
119
120 px3.reset();
121 px3 = px2;
122 BOOST_TEST( px3 == px2 );
123 BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) );
124
125 boost::shared_ptr<X volatile[]> px4( px2 );
126 BOOST_TEST( px4 == px2 );
127 BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) );
128
129 {
130 X volatile & rx = px4[ 2 ];
131 BOOST_TEST( &rx == px4.get() + 2 );
132 }
133
134 px4.reset();
135 px4 = px2;
136 BOOST_TEST( px4 == px2 );
137 BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) );
138
139 boost::shared_ptr<void> px5( px2 );
140 BOOST_TEST( px5 == px2 );
141 BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) );
142
143 px5.reset();
144 px5 = px2;
145 BOOST_TEST( px5 == px2 );
146 BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) );
147
148 boost::weak_ptr<X[]> wp( px );
149 BOOST_TEST( wp.lock() == px );
150
151 boost::weak_ptr<X[]> wp2( px2 );
152 BOOST_TEST( wp2.lock() == px2 );
153
154 wp2.reset();
155 wp2 = px2;
156 BOOST_TEST( wp2.lock() == px2 );
157
158 boost::weak_ptr<X const[]> wp3( px2 );
159 BOOST_TEST( wp3.lock() == px2 );
160
161 wp3.reset();
162 wp3 = px2;
163 BOOST_TEST( wp3.lock() == px2 );
164
165 boost::weak_ptr<X volatile[]> wp4( px2 );
166 BOOST_TEST( wp4.lock() == px2 );
167
168 wp4.reset();
169 wp4 = px2;
170 BOOST_TEST( wp4.lock() == px2 );
171
172 boost::weak_ptr<void> wp5( px2 );
173 BOOST_TEST( wp5.lock() == px2 );
174
175 wp5.reset();
176 wp5 = px2;
177 BOOST_TEST( wp5.lock() == px2 );
178
179 px2.reset();
180
181 BOOST_TEST( X::allocations == 1 );
182 BOOST_TEST( X::instances == 3 );
183
184 px3.reset();
185 px4.reset();
186 px5.reset();
187
188 BOOST_TEST( X::allocations == 0 );
189 BOOST_TEST( X::instances == 0 );
190
191 BOOST_TEST( wp2.lock() == 0 );
192 BOOST_TEST( wp3.lock() == 0 );
193 BOOST_TEST( wp4.lock() == 0 );
194 BOOST_TEST( wp5.lock() == 0 );
195 }
196
197#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
198
199 {
200 std::unique_ptr<X[]> px( new X[ 4 ] );
201 BOOST_TEST( X::allocations == 1 );
202 BOOST_TEST( X::instances == 4 );
203
204 boost::shared_ptr<X[]> px2( std::move( px ) );
205 BOOST_TEST( X::allocations == 1 );
206 BOOST_TEST( X::instances == 4 );
207 BOOST_TEST( px.get() == 0 );
208
209 try
210 {
211 px2[0].shared_from_this();
212 BOOST_ERROR( "px2[0].shared_from_this() failed to throw" );
213 }
214 catch( boost::bad_weak_ptr const& )
215 {
216 }
217 catch( ... )
218 {
219 BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" );
220 }
221
222 px2.reset();
223
224 BOOST_TEST( X::allocations == 0 );
225 BOOST_TEST( X::instances == 0 );
226 }
227
228 {
229 std::unique_ptr<X[]> px( new X[ 4 ] );
230 BOOST_TEST( X::allocations == 1 );
231 BOOST_TEST( X::instances == 4 );
232
233 boost::shared_ptr<X[]> px2;
234 px2 = std::move( px );
235 BOOST_TEST( X::allocations == 1 );
236 BOOST_TEST( X::instances == 4 );
237 BOOST_TEST( px.get() == 0 );
238
239 try
240 {
241 px2[0].shared_from_this();
242 BOOST_ERROR( "px2[0].shared_from_this() failed to throw" );
243 }
244 catch( boost::bad_weak_ptr const& )
245 {
246 }
247 catch( ... )
248 {
249 BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" );
250 }
251
252 px2.reset();
253
254 BOOST_TEST( X::allocations == 0 );
255 BOOST_TEST( X::instances == 0 );
256 }
257
258#endif
259
260 {
261 boost::shared_ptr<X[]> px( new X[ 5 ], array_deleter< X >() );
262 BOOST_TEST( X::allocations == 1 );
263 BOOST_TEST( X::instances == 5 );
264
265 try
266 {
267 px[0].shared_from_this();
268 BOOST_ERROR( "px[0].shared_from_this() failed to throw" );
269 }
270 catch( boost::bad_weak_ptr const& )
271 {
272 }
273 catch( ... )
274 {
275 BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" );
276 }
277
278 px.reset();
279
280 BOOST_TEST( X::allocations == 0 );
281 BOOST_TEST( X::instances == 0 );
282 BOOST_TEST( array_deleter< X >::calls == 1 );
283 }
284
285 {
286 boost::shared_ptr<X[]> px( new X[ 6 ], array_deleter< X >(), std::allocator< X >() );
287 BOOST_TEST( X::allocations == 1 );
288 BOOST_TEST( X::instances == 6 );
289
290 try
291 {
292 px[0].shared_from_this();
293 BOOST_ERROR( "px[0].shared_from_this() failed to throw" );
294 }
295 catch( boost::bad_weak_ptr const& )
296 {
297 }
298 catch( ... )
299 {
300 BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" );
301 }
302
303 px.reset();
304
305 BOOST_TEST( X::allocations == 0 );
306 BOOST_TEST( X::instances == 0 );
307 BOOST_TEST( array_deleter< X >::calls == 2 );
308 }
309
310 return boost::report_errors();
311}
312

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