412 lines
13 KiB
C++
412 lines
13 KiB
C++
|
//
|
||
|
// 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
|