Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/ptr_container/test/ptr_map.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 10.2 KB
Line 
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/test/unit_test.hpp>
13#include "test_data.hpp"
14#include <boost/ptr_container/exception.hpp>
15#include <boost/range/sub_range.hpp>
16#include <boost/cast.hpp>
17#include <cstdlib>
18#include <iostream>
19#include <memory>
20#include <string>
21
22//
23// abstract base class definition
24//
25struct abstract_base
26{
27    virtual ~abstract_base() {}
28    virtual void foo() = 0;
29    virtual abstract_base* clone() const = 0;
30};
31
32struct implementation : abstract_base
33{
34    implementation()
35    { }
36
37    implementation( const implementation& )
38    { }
39   
40    implementation( int, std::string, int, std::string )
41    { }
42
43    virtual void foo() {}
44    virtual abstract_base* clone() const
45    {
46        return new implementation( *this );
47    }
48};
49
50inline std::ostream& operator<<( std::ostream& out, const abstract_base& r )
51{
52    return out;   
53}
54
55inline abstract_base* new_clone( const abstract_base& r )
56{
57    return r.clone();
58}
59
60//
61// ptr_map test
62//
63
64template< typename C, typename B, typename T >
65void ptr_map_test();
66
67template< class Key >
68Key get_next_key( const Key& k );
69
70template<>
71int get_next_key<int>( const int& )
72{
73    return rand();
74}
75
76template<>
77std::string get_next_key<std::string>( const std::string& )
78{
79    return boost::lexical_cast<std::string>( rand() );
80}
81
82
83template< typename C, typename B, typename T >
84void ptr_map_test()
85{
86    using namespace boost;
87
88    BOOST_MESSAGE( "starting associative container test" );
89    enum { max_cnt = 10, size = 100 };
90    C  c;
91    BOOST_CHECK( c.size() == 0 );
92
93    const C c2( c.begin(), c.end() );
94    BOOST_CHECK( c.size() == c2.size() );
95
96    C c3;
97
98    BOOST_MESSAGE( "finished construction test" );
99
100    BOOST_DEDUCED_TYPENAME C::allocator_type alloc        = c.get_allocator();
101    BOOST_DEDUCED_TYPENAME C::iterator i                  = c.begin();
102    BOOST_DEDUCED_TYPENAME C::const_iterator ci           = c2.begin();
103    BOOST_DEDUCED_TYPENAME C::iterator i2                 = c.end();
104    BOOST_DEDUCED_TYPENAME C::const_iterator ci2          = c2.begin();
105    BOOST_DEDUCED_TYPENAME C::reverse_iterator ri         = c.rbegin();
106    BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cri  = c2.rbegin();
107    BOOST_DEDUCED_TYPENAME C::reverse_iterator rv2        = c.rend();
108    BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cvr2 = c2.rend();
109
110    BOOST_DEDUCED_TYPENAME C::key_type a_key;
111
112    BOOST_MESSAGE( "finished iterator test" );
113
114    BOOST_DEDUCED_TYPENAME C::size_type s                 = c.size();
115    BOOST_DEDUCED_TYPENAME C::size_type s2                = c.max_size();
116    hide_warning(s2);
117    BOOST_CHECK_EQUAL( c.size(), s );
118    bool b                                                = c.empty();
119    hide_warning(b);
120    BOOST_MESSAGE( "finished accessors test" );
121
122    a_key = get_next_key( a_key );
123    c.insert( a_key, new T );
124    a_key = get_next_key( a_key );
125    c.insert( a_key, new T );
126    c3.insert( c.begin(), c.end() );
127    c.insert( c3 );
128    c.erase( c.begin() );
129    c3.erase( c3.begin(), c3.end() );
130
131    BOOST_CHECK( c3.empty() );
132    c.swap( c3 );
133    swap(c,c3);
134    swap(c3,c);
135    BOOST_CHECK( !c3.empty() );
136    c3.clear();
137    BOOST_CHECK( c3.empty() );
138    BOOST_MESSAGE( "finished modifiers test" );
139
140
141    a_key = get_next_key( a_key );
142    c.insert( a_key, new T );
143    a_key = get_next_key( a_key );
144    c.insert( a_key, std::auto_ptr<T>( new T ) );
145    typename C::auto_type ptr2  = c.release( c.begin() );
146    std::auto_ptr<C> ap         = c.release();
147    c                           = c2.clone();
148    BOOST_MESSAGE( "finished release/clone test" );
149
150
151    a_key = get_next_key( a_key );
152    c3.insert( a_key, new T );
153    a_key = get_next_key( a_key );
154    c3.insert( a_key, new T );
155
156    c. BOOST_NESTED_TEMPLATE transfer<C>( c3.begin(), c3 );
157    c. BOOST_NESTED_TEMPLATE transfer<C>( c3.begin(), c3.end(), c3 );
158    BOOST_CHECK( c3.empty() );
159    BOOST_CHECK( !c.empty() );
160    c3. BOOST_NESTED_TEMPLATE transfer<C>( c );
161    BOOST_CHECK( !c3.empty() );
162    BOOST_CHECK( c.empty() );
163#ifdef BOOST_NO_SFINAE
164#else
165    c. BOOST_NESTED_TEMPLATE transfer<C>( make_iterator_range(c3), c3 );
166    BOOST_CHECK( !c.empty() );
167    BOOST_CHECK( c3.empty() );
168    c3. BOOST_NESTED_TEMPLATE transfer<C>(c);
169#endif
170    BOOST_MESSAGE( "finished transfer test" );
171
172    BOOST_CHECK( !c3.empty() );
173    c3.replace( c3.begin(), new T );
174    c3.replace( c3.begin(), std::auto_ptr<T>( new T ) );
175    BOOST_MESSAGE( "finished set/map interface test" );
176
177    // @todo: make macro with algorithms so that the right erase() is called.
178    //  c.unique();
179    //  c.unique( std::not_equal_to<T>() );
180    //  c.remove( T() );
181    //  c.remove_if( std::binder1st< std::equal_to<T> >( T() ) );
182
183    sub_range<C>        sub;
184    sub_range<const C> csub;
185
186    i  = c.find( get_next_key( a_key ) );
187    ci = c2.find( get_next_key( a_key ) );
188    c2.count( get_next_key( a_key ) );
189    i  = c.lower_bound( get_next_key( a_key ) );
190    ci = c2.lower_bound( get_next_key( a_key ) );
191    i  = c.upper_bound( get_next_key( a_key ) );
192    ci = c2.upper_bound( get_next_key( a_key ) );
193    sub  = c.equal_range( get_next_key( a_key ) );
194    csub = c2.equal_range( get_next_key( a_key ) );
195
196    try
197    {
198        c.at( get_next_key( a_key ) );
199    }
200    catch( const bad_ptr_container_operation& )
201    { }
202
203    try
204    {
205        c2.at( get_next_key( a_key ) );
206    }
207    catch( const bad_ptr_container_operation& )
208    { }
209
210    BOOST_MESSAGE( "finished algorithms interface test" );
211
212    typename C::iterator it = c.begin(), e = c.end();
213    for( ; it != e; ++it )
214    {
215        std::cout << "\n mapped value = " << *it->second << " key = " << it->first;
216        //std::cout << "\n mapped value = " << it.value() << " key = " << it.key();
217    }
218   
219    typename C::reverse_iterator rit = c.rbegin(), re = c.rend();
220    for( ; rit != re; ++rit )
221    {
222        std::cout << "\n mapped value = " << *rit->second << " key = " << rit->first;
223        //std::cout << "\n mapped value = " << rit.value() << " key = " << rit.key();   
224        //std::cout << "\n mapped value (base) = "
225        //          << rit.base().value() << " key = " << rit.base().key();   
226    }
227   
228    typename C::const_reverse_iterator crit = c2.rbegin(), cre = c2.rend();
229    for( ; crit != cre; ++crit )
230    {
231        std::cout << "\n mapped value = " << *(*crit).second << " key = " << (*crit).first;
232        //std::cout << "\n mapped value = " << crit.value() << " key = " << crit.key();   
233        //std::cout << "\n mapped value (base) = "
234        //          << crit.base().value() << " key = " << crit.base().key();   
235    }
236   
237    BOOST_MESSAGE( "finished iterator test" );
238
239    a_key = get_next_key( a_key );
240    c.insert( a_key, new T );
241    c.erase( a_key );
242    c.erase( a_key );
243
244}
245
246
247
248template< class CDerived, class CBase, class T >
249void test_transfer()
250{
251    CDerived from;
252    CBase    to;
253
254    int key = get_next_key( key );
255    from.insert( key, new T );
256    key = get_next_key( key );
257    from.insert( key, new T );
258    transfer_test( from, to );
259}
260
261
262
263#include <boost/ptr_container/ptr_map.hpp>
264
265using namespace std;
266
267void test_map()
268{
269    ptr_map_test< ptr_map<int, Base>, Base, Derived_class >();
270    ptr_map_test< ptr_map<int, Value>, Value, Value >();
271    ptr_map_test< ptr_map<int, nullable<Base> >, Base, Derived_class >();
272    ptr_map_test< ptr_map<int, nullable<Value> >, Value, Value >();
273    ptr_map_test< ptr_map<int, abstract_base>, abstract_base, implementation >();
274
275    ptr_map_test< ptr_multimap<int,Base>, Base, Derived_class >();
276    ptr_map_test< ptr_multimap<int,Value>, Value, Value >();   
277    ptr_map_test< ptr_multimap<int, nullable<Base> >, Base, Derived_class >();
278    ptr_map_test< ptr_multimap<int, nullable<Value> >, Value, Value >();
279
280    test_transfer< ptr_map<int,Derived_class>, ptr_map<int,Base>, Derived_class >();
281    test_transfer< ptr_multimap<int,Derived_class>, ptr_multimap<int,Base>, Derived_class >();
282   
283    string joe   = "joe";
284    string brian = "brian";
285    string kenny = "kenny"; 
286   
287    ptr_map<string,int> m;
288    m.insert( joe, new int( 4 ) );
289    m.insert( brian, new int( 6 ) );
290    BOOST_CHECK( m[ "foo" ] == 0 );
291    m[ "bar" ] += 5;
292    BOOST_CHECK( m[ "bar" ] == 5 );
293    m[ joe ]   += 56;
294    m[ brian ] += 10;
295
296    BOOST_CHECK_THROW( (m.insert(kenny, 0 )), bad_ptr_container_operation );
297    BOOST_CHECK_THROW( (m.replace(m.begin(), 0 )), bad_ptr_container_operation ); 
298    BOOST_CHECK_THROW( (m.at("not there")), bad_ptr_container_operation );
299
300    for( ptr_map<string,int>::iterator i = m.begin();
301         i != m.end(); ++i )
302    {
303        if( is_null(i) )
304            BOOST_CHECK( false );
305        const string& ref  = i->first;
306        hide_warning(ref);
307        int&          ref2 = *(*i).second;
308        ref2++;
309    }
310
311    typedef ptr_map<string,Derived_class> map_type;
312    map_type m2;
313    m2.insert( joe, new Derived_class );
314    //
315    // This works fine since 'm2' is not const
316    //
317    m2.begin()->second->foo();
318
319    //
320    // These all return an implementation-defined proxy
321    // with two public members: 'first' and 'second'
322    //
323    map_type::value_type       a_value      = *m2.begin();
324    a_value.second->foo();
325    map_type::reference        a_reference  = *m2.begin();
326    a_reference.second->foo();
327    map_type::const_reference  a_creference = *const_begin(m2);
328    //
329    // @remark: taking the adress of an rvalue is not valid, thought
330    //          many compilers accept it.
331    //
332    // map_type::pointer          a_pointer    = &*m2.begin();
333    //a_pointer->second->foo();
334    //map_type::const_pointer    a_cpointer   = &*const_begin(m2);
335   
336    //
337    //
338    // These will fail as iterators propagate constness
339    //
340    //a_creference.second->foo();
341    //a_cpointer->second->foo();
342    //const_begin(m2)->second->foo();
343
344}
345
346using boost::unit_test::test_suite;
347
348test_suite* init_unit_test_suite( int argc, char* argv[] )
349{
350    test_suite* test = BOOST_TEST_SUITE( "Pointer Container Test Suite" );
351
352    test->add( BOOST_TEST_CASE( &test_map ) );
353
354    return test;
355}
356
357
358
359
360
361
362
Note: See TracBrowser for help on using the repository browser.