File indexing completed on 2025-01-18 09:50:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP
0013 #define BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP
0014
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018
0019 #include <boost/ptr_container/detail/map_iterator.hpp>
0020 #include <boost/ptr_container/detail/associative_ptr_container.hpp>
0021 #include <boost/ptr_container/detail/meta_functions.hpp>
0022 #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
0023 #include <boost/static_assert.hpp>
0024 #include <boost/range/iterator_range.hpp>
0025
0026 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0027 #pragma GCC diagnostic push
0028 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0029 #endif
0030
0031 namespace boost
0032 {
0033 namespace ptr_container_detail
0034 {
0035
0036 template
0037 <
0038 class T,
0039 class VoidPtrMap,
0040 bool Ordered
0041 >
0042 struct map_config
0043 {
0044 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type
0045 U;
0046 typedef VoidPtrMap
0047 void_container_type;
0048
0049 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
0050 allocator_type;
0051
0052 typedef BOOST_DEDUCED_TYPENAME
0053 mpl::eval_if_c<Ordered,
0054 select_value_compare<VoidPtrMap>,
0055 mpl::identity<void> >::type
0056 value_compare;
0057
0058 typedef BOOST_DEDUCED_TYPENAME
0059 mpl::eval_if_c<Ordered,
0060 select_key_compare<VoidPtrMap>,
0061 mpl::identity<void> >::type
0062 key_compare;
0063
0064 typedef BOOST_DEDUCED_TYPENAME
0065 mpl::eval_if_c<Ordered,
0066 mpl::identity<void>,
0067 select_hasher<VoidPtrMap> >::type
0068 hasher;
0069
0070 typedef BOOST_DEDUCED_TYPENAME
0071 mpl::eval_if_c<Ordered,
0072 mpl::identity<void>,
0073 select_key_equal<VoidPtrMap> >::type
0074 key_equal;
0075
0076 typedef BOOST_DEDUCED_TYPENAME
0077 mpl::if_c<Ordered,
0078 ptr_container_detail::ordered_associative_container_tag,
0079 ptr_container_detail::unordered_associative_container_tag>::type
0080 container_type;
0081
0082 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type
0083 key_type;
0084
0085 typedef U value_type;
0086
0087 typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const >
0088 iterator;
0089
0090 typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const>
0091 const_iterator;
0092
0093 typedef ptr_map_iterator<
0094 BOOST_DEDUCED_TYPENAME
0095 mpl::eval_if_c<Ordered,
0096 select_iterator<VoidPtrMap>,
0097 select_local_iterator<VoidPtrMap> >::type,
0098 key_type, U* const >
0099 local_iterator;
0100
0101 typedef ptr_map_iterator<
0102 BOOST_DEDUCED_TYPENAME
0103 mpl::eval_if_c<Ordered,
0104 select_iterator<VoidPtrMap>,
0105 select_const_local_iterator<VoidPtrMap> >::type,
0106 key_type, const U* const >
0107 const_local_iterator;
0108
0109 template< class Iter >
0110 static U* get_pointer( Iter i )
0111 {
0112 return i->second;
0113 }
0114
0115 template< class Iter >
0116 static const U* get_const_pointer( Iter i )
0117 {
0118 return i->second;
0119 }
0120
0121 BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable<T>::value );
0122 };
0123
0124
0125
0126 template
0127 <
0128 class T,
0129 class VoidPtrMap,
0130 class CloneAllocator,
0131 bool Ordered
0132 >
0133 class ptr_map_adapter_base :
0134 public ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>,
0135 CloneAllocator >
0136 {
0137 typedef ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>,
0138 CloneAllocator >
0139 base_type;
0140
0141 typedef map_config<T,VoidPtrMap,Ordered> config;
0142 typedef ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered> this_type;
0143
0144 public:
0145
0146 typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type
0147 allocator_type;
0148 typedef BOOST_DEDUCED_TYPENAME base_type::iterator
0149 iterator;
0150 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
0151 const_iterator;
0152 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
0153 size_type;
0154 typedef BOOST_DEDUCED_TYPENAME base_type::key_type
0155 key_type;
0156 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
0157 auto_type;
0158 typedef BOOST_DEDUCED_TYPENAME base_type::value_type
0159 mapped_type;
0160 typedef BOOST_DEDUCED_TYPENAME base_type::reference
0161 mapped_reference;
0162 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0163 const_mapped_reference;
0164 typedef BOOST_DEDUCED_TYPENAME iterator_value<iterator>::type
0165 value_type;
0166 typedef value_type
0167 reference;
0168 typedef BOOST_DEDUCED_TYPENAME iterator_value<const_iterator>::type
0169 const_reference;
0170 typedef value_type
0171 pointer;
0172 typedef const_reference
0173 const_pointer;
0174
0175 private:
0176 const_mapped_reference lookup( const key_type& key ) const
0177 {
0178 const_iterator i = this->find( key );
0179 BOOST_PTR_CONTAINER_THROW_EXCEPTION( i == this->end(), bad_ptr_container_operation,
0180 "'ptr_map/multimap::at()' could"
0181 " not find key" );
0182 return *i->second;
0183 }
0184
0185 struct eraser
0186 {
0187 bool released_;
0188 VoidPtrMap* m_;
0189 const key_type& key_;
0190
0191 eraser( VoidPtrMap* m, const key_type& key )
0192 : released_(false), m_(m), key_(key)
0193 {}
0194
0195 ~eraser()
0196 {
0197 if( !released_ )
0198 m_->erase(key_);
0199 }
0200
0201 void release() { released_ = true; }
0202
0203 private:
0204 eraser& operator=(const eraser&);
0205 };
0206
0207 mapped_reference insert_lookup( const key_type& key )
0208 {
0209 void*& ref = this->base()[key];
0210 if( ref )
0211 {
0212 return *static_cast<mapped_type>(ref);
0213 }
0214 else
0215 {
0216 eraser e(&this->base(),key);
0217 mapped_type res = new T();
0218 ref = res;
0219 e.release();
0220 return *res;
0221 }
0222 }
0223
0224 public:
0225
0226 ptr_map_adapter_base()
0227 { }
0228
0229 template< class SizeType >
0230 explicit ptr_map_adapter_base( SizeType n,
0231 ptr_container_detail::unordered_associative_container_tag tag )
0232 : base_type( n, tag )
0233 { }
0234
0235 template< class Compare, class Allocator >
0236 ptr_map_adapter_base( const Compare& comp,
0237 const Allocator& a )
0238 : base_type( comp, a )
0239 { }
0240
0241 template< class Hash, class Pred, class Allocator >
0242 ptr_map_adapter_base( const Hash& hash,
0243 const Pred& pred,
0244 const Allocator& a )
0245 : base_type( hash, pred, a )
0246 { }
0247
0248 template< class InputIterator >
0249 ptr_map_adapter_base( InputIterator first, InputIterator last )
0250 : base_type( first, last )
0251 { }
0252
0253 template< class InputIterator, class Comp >
0254 ptr_map_adapter_base( InputIterator first, InputIterator last,
0255 const Comp& comp,
0256 const allocator_type& a = allocator_type() )
0257 : base_type( first, last, comp, a )
0258 { }
0259
0260 template< class InputIterator, class Hash, class Pred, class Allocator >
0261 ptr_map_adapter_base( InputIterator first, InputIterator last,
0262 const Hash& hash,
0263 const Pred& pred,
0264 const Allocator& a )
0265 : base_type( first, last, hash, pred, a )
0266 { }
0267
0268 #ifndef BOOST_NO_AUTO_PTR
0269 template< class PtrContainer >
0270 explicit ptr_map_adapter_base( std::auto_ptr<PtrContainer> clone )
0271 : base_type( clone )
0272 { }
0273
0274 template< typename PtrContainer >
0275 ptr_map_adapter_base& operator=( std::auto_ptr<PtrContainer> clone )
0276 {
0277 base_type::operator=( clone );
0278 return *this;
0279 }
0280 #endif
0281 #ifndef BOOST_NO_CXX11_SMART_PTR
0282 template< class PtrContainer >
0283 explicit ptr_map_adapter_base( std::unique_ptr<PtrContainer> clone )
0284 : base_type( std::move( clone ) )
0285 { }
0286
0287 template< typename PtrContainer >
0288 ptr_map_adapter_base& operator=( std::unique_ptr<PtrContainer> clone )
0289 {
0290 base_type::operator=( std::move( clone ) );
0291 return *this;
0292 }
0293 #endif
0294
0295 iterator find( const key_type& x )
0296 {
0297 return iterator( this->base().find( x ) );
0298 }
0299
0300 const_iterator find( const key_type& x ) const
0301 {
0302 return const_iterator( this->base().find( x ) );
0303 }
0304
0305 size_type count( const key_type& x ) const
0306 {
0307 return this->base().count( x );
0308 }
0309
0310 iterator lower_bound( const key_type& x )
0311 {
0312 return iterator( this->base().lower_bound( x ) );
0313 }
0314
0315 const_iterator lower_bound( const key_type& x ) const
0316 {
0317 return const_iterator( this->base().lower_bound( x ) );
0318 }
0319
0320 iterator upper_bound( const key_type& x )
0321 {
0322 return iterator( this->base().upper_bound( x ) );
0323 }
0324
0325 const_iterator upper_bound( const key_type& x ) const
0326 {
0327 return const_iterator( this->base().upper_bound( x ) );
0328 }
0329
0330 iterator_range<iterator> equal_range( const key_type& x )
0331 {
0332 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,
0333 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator>
0334 p = this->base().equal_range( x );
0335 return make_iterator_range( iterator( p.first ), iterator( p.second ) );
0336 }
0337
0338 iterator_range<const_iterator> equal_range( const key_type& x ) const
0339 {
0340 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator,
0341 BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator>
0342 p = this->base().equal_range( x );
0343 return make_iterator_range( const_iterator( p.first ),
0344 const_iterator( p.second ) );
0345 }
0346
0347 mapped_reference at( const key_type& key )
0348 {
0349 return const_cast<mapped_reference>( lookup( key ) );
0350 }
0351
0352 const_mapped_reference at( const key_type& key ) const
0353 {
0354 return lookup( key );
0355 }
0356
0357 mapped_reference operator[]( const key_type& key )
0358 {
0359 return insert_lookup( key );
0360 }
0361
0362 auto_type replace( iterator where, mapped_type x )
0363 {
0364 BOOST_ASSERT( where != this->end() );
0365 this->enforce_null_policy( x, "Null pointer in 'replace()'" );
0366
0367 auto_type ptr( x, *this );
0368 BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(),
0369 bad_ptr_container_operation,
0370 "'replace()' on empty container" );
0371
0372 auto_type old( where->second, *this );
0373 where.base()->second = ptr.release();
0374 return boost::ptr_container::move( old );
0375 }
0376
0377 #ifndef BOOST_NO_AUTO_PTR
0378 template< class U >
0379 auto_type replace( iterator where, std::auto_ptr<U> x )
0380 {
0381 return replace( where, x.release() );
0382 }
0383 #endif
0384 #ifndef BOOST_NO_CXX11_SMART_PTR
0385 template< class U >
0386 auto_type replace( iterator where, std::unique_ptr<U> x )
0387 {
0388 return replace( where, x.release() );
0389 }
0390 #endif
0391
0392 protected:
0393 size_type bucket( const key_type& key ) const
0394 {
0395 return this->base().bucket( key );
0396 }
0397 };
0398
0399 }
0400
0401
0402
0403
0404
0405 template
0406 <
0407 class T,
0408 class VoidPtrMap,
0409 class CloneAllocator = heap_clone_allocator,
0410 bool Ordered = true
0411 >
0412 class ptr_map_adapter :
0413 public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>
0414 {
0415 typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>
0416 base_type;
0417
0418 public:
0419 typedef BOOST_DEDUCED_TYPENAME base_type::iterator
0420 iterator;
0421 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
0422 const_iterator;
0423 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
0424 size_type;
0425 typedef BOOST_DEDUCED_TYPENAME base_type::key_type
0426 key_type;
0427 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0428 const_reference;
0429 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
0430 auto_type;
0431 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
0432 allocator_type;
0433 typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
0434 mapped_type;
0435 private:
0436
0437 void safe_insert( const key_type& key, auto_type ptr )
0438 {
0439 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
0440 res =
0441 this->base().insert( std::make_pair( key, ptr.get() ) );
0442 if( res.second )
0443 ptr.release();
0444 }
0445
0446 template< class II >
0447 void map_basic_clone_and_insert( II first, II last )
0448 {
0449 while( first != last )
0450 {
0451 if( this->find( first->first ) == this->end() )
0452 {
0453 const_reference p = *first.base();
0454 auto_type ptr( this->null_policy_allocate_clone(p.second), *this );
0455
0456 this->safe_insert( p.first,
0457 boost::ptr_container::move( ptr ) );
0458
0459 }
0460 ++first;
0461 }
0462 }
0463
0464 public:
0465 ptr_map_adapter( )
0466 { }
0467
0468 template< class Comp >
0469 explicit ptr_map_adapter( const Comp& comp,
0470 const allocator_type& a )
0471 : base_type( comp, a ) { }
0472
0473 template< class SizeType >
0474 explicit ptr_map_adapter( SizeType n,
0475 ptr_container_detail::unordered_associative_container_tag tag )
0476 : base_type( n, tag ) { }
0477
0478 template< class Hash, class Pred, class Allocator >
0479 ptr_map_adapter( const Hash& hash,
0480 const Pred& pred,
0481 const Allocator& a )
0482 : base_type( hash, pred, a )
0483 { }
0484
0485 template< class InputIterator >
0486 ptr_map_adapter( InputIterator first, InputIterator last )
0487 {
0488 map_basic_clone_and_insert( first, last );
0489 }
0490
0491 template< class InputIterator, class Comp >
0492 ptr_map_adapter( InputIterator first, InputIterator last,
0493 const Comp& comp,
0494 const allocator_type& a = allocator_type() )
0495 : base_type( comp, a )
0496 {
0497 map_basic_clone_and_insert( first, last );
0498 }
0499
0500 template< class InputIterator, class Hash, class Pred, class Allocator >
0501 ptr_map_adapter( InputIterator first, InputIterator last,
0502 const Hash& hash,
0503 const Pred& pred,
0504 const Allocator& a )
0505 : base_type( hash, pred, a )
0506 {
0507 map_basic_clone_and_insert( first, last );
0508 }
0509
0510 ptr_map_adapter( const ptr_map_adapter& r )
0511 {
0512 map_basic_clone_and_insert( r.begin(), r.end() );
0513 }
0514
0515 template< class Key, class U, class CA, bool b >
0516 ptr_map_adapter( const ptr_map_adapter<Key,U,CA,b>& r )
0517 {
0518 map_basic_clone_and_insert( r.begin(), r.end() );
0519 }
0520
0521 #ifndef BOOST_NO_AUTO_PTR
0522 template< class U >
0523 ptr_map_adapter( std::auto_ptr<U> r ) : base_type( r )
0524 { }
0525 #endif
0526 #ifndef BOOST_NO_CXX11_SMART_PTR
0527 template< class U >
0528 ptr_map_adapter( std::unique_ptr<U> r ) : base_type( std::move( r ) )
0529 { }
0530 #endif
0531
0532 ptr_map_adapter& operator=( ptr_map_adapter r )
0533 {
0534 this->swap( r );
0535 return *this;
0536 }
0537
0538 #ifndef BOOST_NO_AUTO_PTR
0539 template< class U >
0540 ptr_map_adapter& operator=( std::auto_ptr<U> r )
0541 {
0542 base_type::operator=( r );
0543 return *this;
0544 }
0545 #endif
0546 #ifndef BOOST_NO_CXX11_SMART_PTR
0547 template< class U >
0548 ptr_map_adapter& operator=( std::unique_ptr<U> r )
0549 {
0550 base_type::operator=( std::move( r ) );
0551 return *this;
0552 }
0553 #endif
0554
0555 using base_type::release;
0556
0557 template< typename InputIterator >
0558 void insert( InputIterator first, InputIterator last )
0559 {
0560 map_basic_clone_and_insert( first, last );
0561 }
0562
0563 template< class Range >
0564 void insert( const Range& r )
0565 {
0566 insert( boost::begin(r), boost::end(r) );
0567 }
0568
0569 private:
0570 std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x )
0571 {
0572 this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" );
0573
0574 auto_type ptr( x, *this );
0575 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
0576 res = this->base().insert( std::make_pair( key, x ) );
0577 if( res.second )
0578 ptr.release();
0579 return std::make_pair( iterator( res.first ), res.second );
0580 }
0581
0582 iterator insert_impl( iterator before, const key_type& key, mapped_type x )
0583 {
0584 this->enforce_null_policy( x,
0585 "Null pointer in 'ptr_map_adapter::insert()'" );
0586
0587 auto_type ptr( x, *this );
0588 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0589 res = this->base().insert( before.base(), std::make_pair( key, x ) );
0590
0591 ptr.release();
0592 return iterator( res );
0593 }
0594
0595 public:
0596
0597 std::pair<iterator,bool> insert( key_type& key, mapped_type x )
0598 {
0599 return insert_impl( key, x );
0600 }
0601
0602 #ifndef BOOST_NO_AUTO_PTR
0603 template< class U >
0604 std::pair<iterator,bool> insert( const key_type& key, std::auto_ptr<U> x )
0605 {
0606 return insert_impl( key, x.release() );
0607 }
0608 #endif
0609 #ifndef BOOST_NO_CXX11_SMART_PTR
0610 template< class U >
0611 std::pair<iterator,bool> insert( const key_type& key, std::unique_ptr<U> x )
0612 {
0613 return insert_impl( key, x.release() );
0614 }
0615 #endif
0616
0617 template< class F, class S >
0618 iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p )
0619 {
0620 this->enforce_null_policy( p.second,
0621 "Null pointer in 'ptr_map_adapter::insert()'" );
0622
0623 auto_type ptr( this->null_policy_allocate_clone(p.second), *this );
0624 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0625 result = this->base().insert( before.base(),
0626 std::make_pair(p.first,ptr.get()) );
0627 if( ptr.get() == result->second )
0628 ptr.release();
0629
0630 return iterator( result );
0631 }
0632
0633 iterator insert( iterator before, key_type& key, mapped_type x )
0634 {
0635 return insert_impl( before, key, x );
0636 }
0637
0638 #ifndef BOOST_NO_AUTO_PTR
0639 template< class U >
0640 iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x )
0641 {
0642 return insert_impl( before, key, x.release() );
0643 }
0644 #endif
0645 #ifndef BOOST_NO_CXX11_SMART_PTR
0646 template< class U >
0647 iterator insert( iterator before, const key_type& key, std::unique_ptr<U> x )
0648 {
0649 return insert_impl( before, key, x.release() );
0650 }
0651 #endif
0652
0653 template< class PtrMapAdapter >
0654 bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,
0655 PtrMapAdapter& from )
0656 {
0657 return this->single_transfer( object, from );
0658 }
0659
0660 template< class PtrMapAdapter >
0661 size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,
0662 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,
0663 PtrMapAdapter& from )
0664 {
0665 return this->single_transfer( first, last, from );
0666 }
0667
0668 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0669 #else
0670
0671 template< class PtrMapAdapter, class Range >
0672 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
0673 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
0674 size_type >::type
0675 transfer( const Range& r, PtrMapAdapter& from )
0676 {
0677 return transfer( boost::begin(r), boost::end(r), from );
0678 }
0679
0680 #endif
0681
0682 template< class PtrMapAdapter >
0683 size_type transfer( PtrMapAdapter& from )
0684 {
0685 return transfer( from.begin(), from.end(), from );
0686 }
0687 };
0688
0689
0690
0691
0692
0693 template
0694 <
0695 class T,
0696 class VoidPtrMultiMap,
0697 class CloneAllocator = heap_clone_allocator,
0698 bool Ordered = true
0699 >
0700 class ptr_multimap_adapter :
0701 public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered>
0702 {
0703 typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered>
0704 base_type;
0705
0706 public:
0707 typedef BOOST_DEDUCED_TYPENAME base_type::iterator
0708 iterator;
0709 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
0710 const_iterator;
0711 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
0712 size_type;
0713 typedef BOOST_DEDUCED_TYPENAME base_type::key_type
0714 key_type;
0715 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0716 const_reference;
0717 typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
0718 mapped_type;
0719 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
0720 auto_type;
0721 typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type
0722 allocator_type;
0723 private:
0724
0725 void safe_insert( const key_type& key, auto_type ptr )
0726 {
0727 this->base().insert(
0728 std::make_pair( key, ptr.get() ) );
0729 ptr.release();
0730 }
0731
0732 template< typename II >
0733 void map_basic_clone_and_insert( II first, II last )
0734 {
0735 while( first != last )
0736 {
0737 const_reference pair = *first.base();
0738 auto_type ptr( this->null_policy_allocate_clone(pair.second), *this );
0739
0740 safe_insert( pair.first,
0741 boost::ptr_container::move( ptr ) );
0742
0743 ++first;
0744 }
0745 }
0746
0747 public:
0748
0749 ptr_multimap_adapter()
0750 { }
0751
0752 template< class SizeType >
0753 ptr_multimap_adapter( SizeType n,
0754 ptr_container_detail::unordered_associative_container_tag tag )
0755 : base_type( n, tag )
0756 { }
0757
0758 template< class Comp >
0759 explicit ptr_multimap_adapter( const Comp& comp,
0760 const allocator_type& a )
0761 : base_type( comp, a ) { }
0762
0763 template< class Hash, class Pred, class Allocator >
0764 ptr_multimap_adapter( const Hash& hash,
0765 const Pred& pred,
0766 const Allocator& a )
0767 : base_type( hash, pred, a )
0768 { }
0769
0770 template< class InputIterator >
0771 ptr_multimap_adapter( InputIterator first, InputIterator last )
0772 {
0773 map_basic_clone_and_insert( first, last );
0774 }
0775
0776 template< class InputIterator, class Comp >
0777 ptr_multimap_adapter( InputIterator first, InputIterator last,
0778 const Comp& comp,
0779 const allocator_type& a )
0780 : base_type( comp, a )
0781 {
0782 map_basic_clone_and_insert( first, last );
0783 }
0784
0785 template< class InputIterator, class Hash, class Pred, class Allocator >
0786 ptr_multimap_adapter( InputIterator first, InputIterator last,
0787 const Hash& hash,
0788 const Pred& pred,
0789 const Allocator& a )
0790 : base_type( hash, pred, a )
0791 {
0792 map_basic_clone_and_insert( first, last );
0793 }
0794
0795 ptr_multimap_adapter( const ptr_multimap_adapter& r )
0796 {
0797 map_basic_clone_and_insert( r.begin(), r.end() );
0798 }
0799
0800 template< class Key, class U, class CA, bool b >
0801 ptr_multimap_adapter( const ptr_multimap_adapter<Key,U,CA,b>& r )
0802 {
0803 map_basic_clone_and_insert( r.begin(), r.end() );
0804 }
0805
0806 #ifndef BOOST_NO_AUTO_PTR
0807 template< class U >
0808 explicit ptr_multimap_adapter( std::auto_ptr<U> r ) : base_type( r )
0809 { }
0810 #endif
0811 #ifndef BOOST_NO_CXX11_SMART_PTR
0812 template< class U >
0813 explicit ptr_multimap_adapter( std::unique_ptr<U> r ) : base_type( std::move( r ) )
0814 { }
0815 #endif
0816
0817 ptr_multimap_adapter& operator=( ptr_multimap_adapter r )
0818 {
0819 this->swap( r );
0820 return *this;
0821 }
0822
0823 #ifndef BOOST_NO_AUTO_PTR
0824 template< class U >
0825 ptr_multimap_adapter& operator=( std::auto_ptr<U> r )
0826 {
0827 base_type::operator=( r );
0828 return *this;
0829 }
0830 #endif
0831 #ifndef BOOST_NO_CXX11_SMART_PTR
0832 template< class U >
0833 ptr_multimap_adapter& operator=( std::unique_ptr<U> r )
0834 {
0835 base_type::operator=( std::move( r ) );
0836 return *this;
0837 }
0838 #endif
0839
0840 using base_type::release;
0841
0842 private:
0843 iterator insert_impl( const key_type& key, mapped_type x )
0844 {
0845 this->enforce_null_policy( x,
0846 "Null pointer in 'ptr_multimap_adapter::insert()'" );
0847
0848 auto_type ptr( x, *this );
0849 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0850 res = this->base().insert( std::make_pair( key, x ) );
0851
0852 ptr.release();
0853 return iterator( res );
0854 }
0855
0856 iterator insert_impl( iterator before, const key_type& key, mapped_type x )
0857 {
0858 this->enforce_null_policy( x,
0859 "Null pointer in 'ptr_multimap_adapter::insert()'" );
0860
0861 auto_type ptr( x, *this );
0862 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0863 res = this->base().insert( before.base(),
0864 std::make_pair( key, x ) );
0865
0866 ptr.release();
0867 return iterator( res );
0868 }
0869
0870 public:
0871 template< typename InputIterator >
0872 void insert( InputIterator first, InputIterator last )
0873 {
0874 map_basic_clone_and_insert( first, last );
0875 }
0876
0877 template< class Range >
0878 void insert( const Range& r )
0879 {
0880 insert( boost::begin(r), boost::end(r) );
0881 }
0882
0883 iterator insert( key_type& key, mapped_type x )
0884 {
0885 return insert_impl( key, x );
0886 }
0887
0888 #ifndef BOOST_NO_AUTO_PTR
0889 template< class U >
0890 iterator insert( const key_type& key, std::auto_ptr<U> x )
0891 {
0892 return insert_impl( key, x.release() );
0893 }
0894 #endif
0895 #ifndef BOOST_NO_CXX11_SMART_PTR
0896 template< class U >
0897 iterator insert( const key_type& key, std::unique_ptr<U> x )
0898 {
0899 return insert_impl( key, x.release() );
0900 }
0901 #endif
0902
0903 template< class F, class S >
0904 iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p )
0905 {
0906 this->enforce_null_policy( p.second,
0907 "Null pointer in 'ptr_multimap_adapter::insert()'" );
0908 iterator res = insert_impl( before, p.first,
0909 this->null_policy_allocate_clone( p.second ) );
0910 return res;
0911 }
0912
0913 iterator insert( iterator before, key_type& key, mapped_type x )
0914 {
0915 return insert_impl( before, key, x );
0916 }
0917
0918 #ifndef BOOST_NO_AUTO_PTR
0919 template< class U >
0920 iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x )
0921 {
0922 return insert_impl( before, key, x.release() );
0923 }
0924 #endif
0925 #ifndef BOOST_NO_CXX11_SMART_PTR
0926 template< class U >
0927 iterator insert( iterator before, const key_type& key, std::unique_ptr<U> x )
0928 {
0929 return insert_impl( before, key, x.release() );
0930 }
0931 #endif
0932
0933 template< class PtrMapAdapter >
0934 void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,
0935 PtrMapAdapter& from )
0936 {
0937 this->multi_transfer( object, from );
0938 }
0939
0940 template< class PtrMapAdapter >
0941 size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,
0942 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,
0943 PtrMapAdapter& from )
0944 {
0945 return this->multi_transfer( first, last, from );
0946 }
0947
0948 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0949 #else
0950
0951 template< class PtrMapAdapter, class Range >
0952 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
0953 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
0954 size_type >::type
0955 transfer( const Range& r, PtrMapAdapter& from )
0956 {
0957 return transfer( boost::begin(r), boost::end(r), from );
0958 }
0959
0960 #endif
0961 template< class PtrMapAdapter >
0962 void transfer( PtrMapAdapter& from )
0963 {
0964 transfer( from.begin(), from.end(), from );
0965 BOOST_ASSERT( from.empty() );
0966 }
0967
0968 };
0969
0970 template< class I, class F, class S >
0971 inline bool is_null( const ptr_map_iterator<I,F,S>& i )
0972 {
0973 return i->second == 0;
0974 }
0975
0976 }
0977
0978 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0979 #pragma GCC diagnostic pop
0980 #endif
0981
0982 #endif