| // |
| // 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/ |
| // |
| |
| |
| #ifndef BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP |
| #define BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
| # pragma once |
| #endif |
| |
| #include <boost/ptr_container/detail/reversible_ptr_container.hpp> |
| |
| namespace boost |
| { |
| |
| namespace ptr_container_detail |
| { |
| template |
| < |
| class Config, |
| class CloneAllocator |
| > |
| class associative_ptr_container : |
| public reversible_ptr_container<Config,CloneAllocator> |
| { |
| typedef reversible_ptr_container<Config,CloneAllocator> |
| base_type; |
| |
| typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter |
| scoped_deleter; |
| |
| typedef BOOST_DEDUCED_TYPENAME Config::container_type |
| container_type; |
| public: // typedefs |
| typedef BOOST_DEDUCED_TYPENAME Config::key_type |
| key_type; |
| typedef BOOST_DEDUCED_TYPENAME Config::key_compare |
| key_compare; |
| typedef BOOST_DEDUCED_TYPENAME Config::value_compare |
| value_compare; |
| typedef BOOST_DEDUCED_TYPENAME Config::hasher |
| hasher; |
| typedef BOOST_DEDUCED_TYPENAME Config::key_equal |
| key_equal; |
| typedef BOOST_DEDUCED_TYPENAME Config::iterator |
| iterator; |
| typedef BOOST_DEDUCED_TYPENAME Config::const_iterator |
| const_iterator; |
| typedef BOOST_DEDUCED_TYPENAME Config::local_iterator |
| local_iterator; |
| typedef BOOST_DEDUCED_TYPENAME Config::const_local_iterator |
| const_local_iterator; |
| typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
| size_type; |
| typedef BOOST_DEDUCED_TYPENAME base_type::reference |
| reference; |
| typedef BOOST_DEDUCED_TYPENAME base_type::const_reference |
| const_reference; |
| |
| public: // foundation |
| associative_ptr_container() |
| { } |
| |
| template< class SizeType > |
| associative_ptr_container( SizeType n, unordered_associative_container_tag tag ) |
| : base_type( n, tag ) |
| { } |
| |
| template< class Compare, class Allocator > |
| associative_ptr_container( const Compare& comp, |
| const Allocator& a ) |
| : base_type( comp, a, container_type() ) |
| { } |
| |
| template< class Hash, class Pred, class Allocator > |
| associative_ptr_container( const Hash& hash, |
| const Pred& pred, |
| const Allocator& a ) |
| : base_type( hash, pred, a ) |
| { } |
| |
| template< class InputIterator, class Compare, class Allocator > |
| associative_ptr_container( InputIterator first, InputIterator last, |
| const Compare& comp, |
| const Allocator& a ) |
| : base_type( first, last, comp, a, container_type() ) |
| { } |
| |
| template< class InputIterator, class Hash, class Pred, class Allocator > |
| associative_ptr_container( InputIterator first, InputIterator last, |
| const Hash& hash, |
| const Pred& pred, |
| const Allocator& a ) |
| : base_type( first, last, hash, pred, a ) |
| { } |
| |
| template< class PtrContainer > |
| explicit associative_ptr_container( std::auto_ptr<PtrContainer> r ) |
| : base_type( r ) |
| { } |
| |
| associative_ptr_container( const associative_ptr_container& r ) |
| : base_type( r.begin(), r.end(), container_type() ) |
| { } |
| |
| template< class C, class V > |
| associative_ptr_container( const associative_ptr_container<C,V>& r ) |
| : base_type( r.begin(), r.end(), container_type() ) |
| { } |
| |
| template< class PtrContainer > |
| associative_ptr_container& operator=( std::auto_ptr<PtrContainer> r ) // nothrow |
| { |
| base_type::operator=( r ); |
| return *this; |
| } |
| |
| associative_ptr_container& operator=( associative_ptr_container r ) // strong |
| { |
| this->swap( r ); |
| return *this; |
| } |
| |
| public: // associative container interface |
| key_compare key_comp() const |
| { |
| return this->base().key_comp(); |
| } |
| |
| value_compare value_comp() const |
| { |
| return this->base().value_comp(); |
| } |
| |
| iterator erase( iterator before ) // nothrow |
| { |
| BOOST_ASSERT( !this->empty() ); |
| BOOST_ASSERT( before != this->end() ); |
| |
| this->remove( before ); // nothrow |
| iterator res( before ); // nothrow |
| ++res; // nothrow |
| this->base().erase( before.base() ); // nothrow |
| return res; // nothrow |
| } |
| |
| size_type erase( const key_type& x ) // nothrow |
| { |
| iterator i( this->base().find( x ) ); |
| // nothrow |
| if( i == this->end() ) // nothrow |
| return 0u; // nothrow |
| this->remove( i ); // nothrow |
| return this->base().erase( x ); // nothrow |
| } |
| |
| iterator erase( iterator first, |
| iterator last ) // nothrow |
| { |
| iterator res( last ); // nothrow |
| if( res != this->end() ) |
| ++res; // nothrow |
| |
| this->remove( first, last ); // nothrow |
| this->base().erase( first.base(), last.base() ); // nothrow |
| return res; // nothrow |
| } |
| |
| #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) |
| #else |
| template< class Range > |
| BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_convertible<Range&,key_type&>, |
| iterator >::type |
| erase( const Range& r ) |
| { |
| return erase( boost::begin(r), boost::end(r) ); |
| } |
| |
| #endif |
| |
| protected: |
| |
| template< class AssociatePtrCont > |
| void multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object, |
| AssociatePtrCont& from ) // strong |
| { |
| BOOST_ASSERT( (void*)&from != (void*)this ); |
| BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); |
| |
| this->base().insert( *object.base() ); // strong |
| from.base().erase( object.base() ); // nothrow |
| } |
| |
| template< class AssociatePtrCont > |
| size_type multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first, |
| BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last, |
| AssociatePtrCont& from ) // basic |
| { |
| BOOST_ASSERT( (void*)&from != (void*)this ); |
| |
| size_type res = 0; |
| for( ; first != last; ) |
| { |
| BOOST_ASSERT( first != from.end() ); |
| this->base().insert( *first.base() ); // strong |
| BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator |
| to_delete( first ); |
| ++first; |
| from.base().erase( to_delete.base() ); // nothrow |
| ++res; |
| } |
| |
| return res; |
| } |
| |
| template< class AssociatePtrCont > |
| bool single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object, |
| AssociatePtrCont& from ) // strong |
| { |
| BOOST_ASSERT( (void*)&from != (void*)this ); |
| BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); |
| |
| std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p = |
| this->base().insert( *object.base() ); // strong |
| if( p.second ) |
| from.base().erase( object.base() ); // nothrow |
| |
| return p.second; |
| } |
| |
| template< class AssociatePtrCont > |
| size_type single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first, |
| BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last, |
| AssociatePtrCont& from ) // basic |
| { |
| BOOST_ASSERT( (void*)&from != (void*)this ); |
| |
| size_type res = 0; |
| for( ; first != last; ) |
| { |
| BOOST_ASSERT( first != from.end() ); |
| std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p = |
| this->base().insert( *first.base() ); // strong |
| BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator |
| to_delete( first ); |
| ++first; |
| if( p.second ) |
| { |
| from.base().erase( to_delete.base() ); // nothrow |
| ++res; |
| } |
| } |
| return res; |
| } |
| |
| reference front() |
| { |
| BOOST_ASSERT( !this->empty() ); |
| BOOST_ASSERT( *this->begin().base() != 0 ); |
| return *this->begin(); |
| } |
| |
| const_reference front() const |
| { |
| return const_cast<associative_ptr_container*>(this)->front(); |
| } |
| |
| reference back() |
| { |
| BOOST_ASSERT( !this->empty() ); |
| BOOST_ASSERT( *(--this->end()).base() != 0 ); |
| return *--this->end(); |
| } |
| |
| const_reference back() const |
| { |
| return const_cast<associative_ptr_container*>(this)->back(); |
| } |
| |
| protected: // unordered interface |
| hasher hash_function() const |
| { |
| return this->base().hash_function(); |
| } |
| |
| key_equal key_eq() const |
| { |
| return this->base().key_eq(); |
| } |
| |
| size_type bucket_count() const |
| { |
| return this->base().bucket_count(); |
| } |
| |
| size_type max_bucket_count() const |
| { |
| return this->base().max_bucket_count(); |
| } |
| |
| size_type bucket_size( size_type n ) const |
| { |
| return this->base().bucket_size( n ); |
| } |
| |
| float load_factor() const |
| { |
| return this->base().load_factor(); |
| } |
| |
| float max_load_factor() const |
| { |
| return this->base().max_load_factor(); |
| } |
| |
| void max_load_factor( float factor ) |
| { |
| return this->base().max_load_factor( factor ); |
| } |
| |
| void rehash( size_type n ) |
| { |
| this->base().rehash( n ); |
| } |
| |
| public: |
| #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006)) |
| iterator begin() |
| { |
| return base_type::begin(); |
| } |
| |
| const_iterator begin() const |
| { |
| return base_type::begin(); |
| } |
| |
| iterator end() |
| { |
| return base_type::end(); |
| } |
| |
| const_iterator end() const |
| { |
| return base_type::end(); |
| } |
| |
| const_iterator cbegin() const |
| { |
| return base_type::cbegin(); |
| } |
| |
| const_iterator cend() const |
| { |
| return base_type::cend(); |
| } |
| #else |
| using base_type::begin; |
| using base_type::end; |
| using base_type::cbegin; |
| using base_type::cend; |
| #endif |
| |
| protected: |
| local_iterator begin( size_type n ) |
| { |
| return local_iterator( this->base().begin( n ) ); |
| } |
| |
| const_local_iterator begin( size_type n ) const |
| { |
| return const_local_iterator( this->base().begin( n ) ); |
| } |
| |
| local_iterator end( size_type n ) |
| { |
| return local_iterator( this->base().end( n ) ); |
| } |
| |
| const_local_iterator end( size_type n ) const |
| { |
| return const_local_iterator( this->base().end( n ) ); |
| } |
| |
| const_local_iterator cbegin( size_type n ) const |
| { |
| return const_local_iterator( this->base().cbegin( n ) ); |
| } |
| |
| const_local_iterator cend( size_type n ) |
| { |
| return const_local_iterator( this->base().cend( n ) ); |
| } |
| |
| }; // class 'associative_ptr_container' |
| |
| } // namespace 'ptr_container_detail' |
| |
| } // namespace 'boost' |
| |
| |
| #endif |