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 | |
37 | namespace N |
38 | { |
39 | |
40 | class base |
41 | { |
42 | private: |
43 | |
44 | mutable boost::detail::atomic_count use_count_; |
45 | |
46 | base(base const &); |
47 | base & operator=(base const &); |
48 | |
49 | protected: |
50 | |
51 | base(): use_count_(0) |
52 | { |
53 | ++instances; |
54 | } |
55 | |
56 | virtual ~base() |
57 | { |
58 | --instances; |
59 | } |
60 | |
61 | public: |
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 | |
97 | long base::instances = 0; |
98 | |
99 | } // namespace N |
100 | |
101 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
102 | |
103 | namespace boost |
104 | { |
105 | |
106 | inline void intrusive_ptr_add_ref(N::base const * p) |
107 | { |
108 | p->add_ref(); |
109 | } |
110 | |
111 | inline void intrusive_ptr_release(N::base const * p) |
112 | { |
113 | p->release(); |
114 | } |
115 | |
116 | } // namespace boost |
117 | |
118 | #endif |
119 | |
120 | // |
121 | |
122 | struct X: public virtual N::base |
123 | { |
124 | }; |
125 | |
126 | struct Y: public X |
127 | { |
128 | }; |
129 | |
130 | int 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 | |
269 | int main() |
270 | { |
271 | return 0; |
272 | } |
273 | |
274 | #endif |
275 |