williamr@2: // williamr@2: // Boost.Pointer Container williamr@2: // williamr@2: // Copyright Thorsten Ottosen 2003-2005. Use, modification and williamr@2: // distribution is subject to the Boost Software License, Version williamr@2: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // williamr@2: // For more information, see http://www.boost.org/libs/ptr_container/ williamr@2: // williamr@2: williamr@2: williamr@2: #ifndef BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP williamr@2: #define BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP williamr@2: williamr@2: #if defined(_MSC_VER) && (_MSC_VER >= 1200) williamr@2: # pragma once williamr@2: #endif williamr@2: williamr@2: #include williamr@2: williamr@2: namespace boost williamr@2: { williamr@2: williamr@2: namespace ptr_container_detail williamr@2: { williamr@2: template williamr@2: < williamr@2: class Config, williamr@2: class CloneAllocator williamr@2: > williamr@2: class associative_ptr_container : williamr@2: public reversible_ptr_container williamr@2: { williamr@2: typedef reversible_ptr_container williamr@2: base_type; williamr@2: williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter williamr@2: scoped_deleter; williamr@2: williamr@2: public: // typedefs williamr@2: typedef BOOST_DEDUCED_TYPENAME Config::key_type williamr@2: key_type; williamr@2: typedef BOOST_DEDUCED_TYPENAME Config::key_compare williamr@2: key_compare; williamr@2: typedef BOOST_DEDUCED_TYPENAME Config::value_compare williamr@2: value_compare; williamr@2: typedef BOOST_DEDUCED_TYPENAME Config::iterator williamr@2: iterator; williamr@2: typedef BOOST_DEDUCED_TYPENAME Config::const_iterator williamr@2: const_iterator; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::size_type williamr@2: size_type; williamr@2: williamr@2: public: // foundation williamr@2: williamr@2: template< class Compare, class Allocator > williamr@2: associative_ptr_container( const Compare& comp, williamr@2: const Allocator& a ) williamr@2: : base_type( comp, a ) williamr@2: { } williamr@2: williamr@2: template< class InputIterator, class Compare, class Allocator > williamr@2: associative_ptr_container( InputIterator first, InputIterator last, williamr@2: const Compare& comp, williamr@2: const Allocator& a ) williamr@2: : base_type( first, last, comp, a ) williamr@2: { } williamr@2: williamr@2: template< class PtrContainer > williamr@2: associative_ptr_container( std::auto_ptr r ) williamr@2: : base_type( r, key_compare() ) williamr@2: { } williamr@2: williamr@2: template< class PtrContainer > williamr@2: void operator=( std::auto_ptr r ) williamr@2: { williamr@2: base_type::operator=( r ); williamr@2: } williamr@2: williamr@2: public: // associative container interface williamr@2: key_compare key_comp() const williamr@2: { williamr@2: return this->c_private().key_comp(); williamr@2: } williamr@2: williamr@2: value_compare value_comp() const williamr@2: { williamr@2: return this->c_private().value_comp(); williamr@2: } williamr@2: williamr@2: iterator erase( iterator before ) // nothrow williamr@2: { williamr@2: BOOST_ASSERT( !this->empty() ); williamr@2: BOOST_ASSERT( before != this->end() ); williamr@2: williamr@2: this->remove( before ); // nothrow williamr@2: iterator res( before ); // nothrow williamr@2: ++res; // nothrow williamr@2: this->c_private().erase( before.base() ); // nothrow williamr@2: return res; // nothrow williamr@2: } williamr@2: williamr@2: size_type erase( const key_type& x ) // nothrow williamr@2: { williamr@2: iterator i( this->c_private().find( x ) ); // nothrow williamr@2: if( i == this->end() ) // nothrow williamr@2: return 0u; // nothrow williamr@2: this->remove( i ); // nothrow williamr@2: return this->c_private().erase( x ); // nothrow williamr@2: } williamr@2: williamr@2: iterator erase( iterator first, williamr@2: iterator last ) // nothrow williamr@2: { williamr@2: iterator res( last ); // nothrow williamr@2: if( res != this->end() ) williamr@2: ++res; // nothrow williamr@2: williamr@2: this->remove( first, last ); // nothrow williamr@2: this->c_private().erase( first.base(), last.base() );// nothrow williamr@2: return res; // nothrow williamr@2: } williamr@2: williamr@2: protected: williamr@2: williamr@2: template< class AssociatePtrCont > williamr@2: void multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object, williamr@2: AssociatePtrCont& from ) // strong williamr@2: { williamr@2: BOOST_ASSERT( (void*)&from != (void*)this ); williamr@2: BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); williamr@2: williamr@2: this->c_private().insert( *object.base() ); // strong williamr@2: from.c_private().erase( object.base() ); // nothrow williamr@2: } williamr@2: williamr@2: template< class AssociatePtrCont > williamr@2: size_type multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first, williamr@2: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last, williamr@2: AssociatePtrCont& from ) // basic williamr@2: { williamr@2: BOOST_ASSERT( (void*)&from != (void*)this ); williamr@2: BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); williamr@2: williamr@2: size_type res = 0; williamr@2: for( ; first != last; ) williamr@2: { williamr@2: BOOST_ASSERT( first != from.end() ); williamr@2: this->c_private().insert( *first.base() ); // strong williamr@2: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator williamr@2: to_delete( first ); williamr@2: ++first; williamr@2: from.c_private().erase( to_delete.base() ); // nothrow williamr@2: ++res; williamr@2: } williamr@2: williamr@2: return res; williamr@2: } williamr@2: williamr@2: template< class AssociatePtrCont > williamr@2: bool single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object, williamr@2: AssociatePtrCont& from ) // strong williamr@2: { williamr@2: BOOST_ASSERT( (void*)&from != (void*)this ); williamr@2: BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); williamr@2: williamr@2: std::pair p = williamr@2: this->c_private().insert( *object.base() ); // strong williamr@2: if( p.second ) williamr@2: from.c_private().erase( object.base() ); // nothrow williamr@2: williamr@2: return p.second; williamr@2: } williamr@2: williamr@2: template< class AssociatePtrCont > williamr@2: size_type single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first, williamr@2: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last, williamr@2: AssociatePtrCont& from ) // basic williamr@2: { williamr@2: BOOST_ASSERT( (void*)&from != (void*)this ); williamr@2: BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" ); williamr@2: williamr@2: size_type res = 0; williamr@2: for( ; first != last; ) williamr@2: { williamr@2: BOOST_ASSERT( first != from.end() ); williamr@2: std::pair p = williamr@2: this->c_private().insert( *first.base() ); // strong williamr@2: BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator williamr@2: to_delete( first ); williamr@2: ++first; williamr@2: if( p.second ) williamr@2: { williamr@2: from.c_private().erase( to_delete.base() ); // nothrow williamr@2: ++res; williamr@2: } williamr@2: } williamr@2: return res; williamr@2: } williamr@2: williamr@2: }; // class 'associative_ptr_container' williamr@2: williamr@2: } // namespace 'ptr_container_detail' williamr@2: williamr@2: } // namespace 'boost' williamr@2: williamr@2: williamr@2: #endif