1#include <boost/config.hpp>
2
3#if defined(BOOST_MSVC)
4
5#pragma warning(disable: 4786) // identifier truncated in debug info
6#pragma warning(disable: 4710) // function not inlined
7#pragma warning(disable: 4711) // function selected for automatic inline expansion
8#pragma warning(disable: 4514) // unreferenced inline removed
9#pragma warning(disable: 4355) // 'this' : used in base member initializer list
10#pragma warning(disable: 4511) // copy constructor could not be generated
11#pragma warning(disable: 4512) // assignment operator could not be generated
12
13#if (BOOST_MSVC >= 1310)
14#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
15#endif
16
17#endif
18
19//
20// intrusive_ptr_move_test.cpp
21//
22// Copyright (c) 2002-2005 Peter Dimov
23//
24// Distributed under the Boost Software License, Version 1.0. (See
25// accompanying file LICENSE_1_0.txt or copy at
26// http://www.boost.org/LICENSE_1_0.txt)
27//
28
29#include <boost/core/lightweight_test.hpp>
30#include <boost/intrusive_ptr.hpp>
31#include <boost/detail/atomic_count.hpp>
32#include <boost/config.hpp>
33#include <utility>
34
35#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
36
37namespace N
38{
39
40class base
41{
42private:
43
44 mutable boost::detail::atomic_count use_count_;
45
46 base(base const &);
47 base & operator=(base const &);
48
49protected:
50
51 base(): use_count_(0)
52 {
53 ++instances;
54 }
55
56 virtual ~base()
57 {
58 --instances;
59 }
60
61public:
62
63 static long instances;
64
65 long use_count() const
66 {
67 return use_count_;
68 }
69
70#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
71
72 inline friend void intrusive_ptr_add_ref(base const * p)
73 {
74 ++p->use_count_;
75 }
76
77 inline friend void intrusive_ptr_release(base const * p)
78 {
79 if(--p->use_count_ == 0) delete p;
80 }
81
82#else
83
84 void add_ref() const
85 {
86 ++use_count_;
87 }
88
89 void release() const
90 {
91 if(--use_count_ == 0) delete this;
92 }
93
94#endif
95};
96
97long base::instances = 0;
98
99} // namespace N
100
101#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
102
103namespace boost
104{
105
106inline void intrusive_ptr_add_ref(N::base const * p)
107{
108 p->add_ref();
109}
110
111inline void intrusive_ptr_release(N::base const * p)
112{
113 p->release();
114}
115
116} // namespace boost
117
118#endif
119
120//
121
122struct X: public virtual N::base
123{
124};
125
126struct Y: public X
127{
128};
129
130int main()
131{
132 BOOST_TEST( N::base::instances == 0 );
133
134 {
135 boost::intrusive_ptr<X> p( new X );
136 BOOST_TEST( N::base::instances == 1 );
137
138 boost::intrusive_ptr<X> p2( std::move( p ) );
139 BOOST_TEST( N::base::instances == 1 );
140 BOOST_TEST( p.get() == 0 );
141
142 p2.reset();
143 BOOST_TEST( N::base::instances == 0 );
144 }
145
146 {
147 boost::intrusive_ptr<Y> p( new Y );
148 BOOST_TEST( N::base::instances == 1 );
149
150 boost::intrusive_ptr<X> p2( std::move( p ) );
151 BOOST_TEST( N::base::instances == 1 );
152 BOOST_TEST( p.get() == 0 );
153
154 p2.reset();
155 BOOST_TEST( N::base::instances == 0 );
156 }
157
158 {
159 boost::intrusive_ptr<X> p( new X );
160 BOOST_TEST( N::base::instances == 1 );
161
162 boost::intrusive_ptr<X> p2;
163 p2 = std::move( p );
164 BOOST_TEST( N::base::instances == 1 );
165 BOOST_TEST( p.get() == 0 );
166
167 p2.reset();
168 BOOST_TEST( N::base::instances == 0 );
169 }
170
171 {
172 boost::intrusive_ptr<X> p( new X );
173 BOOST_TEST( N::base::instances == 1 );
174
175 boost::intrusive_ptr<X> p2( new X );
176 BOOST_TEST( N::base::instances == 2 );
177 p2 = std::move( p );
178 BOOST_TEST( N::base::instances == 1 );
179 BOOST_TEST( p.get() == 0 );
180
181 p2.reset();
182 BOOST_TEST( N::base::instances == 0 );
183 }
184
185 {
186 boost::intrusive_ptr<Y> p( new Y );
187 BOOST_TEST( N::base::instances == 1 );
188
189 boost::intrusive_ptr<X> p2;
190 p2 = std::move( p );
191 BOOST_TEST( N::base::instances == 1 );
192 BOOST_TEST( p.get() == 0 );
193
194 p2.reset();
195 BOOST_TEST( N::base::instances == 0 );
196 }
197
198 {
199 boost::intrusive_ptr<Y> p( new Y );
200 BOOST_TEST( N::base::instances == 1 );
201
202 boost::intrusive_ptr<X> p2( new X );
203 BOOST_TEST( N::base::instances == 2 );
204 p2 = std::move( p );
205 BOOST_TEST( N::base::instances == 1 );
206 BOOST_TEST( p.get() == 0 );
207
208 p2.reset();
209 BOOST_TEST( N::base::instances == 0 );
210 }
211
212 {
213 boost::intrusive_ptr<X> px( new Y );
214
215 X * px2 = px.get();
216
217 boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( p: std::move( px ) );
218 BOOST_TEST( py.get() == px2 );
219 BOOST_TEST( px.get() == 0 );
220 BOOST_TEST( py->use_count() == 1 );
221 }
222
223 BOOST_TEST( N::base::instances == 0 );
224
225 {
226 boost::intrusive_ptr<X const> px( new X );
227
228 X const * px2 = px.get();
229
230 boost::intrusive_ptr<X> px3 = boost::const_pointer_cast<X>( p: std::move( px ) );
231 BOOST_TEST( px3.get() == px2 );
232 BOOST_TEST( px.get() == 0 );
233 BOOST_TEST( px3->use_count() == 1 );
234 }
235
236 BOOST_TEST( N::base::instances == 0 );
237
238 {
239 boost::intrusive_ptr<X> px( new Y );
240
241 X * px2 = px.get();
242
243 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( p: std::move( px ) );
244 BOOST_TEST( py.get() == px2 );
245 BOOST_TEST( px.get() == 0 );
246 BOOST_TEST( py->use_count() == 1 );
247 }
248
249 BOOST_TEST( N::base::instances == 0 );
250
251 {
252 boost::intrusive_ptr<X> px( new X );
253
254 X * px2 = px.get();
255
256 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( p: std::move( px ) );
257 BOOST_TEST( py.get() == 0 );
258 BOOST_TEST( px.get() == px2 );
259 BOOST_TEST( px->use_count() == 1 );
260 }
261
262 BOOST_TEST( N::base::instances == 0 );
263
264 return boost::report_errors();
265}
266
267#else // defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
268
269int main()
270{
271 return 0;
272}
273
274#endif
275

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