• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 using namespace std;
25 using namespace boost;
26 
27 //////////////////////////////////////////////////////////////////////////////
28 // Test class 1: a class hierarchy
29 //////////////////////////////////////////////////////////////////////////////
30 
31 namespace test
32 {
33     class Base
34     {
35     protected:
Base(const Base & r)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 
Base()53         Base() : data1(1), data2(2), data3(rand()%256),
54                  data(lexical_cast<string>(rand()))
55         {
56     #ifdef PTR_CONTAINER_DEBUG
57             objects++;
58             std::cout <<"+ " << objects << "\n";
59     #endif
60         }
61 
~Base()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 
print(ostream & out) const72         void     print( ostream& out ) const  { do_print( out); }
clone() const73         Base*    clone() const                { return do_clone(); }
foo()74         void     foo()                        { do_foo(); }
75 
less_than(const Base & b) const76         virtual bool less_than( const Base& b ) const
77         {
78             return data3 < b.data3;
79         }
80 
equal(const Base & b) const81         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:
do_print(ostream &) const94         virtual void  do_print( ostream& /*out*/ ) const   { };
do_clone() const95         virtual Base* do_clone() const                     { return new Base( *this ); };
do_foo()96         virtual void  do_foo()                             { };
97     };
98 
99     #ifdef PTR_CONTAINER_DEBUG
100     int Base::objects = 0;
101     #endif
102 
103 
104 
operator <<(ostream & out,const Base & b)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     //
new_clone(const Base & b)116     inline Base* new_clone( const Base& b )
117     {
118         return b.clone();
119     }
120 
121 
122 
operator <(const Base & l,const Base & r)123     inline bool operator<( const Base& l, const Base& r )
124     {
125         return l.less_than( r );
126     }
127 
128 
129 
operator >(const Base & l,const Base & r)130     inline bool operator>( const Base& l, const Base& r )
131     {
132         return r < l;
133     }
134 
135 
136 
operator ==(const Base & l,const Base & r)137     inline bool operator==( const Base& l, const Base& r )
138     {
139         return l.equal( r );
140     }
141 
142 
143 
operator !=(const Base & l,const Base & r)144     inline bool operator!=( const Base& l, const Base& r )
145     {
146         return !l.equal( r );
147     }
148 
149 
150 
hash_value(const Base & b)151     inline std::size_t hash_value( const Base& b )
152     {
153         std::size_t seed = 0;
154         boost::hash_combine( seed, b.data );
155         boost::hash_combine( seed, b.data1 );
156         boost::hash_combine( seed, b.data2 );
157         boost::hash_combine( seed, b.data3 );
158         return seed;
159     }
160 
161 
162     class Derived_class : public Base
163     {
164     protected:
Derived_class(const Derived_class & r)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 
do_print(ostream & out) const173         virtual void  do_print( ostream& out ) const
174         {
175             out << i_;
176         }
177 
178 
do_clone() const179         virtual Base* do_clone() const
180         {
181             return new Derived_class( *this );
182         }
183 
do_foo()184         virtual void do_foo()
185         {
186             ++i_;
187         }
188 
189     public:
Derived_class()190         Derived_class() : i_( rand() )
191         { }
192 
less_than(const Base & b) const193         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 
hash_value(const Derived_class & b)202     inline std::size_t hash_value( const Derived_class& b )
203     {
204         std::size_t seed = hash_value( static_cast<const Base&>( b ) );
205         boost::hash_combine( seed, b.i_ );
206         return seed;
207     }
208 }
209 
210 using test::Base;
211 using test::Derived_class;
212 
213 //////////////////////////////////////////////////////////////////////////////
214 // Test class 2: a value class
215 //////////////////////////////////////////////////////////////////////////////
216 
217 class Value
218 {
219 public: // for test reasons only
220     string s_;
221 
222 public:
223 
Value()224     Value() : s_( boost::lexical_cast<string>( rand() ) )
225     {}
226 
~Value()227     ~Value()      { /** debug code here */ }
228 
name() const229     string name() const
230     {
231         return s_;
232     }
233 };
234 
235 
236 
operator <(const Value & l,const Value & r)237 inline bool operator<( const Value& l, const Value& r )
238 {
239     return l.name() < r.name();
240 }
241 
242 
243 
operator >(const Value & l,const Value & r)244 inline bool operator>( const Value& l, const Value& r )
245 {
246     return l.name() > r.name();
247 }
248 
249 
250 
operator ==(const Value & l,const Value & r)251 inline bool operator==( const Value& l, const Value& r )
252 {
253     return l.name() == r.name();
254 }
255 
256 
257 
operator !=(const Value & l,const Value & r)258 inline bool operator!=( const Value& l, const Value& r )
259 {
260     return l.name() != r.name();
261 }
262 
263 
264 
operator <<(ostream & out,const Value & v)265 inline ostream& operator<<( ostream& out, const Value& v )
266 {
267     return out << v.name() << " ";
268 }
269 
270 
271 
hash_value(const Value & v)272 inline std::size_t hash_value( const Value& v )
273 {
274     return boost::hash_value( v.s_ );
275 }
276 
277 //
278 // used to hide "unused variable" warnings
279 //
280 template< class T >
hide_warning(T &)281 inline void hide_warning( T& /*r*/ )
282 { }
283 
284 //
285 // used to customize tests for circular_buffer
286 //
287 template< class Cont >
288 struct set_capacity
289 {
operator ()set_capacity290     void operator()( Cont& ) const
291     { }
292 };
293 
294 //
295 //  transfer() test
296 //
297 
298 template< class Cont1, class Cont2 >
transfer_test(Cont1 & from,Cont2 & to)299 void 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 
313 template< class BaseContainer, class DerivedContainer, class Derived >
container_assignment_test()314 void 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