1// smart pointer test program ----------------------------------------------//
2
3// Copyright Beman Dawes 1998, 1999. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7// See http://www.boost.org/libs/smart_ptr for documentation.
8
9// Revision History
10// 24 May 01 use Boost test library for error detection, reporting, add tests
11// for operations on incomplete types (Beman Dawes)
12// 29 Nov 99 added std::swap and associative container tests (Darin Adler)
13// 25 Sep 99 added swap tests
14// 20 Jul 99 header name changed to .hpp
15// 20 Apr 99 additional error tests added.
16
17#define _CRT_SECURE_NO_WARNINGS
18
19#include <boost/config.hpp>
20
21#if defined(BOOST_MSVC)
22
23# pragma warning(disable: 4786) // identifier truncated in debug info
24# pragma warning(disable: 4710) // function not inlined
25# pragma warning(disable: 4711) // function selected for automatic inline expansion
26# pragma warning(disable: 4514) // unreferenced inline removed
27
28#if (BOOST_MSVC >= 1310)
29# pragma warning(disable: 4675) // resolved overload found with Koenig lookup
30#endif
31
32#endif
33
34#ifdef BOOST_BORLANDC
35# pragma warn -8092 // template argument passed to 'find' is not an iterator
36#endif
37
38#include <boost/smart_ptr.hpp>
39
40#include <boost/core/lightweight_test.hpp>
41
42#include <iostream>
43#include <set>
44#include <string.h>
45
46class Incomplete;
47
48Incomplete * get_ptr( boost::shared_ptr<Incomplete>& incomplete )
49{
50 return incomplete.get();
51}
52
53template<class T>
54void ck( const T* v1, T v2 ) { BOOST_TEST( *v1 == v2 ); }
55
56namespace {
57 int UDT_use_count; // independent of pointer maintained counts
58 }
59
60// user defined type -------------------------------------------------------//
61
62class UDT {
63 long value_;
64 public:
65 explicit UDT( long value=0 ) : value_(value) { ++UDT_use_count; }
66 ~UDT() {
67 --UDT_use_count;
68 std::cout << "UDT with value " << value_ << " being destroyed\n";
69 }
70 long value() const { return value_; }
71 void value( long v ) { value_ = v;; }
72 }; // UDT
73
74// tests on incomplete types -----------------------------------------------//
75
76// Certain smart pointer operations are specified to work on incomplete types,
77// and some uses depend upon this feature. These tests verify compilation
78// only - the functions aren't actually invoked.
79
80class Incomplete;
81
82Incomplete * check_incomplete( boost::scoped_ptr<Incomplete>& incomplete )
83{
84 return incomplete.get();
85}
86
87Incomplete * check_incomplete( boost::shared_ptr<Incomplete>& incomplete,
88 boost::shared_ptr<Incomplete>& i2 )
89{
90 incomplete.swap(other&: i2);
91 std::cout << incomplete.use_count() << ' ' << incomplete.unique() << '\n';
92 return incomplete.get();
93}
94
95// This isn't a very systematic test; it just hits some of the basics.
96
97void test()
98{
99 BOOST_TEST( UDT_use_count == 0 ); // reality check
100
101 // test scoped_ptr with a built-in type
102 long * lp = new long;
103 boost::scoped_ptr<long> sp ( lp );
104 BOOST_TEST( sp.get() == lp );
105 BOOST_TEST( lp == sp.get() );
106 BOOST_TEST( &*sp == lp );
107
108 *sp = 1234568901L;
109 BOOST_TEST( *sp == 1234568901L );
110 BOOST_TEST( *lp == 1234568901L );
111 ck( v1: static_cast<long*>(sp.get()), v2: 1234568901L );
112 ck( v1: lp, v2: *sp );
113
114 sp.reset();
115 BOOST_TEST( sp.get() == 0 );
116
117 // test scoped_ptr with a user defined type
118 boost::scoped_ptr<UDT> udt_sp ( new UDT( 999888777 ) );
119 BOOST_TEST( udt_sp->value() == 999888777 );
120 udt_sp.reset();
121 udt_sp.reset( p: new UDT( 111222333 ) );
122 BOOST_TEST( udt_sp->value() == 111222333 );
123 udt_sp.reset( p: new UDT( 333222111 ) );
124 BOOST_TEST( udt_sp->value() == 333222111 );
125
126 // test scoped_array with a build-in type
127 char * sap = new char [ 100 ];
128 boost::scoped_array<char> sa ( sap );
129 BOOST_TEST( sa.get() == sap );
130 BOOST_TEST( sap == sa.get() );
131
132 strcpy( dest: sa.get(), src: "Hot Dog with mustard and relish" );
133 BOOST_TEST( strcmp( sa.get(), "Hot Dog with mustard and relish" ) == 0 );
134 BOOST_TEST( strcmp( sap, "Hot Dog with mustard and relish" ) == 0 );
135
136 BOOST_TEST( sa[0] == 'H' );
137 BOOST_TEST( sa[30] == 'h' );
138
139 sa[0] = 'N';
140 sa[4] = 'd';
141 BOOST_TEST( strcmp( sap, "Not dog with mustard and relish" ) == 0 );
142
143 sa.reset();
144 BOOST_TEST( sa.get() == 0 );
145
146 // test shared_ptr with a built-in type
147 int * ip = new int;
148 boost::shared_ptr<int> cp ( ip );
149 BOOST_TEST( ip == cp.get() );
150 BOOST_TEST( cp.use_count() == 1 );
151
152 *cp = 54321;
153 BOOST_TEST( *cp == 54321 );
154 BOOST_TEST( *ip == 54321 );
155 ck( v1: static_cast<int*>(cp.get()), v2: 54321 );
156 ck( v1: static_cast<int*>(ip), v2: *cp );
157
158 boost::shared_ptr<int> cp2 ( cp );
159 BOOST_TEST( ip == cp2.get() );
160 BOOST_TEST( cp.use_count() == 2 );
161 BOOST_TEST( cp2.use_count() == 2 );
162
163 BOOST_TEST( *cp == 54321 );
164 BOOST_TEST( *cp2 == 54321 );
165 ck( v1: static_cast<int*>(cp2.get()), v2: 54321 );
166 ck( v1: static_cast<int*>(ip), v2: *cp2 );
167
168 boost::shared_ptr<int> cp3 ( cp );
169 BOOST_TEST( cp.use_count() == 3 );
170 BOOST_TEST( cp2.use_count() == 3 );
171 BOOST_TEST( cp3.use_count() == 3 );
172 cp.reset();
173 BOOST_TEST( cp2.use_count() == 2 );
174 BOOST_TEST( cp3.use_count() == 2 );
175 cp.reset( p: new int );
176 *cp = 98765;
177 BOOST_TEST( *cp == 98765 );
178 *cp3 = 87654;
179 BOOST_TEST( *cp3 == 87654 );
180 BOOST_TEST( *cp2 == 87654 );
181 cp.swap( other&: cp3 );
182 BOOST_TEST( *cp == 87654 );
183 BOOST_TEST( *cp2 == 87654 );
184 BOOST_TEST( *cp3 == 98765 );
185 cp.swap( other&: cp3 );
186 BOOST_TEST( *cp == 98765 );
187 BOOST_TEST( *cp2 == 87654 );
188 BOOST_TEST( *cp3 == 87654 );
189 cp2 = cp2;
190 BOOST_TEST( cp2.use_count() == 2 );
191 BOOST_TEST( *cp2 == 87654 );
192 cp = cp2;
193 BOOST_TEST( cp2.use_count() == 3 );
194 BOOST_TEST( *cp2 == 87654 );
195 BOOST_TEST( cp.use_count() == 3 );
196 BOOST_TEST( *cp == 87654 );
197
198#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP )
199 using boost::swap;
200#endif
201
202 boost::shared_ptr<int> cp4;
203 swap( a&: cp2, b&: cp4 );
204 BOOST_TEST( cp4.use_count() == 3 );
205 BOOST_TEST( *cp4 == 87654 );
206 BOOST_TEST( cp2.get() == 0 );
207
208 std::set< boost::shared_ptr<int> > scp;
209 scp.insert(x: cp4);
210 BOOST_TEST( scp.find(cp4) != scp.end() );
211 BOOST_TEST( scp.find(cp4) == scp.find( boost::shared_ptr<int>(cp4) ) );
212
213 // test shared_array with a built-in type
214 char * cap = new char [ 100 ];
215 boost::shared_array<char> ca ( cap );
216 BOOST_TEST( ca.get() == cap );
217 BOOST_TEST( cap == ca.get() );
218 BOOST_TEST( &ca[0] == cap );
219
220 strcpy( dest: ca.get(), src: "Hot Dog with mustard and relish" );
221 BOOST_TEST( strcmp( ca.get(), "Hot Dog with mustard and relish" ) == 0 );
222 BOOST_TEST( strcmp( cap, "Hot Dog with mustard and relish" ) == 0 );
223
224 BOOST_TEST( ca[0] == 'H' );
225 BOOST_TEST( ca[30] == 'h' );
226
227 boost::shared_array<char> ca2 ( ca );
228 boost::shared_array<char> ca3 ( ca2 );
229
230 ca[0] = 'N';
231 ca[4] = 'd';
232 BOOST_TEST( strcmp( ca.get(), "Not dog with mustard and relish" ) == 0 );
233 BOOST_TEST( strcmp( ca2.get(), "Not dog with mustard and relish" ) == 0 );
234 BOOST_TEST( strcmp( ca3.get(), "Not dog with mustard and relish" ) == 0 );
235 BOOST_TEST( ca.use_count() == 3 );
236 BOOST_TEST( ca2.use_count() == 3 );
237 BOOST_TEST( ca3.use_count() == 3 );
238 ca2.reset();
239 BOOST_TEST( ca.use_count() == 2 );
240 BOOST_TEST( ca3.use_count() == 2 );
241 BOOST_TEST( ca2.use_count() == 0 );
242
243 ca.reset();
244 BOOST_TEST( ca.get() == 0 );
245
246 boost::shared_array<char> ca4;
247 swap( a&: ca3, b&: ca4 );
248 BOOST_TEST( ca4.use_count() == 1 );
249 BOOST_TEST( strcmp( ca4.get(), "Not dog with mustard and relish" ) == 0 );
250 BOOST_TEST( ca3.get() == 0 );
251
252 std::set< boost::shared_array<char> > sca;
253 sca.insert(x: ca4);
254 BOOST_TEST( sca.find(ca4) != sca.end() );
255 BOOST_TEST( sca.find(ca4) == sca.find( boost::shared_array<char>(ca4) ) );
256
257 // test shared_array with user defined type
258 boost::shared_array<UDT> udta ( new UDT[3] );
259
260 udta[0].value( v: 111 );
261 udta[1].value( v: 222 );
262 udta[2].value( v: 333 );
263 boost::shared_array<UDT> udta2 ( udta );
264
265 BOOST_TEST( udta[0].value() == 111 );
266 BOOST_TEST( udta[1].value() == 222 );
267 BOOST_TEST( udta[2].value() == 333 );
268 BOOST_TEST( udta2[0].value() == 111 );
269 BOOST_TEST( udta2[1].value() == 222 );
270 BOOST_TEST( udta2[2].value() == 333 );
271 udta2.reset();
272 BOOST_TEST( udta2.get() == 0 );
273 BOOST_TEST( udta.use_count() == 1 );
274 BOOST_TEST( udta2.use_count() == 0 );
275
276 BOOST_TEST( UDT_use_count == 4 ); // reality check
277
278 // test shared_ptr with a user defined type
279 UDT * up = new UDT;
280 boost::shared_ptr<UDT> sup ( up );
281 BOOST_TEST( up == sup.get() );
282 BOOST_TEST( sup.use_count() == 1 );
283
284 sup->value( v: 54321 ) ;
285 BOOST_TEST( sup->value() == 54321 );
286 BOOST_TEST( up->value() == 54321 );
287
288 boost::shared_ptr<UDT> sup2;
289 sup2 = sup;
290 BOOST_TEST( sup2->value() == 54321 );
291 BOOST_TEST( sup.use_count() == 2 );
292 BOOST_TEST( sup2.use_count() == 2 );
293 sup2 = sup2;
294 BOOST_TEST( sup2->value() == 54321 );
295 BOOST_TEST( sup.use_count() == 2 );
296 BOOST_TEST( sup2.use_count() == 2 );
297
298 std::cout << "OK\n";
299}
300
301int main()
302{
303 test();
304 return boost::report_errors();
305}
306

source code of boost/libs/smart_ptr/test/smart_ptr_test.cpp