blob: 5821648273fbc079066374869936bd272a4d03fe [file] [log] [blame]
//
// 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