1//
2// Boost.Pointer Container
3//
4// Copyright Thorsten Ottosen 2003-2005. Use, modification and
5// distribution is subject to the Boost Software License, Version
6// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// For more information, see http://www.boost.org/libs/ptr_container/
10//
11
12#include <boost/static_assert.hpp>
13#include <boost/type_traits.hpp>
14#include <boost/config.hpp>
15#include <boost/test/unit_test.hpp>
16#include <boost/lexical_cast.hpp>
17#include <boost/functional/hash.hpp>
18#include <algorithm>
19#include <iostream>
20#include <string>
21#include <utility>
22#include <cstdlib>
23
24using namespace std;
25using namespace boost;
26
27//////////////////////////////////////////////////////////////////////////////
28// Test class 1: a class hierarchy
29//////////////////////////////////////////////////////////////////////////////
30
31namespace test
32{
33 class Base
34 {
35 protected:
36 Base( const Base& r ) : data1(r.data1), data2(r.data2),
37 data3(r.data3), data(r.data)
38 {
39 #ifdef PTR_CONTAINER_DEBUG
40 objects++;
41 std::cout <<"+ " << objects << "\n";
42 #endif
43 }
44
45 Base& operator=( const Base& );
46
47 public: // for test reasons only
48 int data1, data2, data3;
49 string data;
50
51 public:
52
53 Base() : data1(1), data2(2), data3(rand()%256),
54 data(lexical_cast<string>(arg: rand()))
55 {
56 #ifdef PTR_CONTAINER_DEBUG
57 objects++;
58 std::cout <<"+ " << objects << "\n";
59 #endif
60 }
61
62 virtual ~Base()
63 {
64 #ifdef PTR_CONTAINER_DEBUG
65 objects--;
66 std::cout <<"- " << objects << "\n";
67 if( objects < 0 )
68 terminate();
69 #endif
70 }
71
72 void print( ostream& out ) const { do_print( out); }
73 Base* clone() const { return do_clone(); }
74 void foo() { do_foo(); }
75
76 virtual bool less_than( const Base& b ) const
77 {
78 return data3 < b.data3;
79 }
80
81 virtual bool equal( const Base& b ) const
82 {
83 return data1 == b.data1 &&
84 data2 == b.data2 &&
85 data3 == b.data3 &&
86 data == b.data;
87 }
88
89 #ifdef PTR_CONTAINER_DEBUG
90 static int objects;
91 #endif
92
93 private:
94 virtual void do_print( ostream& /*out*/ ) const { };
95 virtual Base* do_clone() const { return new Base( *this ); };
96 virtual void do_foo() { };
97 };
98
99 #ifdef PTR_CONTAINER_DEBUG
100 int Base::objects = 0;
101 #endif
102
103
104
105 ostream& operator<<( ostream& out, const Base& b )
106 {
107 b.print( out );
108 return out;
109 }
110
111
112 //
113 // We rely on argument dependent lookup
114 // for this to be found
115 //
116 inline Base* new_clone( const Base& b )
117 {
118 return b.clone();
119 }
120
121
122
123 inline bool operator<( const Base& l, const Base& r )
124 {
125 return l.less_than( b: r );
126 }
127
128
129
130 inline bool operator>( const Base& l, const Base& r )
131 {
132 return r < l;
133 }
134
135
136
137 inline bool operator==( const Base& l, const Base& r )
138 {
139 return l.equal( b: r );
140 }
141
142
143
144 inline bool operator!=( const Base& l, const Base& r )
145 {
146 return !l.equal( b: r );
147 }
148
149
150
151 inline std::size_t hash_value( const Base& b )
152 {
153 std::size_t seed = 0;
154 boost::hash_combine( seed, v: b.data );
155 boost::hash_combine( seed, v: b.data1 );
156 boost::hash_combine( seed, v: b.data2 );
157 boost::hash_combine( seed, v: b.data3 );
158 return seed;
159 }
160
161
162 class Derived_class : public Base
163 {
164 protected:
165 Derived_class( const Derived_class& r ) : Base( r ), i_(r.i_)
166 { }
167
168 public: // for test reasons only
169 int i_;
170
171 private:
172
173 virtual void do_print( ostream& out ) const
174 {
175 out << i_;
176 }
177
178
179 virtual Base* do_clone() const
180 {
181 return new Derived_class( *this );
182 }
183
184 virtual void do_foo()
185 {
186 ++i_;
187 }
188
189 public:
190 Derived_class() : i_( rand() )
191 { }
192
193 virtual bool less_than( const Base& b ) const
194 {
195 const Derived_class& d = dynamic_cast<const Derived_class&>( b );
196 return i_ < d.i_;
197 }
198 };
199
200
201
202 inline std::size_t hash_value( const Derived_class& b )
203 {
204 std::size_t seed = hash_value( b: static_cast<const Base&>( b ) );
205 boost::hash_combine( seed, v: b.i_ );
206 return seed;
207 }
208}
209
210using test::Base;
211using test::Derived_class;
212
213//////////////////////////////////////////////////////////////////////////////
214// Test class 2: a value class
215//////////////////////////////////////////////////////////////////////////////
216
217class Value
218{
219public: // for test reasons only
220 string s_;
221
222public:
223
224 Value() : s_( boost::lexical_cast<string>( arg: rand() ) )
225 {}
226
227 ~Value() { /** debug code here */ }
228
229 string name() const
230 {
231 return s_;
232 }
233};
234
235
236
237inline bool operator<( const Value& l, const Value& r )
238{
239 return l.name() < r.name();
240}
241
242
243
244inline bool operator>( const Value& l, const Value& r )
245{
246 return l.name() > r.name();
247}
248
249
250
251inline bool operator==( const Value& l, const Value& r )
252{
253 return l.name() == r.name();
254}
255
256
257
258inline bool operator!=( const Value& l, const Value& r )
259{
260 return l.name() != r.name();
261}
262
263
264
265inline ostream& operator<<( ostream& out, const Value& v )
266{
267 return out << v.name() << " ";
268}
269
270
271
272inline std::size_t hash_value( const Value& v )
273{
274 return boost::hash_value( v: v.s_ );
275}
276
277//
278// used to hide "unused variable" warnings
279//
280template< class T >
281inline void hide_warning( T& /*r*/ )
282{ }
283
284//
285// used to customize tests for circular_buffer
286//
287template< class Cont >
288struct set_capacity
289{
290 void operator()( Cont& ) const
291 { }
292};
293
294//
295// transfer() test
296//
297
298template< class Cont1, class Cont2 >
299void transfer_test( Cont1& from, Cont2& to )
300{
301 BOOST_TEST_MESSAGE( "starting container transfer test" );
302 BOOST_CHECK( !from.empty() );
303 to. BOOST_NESTED_TEMPLATE transfer<Cont1>( from );
304 BOOST_CHECK( !to.empty() );
305 BOOST_TEST_MESSAGE( "finishing container transfer test" );
306}
307
308
309//
310// test of copy operations
311//
312
313template< class BaseContainer, class DerivedContainer, class Derived >
314void container_assignment_test()
315{
316 BOOST_TEST_MESSAGE( "starting container assignment test" );
317
318 DerivedContainer derived;
319 set_capacity<DerivedContainer>()( derived );
320 derived.insert( derived.begin(), new Derived );
321 derived.insert( derived.begin(), new Derived );
322
323 BaseContainer base( derived );
324 BOOST_CHECK_EQUAL( derived.size(), base.size() );
325 base.clear();
326 base = derived;
327 BOOST_CHECK_EQUAL( derived.size(), base.size() );
328 BaseContainer base2( base );
329 BOOST_CHECK_EQUAL( base2.size(), base.size() );
330 base2 = base;
331 BOOST_CHECK_EQUAL( base2.size(), base.size() );
332 base = base;
333
334 BOOST_TEST_MESSAGE( "finished container assignment test" );
335}
336
337
338

source code of boost/libs/ptr_container/test/test_data.hpp