You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
411 lines
13 KiB
411 lines
13 KiB
// |
|
// 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
|
|
|