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 <memory>
17 #include <string>
18 
19 class X: public boost::enable_shared_from_raw
20 {
21 private:
22 
23     int destroyed_;
24     int deleted_;
25     int expected_;
26 
27 private:
28 
29     X( X const& );
30     X& operator=( X const& );
31 
32 public:
33 
34     static int instances;
35 
36 public:
37 
X(int expected)38     explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
39     {
40         ++instances;
41     }
42 
~X()43     ~X()
44     {
45         BOOST_TEST( deleted_ == expected_ );
46         BOOST_TEST( destroyed_ == 0 );
47         ++destroyed_;
48         --instances;
49     }
50 
51     typedef void (*deleter_type)( X* );
52 
deleter(X * px)53     static void deleter( X * px )
54     {
55         ++px->deleted_;
56     }
57 
deleter2(X * px)58     static void deleter2( X * px )
59     {
60         ++px->deleted_;
61         delete px;
62     }
63 };
64 
65 int X::instances = 0;
66 
test()67 void test()
68 {
69     BOOST_TEST( X::instances == 0 );
70 
71     {
72         X x( 0 );
73         BOOST_TEST( X::instances == 1 );
74     }
75 
76     BOOST_TEST( X::instances == 0 );
77 
78     {
79         std::auto_ptr<X> px( new X( 0 ) );
80         BOOST_TEST( X::instances == 1 );
81     }
82 
83     BOOST_TEST( X::instances == 0 );
84 
85     {
86         boost::shared_ptr<X> px( new X( 0 ) );
87         BOOST_TEST( X::instances == 1 );
88 
89         boost::weak_ptr<X> wp( px );
90         BOOST_TEST( !wp.expired() );
91 
92         px.reset();
93 
94         BOOST_TEST( wp.expired() );
95     }
96 
97     BOOST_TEST( X::instances == 0 );
98 
99     {
100         X x( 1 );
101         boost::shared_ptr<X> px( &x, X::deleter );
102         BOOST_TEST( X::instances == 1 );
103 
104         X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
105         BOOST_TEST( pd != 0 && *pd == X::deleter );
106 
107         boost::weak_ptr<X> wp( px );
108         BOOST_TEST( !wp.expired() );
109 
110         px.reset();
111 
112         BOOST_TEST( wp.expired() );
113     }
114 
115     BOOST_TEST( X::instances == 0 );
116 
117     {
118         boost::shared_ptr<X> px( new X( 1 ), X::deleter2 );
119         BOOST_TEST( X::instances == 1 );
120 
121         X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
122         BOOST_TEST( pd != 0 && *pd == X::deleter2 );
123 
124         boost::weak_ptr<X> wp( px );
125         BOOST_TEST( !wp.expired() );
126 
127         px.reset();
128 
129         BOOST_TEST( wp.expired() );
130     }
131 
132     BOOST_TEST( X::instances == 0 );
133 }
134 
135 struct V: public boost::enable_shared_from_raw
136 {
~VV137     virtual ~V() {}
138     std::string m_;
139 };
140 
141 struct V2
142 {
~V2V2143     virtual ~V2() {}
144     std::string m2_;
145 };
146 
147 struct W: V2, V
148 {
149 };
150 
test2()151 void test2()
152 {
153     boost::shared_ptr<W> p( new W );
154 }
155 
test3()156 void test3()
157 {
158     V * p = new W;
159     boost::shared_ptr<void> pv( p );
160     BOOST_TEST( pv.get() == p );
161     BOOST_TEST( pv.use_count() == 1 );
162 }
163 
164 struct null_deleter
165 {
operator ()null_deleter166     void operator()( void const* ) const {}
167 };
168 
test4()169 void test4()
170 {
171     boost::shared_ptr<V> pv( new V );
172     boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
173     BOOST_TEST( pv2.get() == pv.get() );
174     BOOST_TEST( pv2.use_count() == 1 );
175 }
176 
test5()177 void test5()
178 {
179     V v;
180 
181     boost::shared_ptr<V> p1( &v, null_deleter() );
182     BOOST_TEST( p1.get() == &v );
183     BOOST_TEST( p1.use_count() == 1 );
184 
185     try
186     {
187         boost::shared_from_raw( p1.get() );
188     }
189     catch( ... )
190     {
191         BOOST_ERROR( "shared_from_raw( p1.get() ) failed" );
192     }
193 
194     p1.reset();
195 
196     boost::shared_ptr<V> p2( &v, null_deleter() );
197     BOOST_TEST( p2.get() == &v );
198     BOOST_TEST( p2.use_count() == 1 );
199 
200     try
201     {
202         boost::shared_from_raw( p2.get() );
203     }
204     catch( ... )
205     {
206         BOOST_ERROR( "shared_from_raw( p2.get() ) failed" );
207     }
208 }
209 
main()210 int main()
211 {
212     test();
213     test2();
214     test3();
215     test4();
216     test5();
217 
218     return boost::report_errors();
219 }
220