1 #include <boost/config.hpp>
2
3 // shared_ptr_alias_move_test.cpp
4 //
5 // Copyright (c) 2007 Peter Dimov
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11
12 #include <boost/core/lightweight_test.hpp>
13 #include <boost/shared_ptr.hpp>
14 #include <utility>
15
16 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
17
18 class incomplete;
19
20 struct X
21 {
22 static long instances;
23
24 int v_;
25
XX26 explicit X( int v ): v_( v )
27 {
28 ++instances;
29 }
30
~XX31 ~X()
32 {
33 v_ = 0;
34 --instances;
35 }
36
37 private:
38 X( X const & );
39 X & operator=( X const & );
40 };
41
42 long X::instances = 0;
43
main()44 int main()
45 {
46 BOOST_TEST( X::instances == 0 );
47
48 {
49 int m = 0;
50 boost::shared_ptr< int > p;
51 boost::shared_ptr< int > p2( std::move( p ), &m );
52
53 BOOST_TEST( p2.get() == &m );
54 BOOST_TEST( p2? true: false );
55 BOOST_TEST( !!p2 );
56 BOOST_TEST( p2.use_count() == 0 );
57
58 BOOST_TEST( p.get() == 0 );
59 BOOST_TEST( p.use_count() == 0 );
60
61 p2.reset( std::move( p ), 0 );
62
63 BOOST_TEST( p2.get() == 0 );
64 BOOST_TEST( p2? false: true );
65 BOOST_TEST( !p2 );
66 BOOST_TEST( p2.use_count() == 0 );
67
68 BOOST_TEST( p.get() == 0 );
69 BOOST_TEST( p.use_count() == 0 );
70 }
71
72 {
73 int m = 0;
74 boost::shared_ptr< int > p( new int );
75 boost::shared_ptr< int const > p2( std::move( p ), &m );
76
77 BOOST_TEST( p2.get() == &m );
78 BOOST_TEST( p2? true: false );
79 BOOST_TEST( !!p2 );
80 BOOST_TEST( p2.use_count() == 1 );
81
82 BOOST_TEST( p.get() == 0 );
83 BOOST_TEST( p.use_count() == 0 );
84
85 boost::shared_ptr< int volatile > p3;
86 p2.reset( std::move( p3 ), 0 );
87
88 BOOST_TEST( p2.get() == 0 );
89 BOOST_TEST( p2? false: true );
90 BOOST_TEST( !p2 );
91 BOOST_TEST( p2.use_count() == 0 );
92
93 BOOST_TEST( p3.get() == 0 );
94 BOOST_TEST( p3.use_count() == 0 );
95
96 boost::shared_ptr< int const volatile > p4( new int );
97 p2.reset( std::move( p4 ), &m );
98
99 BOOST_TEST( p2.get() == &m );
100 BOOST_TEST( p2.use_count() == 1 );
101
102 BOOST_TEST( p4.get() == 0 );
103 BOOST_TEST( p4.use_count() == 0 );
104 }
105
106 {
107 boost::shared_ptr< int > p( new int );
108 boost::shared_ptr< void const > p2( std::move( p ), 0 );
109
110 BOOST_TEST( p2.get() == 0 );
111 BOOST_TEST( p2? false: true );
112 BOOST_TEST( !p2 );
113 BOOST_TEST( p2.use_count() == 1 );
114
115 BOOST_TEST( p.get() == 0 );
116 BOOST_TEST( p.use_count() == 0 );
117
118 int m = 0;
119 boost::shared_ptr< void volatile > p3;
120
121 p2.reset( std::move( p3 ), &m );
122
123 BOOST_TEST( p2.get() == &m );
124 BOOST_TEST( p2? true: false );
125 BOOST_TEST( !!p2 );
126 BOOST_TEST( p2.use_count() == 0 );
127
128 BOOST_TEST( p3.get() == 0 );
129 BOOST_TEST( p3.use_count() == 0 );
130
131 boost::shared_ptr< void const volatile > p4( new int );
132 p2.reset( std::move( p4 ), 0 );
133
134 BOOST_TEST( p2.get() == 0 );
135 BOOST_TEST( p2.use_count() == 1 );
136
137 BOOST_TEST( p4.get() == 0 );
138 BOOST_TEST( p4.use_count() == 0 );
139 }
140
141 {
142 boost::shared_ptr< incomplete > p;
143 boost::shared_ptr< incomplete > p2( std::move( p ), 0 );
144
145 BOOST_TEST( p2.get() == 0 );
146 BOOST_TEST( p2? false: true );
147 BOOST_TEST( !p2 );
148 BOOST_TEST( p2.use_count() == 0 );
149
150 BOOST_TEST( p.get() == 0 );
151 BOOST_TEST( p.use_count() == 0 );
152
153 p2.reset( std::move( p ), 0 );
154
155 BOOST_TEST( p2.get() == 0 );
156 BOOST_TEST( p2? false: true );
157 BOOST_TEST( !p2 );
158 BOOST_TEST( p2.use_count() == 0 );
159
160 BOOST_TEST( p.get() == 0 );
161 BOOST_TEST( p.use_count() == 0 );
162 }
163
164 {
165 boost::shared_ptr< X > p( new X( 5 ) ), q( p );
166 boost::shared_ptr< int const > p2( std::move( q ), &q->v_ );
167
168 BOOST_TEST( p2.get() == &p->v_ );
169 BOOST_TEST( p2? true: false );
170 BOOST_TEST( !!p2 );
171 BOOST_TEST( p2.use_count() == p.use_count() );
172 BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
173
174 BOOST_TEST( q.get() == 0 );
175 BOOST_TEST( q.use_count() == 0 );
176
177 p.reset();
178 BOOST_TEST( *p2 == 5 );
179
180 boost::shared_ptr< X const > p3( new X( 8 ) ), q3( p3 );
181 p2.reset( std::move( q3 ), &q3->v_ );
182
183 BOOST_TEST( p2.get() == &p3->v_ );
184 BOOST_TEST( p2? true: false );
185 BOOST_TEST( !!p2 );
186 BOOST_TEST( p2.use_count() == p3.use_count() );
187 BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
188
189 BOOST_TEST( q3.get() == 0 );
190 BOOST_TEST( q3.use_count() == 0 );
191
192 p3.reset();
193 BOOST_TEST( *p2 == 8 );
194 }
195
196 {
197 boost::shared_ptr< X > p( new X( 5 ) );
198 BOOST_TEST( X::instances == 1 );
199 BOOST_TEST( p.unique() );
200 BOOST_TEST( p->v_ == 5 );
201
202 boost::shared_ptr< X > p2( std::move( p ), p.get() );
203 BOOST_TEST( X::instances == 1 );
204 BOOST_TEST( p.get() == 0 );
205 BOOST_TEST( p2.unique() );
206 BOOST_TEST( p2->v_ == 5 );
207
208 boost::shared_ptr< int const > p3( std::move( p2 ), &p2->v_ );
209 BOOST_TEST( X::instances == 1 );
210 BOOST_TEST( p2.get() == 0 );
211 BOOST_TEST( p3.unique() );
212 BOOST_TEST( *p3 == 5 );
213
214 p3.reset();
215 BOOST_TEST( X::instances == 0 );
216 }
217
218 {
219 boost::shared_ptr< X > p( new X( 5 ) );
220 BOOST_TEST( X::instances == 1 );
221 BOOST_TEST( p.unique() );
222 BOOST_TEST( p->v_ == 5 );
223
224 {
225 boost::shared_ptr< X > p2(p);
226 BOOST_TEST( X::instances == 1 );
227 BOOST_TEST( p.get() == p2.get() );
228 BOOST_TEST( p.use_count() == 2 );
229 BOOST_TEST( p2.use_count() == 2 );
230
231 boost::shared_ptr< int const > p3( std::move( p2 ), &p2->v_ );
232 BOOST_TEST( X::instances == 1 );
233 BOOST_TEST( p.use_count() == 2 );
234 BOOST_TEST( p2.use_count() == 0 );
235 BOOST_TEST( p2.get() == 0 );
236 BOOST_TEST( p3.use_count() == 2 );
237 BOOST_TEST( p3.get() == &p->v_ );
238 }
239
240 BOOST_TEST( X::instances == 1 );
241 BOOST_TEST( p.unique() );
242 BOOST_TEST( p->v_ == 5 );
243 }
244
245 return boost::report_errors();
246 }
247
248 #else // defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
249
main()250 int main()
251 {
252 return 0;
253 }
254
255 #endif
256