Chris@16: // Chris@16: // Boost.Pointer Container Chris@16: // Chris@16: // Copyright Thorsten Ottosen 2003-2005. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org/libs/ptr_container/ Chris@16: // Chris@16: Chris@16: Chris@16: #ifndef BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP Chris@16: #define BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: namespace ptr_container_detail Chris@16: { Chris@16: template Chris@16: < Chris@16: class Config, Chris@16: class CloneAllocator Chris@16: > Chris@16: class associative_ptr_container : Chris@16: public reversible_ptr_container Chris@16: { Chris@16: typedef reversible_ptr_container Chris@16: base_type; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter Chris@16: scoped_deleter; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::container_type Chris@16: container_type; Chris@16: public: // typedefs Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::key_type Chris@16: key_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::key_compare Chris@16: key_compare; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::value_compare Chris@16: value_compare; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::hasher Chris@16: hasher; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::key_equal Chris@16: key_equal; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::iterator Chris@16: iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::const_iterator Chris@16: const_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::local_iterator Chris@16: local_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::const_local_iterator Chris@16: const_local_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::size_type Chris@16: size_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::reference Chris@16: reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_reference Chris@16: const_reference; Chris@16: Chris@16: public: // foundation Chris@16: associative_ptr_container() Chris@16: { } Chris@16: Chris@16: template< class SizeType > Chris@16: associative_ptr_container( SizeType n, unordered_associative_container_tag tag ) Chris@16: : base_type( n, tag ) Chris@16: { } Chris@16: Chris@16: template< class Compare, class Allocator > Chris@16: associative_ptr_container( const Compare& comp, Chris@16: const Allocator& a ) Chris@16: : base_type( comp, a, container_type() ) Chris@16: { } Chris@16: Chris@16: template< class Hash, class Pred, class Allocator > Chris@16: associative_ptr_container( const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( hash, pred, a ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator, class Compare, class Allocator > Chris@16: associative_ptr_container( InputIterator first, InputIterator last, Chris@16: const Compare& comp, Chris@16: const Allocator& a ) Chris@16: : base_type( first, last, comp, a, container_type() ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator, class Hash, class Pred, class Allocator > Chris@16: associative_ptr_container( InputIterator first, InputIterator last, Chris@16: const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( first, last, hash, pred, a ) Chris@16: { } Chris@16: Chris@16: template< class PtrContainer > Chris@16: explicit associative_ptr_container( std::auto_ptr r ) Chris@16: : base_type( r ) Chris@16: { } Chris@16: Chris@16: associative_ptr_container( const associative_ptr_container& r ) Chris@16: : base_type( r.begin(), r.end(), container_type() ) Chris@16: { } Chris@16: Chris@16: template< class C, class V > Chris@16: associative_ptr_container( const associative_ptr_container& r ) Chris@16: : base_type( r.begin(), r.end(), container_type() ) Chris@16: { } Chris@16: Chris@16: template< class PtrContainer > Chris@16: associative_ptr_container& operator=( std::auto_ptr r ) // nothrow Chris@16: { Chris@16: base_type::operator=( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: associative_ptr_container& operator=( associative_ptr_container r ) // strong Chris@16: { Chris@16: this->swap( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: public: // associative container interface Chris@16: key_compare key_comp() const Chris@16: { Chris@16: return this->base().key_comp(); Chris@16: } Chris@16: Chris@16: value_compare value_comp() const Chris@16: { Chris@16: return this->base().value_comp(); Chris@16: } Chris@16: Chris@16: iterator erase( iterator before ) // nothrow Chris@16: { Chris@16: BOOST_ASSERT( !this->empty() ); Chris@16: BOOST_ASSERT( before != this->end() ); Chris@16: Chris@16: this->remove( before ); // nothrow Chris@16: iterator res( before ); // nothrow Chris@16: ++res; // nothrow Chris@16: this->base().erase( before.base() ); // nothrow Chris@16: return res; // nothrow Chris@16: } Chris@16: Chris@16: size_type erase( const key_type& x ) // nothrow Chris@16: { Chris@16: iterator i( this->base().find( x ) ); Chris@16: // nothrow Chris@16: if( i == this->end() ) // nothrow Chris@16: return 0u; // nothrow Chris@16: this->remove( i ); // nothrow Chris@16: return this->base().erase( x ); // nothrow Chris@16: } Chris@16: Chris@16: iterator erase( iterator first, Chris@16: iterator last ) // nothrow Chris@16: { Chris@16: iterator res( last ); // nothrow Chris@16: if( res != this->end() ) Chris@16: ++res; // nothrow Chris@16: Chris@16: this->remove( first, last ); // nothrow Chris@16: this->base().erase( first.base(), last.base() ); // nothrow Chris@16: return res; // nothrow Chris@16: } Chris@16: Chris@16: #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: #else Chris@16: template< class Range > Chris@16: BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_convertible, Chris@16: iterator >::type Chris@16: erase( const Range& r ) Chris@16: { Chris@16: return erase( boost::begin(r), boost::end(r) ); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: protected: Chris@16: Chris@16: template< class AssociatePtrCont > Chris@16: void multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object, Chris@16: AssociatePtrCont& from ) // strong Chris@16: { Chris@16: BOOST_ASSERT( (void*)&from != (void*)this ); Chris@16: BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); Chris@16: Chris@16: this->base().insert( *object.base() ); // strong Chris@16: from.base().erase( object.base() ); // nothrow Chris@16: } Chris@16: Chris@16: template< class AssociatePtrCont > Chris@16: size_type multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first, Chris@16: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last, Chris@16: AssociatePtrCont& from ) // basic Chris@16: { Chris@16: BOOST_ASSERT( (void*)&from != (void*)this ); Chris@16: Chris@16: size_type res = 0; Chris@16: for( ; first != last; ) Chris@16: { Chris@16: BOOST_ASSERT( first != from.end() ); Chris@16: this->base().insert( *first.base() ); // strong Chris@16: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator Chris@16: to_delete( first ); Chris@16: ++first; Chris@16: from.base().erase( to_delete.base() ); // nothrow Chris@16: ++res; Chris@16: } Chris@16: Chris@16: return res; Chris@16: } Chris@16: Chris@16: template< class AssociatePtrCont > Chris@16: bool single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object, Chris@16: AssociatePtrCont& from ) // strong Chris@16: { Chris@16: BOOST_ASSERT( (void*)&from != (void*)this ); Chris@16: BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); Chris@16: Chris@16: std::pair p = Chris@16: this->base().insert( *object.base() ); // strong Chris@16: if( p.second ) Chris@16: from.base().erase( object.base() ); // nothrow Chris@16: Chris@16: return p.second; Chris@16: } Chris@16: Chris@16: template< class AssociatePtrCont > Chris@16: size_type single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first, Chris@16: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last, Chris@16: AssociatePtrCont& from ) // basic Chris@16: { Chris@16: BOOST_ASSERT( (void*)&from != (void*)this ); Chris@16: Chris@16: size_type res = 0; Chris@16: for( ; first != last; ) Chris@16: { Chris@16: BOOST_ASSERT( first != from.end() ); Chris@16: std::pair p = Chris@16: this->base().insert( *first.base() ); // strong Chris@16: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator Chris@16: to_delete( first ); Chris@16: ++first; Chris@16: if( p.second ) Chris@16: { Chris@16: from.base().erase( to_delete.base() ); // nothrow Chris@16: ++res; Chris@16: } Chris@16: } Chris@16: return res; Chris@16: } Chris@16: Chris@16: reference front() Chris@16: { Chris@16: BOOST_ASSERT( !this->empty() ); Chris@16: BOOST_ASSERT( *this->begin().base() != 0 ); Chris@16: return *this->begin(); Chris@16: } Chris@16: Chris@16: const_reference front() const Chris@16: { Chris@16: return const_cast(this)->front(); Chris@16: } Chris@16: Chris@16: reference back() Chris@16: { Chris@16: BOOST_ASSERT( !this->empty() ); Chris@16: BOOST_ASSERT( *(--this->end()).base() != 0 ); Chris@16: return *--this->end(); Chris@16: } Chris@16: Chris@16: const_reference back() const Chris@16: { Chris@16: return const_cast(this)->back(); Chris@16: } Chris@16: Chris@16: protected: // unordered interface Chris@16: hasher hash_function() const Chris@16: { Chris@16: return this->base().hash_function(); Chris@16: } Chris@16: Chris@16: key_equal key_eq() const Chris@16: { Chris@16: return this->base().key_eq(); Chris@16: } Chris@16: Chris@16: size_type bucket_count() const Chris@16: { Chris@16: return this->base().bucket_count(); Chris@16: } Chris@16: Chris@16: size_type max_bucket_count() const Chris@16: { Chris@16: return this->base().max_bucket_count(); Chris@16: } Chris@16: Chris@16: size_type bucket_size( size_type n ) const Chris@16: { Chris@16: return this->base().bucket_size( n ); Chris@16: } Chris@16: Chris@16: float load_factor() const Chris@16: { Chris@16: return this->base().load_factor(); Chris@16: } Chris@16: Chris@16: float max_load_factor() const Chris@16: { Chris@16: return this->base().max_load_factor(); Chris@16: } Chris@16: Chris@16: void max_load_factor( float factor ) Chris@16: { Chris@16: return this->base().max_load_factor( factor ); Chris@16: } Chris@16: Chris@16: void rehash( size_type n ) Chris@16: { Chris@16: this->base().rehash( n ); Chris@16: } Chris@16: Chris@16: public: Chris@16: #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006)) Chris@16: iterator begin() Chris@16: { Chris@16: return base_type::begin(); Chris@16: } Chris@16: Chris@16: const_iterator begin() const Chris@16: { Chris@16: return base_type::begin(); Chris@16: } Chris@16: Chris@16: iterator end() Chris@16: { Chris@16: return base_type::end(); Chris@16: } Chris@16: Chris@16: const_iterator end() const Chris@16: { Chris@16: return base_type::end(); Chris@16: } Chris@16: Chris@16: const_iterator cbegin() const Chris@16: { Chris@16: return base_type::cbegin(); Chris@16: } Chris@16: Chris@16: const_iterator cend() const Chris@16: { Chris@16: return base_type::cend(); Chris@16: } Chris@16: #else Chris@16: using base_type::begin; Chris@16: using base_type::end; Chris@16: using base_type::cbegin; Chris@16: using base_type::cend; Chris@16: #endif Chris@16: Chris@16: protected: Chris@16: local_iterator begin( size_type n ) Chris@16: { Chris@16: return local_iterator( this->base().begin( n ) ); Chris@16: } Chris@16: Chris@16: const_local_iterator begin( size_type n ) const Chris@16: { Chris@16: return const_local_iterator( this->base().begin( n ) ); Chris@16: } Chris@16: Chris@16: local_iterator end( size_type n ) Chris@16: { Chris@16: return local_iterator( this->base().end( n ) ); Chris@16: } Chris@16: Chris@16: const_local_iterator end( size_type n ) const Chris@16: { Chris@16: return const_local_iterator( this->base().end( n ) ); Chris@16: } Chris@16: Chris@16: const_local_iterator cbegin( size_type n ) const Chris@16: { Chris@16: return const_local_iterator( this->base().cbegin( n ) ); Chris@16: } Chris@16: Chris@16: const_local_iterator cend( size_type n ) Chris@16: { Chris@16: return const_local_iterator( this->base().cend( n ) ); Chris@16: } Chris@16: Chris@16: }; // class 'associative_ptr_container' Chris@16: Chris@16: } // namespace 'ptr_container_detail' Chris@16: Chris@16: } // namespace 'boost' Chris@16: Chris@16: Chris@16: #endif