// // 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 namespace boost { namespace ptr_container_detail { template < class Config, class CloneAllocator > class associative_ptr_container : public reversible_ptr_container { typedef reversible_ptr_container base_type; typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter scoped_deleter; 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::iterator iterator; typedef BOOST_DEDUCED_TYPENAME Config::const_iterator const_iterator; typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type; public: // foundation template< class Compare, class Allocator > associative_ptr_container( const Compare& comp, const Allocator& a ) : base_type( comp, 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 ) { } template< class PtrContainer > explicit associative_ptr_container( std::auto_ptr r ) : base_type( r, key_compare() ) { } explicit associative_ptr_container( const associative_ptr_container& r ) : base_type( r.begin(), r.end(), key_compare(), BOOST_DEDUCED_TYPENAME Config::allocator_type() ) { } template< class C, class V > explicit associative_ptr_container( const associative_ptr_container& r ) : base_type( r.begin(), r.end(), key_compare(), BOOST_DEDUCED_TYPENAME Config::allocator_type() ) { } template< class PtrContainer > associative_ptr_container& operator=( std::auto_ptr r ) // nothrow { base_type::operator=( r ); return *this; } template< class C, class V > associative_ptr_container& operator=( const associative_ptr_container& r ) // strong { associative_ptr_container clone( r ); this->swap( clone ); return *this; } associative_ptr_container& operator=( const associative_ptr_container& r ) // strong { associative_ptr_container clone( r ); this->swap( clone ); 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, 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 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 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; } }; // class 'associative_ptr_container' } // namespace 'ptr_container_detail' } // namespace 'boost' #endif