Chris@16: // Chris@16: // Boost.Pointer Container Chris@16: // Chris@16: // Copyright Thorsten Ottosen 2003-2005. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org/libs/ptr_container/ Chris@16: // Chris@16: Chris@16: #ifndef BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP Chris@16: #define BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace ptr_container_detail Chris@16: { Chris@16: Chris@16: template Chris@16: < Chris@16: class T, Chris@16: class VoidPtrMap, Chris@16: bool Ordered Chris@16: > Chris@16: struct map_config Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME remove_nullable::type Chris@16: U; Chris@16: typedef VoidPtrMap Chris@16: void_container_type; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type Chris@16: allocator_type; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Chris@16: mpl::eval_if_c, Chris@16: mpl::identity >::type Chris@16: value_compare; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Chris@16: mpl::eval_if_c, Chris@16: mpl::identity >::type Chris@16: key_compare; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Chris@16: mpl::eval_if_c, Chris@16: select_hasher >::type Chris@16: hasher; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Chris@16: mpl::eval_if_c, Chris@16: select_key_equal >::type Chris@16: key_equal; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Chris@16: mpl::if_c::type Chris@16: container_type; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type Chris@16: key_type; Chris@16: Chris@16: typedef U value_type; Chris@16: Chris@16: typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const > Chris@16: iterator; Chris@16: Chris@16: typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const> Chris@16: const_iterator; Chris@16: Chris@16: typedef ptr_map_iterator< Chris@16: BOOST_DEDUCED_TYPENAME Chris@16: mpl::eval_if_c, Chris@16: select_local_iterator >::type, Chris@16: key_type, U* const > Chris@16: local_iterator; Chris@16: Chris@16: typedef ptr_map_iterator< Chris@16: BOOST_DEDUCED_TYPENAME Chris@16: mpl::eval_if_c, Chris@16: select_const_local_iterator >::type, Chris@16: key_type, const U* const > Chris@16: const_local_iterator; Chris@16: Chris@16: template< class Iter > Chris@16: static U* get_pointer( Iter i ) Chris@16: { Chris@16: return i->second; Chris@16: } Chris@16: Chris@16: template< class Iter > Chris@16: static const U* get_const_pointer( Iter i ) Chris@16: { Chris@16: return i->second; Chris@16: } Chris@16: Chris@16: BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable::value ); Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: class T, Chris@16: class VoidPtrMap, Chris@16: class CloneAllocator, Chris@16: bool Ordered Chris@16: > Chris@16: class ptr_map_adapter_base : Chris@16: public ptr_container_detail::associative_ptr_container< map_config, Chris@16: CloneAllocator > Chris@16: { Chris@16: typedef ptr_container_detail::associative_ptr_container< map_config, Chris@16: CloneAllocator > Chris@16: base_type; Chris@16: Chris@16: typedef map_config config; Chris@16: typedef ptr_map_adapter_base this_type; Chris@16: Chris@16: public: Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type Chris@16: allocator_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::iterator Chris@16: iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator Chris@16: const_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::size_type Chris@16: size_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::key_type Chris@16: key_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::auto_type Chris@16: auto_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::value_type Chris@16: mapped_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::reference Chris@16: mapped_reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_reference Chris@16: const_mapped_reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME iterator_value::type Chris@16: value_type; Chris@16: typedef value_type Chris@16: reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME iterator_value::type Chris@16: const_reference; Chris@16: typedef value_type Chris@16: pointer; Chris@16: typedef const_reference Chris@16: const_pointer; Chris@16: Chris@16: private: Chris@16: const_mapped_reference lookup( const key_type& key ) const Chris@16: { Chris@16: const_iterator i = this->find( key ); Chris@16: if( i != this->end() ) Chris@16: return *i->second; Chris@16: else Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( true, bad_ptr_container_operation, Chris@16: "'ptr_map/multimap::at()' could" Chris@16: " not find key" ); Chris@16: } Chris@16: Chris@16: struct eraser // scope guard Chris@16: { Chris@16: bool released_; Chris@16: VoidPtrMap* m_; Chris@16: const key_type& key_; Chris@16: Chris@16: eraser( VoidPtrMap* m, const key_type& key ) Chris@16: : released_(false), m_(m), key_(key) Chris@16: {} Chris@16: Chris@16: ~eraser() Chris@16: { Chris@16: if( !released_ ) Chris@16: m_->erase(key_); Chris@16: } Chris@16: Chris@16: void release() { released_ = true; } Chris@16: Chris@16: private: Chris@16: eraser& operator=(const eraser&); Chris@16: }; Chris@16: Chris@16: mapped_reference insert_lookup( const key_type& key ) Chris@16: { Chris@16: void*& ref = this->base()[key]; Chris@16: if( ref ) Chris@16: { Chris@16: return *static_cast(ref); Chris@16: } Chris@16: else Chris@16: { Chris@16: eraser e(&this->base(),key); // nothrow Chris@16: mapped_type res = new T(); // strong Chris@16: ref = res; // nothrow Chris@16: e.release(); // nothrow Chris@16: return *res; Chris@16: } Chris@16: } Chris@16: Chris@16: public: Chris@16: Chris@16: ptr_map_adapter_base() Chris@16: { } Chris@16: Chris@16: template< class SizeType > Chris@16: explicit ptr_map_adapter_base( SizeType n, Chris@16: ptr_container_detail::unordered_associative_container_tag tag ) Chris@16: : base_type( n, tag ) Chris@16: { } Chris@16: Chris@16: template< class Compare, class Allocator > Chris@16: ptr_map_adapter_base( const Compare& comp, Chris@16: const Allocator& a ) Chris@16: : base_type( comp, a ) Chris@16: { } Chris@16: Chris@16: template< class Hash, class Pred, class Allocator > Chris@16: ptr_map_adapter_base( const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( hash, pred, a ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator > Chris@16: ptr_map_adapter_base( InputIterator first, InputIterator last ) Chris@16: : base_type( first, last ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator, class Comp > Chris@16: ptr_map_adapter_base( InputIterator first, InputIterator last, Chris@16: const Comp& comp, Chris@16: const allocator_type& a = allocator_type() ) Chris@16: : base_type( first, last, comp, a ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator, class Hash, class Pred, class Allocator > Chris@16: ptr_map_adapter_base( InputIterator first, InputIterator last, Chris@16: const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( first, last, hash, pred, a ) Chris@16: { } Chris@16: Chris@16: template< class PtrContainer > Chris@16: explicit ptr_map_adapter_base( std::auto_ptr clone ) Chris@16: : base_type( clone ) Chris@16: { } Chris@16: Chris@16: template< typename PtrContainer > Chris@16: ptr_map_adapter_base& operator=( std::auto_ptr clone ) Chris@16: { Chris@16: base_type::operator=( clone ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: iterator find( const key_type& x ) Chris@16: { Chris@16: return iterator( this->base().find( x ) ); Chris@16: } Chris@16: Chris@16: const_iterator find( const key_type& x ) const Chris@16: { Chris@16: return const_iterator( this->base().find( x ) ); Chris@16: } Chris@16: Chris@16: size_type count( const key_type& x ) const Chris@16: { Chris@16: return this->base().count( x ); Chris@16: } Chris@16: Chris@16: iterator lower_bound( const key_type& x ) Chris@16: { Chris@16: return iterator( this->base().lower_bound( x ) ); Chris@16: } Chris@16: Chris@16: const_iterator lower_bound( const key_type& x ) const Chris@16: { Chris@16: return const_iterator( this->base().lower_bound( x ) ); Chris@16: } Chris@16: Chris@16: iterator upper_bound( const key_type& x ) Chris@16: { Chris@16: return iterator( this->base().upper_bound( x ) ); Chris@16: } Chris@16: Chris@16: const_iterator upper_bound( const key_type& x ) const Chris@16: { Chris@16: return const_iterator( this->base().upper_bound( x ) ); Chris@16: } Chris@16: Chris@16: iterator_range equal_range( const key_type& x ) Chris@16: { Chris@16: std::pair Chris@16: p = this->base().equal_range( x ); Chris@16: return make_iterator_range( iterator( p.first ), iterator( p.second ) ); Chris@16: } Chris@16: Chris@16: iterator_range equal_range( const key_type& x ) const Chris@16: { Chris@16: std::pair Chris@16: p = this->base().equal_range( x ); Chris@16: return make_iterator_range( const_iterator( p.first ), Chris@16: const_iterator( p.second ) ); Chris@16: } Chris@16: Chris@16: mapped_reference at( const key_type& key ) Chris@16: { Chris@16: return const_cast( lookup( key ) ); Chris@16: } Chris@16: Chris@16: const_mapped_reference at( const key_type& key ) const Chris@16: { Chris@16: return lookup( key ); Chris@16: } Chris@16: Chris@16: mapped_reference operator[]( const key_type& key ) Chris@16: { Chris@16: return insert_lookup( key ); Chris@16: } Chris@16: Chris@16: auto_type replace( iterator where, mapped_type x ) // strong Chris@16: { Chris@16: BOOST_ASSERT( where != this->end() ); Chris@16: Chris@16: this->enforce_null_policy( x, "Null pointer in 'replace()'" ); Chris@16: Chris@16: auto_type ptr( x ); Chris@16: Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(), Chris@16: bad_ptr_container_operation, Chris@16: "'replace()' on empty container" ); Chris@16: Chris@16: auto_type old( where->second ); // nothrow Chris@16: where.base()->second = ptr.release(); // nothrow, commit Chris@16: return boost::ptr_container::move( old ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: auto_type replace( iterator where, std::auto_ptr x ) Chris@16: { Chris@16: return replace( where, x.release() ); Chris@16: } Chris@16: Chris@16: protected: Chris@16: size_type bucket( const key_type& key ) const Chris@16: { Chris@16: return this->base().bucket( key ); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // ptr_container_detail Chris@16: Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: // ptr_map_adapter Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: < Chris@16: class T, Chris@16: class VoidPtrMap, Chris@16: class CloneAllocator = heap_clone_allocator, Chris@16: bool Ordered = true Chris@16: > Chris@16: class ptr_map_adapter : Chris@16: public ptr_container_detail::ptr_map_adapter_base Chris@16: { Chris@16: typedef ptr_container_detail::ptr_map_adapter_base Chris@16: base_type; Chris@16: Chris@16: public: Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::iterator Chris@16: iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator Chris@16: const_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::size_type Chris@16: size_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::key_type Chris@16: key_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_reference Chris@16: const_reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::auto_type Chris@16: auto_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type Chris@16: allocator_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type Chris@16: mapped_type; Chris@16: private: Chris@16: Chris@16: void safe_insert( const key_type& key, auto_type ptr ) // strong Chris@16: { Chris@16: std::pair Chris@16: res = Chris@16: this->base().insert( std::make_pair( key, ptr.get() ) ); // strong, commit Chris@16: if( res.second ) // nothrow Chris@16: ptr.release(); // nothrow Chris@16: } Chris@16: Chris@16: template< class II > Chris@16: void map_basic_clone_and_insert( II first, II last ) Chris@16: { Chris@16: while( first != last ) Chris@16: { Chris@16: if( this->find( first->first ) == this->end() ) Chris@16: { Chris@16: const_reference p = *first.base(); // nothrow Chris@16: auto_type ptr( this->null_policy_allocate_clone( p.second ) ); Chris@16: // strong Chris@16: this->safe_insert( p.first, Chris@16: boost::ptr_container::move( ptr ) ); Chris@16: // strong, commit Chris@16: } Chris@16: ++first; Chris@16: } Chris@16: } Chris@16: Chris@16: public: Chris@16: ptr_map_adapter( ) Chris@16: { } Chris@16: Chris@16: template< class Comp > Chris@16: explicit ptr_map_adapter( const Comp& comp, Chris@16: const allocator_type& a ) Chris@16: : base_type( comp, a ) { } Chris@16: Chris@16: template< class Hash, class Pred, class Allocator > Chris@16: ptr_map_adapter( const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( hash, pred, a ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator > Chris@16: ptr_map_adapter( InputIterator first, InputIterator last ) Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class InputIterator, class Comp > Chris@16: ptr_map_adapter( InputIterator first, InputIterator last, Chris@16: const Comp& comp, Chris@16: const allocator_type& a = allocator_type() ) Chris@16: : base_type( comp, a ) Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class InputIterator, class Hash, class Pred, class Allocator > Chris@16: ptr_map_adapter( InputIterator first, InputIterator last, Chris@16: const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( hash, pred, a ) Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: ptr_map_adapter( const ptr_map_adapter& r ) Chris@16: { Chris@16: map_basic_clone_and_insert( r.begin(), r.end() ); Chris@16: } Chris@16: Chris@16: template< class Key, class U, class CA, bool b > Chris@16: ptr_map_adapter( const ptr_map_adapter& r ) Chris@16: { Chris@16: map_basic_clone_and_insert( r.begin(), r.end() ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: ptr_map_adapter( std::auto_ptr r ) : base_type( r ) Chris@16: { } Chris@16: Chris@16: ptr_map_adapter& operator=( ptr_map_adapter r ) Chris@16: { Chris@16: this->swap( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: ptr_map_adapter& operator=( std::auto_ptr r ) Chris@16: { Chris@16: base_type::operator=( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: using base_type::release; Chris@16: Chris@16: template< typename InputIterator > Chris@16: void insert( InputIterator first, InputIterator last ) // basic Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class Range > Chris@16: void insert( const Range& r ) Chris@16: { Chris@16: insert( boost::begin(r), boost::end(r) ); Chris@16: } Chris@16: Chris@16: private: Chris@16: std::pair insert_impl( const key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" ); Chris@16: auto_type ptr( x ); // nothrow Chris@16: Chris@16: std::pair Chris@16: res = this->base().insert( std::make_pair( key, x ) ); // strong, commit Chris@16: if( res.second ) // nothrow Chris@16: ptr.release(); // nothrow Chris@16: return std::make_pair( iterator( res.first ), res.second ); // nothrow Chris@16: } Chris@16: Chris@16: iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: this->enforce_null_policy( x, Chris@16: "Null pointer in 'ptr_map_adapter::insert()'" ); Chris@16: auto_type ptr( x ); // nothrow Chris@16: BOOST_DEDUCED_TYPENAME base_type::ptr_iterator Chris@16: res = this->base().insert( before.base(), std::make_pair( key, x ) ); Chris@16: // strong, commit Chris@16: ptr.release(); // notrow Chris@16: return iterator( res ); Chris@16: } Chris@16: Chris@16: public: Chris@16: Chris@16: std::pair insert( key_type& key, mapped_type x ) Chris@16: { Chris@16: return insert_impl( key, x ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: std::pair insert( const key_type& key, std::auto_ptr x ) Chris@16: { Chris@16: return insert_impl( key, x.release() ); Chris@16: } Chris@16: Chris@16: template< class F, class S > Chris@16: iterator insert( iterator before, ptr_container_detail::ref_pair p ) // strong Chris@16: { Chris@16: this->enforce_null_policy( p.second, Chris@16: "Null pointer in 'ptr_map_adapter::insert()'" ); Chris@16: Chris@16: auto_type ptr( this->null_policy_allocate_clone( p.second ) ); Chris@16: BOOST_DEDUCED_TYPENAME base_type::ptr_iterator Chris@16: result = this->base().insert( before.base(), Chris@16: std::make_pair(p.first,ptr.get()) ); // strong Chris@16: if( ptr.get() == result->second ) Chris@16: ptr.release(); Chris@16: Chris@16: return iterator( result ); Chris@16: } Chris@16: Chris@16: iterator insert( iterator before, key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: return insert_impl( before, key, x ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: iterator insert( iterator before, const key_type& key, std::auto_ptr x ) // strong Chris@16: { Chris@16: return insert_impl( before, key, x.release() ); Chris@16: } Chris@16: Chris@16: template< class PtrMapAdapter > Chris@16: bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, Chris@16: PtrMapAdapter& from ) // strong Chris@16: { Chris@16: return this->single_transfer( object, from ); Chris@16: } Chris@16: Chris@16: template< class PtrMapAdapter > Chris@16: size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, Chris@16: BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, Chris@16: PtrMapAdapter& from ) // basic Chris@16: { Chris@16: return this->single_transfer( first, last, from ); Chris@16: } Chris@16: Chris@16: #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: #else Chris@16: Chris@16: template< class PtrMapAdapter, class Range > Chris@16: BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, Chris@16: BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >, Chris@16: size_type >::type Chris@16: transfer( const Range& r, PtrMapAdapter& from ) // basic Chris@16: { Chris@16: return transfer( boost::begin(r), boost::end(r), from ); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: template< class PtrMapAdapter > Chris@16: size_type transfer( PtrMapAdapter& from ) // basic Chris@16: { Chris@16: return transfer( from.begin(), from.end(), from ); Chris@16: } Chris@16: }; Chris@16: Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: // ptr_multimap_adapter Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: < Chris@16: class T, Chris@16: class VoidPtrMultiMap, Chris@16: class CloneAllocator = heap_clone_allocator, Chris@16: bool Ordered = true Chris@16: > Chris@16: class ptr_multimap_adapter : Chris@16: public ptr_container_detail::ptr_map_adapter_base Chris@16: { Chris@16: typedef ptr_container_detail::ptr_map_adapter_base Chris@16: base_type; Chris@16: Chris@16: public: // typedefs Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::iterator Chris@16: iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator Chris@16: const_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::size_type Chris@16: size_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::key_type Chris@16: key_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_reference Chris@16: const_reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type Chris@16: mapped_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::auto_type Chris@16: auto_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type Chris@16: allocator_type; Chris@16: private: Chris@16: Chris@16: void safe_insert( const key_type& key, auto_type ptr ) // strong Chris@16: { Chris@16: this->base().insert( Chris@16: std::make_pair( key, ptr.get() ) ); // strong, commit Chris@16: ptr.release(); // nothrow Chris@16: } Chris@16: Chris@16: template< typename II > Chris@16: void map_basic_clone_and_insert( II first, II last ) Chris@16: { Chris@16: while( first != last ) Chris@16: { Chris@16: const_reference pair = *first.base(); // nothrow Chris@16: auto_type ptr( this->null_policy_allocate_clone( pair.second ) ); Chris@16: // strong Chris@16: safe_insert( pair.first, Chris@16: boost::ptr_container::move( ptr ) ); Chris@16: // strong, commit Chris@16: ++first; Chris@16: } Chris@16: } Chris@16: Chris@16: public: Chris@16: Chris@16: ptr_multimap_adapter() Chris@16: { } Chris@16: Chris@16: template< class SizeType > Chris@16: ptr_multimap_adapter( SizeType n, Chris@16: ptr_container_detail::unordered_associative_container_tag tag ) Chris@16: : base_type( n, tag ) Chris@16: { } Chris@16: Chris@16: template< class Comp > Chris@16: explicit ptr_multimap_adapter( const Comp& comp, Chris@16: const allocator_type& a ) Chris@16: : base_type( comp, a ) { } Chris@16: Chris@16: template< class Hash, class Pred, class Allocator > Chris@16: ptr_multimap_adapter( const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( hash, pred, a ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator > Chris@16: ptr_multimap_adapter( InputIterator first, InputIterator last ) Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class InputIterator, class Comp > Chris@16: ptr_multimap_adapter( InputIterator first, InputIterator last, Chris@16: const Comp& comp, Chris@16: const allocator_type& a ) Chris@16: : base_type( comp, a ) Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class InputIterator, class Hash, class Pred, class Allocator > Chris@16: ptr_multimap_adapter( InputIterator first, InputIterator last, Chris@16: const Hash& hash, Chris@16: const Pred& pred, Chris@16: const Allocator& a ) Chris@16: : base_type( hash, pred, a ) Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: ptr_multimap_adapter( const ptr_multimap_adapter& r ) Chris@16: { Chris@16: map_basic_clone_and_insert( r.begin(), r.end() ); Chris@16: } Chris@16: Chris@16: template< class Key, class U, class CA, bool b > Chris@16: ptr_multimap_adapter( const ptr_multimap_adapter& r ) Chris@16: { Chris@16: map_basic_clone_and_insert( r.begin(), r.end() ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: explicit ptr_multimap_adapter( std::auto_ptr r ) : base_type( r ) Chris@16: { } Chris@16: Chris@16: ptr_multimap_adapter& operator=( ptr_multimap_adapter r ) Chris@16: { Chris@16: this->swap( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: ptr_multimap_adapter& operator=( std::auto_ptr r ) Chris@16: { Chris@16: base_type::operator=( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: using base_type::release; Chris@16: Chris@16: private: Chris@16: iterator insert_impl( const key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: this->enforce_null_policy( x, Chris@16: "Null pointer in 'ptr_multimap_adapter::insert()'" ); Chris@16: auto_type ptr( x ); // nothrow Chris@16: BOOST_DEDUCED_TYPENAME base_type::ptr_iterator Chris@16: res = this->base().insert( std::make_pair( key, x ) ); Chris@16: // strong, commit Chris@16: ptr.release(); // notrow Chris@16: return iterator( res ); Chris@16: } Chris@16: Chris@16: iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: this->enforce_null_policy( x, Chris@16: "Null pointer in 'ptr_multimap_adapter::insert()'" ); Chris@16: auto_type ptr( x ); // nothrow Chris@16: BOOST_DEDUCED_TYPENAME base_type::ptr_iterator Chris@16: res = this->base().insert( before.base(), Chris@16: std::make_pair( key, x ) ); Chris@16: // strong, commit Chris@16: ptr.release(); // notrow Chris@16: return iterator( res ); Chris@16: } Chris@16: Chris@16: public: Chris@16: template< typename InputIterator > Chris@16: void insert( InputIterator first, InputIterator last ) // basic Chris@16: { Chris@16: map_basic_clone_and_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class Range > Chris@16: void insert( const Range& r ) Chris@16: { Chris@16: insert( boost::begin(r), boost::end(r) ); Chris@16: } Chris@16: Chris@16: iterator insert( key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: return insert_impl( key, x ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: iterator insert( const key_type& key, std::auto_ptr x ) Chris@16: { Chris@16: return insert_impl( key, x.release() ); Chris@16: } Chris@16: Chris@16: template< class F, class S > Chris@16: iterator insert( iterator before, ptr_container_detail::ref_pair p ) // strong Chris@16: { Chris@16: this->enforce_null_policy( p.second, Chris@16: "Null pointer in 'ptr_multimap_adapter::insert()'" ); Chris@16: iterator res = insert_impl( before, p.first, Chris@16: this->null_policy_allocate_clone( p.second ) ); Chris@16: return res; Chris@16: } Chris@16: Chris@16: iterator insert( iterator before, key_type& key, mapped_type x ) // strong Chris@16: { Chris@16: return insert_impl( before, key, x ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: iterator insert( iterator before, const key_type& key, std::auto_ptr x ) // strong Chris@16: { Chris@16: return insert_impl( before, key, x.release() ); Chris@16: } Chris@16: Chris@16: template< class PtrMapAdapter > Chris@16: void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, Chris@16: PtrMapAdapter& from ) // strong Chris@16: { Chris@16: this->multi_transfer( object, from ); Chris@16: } Chris@16: Chris@16: template< class PtrMapAdapter > Chris@16: size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, Chris@16: BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, Chris@16: PtrMapAdapter& from ) // basic Chris@16: { Chris@16: return this->multi_transfer( first, last, from ); Chris@16: } Chris@16: Chris@16: #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: #else Chris@16: Chris@16: template< class PtrMapAdapter, class Range > Chris@16: BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, Chris@16: BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >, Chris@16: size_type >::type Chris@16: transfer( const Range& r, PtrMapAdapter& from ) // basic Chris@16: { Chris@16: return transfer( boost::begin(r), boost::end(r), from ); Chris@16: } Chris@16: Chris@16: #endif Chris@16: template< class PtrMapAdapter > Chris@16: void transfer( PtrMapAdapter& from ) // basic Chris@16: { Chris@16: transfer( from.begin(), from.end(), from ); Chris@16: BOOST_ASSERT( from.empty() ); Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: template< class I, class F, class S > Chris@16: inline bool is_null( const ptr_map_iterator& i ) Chris@16: { Chris@16: return i->second == 0; Chris@16: } Chris@16: Chris@16: } // namespace 'boost' Chris@16: Chris@16: #endif