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: #ifndef BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP williamr@2: #define BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_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: #include williamr@2: #include williamr@2: williamr@2: namespace boost williamr@2: { williamr@2: namespace ptr_container_detail williamr@2: { williamr@2: template williamr@2: < williamr@2: class Key, williamr@2: class VoidPtrSet williamr@2: > williamr@2: struct set_config williamr@2: { williamr@2: typedef VoidPtrSet williamr@2: void_container_type; williamr@2: williamr@2: typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type williamr@2: allocator_type; williamr@2: williamr@2: typedef Key value_type; williamr@2: williamr@2: typedef value_type williamr@2: key_type; williamr@2: williamr@2: typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::value_compare williamr@2: value_compare; williamr@2: williamr@2: typedef value_compare williamr@2: key_compare; williamr@2: williamr@2: typedef void_ptr_iterator< williamr@2: BOOST_DEDUCED_TYPENAME VoidPtrSet::iterator, Key > williamr@2: iterator; williamr@2: williamr@2: typedef void_ptr_iterator< williamr@2: BOOST_DEDUCED_TYPENAME VoidPtrSet::const_iterator, const Key > williamr@2: const_iterator; williamr@2: williamr@2: template< class Iter > williamr@2: static Key* get_pointer( Iter i ) williamr@2: { williamr@2: return static_cast( *i.base() ); williamr@2: } williamr@2: williamr@2: template< class Iter > williamr@2: static const Key* get_const_pointer( Iter i ) williamr@2: { williamr@2: return static_cast( *i.base() ); williamr@2: } williamr@2: williamr@2: BOOST_STATIC_CONSTANT(bool, allow_null = false ); williamr@2: }; williamr@2: williamr@2: williamr@2: williamr@2: template williamr@2: < williamr@2: class Key, williamr@2: class VoidPtrSet, williamr@2: class CloneAllocator = heap_clone_allocator williamr@2: > williamr@2: class ptr_set_adapter_base williamr@2: : public ptr_container_detail::associative_ptr_container< set_config, williamr@2: CloneAllocator > williamr@2: { williamr@2: typedef ptr_container_detail::associative_ptr_container< set_config, williamr@2: CloneAllocator > williamr@2: base_type; williamr@2: public: williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::iterator williamr@2: iterator; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator williamr@2: const_iterator; williamr@2: typedef Key key_type; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::size_type williamr@2: size_type; williamr@2: williamr@2: private: williamr@2: ptr_set_adapter_base() williamr@2: : base_type( BOOST_DEDUCED_TYPENAME VoidPtrSet::key_compare(), williamr@2: BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type() ) williamr@2: { } williamr@2: williamr@2: public: williamr@2: williamr@2: template< class Compare, class Allocator > williamr@2: ptr_set_adapter_base( 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: ptr_set_adapter_base( 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: ptr_set_adapter_base( std::auto_ptr clone ) williamr@2: : base_type( clone ) williamr@2: { } williamr@2: williamr@2: template< typename PtrContainer > williamr@2: void operator=( std::auto_ptr clone ) williamr@2: { williamr@2: base_type::operator=( clone ); williamr@2: } williamr@2: williamr@2: iterator find( const key_type& x ) williamr@2: { williamr@2: return iterator( this->c_private(). williamr@2: find( const_cast(&x) ) ); williamr@2: } williamr@2: williamr@2: const_iterator find( const key_type& x ) const williamr@2: { williamr@2: return const_iterator( this->c_private(). williamr@2: find( const_cast(&x) ) ); williamr@2: } williamr@2: williamr@2: size_type count( const key_type& x ) const williamr@2: { williamr@2: return this->c_private().count( const_cast(&x) ); williamr@2: } williamr@2: williamr@2: iterator lower_bound( const key_type& x ) williamr@2: { williamr@2: return iterator( this->c_private(). williamr@2: lower_bound( const_cast(&x) ) ); williamr@2: } williamr@2: williamr@2: const_iterator lower_bound( const key_type& x ) const williamr@2: { williamr@2: return const_iterator( this->c_private(). williamr@2: lower_bound( const_cast(&x) ) ); williamr@2: } williamr@2: williamr@2: iterator upper_bound( const key_type& x ) williamr@2: { williamr@2: return iterator( this->c_private(). williamr@2: upper_bound( const_cast(&x) ) ); williamr@2: } williamr@2: williamr@2: const_iterator upper_bound( const key_type& x ) const williamr@2: { williamr@2: return const_iterator( this->c_private(). williamr@2: upper_bound( const_cast(&x) ) ); williamr@2: } williamr@2: williamr@2: iterator_range equal_range( const key_type& x ) williamr@2: { williamr@2: std::pair williamr@2: p = this->c_private(). williamr@2: equal_range( const_cast(&x) ); williamr@2: return make_iterator_range( iterator( p.first ), williamr@2: iterator( p.second ) ); williamr@2: } williamr@2: williamr@2: iterator_range equal_range( const key_type& x ) const williamr@2: { williamr@2: std::pair williamr@2: p = this->c_private(). williamr@2: equal_range( const_cast(&x) ); williamr@2: return make_iterator_range( const_iterator( p.first ), williamr@2: const_iterator( p.second ) ); williamr@2: } williamr@2: williamr@2: }; williamr@2: williamr@2: } // ptr_container_detail williamr@2: williamr@2: ///////////////////////////////////////////////////////////////////////// williamr@2: // ptr_set_adapter williamr@2: ///////////////////////////////////////////////////////////////////////// williamr@2: williamr@2: template williamr@2: < williamr@2: class Key, williamr@2: class VoidPtrSet, williamr@2: class CloneAllocator = heap_clone_allocator williamr@2: > williamr@2: class ptr_set_adapter : williamr@2: public ptr_container_detail::ptr_set_adapter_base williamr@2: { williamr@2: typedef ptr_container_detail::ptr_set_adapter_base williamr@2: base_type; williamr@2: williamr@2: public: // typedefs williamr@2: williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::iterator williamr@2: iterator; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator williamr@2: const_iterator; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::size_type williamr@2: size_type; williamr@2: typedef Key key_type; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::auto_type williamr@2: auto_type; williamr@2: typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::key_compare williamr@2: key_compare; williamr@2: typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type williamr@2: allocator_type; williamr@2: private: williamr@2: williamr@2: template< typename II > williamr@2: void set_basic_clone_and_insert( II first, II last ) // basic williamr@2: { williamr@2: while( first != last ) williamr@2: { williamr@2: if( this->find( *first ) == this->end() ) williamr@2: insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit williamr@2: ++first; williamr@2: } williamr@2: } williamr@2: williamr@2: public: williamr@2: williamr@2: explicit ptr_set_adapter( const key_compare& comp = key_compare(), williamr@2: const allocator_type& a = allocator_type() ) williamr@2: : base_type( comp, a ) williamr@2: { williamr@2: BOOST_ASSERT( this->empty() ); williamr@2: } williamr@2: williamr@2: template< class InputIterator, class Compare, class Allocator > williamr@2: ptr_set_adapter( InputIterator first, InputIterator last, williamr@2: const Compare& comp = Compare(), williamr@2: const Allocator a = Allocator() ) williamr@2: : base_type( comp, a ) williamr@2: { williamr@2: BOOST_ASSERT( this->empty() ); williamr@2: set_basic_clone_and_insert( first, last ); williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: ptr_set_adapter( std::auto_ptr r ) : base_type( r ) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator=( std::auto_ptr r ) williamr@2: { williamr@2: base_type::operator=( r ); williamr@2: } williamr@2: williamr@2: std::pair insert( key_type* x ) // strong williamr@2: { williamr@2: this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" ); williamr@2: williamr@2: auto_type ptr( x ); williamr@2: std::pair williamr@2: res = this->c_private().insert( x ); williamr@2: if( res.second ) williamr@2: ptr.release(); williamr@2: return std::make_pair( iterator( res.first ), res.second ); williamr@2: } williamr@2: williamr@2: template< class U > williamr@2: std::pair insert( std::auto_ptr x ) williamr@2: { williamr@2: return insert( x.release() ); williamr@2: } williamr@2: williamr@2: williamr@2: iterator insert( iterator where, key_type* x ) // strong williamr@2: { williamr@2: this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" ); williamr@2: williamr@2: auto_type ptr( x ); williamr@2: BOOST_DEDUCED_TYPENAME base_type::ptr_iterator williamr@2: res = this->c_private().insert( where.base(), x ); williamr@2: if( *res == x ) williamr@2: ptr.release(); williamr@2: return iterator( res); williamr@2: } williamr@2: williamr@2: template< class U > williamr@2: iterator insert( iterator where, std::auto_ptr x ) williamr@2: { williamr@2: return insert( where, x.release() ); williamr@2: } williamr@2: williamr@2: template< typename InputIterator > williamr@2: void insert( InputIterator first, InputIterator last ) // basic williamr@2: { williamr@2: set_basic_clone_and_insert( first, last ); williamr@2: } williamr@2: williamr@2: #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) williamr@2: #else williamr@2: williamr@2: template< class Range > williamr@2: BOOST_DEDUCED_TYPENAME williamr@2: boost::disable_if< ptr_container_detail::is_pointer_or_integral >::type williamr@2: insert( const Range& r ) williamr@2: { williamr@2: insert( boost::begin(r), boost::end(r) ); williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: template< class PtrSetAdapter > williamr@2: bool transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object, williamr@2: PtrSetAdapter& from ) // strong williamr@2: { williamr@2: return this->single_transfer( object, from ); williamr@2: } williamr@2: williamr@2: template< class PtrSetAdapter > williamr@2: size_type williamr@2: transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first, williamr@2: BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last, williamr@2: PtrSetAdapter& from ) // basic williamr@2: { williamr@2: return this->single_transfer( first, last, from ); williamr@2: } williamr@2: williamr@2: #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) williamr@2: #else williamr@2: williamr@2: template< class PtrSetAdapter, class Range > williamr@2: BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, williamr@2: BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >, williamr@2: size_type >::type williamr@2: transfer( const Range& r, PtrSetAdapter& from ) // basic williamr@2: { williamr@2: return transfer( boost::begin(r), boost::end(r), from ); williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: template< class PtrSetAdapter > williamr@2: size_type transfer( PtrSetAdapter& from ) // basic williamr@2: { williamr@2: return transfer( from.begin(), from.end(), from ); williamr@2: } williamr@2: williamr@2: }; williamr@2: williamr@2: ///////////////////////////////////////////////////////////////////////// williamr@2: // ptr_multiset_adapter williamr@2: ///////////////////////////////////////////////////////////////////////// williamr@2: williamr@2: template williamr@2: < williamr@2: class Key, williamr@2: class VoidPtrMultiSet, williamr@2: class CloneAllocator = heap_clone_allocator williamr@2: > williamr@2: class ptr_multiset_adapter : williamr@2: public ptr_container_detail::ptr_set_adapter_base williamr@2: { williamr@2: typedef ptr_container_detail::ptr_set_adapter_base base_type; williamr@2: williamr@2: public: // typedefs williamr@2: williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::iterator williamr@2: iterator; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::size_type williamr@2: size_type; williamr@2: typedef Key key_type; williamr@2: typedef BOOST_DEDUCED_TYPENAME base_type::auto_type williamr@2: auto_type; williamr@2: typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiSet::key_compare williamr@2: key_compare; williamr@2: typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiSet::allocator_type williamr@2: allocator_type; williamr@2: private: williamr@2: template< typename II > williamr@2: void set_basic_clone_and_insert( II first, II last ) // basic williamr@2: { williamr@2: while( first != last ) williamr@2: { williamr@2: insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit williamr@2: ++first; williamr@2: } williamr@2: } williamr@2: williamr@2: public: williamr@2: williamr@2: explicit ptr_multiset_adapter( const key_compare& comp = key_compare(), williamr@2: const allocator_type& a = allocator_type() ) williamr@2: : base_type( comp, a ) williamr@2: { } williamr@2: williamr@2: template< class InputIterator > williamr@2: ptr_multiset_adapter( InputIterator first, InputIterator last, williamr@2: const key_compare& comp = key_compare(), williamr@2: const allocator_type& a = allocator_type() ) williamr@2: : base_type( comp, a ) williamr@2: { williamr@2: set_basic_clone_and_insert( first, last ); williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: ptr_multiset_adapter( std::auto_ptr r ) : base_type( r ) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator=( std::auto_ptr r ) williamr@2: { williamr@2: base_type::operator=( r ); williamr@2: } williamr@2: williamr@2: iterator insert( iterator before, key_type* x ) // strong williamr@2: { williamr@2: return base_type::insert( before, x ); williamr@2: } williamr@2: williamr@2: template< class U > williamr@2: iterator insert( iterator before, std::auto_ptr x ) williamr@2: { williamr@2: return insert( before, x.release() ); williamr@2: } williamr@2: williamr@2: iterator insert( key_type* x ) // strong williamr@2: { williamr@2: this->enforce_null_policy( x, "Null pointer in 'ptr_multiset::insert()'" ); williamr@2: williamr@2: auto_type ptr( x ); williamr@2: BOOST_DEDUCED_TYPENAME base_type::ptr_iterator williamr@2: res = this->c_private().insert( x ); williamr@2: ptr.release(); williamr@2: return iterator( res ); williamr@2: } williamr@2: williamr@2: template< class U > williamr@2: iterator insert( std::auto_ptr x ) williamr@2: { williamr@2: return insert( x.release() ); williamr@2: } williamr@2: williamr@2: template< typename InputIterator > williamr@2: void insert( InputIterator first, InputIterator last ) // basic williamr@2: { williamr@2: set_basic_clone_and_insert( first, last ); williamr@2: } williamr@2: williamr@2: #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) williamr@2: #else williamr@2: williamr@2: template< class Range > williamr@2: BOOST_DEDUCED_TYPENAME williamr@2: boost::disable_if< ptr_container_detail::is_pointer_or_integral >::type williamr@2: insert( const Range& r ) williamr@2: { williamr@2: insert( boost::begin(r), boost::end(r) ); williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: template< class PtrSetAdapter > williamr@2: void transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object, williamr@2: PtrSetAdapter& from ) // strong williamr@2: { williamr@2: this->multi_transfer( object, from ); williamr@2: } williamr@2: williamr@2: template< class PtrSetAdapter > williamr@2: size_type transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first, williamr@2: BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last, williamr@2: PtrSetAdapter& from ) // basic williamr@2: { williamr@2: return this->multi_transfer( first, last, from ); williamr@2: } williamr@2: williamr@2: #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) williamr@2: #else williamr@2: williamr@2: template< class PtrSetAdapter, class Range > williamr@2: BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, williamr@2: BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >, size_type >::type williamr@2: transfer( const Range& r, PtrSetAdapter& from ) // basic williamr@2: { williamr@2: return transfer( boost::begin(r), boost::end(r), from ); williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: template< class PtrSetAdapter > williamr@2: void transfer( PtrSetAdapter& from ) // basic williamr@2: { williamr@2: transfer( from.begin(), from.end(), from ); williamr@2: BOOST_ASSERT( from.empty() ); williamr@2: } williamr@2: williamr@2: }; williamr@2: williamr@2: } // namespace 'boost' williamr@2: williamr@2: #endif