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