1//
2// sp_array_n_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[3]> px;
82 BOOST_TEST( !px );
83
84 BOOST_TEST( X::allocations == 0 );
85 BOOST_TEST( X::instances == 0 );
86
87 boost::shared_ptr<X[3]> 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[3]> 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[3]> 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[3]> wp( px );
149 BOOST_TEST( wp.lock() == px );
150
151 boost::weak_ptr<X[3]> 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[3]> 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[3]> 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 {
198 boost::shared_ptr<X[5]> px( new X[ 5 ], array_deleter< X >() );
199 BOOST_TEST( X::allocations == 1 );
200 BOOST_TEST( X::instances == 5 );
201
202 try
203 {
204 px[0].shared_from_this();
205 BOOST_ERROR( "px[0].shared_from_this() failed to throw" );
206 }
207 catch( boost::bad_weak_ptr const& )
208 {
209 }
210 catch( ... )
211 {
212 BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" );
213 }
214
215 px.reset();
216
217 BOOST_TEST( X::allocations == 0 );
218 BOOST_TEST( X::instances == 0 );
219 BOOST_TEST( array_deleter< X >::calls == 1 );
220 }
221
222 {
223 boost::shared_ptr<X[6]> px( new X[ 6 ], array_deleter< X >(), std::allocator< X >() );
224 BOOST_TEST( X::allocations == 1 );
225 BOOST_TEST( X::instances == 6 );
226
227 try
228 {
229 px[0].shared_from_this();
230 BOOST_ERROR( "px[0].shared_from_this() failed to throw" );
231 }
232 catch( boost::bad_weak_ptr const& )
233 {
234 }
235 catch( ... )
236 {
237 BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" );
238 }
239
240 px.reset();
241
242 BOOST_TEST( X::allocations == 0 );
243 BOOST_TEST( X::instances == 0 );
244 BOOST_TEST( array_deleter< X >::calls == 2 );
245 }
246
247 return boost::report_errors();
248}
249

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