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/detail/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