123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- //
- // Boost.Pointer Container
- //
- // Copyright Thorsten Ottosen 2003-2005. Use, modification and
- // distribution is subject to the Boost Software License, Version
- // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // For more information, see http://www.boost.org/libs/ptr_container/
- //
- #include "test_data.hpp"
- #include <boost/test/unit_test.hpp>
- #include <boost/ptr_container/exception.hpp>
- #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
- #include <boost/range/sub_range.hpp>
- #include <boost/cast.hpp>
- #include <cstdlib>
- #include <iostream>
- #include <memory>
- #include <string>
- //
- // abstract base class definition
- //
- struct abstract_base
- {
- virtual ~abstract_base() {}
- virtual void foo() = 0;
- virtual abstract_base* clone() const = 0;
- };
- struct implementation : abstract_base
- {
- implementation()
- { }
- implementation( const implementation& )
- { }
-
- implementation( int, std::string, int, std::string )
- { }
- virtual void foo() {}
- virtual abstract_base* clone() const
- {
- return new implementation( *this );
- }
- };
- inline std::ostream& operator<<( std::ostream& out, const abstract_base& r )
- {
- return out;
- }
- inline abstract_base* new_clone( const abstract_base& r )
- {
- return r.clone();
- }
- //
- // ptr_map test
- //
- template< typename C, typename B, typename T >
- void ptr_map_test();
- template< class Key >
- Key get_next_key( const Key& k );
- template<>
- int get_next_key<int>( const int& )
- {
- return rand();
- }
- template<>
- std::string get_next_key<std::string>( const std::string& )
- {
- return boost::lexical_cast<std::string>( rand() );
- }
- #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- #endif
- template< typename C, typename B, typename T >
- void ptr_map_test()
- {
- using namespace boost;
- BOOST_TEST_MESSAGE( "starting associative container test" );
- enum { max_cnt = 10, size = 100 };
- C c;
- BOOST_CHECK( c.size() == 0 );
- const C c2( c.begin(), c.end() );
- BOOST_CHECK( c.size() == c2.size() );
- C c3;
- BOOST_TEST_MESSAGE( "finished construction test" );
- BOOST_DEDUCED_TYPENAME C::allocator_type alloc = c.get_allocator();
- BOOST_DEDUCED_TYPENAME C::iterator i = c.begin();
- BOOST_DEDUCED_TYPENAME C::const_iterator ci = c2.begin();
- BOOST_DEDUCED_TYPENAME C::iterator i2 = c.end();
- hide_warning(i2);
- BOOST_DEDUCED_TYPENAME C::const_iterator ci2 = c2.begin();
- hide_warning(ci2);
- BOOST_DEDUCED_TYPENAME C::reverse_iterator ri = c.rbegin();
- hide_warning(ri);
- BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cri = c2.rbegin();
- hide_warning(cri);
- BOOST_DEDUCED_TYPENAME C::reverse_iterator rv2 = c.rend();
- hide_warning(rv2);
- BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cvr2 = c2.rend();
- hide_warning(cvr2);
- BOOST_DEDUCED_TYPENAME C::key_type a_key;
- BOOST_TEST_MESSAGE( "finished iterator test" );
- BOOST_DEDUCED_TYPENAME C::size_type s = c.size();
- BOOST_DEDUCED_TYPENAME C::size_type s2 = c.max_size();
- hide_warning(s2);
- BOOST_CHECK_EQUAL( c.size(), s );
- bool b = c.empty();
- hide_warning(b);
- BOOST_TEST_MESSAGE( "finished accessors test" );
- a_key = get_next_key( a_key );
- c.insert( a_key, new T );
- a_key = get_next_key( a_key );
- c.insert( a_key, new T );
- c3.insert( c.begin(), c.end() );
- c.insert( c3 );
- c.erase( c.begin() );
- BOOST_CHECK( c3.end() == c3.erase( boost::make_iterator_range(c3) ) );
- c3.erase( a_key );
- BOOST_CHECK( c3.empty() );
- c.swap( c3 );
- swap(c,c3);
- swap(c3,c);
- BOOST_CHECK( !c3.empty() );
- c3.clear();
- BOOST_CHECK( c3.empty() );
- BOOST_TEST_MESSAGE( "finished modifiers test" );
- a_key = get_next_key( a_key );
- c.insert( a_key, new T );
- a_key = get_next_key( a_key );
- #ifndef BOOST_NO_AUTO_PTR
- c.insert( a_key, std::auto_ptr<T>( new T ) );
- #endif
- #ifndef BOOST_NO_CXX11_SMART_PTR
- c.insert( a_key, std::unique_ptr<T>( new T ) );
- #endif
- typename C::auto_type ptr2 = c.release( c.begin() );
- #ifndef BOOST_NO_AUTO_PTR
- std::auto_ptr<C> ap = c.release();
- #else
- std::unique_ptr<C> up = c.release();
- #endif
- c = c2.clone();
- BOOST_TEST_MESSAGE( "finished release/clone test" );
- a_key = get_next_key( a_key );
- c3.insert( a_key, new T );
- a_key = get_next_key( a_key );
- c3.insert( a_key, new T );
- c. BOOST_NESTED_TEMPLATE transfer<C>( c3.begin(), c3 );
- c. BOOST_NESTED_TEMPLATE transfer<C>( c3.begin(), c3.end(), c3 );
- BOOST_CHECK( c3.empty() );
- BOOST_CHECK( !c.empty() );
- c3. BOOST_NESTED_TEMPLATE transfer<C>( c );
- BOOST_CHECK( !c3.empty() );
- BOOST_CHECK( c.empty() );
- #ifdef BOOST_NO_SFINAE
- #else
- c. BOOST_NESTED_TEMPLATE transfer<C>( make_iterator_range(c3), c3 );
- BOOST_CHECK( !c.empty() );
- BOOST_CHECK( c3.empty() );
- c3. BOOST_NESTED_TEMPLATE transfer<C>(c);
- #endif
- BOOST_TEST_MESSAGE( "finished transfer test" );
- BOOST_CHECK( !c3.empty() );
- c3.replace( c3.begin(), new T );
- #ifndef BOOST_NO_AUTO_PTR
- c3.replace( c3.begin(), std::auto_ptr<T>( new T ) );
- #endif
- #ifndef BOOST_NO_CXX11_SMART_PTR
- c3.replace( c3.begin(), std::unique_ptr<T>( new T ) );
- #endif
- BOOST_TEST_MESSAGE( "finished set/map interface test" );
- // @todo: make macro with algorithms so that the right erase() is called.
- // c.unique();
- // c.unique( std::not_equal_to<T>() );
- // c.remove( T() );
- // c.remove_if( std::binder1st< std::equal_to<T> >( T() ) );
- sub_range<C> sub;
- sub_range<const C> csub;
- i = c.find( get_next_key( a_key ) );
- ci = c2.find( get_next_key( a_key ) );
- BOOST_CHECK_EQUAL(0, c2.count( get_next_key( a_key ) ));
- i = c.lower_bound( get_next_key( a_key ) );
- ci = c2.lower_bound( get_next_key( a_key ) );
- i = c.upper_bound( get_next_key( a_key ) );
- ci = c2.upper_bound( get_next_key( a_key ) );
- sub = c.equal_range( get_next_key( a_key ) );
- csub = c2.equal_range( get_next_key( a_key ) );
- try
- {
- c.at( get_next_key( a_key ) );
- }
- catch( const bad_ptr_container_operation& )
- { }
- try
- {
- c2.at( get_next_key( a_key ) );
- }
- catch( const bad_ptr_container_operation& )
- { }
- BOOST_TEST_MESSAGE( "finished algorithms interface test" );
- typename C::iterator it = c.begin(), e = c.end();
- for( ; it != e; ++it )
- {
- std::cout << "\n mapped value = " << *it->second << " key = " << it->first;
- //std::cout << "\n mapped value = " << it.value() << " key = " << it.key();
- }
-
- typename C::reverse_iterator rit = c.rbegin(), re = c.rend();
- for( ; rit != re; ++rit )
- {
- std::cout << "\n mapped value = " << *rit->second << " key = " << rit->first;
- //std::cout << "\n mapped value = " << rit.value() << " key = " << rit.key();
- //std::cout << "\n mapped value (base) = "
- // << rit.base().value() << " key = " << rit.base().key();
- }
-
- typename C::const_reverse_iterator crit = c2.rbegin(), cre = c2.rend();
- for( ; crit != cre; ++crit )
- {
- std::cout << "\n mapped value = " << *(*crit).second << " key = " << (*crit).first;
- //std::cout << "\n mapped value = " << crit.value() << " key = " << crit.key();
- //std::cout << "\n mapped value (base) = "
- // << crit.base().value() << " key = " << crit.base().key();
- }
-
- BOOST_TEST_MESSAGE( "finished iterator test" );
- a_key = get_next_key( a_key );
- c.insert( a_key, new T );
- c.erase( a_key );
- c.erase( a_key );
- }
- #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
- #pragma GCC diagnostic pop
- #endif
- template< class CDerived, class CBase, class T >
- void test_transfer()
- {
- CDerived from;
- CBase to;
- int key = get_next_key( key );
- from.insert( key, new T );
- key = get_next_key( key );
- from.insert( key, new T );
- transfer_test( from, to );
- }
- template< class BaseContainer, class DerivedContainer, class Derived >
- void map_container_assignment_test()
- {
- DerivedContainer derived;
- std::string foo( "foo" );
- std::string bar( "foo" );
- derived.insert( foo, new Derived );
- derived.insert( bar, new Derived );
- BaseContainer base_container( derived );
- BOOST_CHECK_EQUAL( derived.size(), base_container.size() );
- base_container.clear();
- base_container = derived;
- BOOST_CHECK_EQUAL( derived.size(), base_container.size() );
-
- BaseContainer base2( base_container );
- BOOST_CHECK_EQUAL( base2.size(), base_container.size() );
- base2 = base_container;
- BOOST_CHECK_EQUAL( base2.size(), base_container.size() );
- base_container = base_container;
- }
- #include <boost/ptr_container/ptr_map.hpp>
- using namespace std;
- void test_map()
- {
- ptr_map_test< ptr_map<int, Base>, Base, Derived_class >();
- ptr_map_test< ptr_map<int, Value>, Value, Value >();
- ptr_map_test< ptr_map<int, nullable<Base> >, Base, Derived_class >();
- ptr_map_test< ptr_map<int, nullable<Value> >, Value, Value >();
- ptr_map_test< ptr_map<int, abstract_base>, abstract_base, implementation >();
- ptr_map_test< ptr_multimap<int,Base>, Base, Derived_class >();
- ptr_map_test< ptr_multimap<int,Value>, Value, Value >();
- ptr_map_test< ptr_multimap<int, nullable<Base> >, Base, Derived_class >();
- ptr_map_test< ptr_multimap<int, nullable<Value> >, Value, Value >();
- map_container_assignment_test< ptr_map<std::string,Base>,
- ptr_map<std::string,Derived_class>,
- Derived_class>();
- map_container_assignment_test< ptr_map<std::string, nullable<Base> >,
- ptr_map<std::string,Derived_class>,
- Derived_class>();
- map_container_assignment_test< ptr_map<std::string, nullable<Base> >,
- ptr_map<std::string, nullable<Derived_class> >,
- Derived_class>();
- map_container_assignment_test< ptr_multimap<std::string,Base>,
- ptr_multimap<std::string,Derived_class>,
- Derived_class>();
- map_container_assignment_test< ptr_multimap<std::string, nullable<Base> >,
- ptr_multimap<std::string,Derived_class>,
- Derived_class>();
- map_container_assignment_test< ptr_multimap<std::string, nullable<Base> >,
- ptr_multimap<std::string, nullable<Derived_class> >,
- Derived_class>();
-
- test_transfer< ptr_map<int,Derived_class>, ptr_map<int,Base>, Derived_class >();
- test_transfer< ptr_multimap<int,Derived_class>, ptr_multimap<int,Base>, Derived_class >();
-
- string joe = "joe";
- string brian = "brian";
- string kenny = "kenny";
-
- ptr_map<string,int> m;
- m.insert( joe, new int( 4 ) );
- m.insert( brian, new int( 6 ) );
- BOOST_CHECK( m[ "foo" ] == 0 );
- m[ "bar" ] += 5;
- BOOST_CHECK( m[ "bar" ] == 5 );
- m[ joe ] += 56;
- m[ brian ] += 10;
- BOOST_CHECK_THROW( (m.insert(kenny, 0 )), bad_ptr_container_operation );
- BOOST_CHECK_THROW( (m.replace(m.begin(), 0 )), bad_ptr_container_operation );
- BOOST_CHECK_THROW( (m.at("not there")), bad_ptr_container_operation );
- for( ptr_map<string,int>::iterator i = m.begin();
- i != m.end(); ++i )
- {
- if( is_null(i) )
- BOOST_CHECK( false );
- const string& ref = i->first;
- hide_warning(ref);
- int& ref2 = *(*i).second;
- ref2++;
- }
- typedef ptr_map<string,Derived_class> map_type;
- map_type m2;
- m2.insert( joe, new Derived_class );
- //
- // This works fine since 'm2' is not const
- //
- m2.begin()->second->foo();
- //
- // These all return an implementation-defined proxy
- // with two public members: 'first' and 'second'
- //
- map_type::value_type a_value = *m2.begin();
- a_value.second->foo();
- map_type::reference a_reference = *m2.begin();
- a_reference.second->foo();
- map_type::const_reference a_creference = *const_begin(m2);
- hide_warning(a_creference);
-
- //
- //
- // These will fail as iterators propagate constness
- //
- //a_creference.second->foo();
- //a_cpointer->second->foo();
- //const_begin(m2)->second->foo();
- }
- #include <boost/tuple/tuple.hpp>
- #include <boost/iterator/zip_iterator.hpp>
- #include <map>
- #include <boost/ptr_container/ptr_map.hpp>
- void test_map_iterators()
- {
- using boost::zip_iterator;
- using boost::tuple;
- using boost::make_tuple;
- using boost::ptr_map;
- using std::map;
- //typedef map<int, int> theMapType;
- /*
- @remark: the following will not compile
- because of the proxy (non-reference) returned by operator*()
- of the ptr_map's iterator type.
-
- typedef boost::ptr_map<int, int> theMapType;
- typedef zip_iterator
- <tuple<theMapType::iterator, theMapType::iterator> > zipIter;
- theMapType map1;
- theMapType map2;
- zipIter zip(make_tuple(map1.begin(), map2.begin()));
- */
- }
- using boost::unit_test::test_suite;
- test_suite* init_unit_test_suite( int argc, char* argv[] )
- {
- test_suite* test = BOOST_TEST_SUITE( "Pointer Container Test Suite" );
- test->add( BOOST_TEST_CASE( &test_map ) );
- test->add( BOOST_TEST_CASE( &test_map_iterators ) );
- return test;
- }
|