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>
16 #include <boost/config.hpp>
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 
X(int expected)39     explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
40     {
41         ++instances;
42     }
43 
~X()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 
deleter(X * px)54     static void deleter( X * px )
55     {
56         ++px->deleted_;
57     }
58 
deleter2(X * px)59     static void deleter2( X * px )
60     {
61         ++px->deleted_;
62         delete px;
63     }
64 };
65 
66 int X::instances = 0;
67 
test()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 
79 #if !defined( BOOST_NO_AUTO_PTR )
80 
81     {
82         std::auto_ptr<X> px( new X( 0 ) );
83         BOOST_TEST( X::instances == 1 );
84     }
85 
86 #endif
87 
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 {
~VV142     virtual ~V() {}
143     std::string m_;
144 };
145 
146 struct V2
147 {
~V2V2148     virtual ~V2() {}
149     std::string m2_;
150 };
151 
152 struct W: V2, V
153 {
154 };
155 
test2()156 void test2()
157 {
158     boost::shared_ptr<W> p( new W );
159 }
160 
test3()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 {
operator ()null_deleter171     void operator()( void const* ) const {}
172 };
173 
test4()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 
test5()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 
main()215 int main()
216 {
217     test();
218     test2();
219     test3();
220     test4();
221     test5();
222 
223     return boost::report_errors();
224 }
225