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