]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // shared_from_raw_test2.cpp - based on esft_regtest.cpp | |
3 | // | |
4 | // Copyright (c) 2008, 2014 Peter Dimov | |
5 | // | |
6 | // Distributed under the Boost Software License, Version 1.0. | |
7 | // | |
8 | // See accompanying file LICENSE_1_0.txt or copy at | |
9 | // http://www.boost.org/LICENSE_1_0.txt | |
10 | // | |
11 | ||
12 | #include <boost/smart_ptr/enable_shared_from_raw.hpp> | |
13 | #include <boost/shared_ptr.hpp> | |
14 | #include <boost/weak_ptr.hpp> | |
15 | #include <boost/detail/lightweight_test.hpp> | |
b32b8144 | 16 | #include <boost/config.hpp> |
7c673cae FG |
17 | #include <memory> |
18 | #include <string> | |
19 | ||
20 | class X: public boost::enable_shared_from_raw | |
21 | { | |
22 | private: | |
23 | ||
24 | int destroyed_; | |
25 | int deleted_; | |
26 | int expected_; | |
27 | ||
28 | private: | |
29 | ||
30 | X( X const& ); | |
31 | X& operator=( X const& ); | |
32 | ||
33 | public: | |
34 | ||
35 | static int instances; | |
36 | ||
37 | public: | |
38 | ||
39 | explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected ) | |
40 | { | |
41 | ++instances; | |
42 | } | |
43 | ||
44 | ~X() | |
45 | { | |
46 | BOOST_TEST( deleted_ == expected_ ); | |
47 | BOOST_TEST( destroyed_ == 0 ); | |
48 | ++destroyed_; | |
49 | --instances; | |
50 | } | |
51 | ||
52 | typedef void (*deleter_type)( X* ); | |
53 | ||
54 | static void deleter( X * px ) | |
55 | { | |
56 | ++px->deleted_; | |
57 | } | |
58 | ||
59 | static void deleter2( X * px ) | |
60 | { | |
61 | ++px->deleted_; | |
62 | delete px; | |
63 | } | |
64 | }; | |
65 | ||
66 | int X::instances = 0; | |
67 | ||
68 | void test() | |
69 | { | |
70 | BOOST_TEST( X::instances == 0 ); | |
71 | ||
72 | { | |
73 | X x( 0 ); | |
74 | BOOST_TEST( X::instances == 1 ); | |
75 | } | |
76 | ||
77 | BOOST_TEST( X::instances == 0 ); | |
78 | ||
b32b8144 FG |
79 | #if !defined( BOOST_NO_AUTO_PTR ) |
80 | ||
7c673cae FG |
81 | { |
82 | std::auto_ptr<X> px( new X( 0 ) ); | |
83 | BOOST_TEST( X::instances == 1 ); | |
84 | } | |
85 | ||
b32b8144 FG |
86 | #endif |
87 | ||
7c673cae FG |
88 | BOOST_TEST( X::instances == 0 ); |
89 | ||
90 | { | |
91 | boost::shared_ptr<X> px( new X( 0 ) ); | |
92 | BOOST_TEST( X::instances == 1 ); | |
93 | ||
94 | boost::weak_ptr<X> wp( px ); | |
95 | BOOST_TEST( !wp.expired() ); | |
96 | ||
97 | px.reset(); | |
98 | ||
99 | BOOST_TEST( wp.expired() ); | |
100 | } | |
101 | ||
102 | BOOST_TEST( X::instances == 0 ); | |
103 | ||
104 | { | |
105 | X x( 1 ); | |
106 | boost::shared_ptr<X> px( &x, X::deleter ); | |
107 | BOOST_TEST( X::instances == 1 ); | |
108 | ||
109 | X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px ); | |
110 | BOOST_TEST( pd != 0 && *pd == X::deleter ); | |
111 | ||
112 | boost::weak_ptr<X> wp( px ); | |
113 | BOOST_TEST( !wp.expired() ); | |
114 | ||
115 | px.reset(); | |
116 | ||
117 | BOOST_TEST( wp.expired() ); | |
118 | } | |
119 | ||
120 | BOOST_TEST( X::instances == 0 ); | |
121 | ||
122 | { | |
123 | boost::shared_ptr<X> px( new X( 1 ), X::deleter2 ); | |
124 | BOOST_TEST( X::instances == 1 ); | |
125 | ||
126 | X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px ); | |
127 | BOOST_TEST( pd != 0 && *pd == X::deleter2 ); | |
128 | ||
129 | boost::weak_ptr<X> wp( px ); | |
130 | BOOST_TEST( !wp.expired() ); | |
131 | ||
132 | px.reset(); | |
133 | ||
134 | BOOST_TEST( wp.expired() ); | |
135 | } | |
136 | ||
137 | BOOST_TEST( X::instances == 0 ); | |
138 | } | |
139 | ||
140 | struct V: public boost::enable_shared_from_raw | |
141 | { | |
142 | virtual ~V() {} | |
143 | std::string m_; | |
144 | }; | |
145 | ||
146 | struct V2 | |
147 | { | |
148 | virtual ~V2() {} | |
149 | std::string m2_; | |
150 | }; | |
151 | ||
152 | struct W: V2, V | |
153 | { | |
154 | }; | |
155 | ||
156 | void test2() | |
157 | { | |
158 | boost::shared_ptr<W> p( new W ); | |
159 | } | |
160 | ||
161 | void test3() | |
162 | { | |
163 | V * p = new W; | |
164 | boost::shared_ptr<void> pv( p ); | |
165 | BOOST_TEST( pv.get() == p ); | |
166 | BOOST_TEST( pv.use_count() == 1 ); | |
167 | } | |
168 | ||
169 | struct null_deleter | |
170 | { | |
171 | void operator()( void const* ) const {} | |
172 | }; | |
173 | ||
174 | void test4() | |
175 | { | |
176 | boost::shared_ptr<V> pv( new V ); | |
177 | boost::shared_ptr<V> pv2( pv.get(), null_deleter() ); | |
178 | BOOST_TEST( pv2.get() == pv.get() ); | |
179 | BOOST_TEST( pv2.use_count() == 1 ); | |
180 | } | |
181 | ||
182 | void test5() | |
183 | { | |
184 | V v; | |
185 | ||
186 | boost::shared_ptr<V> p1( &v, null_deleter() ); | |
187 | BOOST_TEST( p1.get() == &v ); | |
188 | BOOST_TEST( p1.use_count() == 1 ); | |
189 | ||
190 | try | |
191 | { | |
192 | boost::shared_from_raw( p1.get() ); | |
193 | } | |
194 | catch( ... ) | |
195 | { | |
196 | BOOST_ERROR( "shared_from_raw( p1.get() ) failed" ); | |
197 | } | |
198 | ||
199 | p1.reset(); | |
200 | ||
201 | boost::shared_ptr<V> p2( &v, null_deleter() ); | |
202 | BOOST_TEST( p2.get() == &v ); | |
203 | BOOST_TEST( p2.use_count() == 1 ); | |
204 | ||
205 | try | |
206 | { | |
207 | boost::shared_from_raw( p2.get() ); | |
208 | } | |
209 | catch( ... ) | |
210 | { | |
211 | BOOST_ERROR( "shared_from_raw( p2.get() ) failed" ); | |
212 | } | |
213 | } | |
214 | ||
215 | int main() | |
216 | { | |
217 | test(); | |
218 | test2(); | |
219 | test3(); | |
220 | test4(); | |
221 | test5(); | |
222 | ||
223 | return boost::report_errors(); | |
224 | } |