1 // 2 // Boost.Pointer Container 3 // 4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and 5 // distribution is subject to the Boost Software License, Version 6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // For more information, see http://www.boost.org/libs/ptr_container/ 10 // 11 12 #ifndef BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP 13 #define BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP 14 15 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 # pragma once 17 #endif 18 19 #include <boost/ptr_container/detail/map_iterator.hpp> 20 #include <boost/ptr_container/detail/associative_ptr_container.hpp> 21 #include <boost/ptr_container/detail/meta_functions.hpp> 22 #include <boost/static_assert.hpp> 23 #include <boost/range/iterator_range.hpp> 24 25 namespace boost 26 { 27 namespace ptr_container_detail 28 { 29 30 template 31 < 32 class T, 33 class VoidPtrMap, 34 bool Ordered 35 > 36 struct map_config 37 { 38 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type 39 U; 40 typedef VoidPtrMap 41 void_container_type; 42 43 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type 44 allocator_type; 45 46 typedef BOOST_DEDUCED_TYPENAME 47 mpl::eval_if_c<Ordered, 48 select_value_compare<VoidPtrMap>, 49 mpl::identity<void> >::type 50 value_compare; 51 52 typedef BOOST_DEDUCED_TYPENAME 53 mpl::eval_if_c<Ordered, 54 select_key_compare<VoidPtrMap>, 55 mpl::identity<void> >::type 56 key_compare; 57 58 typedef BOOST_DEDUCED_TYPENAME 59 mpl::eval_if_c<Ordered, 60 mpl::identity<void>, 61 select_hasher<VoidPtrMap> >::type 62 hasher; 63 64 typedef BOOST_DEDUCED_TYPENAME 65 mpl::eval_if_c<Ordered, 66 mpl::identity<void>, 67 select_key_equal<VoidPtrMap> >::type 68 key_equal; 69 70 typedef BOOST_DEDUCED_TYPENAME 71 mpl::if_c<Ordered, 72 ptr_container_detail::ordered_associative_container_tag, 73 ptr_container_detail::unordered_associative_container_tag>::type 74 container_type; 75 76 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type 77 key_type; 78 79 typedef U value_type; 80 81 typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const > 82 iterator; 83 84 typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const> 85 const_iterator; 86 87 typedef ptr_map_iterator< 88 BOOST_DEDUCED_TYPENAME 89 mpl::eval_if_c<Ordered, 90 select_iterator<VoidPtrMap>, 91 select_local_iterator<VoidPtrMap> >::type, 92 key_type, U* const > 93 local_iterator; 94 95 typedef ptr_map_iterator< 96 BOOST_DEDUCED_TYPENAME 97 mpl::eval_if_c<Ordered, 98 select_iterator<VoidPtrMap>, 99 select_const_local_iterator<VoidPtrMap> >::type, 100 key_type, const U* const > 101 const_local_iterator; 102 103 template< class Iter > get_pointerboost::ptr_container_detail::map_config104 static U* get_pointer( Iter i ) 105 { 106 return i->second; 107 } 108 109 template< class Iter > get_const_pointerboost::ptr_container_detail::map_config110 static const U* get_const_pointer( Iter i ) 111 { 112 return i->second; 113 } 114 115 BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable<T>::value ); 116 }; 117 118 119 120 template 121 < 122 class T, 123 class VoidPtrMap, 124 class CloneAllocator, 125 bool Ordered 126 > 127 class ptr_map_adapter_base : 128 public ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>, 129 CloneAllocator > 130 { 131 typedef ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>, 132 CloneAllocator > 133 base_type; 134 135 typedef map_config<T,VoidPtrMap,Ordered> config; 136 typedef ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered> this_type; 137 138 public: 139 140 typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type 141 allocator_type; 142 typedef BOOST_DEDUCED_TYPENAME base_type::iterator 143 iterator; 144 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator 145 const_iterator; 146 typedef BOOST_DEDUCED_TYPENAME base_type::size_type 147 size_type; 148 typedef BOOST_DEDUCED_TYPENAME base_type::key_type 149 key_type; 150 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type 151 auto_type; 152 typedef BOOST_DEDUCED_TYPENAME base_type::value_type 153 mapped_type; 154 typedef BOOST_DEDUCED_TYPENAME base_type::reference 155 mapped_reference; 156 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference 157 const_mapped_reference; 158 typedef BOOST_DEDUCED_TYPENAME iterator_value<iterator>::type 159 value_type; 160 typedef value_type 161 reference; 162 typedef BOOST_DEDUCED_TYPENAME iterator_value<const_iterator>::type 163 const_reference; 164 typedef value_type 165 pointer; 166 typedef const_reference 167 const_pointer; 168 169 private: lookup(const key_type & key) const170 const_mapped_reference lookup( const key_type& key ) const 171 { 172 const_iterator i = this->find( key ); 173 if( i != this->end() ) 174 return *i->second; 175 else 176 BOOST_PTR_CONTAINER_THROW_EXCEPTION( true, bad_ptr_container_operation, 177 "'ptr_map/multimap::at()' could" 178 " not find key" ); 179 } 180 181 struct eraser // scope guard 182 { 183 bool released_; 184 VoidPtrMap* m_; 185 const key_type& key_; 186 eraserboost::ptr_container_detail::ptr_map_adapter_base::eraser187 eraser( VoidPtrMap* m, const key_type& key ) 188 : released_(false), m_(m), key_(key) 189 {} 190 ~eraserboost::ptr_container_detail::ptr_map_adapter_base::eraser191 ~eraser() 192 { 193 if( !released_ ) 194 m_->erase(key_); 195 } 196 releaseboost::ptr_container_detail::ptr_map_adapter_base::eraser197 void release() { released_ = true; } 198 199 private: 200 eraser& operator=(const eraser&); 201 }; 202 insert_lookup(const key_type & key)203 mapped_reference insert_lookup( const key_type& key ) 204 { 205 void*& ref = this->base()[key]; 206 if( ref ) 207 { 208 return *static_cast<mapped_type>(ref); 209 } 210 else 211 { 212 eraser e(&this->base(),key); // nothrow 213 mapped_type res = new T(); // strong 214 ref = res; // nothrow 215 e.release(); // nothrow 216 return *res; 217 } 218 } 219 220 public: 221 ptr_map_adapter_base()222 ptr_map_adapter_base() 223 { } 224 225 template< class SizeType > ptr_map_adapter_base(SizeType n,ptr_container_detail::unordered_associative_container_tag tag)226 explicit ptr_map_adapter_base( SizeType n, 227 ptr_container_detail::unordered_associative_container_tag tag ) 228 : base_type( n, tag ) 229 { } 230 231 template< class Compare, class Allocator > ptr_map_adapter_base(const Compare & comp,const Allocator & a)232 ptr_map_adapter_base( const Compare& comp, 233 const Allocator& a ) 234 : base_type( comp, a ) 235 { } 236 237 template< class Hash, class Pred, class Allocator > ptr_map_adapter_base(const Hash & hash,const Pred & pred,const Allocator & a)238 ptr_map_adapter_base( const Hash& hash, 239 const Pred& pred, 240 const Allocator& a ) 241 : base_type( hash, pred, a ) 242 { } 243 244 template< class InputIterator > ptr_map_adapter_base(InputIterator first,InputIterator last)245 ptr_map_adapter_base( InputIterator first, InputIterator last ) 246 : base_type( first, last ) 247 { } 248 249 template< class InputIterator, class Comp > ptr_map_adapter_base(InputIterator first,InputIterator last,const Comp & comp,const allocator_type & a=allocator_type ())250 ptr_map_adapter_base( InputIterator first, InputIterator last, 251 const Comp& comp, 252 const allocator_type& a = allocator_type() ) 253 : base_type( first, last, comp, a ) 254 { } 255 256 template< class InputIterator, class Hash, class Pred, class Allocator > ptr_map_adapter_base(InputIterator first,InputIterator last,const Hash & hash,const Pred & pred,const Allocator & a)257 ptr_map_adapter_base( InputIterator first, InputIterator last, 258 const Hash& hash, 259 const Pred& pred, 260 const Allocator& a ) 261 : base_type( first, last, hash, pred, a ) 262 { } 263 264 template< class PtrContainer > ptr_map_adapter_base(std::auto_ptr<PtrContainer> clone)265 explicit ptr_map_adapter_base( std::auto_ptr<PtrContainer> clone ) 266 : base_type( clone ) 267 { } 268 269 template< typename PtrContainer > operator =(std::auto_ptr<PtrContainer> clone)270 ptr_map_adapter_base& operator=( std::auto_ptr<PtrContainer> clone ) 271 { 272 base_type::operator=( clone ); 273 return *this; 274 } 275 find(const key_type & x)276 iterator find( const key_type& x ) 277 { 278 return iterator( this->base().find( x ) ); 279 } 280 find(const key_type & x) const281 const_iterator find( const key_type& x ) const 282 { 283 return const_iterator( this->base().find( x ) ); 284 } 285 count(const key_type & x) const286 size_type count( const key_type& x ) const 287 { 288 return this->base().count( x ); 289 } 290 lower_bound(const key_type & x)291 iterator lower_bound( const key_type& x ) 292 { 293 return iterator( this->base().lower_bound( x ) ); 294 } 295 lower_bound(const key_type & x) const296 const_iterator lower_bound( const key_type& x ) const 297 { 298 return const_iterator( this->base().lower_bound( x ) ); 299 } 300 upper_bound(const key_type & x)301 iterator upper_bound( const key_type& x ) 302 { 303 return iterator( this->base().upper_bound( x ) ); 304 } 305 upper_bound(const key_type & x) const306 const_iterator upper_bound( const key_type& x ) const 307 { 308 return const_iterator( this->base().upper_bound( x ) ); 309 } 310 equal_range(const key_type & x)311 iterator_range<iterator> equal_range( const key_type& x ) 312 { 313 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator, 314 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator> 315 p = this->base().equal_range( x ); 316 return make_iterator_range( iterator( p.first ), iterator( p.second ) ); 317 } 318 equal_range(const key_type & x) const319 iterator_range<const_iterator> equal_range( const key_type& x ) const 320 { 321 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator, 322 BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator> 323 p = this->base().equal_range( x ); 324 return make_iterator_range( const_iterator( p.first ), 325 const_iterator( p.second ) ); 326 } 327 at(const key_type & key)328 mapped_reference at( const key_type& key ) 329 { 330 return const_cast<mapped_reference>( lookup( key ) ); 331 } 332 at(const key_type & key) const333 const_mapped_reference at( const key_type& key ) const 334 { 335 return lookup( key ); 336 } 337 operator [](const key_type & key)338 mapped_reference operator[]( const key_type& key ) 339 { 340 return insert_lookup( key ); 341 } 342 replace(iterator where,mapped_type x)343 auto_type replace( iterator where, mapped_type x ) // strong 344 { 345 BOOST_ASSERT( where != this->end() ); 346 347 this->enforce_null_policy( x, "Null pointer in 'replace()'" ); 348 349 auto_type ptr( x ); 350 351 BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(), 352 bad_ptr_container_operation, 353 "'replace()' on empty container" ); 354 355 auto_type old( where->second ); // nothrow 356 where.base()->second = ptr.release(); // nothrow, commit 357 return boost::ptr_container::move( old ); 358 } 359 360 template< class U > replace(iterator where,std::auto_ptr<U> x)361 auto_type replace( iterator where, std::auto_ptr<U> x ) 362 { 363 return replace( where, x.release() ); 364 } 365 366 protected: bucket(const key_type & key) const367 size_type bucket( const key_type& key ) const 368 { 369 return this->base().bucket( key ); 370 } 371 }; 372 373 } // ptr_container_detail 374 375 ///////////////////////////////////////////////////////////////////////// 376 // ptr_map_adapter 377 ///////////////////////////////////////////////////////////////////////// 378 379 template 380 < 381 class T, 382 class VoidPtrMap, 383 class CloneAllocator = heap_clone_allocator, 384 bool Ordered = true 385 > 386 class ptr_map_adapter : 387 public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered> 388 { 389 typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered> 390 base_type; 391 392 public: 393 typedef BOOST_DEDUCED_TYPENAME base_type::iterator 394 iterator; 395 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator 396 const_iterator; 397 typedef BOOST_DEDUCED_TYPENAME base_type::size_type 398 size_type; 399 typedef BOOST_DEDUCED_TYPENAME base_type::key_type 400 key_type; 401 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference 402 const_reference; 403 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type 404 auto_type; 405 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type 406 allocator_type; 407 typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type 408 mapped_type; 409 private: 410 safe_insert(const key_type & key,auto_type ptr)411 void safe_insert( const key_type& key, auto_type ptr ) // strong 412 { 413 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> 414 res = 415 this->base().insert( std::make_pair( key, ptr.get() ) ); // strong, commit 416 if( res.second ) // nothrow 417 ptr.release(); // nothrow 418 } 419 420 template< class II > map_basic_clone_and_insert(II first,II last)421 void map_basic_clone_and_insert( II first, II last ) 422 { 423 while( first != last ) 424 { 425 if( this->find( first->first ) == this->end() ) 426 { 427 const_reference p = *first.base(); // nothrow 428 auto_type ptr( this->null_policy_allocate_clone( p.second ) ); 429 // strong 430 this->safe_insert( p.first, 431 boost::ptr_container::move( ptr ) ); 432 // strong, commit 433 } 434 ++first; 435 } 436 } 437 438 public: ptr_map_adapter()439 ptr_map_adapter( ) 440 { } 441 442 template< class Comp > ptr_map_adapter(const Comp & comp,const allocator_type & a)443 explicit ptr_map_adapter( const Comp& comp, 444 const allocator_type& a ) 445 : base_type( comp, a ) { } 446 447 template< class Hash, class Pred, class Allocator > ptr_map_adapter(const Hash & hash,const Pred & pred,const Allocator & a)448 ptr_map_adapter( const Hash& hash, 449 const Pred& pred, 450 const Allocator& a ) 451 : base_type( hash, pred, a ) 452 { } 453 454 template< class InputIterator > ptr_map_adapter(InputIterator first,InputIterator last)455 ptr_map_adapter( InputIterator first, InputIterator last ) 456 { 457 map_basic_clone_and_insert( first, last ); 458 } 459 460 template< class InputIterator, class Comp > ptr_map_adapter(InputIterator first,InputIterator last,const Comp & comp,const allocator_type & a=allocator_type ())461 ptr_map_adapter( InputIterator first, InputIterator last, 462 const Comp& comp, 463 const allocator_type& a = allocator_type() ) 464 : base_type( comp, a ) 465 { 466 map_basic_clone_and_insert( first, last ); 467 } 468 469 template< class InputIterator, class Hash, class Pred, class Allocator > ptr_map_adapter(InputIterator first,InputIterator last,const Hash & hash,const Pred & pred,const Allocator & a)470 ptr_map_adapter( InputIterator first, InputIterator last, 471 const Hash& hash, 472 const Pred& pred, 473 const Allocator& a ) 474 : base_type( hash, pred, a ) 475 { 476 map_basic_clone_and_insert( first, last ); 477 } 478 ptr_map_adapter(const ptr_map_adapter & r)479 ptr_map_adapter( const ptr_map_adapter& r ) 480 { 481 map_basic_clone_and_insert( r.begin(), r.end() ); 482 } 483 484 template< class Key, class U, class CA, bool b > ptr_map_adapter(const ptr_map_adapter<Key,U,CA,b> & r)485 ptr_map_adapter( const ptr_map_adapter<Key,U,CA,b>& r ) 486 { 487 map_basic_clone_and_insert( r.begin(), r.end() ); 488 } 489 490 template< class U > ptr_map_adapter(std::auto_ptr<U> r)491 ptr_map_adapter( std::auto_ptr<U> r ) : base_type( r ) 492 { } 493 operator =(ptr_map_adapter r)494 ptr_map_adapter& operator=( ptr_map_adapter r ) 495 { 496 this->swap( r ); 497 return *this; 498 } 499 500 template< class U > operator =(std::auto_ptr<U> r)501 ptr_map_adapter& operator=( std::auto_ptr<U> r ) 502 { 503 base_type::operator=( r ); 504 return *this; 505 } 506 507 using base_type::release; 508 509 template< typename InputIterator > insert(InputIterator first,InputIterator last)510 void insert( InputIterator first, InputIterator last ) // basic 511 { 512 map_basic_clone_and_insert( first, last ); 513 } 514 515 template< class Range > insert(const Range & r)516 void insert( const Range& r ) 517 { 518 insert( boost::begin(r), boost::end(r) ); 519 } 520 521 private: insert_impl(const key_type & key,mapped_type x)522 std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x ) // strong 523 { 524 this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" ); 525 auto_type ptr( x ); // nothrow 526 527 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> 528 res = this->base().insert( std::make_pair( key, x ) ); // strong, commit 529 if( res.second ) // nothrow 530 ptr.release(); // nothrow 531 return std::make_pair( iterator( res.first ), res.second ); // nothrow 532 } 533 insert_impl(iterator before,const key_type & key,mapped_type x)534 iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong 535 { 536 this->enforce_null_policy( x, 537 "Null pointer in 'ptr_map_adapter::insert()'" ); 538 auto_type ptr( x ); // nothrow 539 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator 540 res = this->base().insert( before.base(), std::make_pair( key, x ) ); 541 // strong, commit 542 ptr.release(); // notrow 543 return iterator( res ); 544 } 545 546 public: 547 insert(key_type & key,mapped_type x)548 std::pair<iterator,bool> insert( key_type& key, mapped_type x ) 549 { 550 return insert_impl( key, x ); 551 } 552 553 template< class U > insert(const key_type & key,std::auto_ptr<U> x)554 std::pair<iterator,bool> insert( const key_type& key, std::auto_ptr<U> x ) 555 { 556 return insert_impl( key, x.release() ); 557 } 558 559 template< class F, class S > insert(iterator before,ptr_container_detail::ref_pair<F,S> p)560 iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p ) // strong 561 { 562 this->enforce_null_policy( p.second, 563 "Null pointer in 'ptr_map_adapter::insert()'" ); 564 565 auto_type ptr( this->null_policy_allocate_clone( p.second ) ); 566 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator 567 result = this->base().insert( before.base(), 568 std::make_pair(p.first,ptr.get()) ); // strong 569 if( ptr.get() == result->second ) 570 ptr.release(); 571 572 return iterator( result ); 573 } 574 insert(iterator before,key_type & key,mapped_type x)575 iterator insert( iterator before, key_type& key, mapped_type x ) // strong 576 { 577 return insert_impl( before, key, x ); 578 } 579 580 template< class U > insert(iterator before,const key_type & key,std::auto_ptr<U> x)581 iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x ) // strong 582 { 583 return insert_impl( before, key, x.release() ); 584 } 585 586 template< class PtrMapAdapter > transfer(BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,PtrMapAdapter & from)587 bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, 588 PtrMapAdapter& from ) // strong 589 { 590 return this->single_transfer( object, from ); 591 } 592 593 template< class PtrMapAdapter > transfer(BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,PtrMapAdapter & from)594 size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, 595 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, 596 PtrMapAdapter& from ) // basic 597 { 598 return this->single_transfer( first, last, from ); 599 } 600 601 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) 602 #else 603 604 template< class PtrMapAdapter, class Range > 605 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, 606 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >, 607 size_type >::type transfer(const Range & r,PtrMapAdapter & from)608 transfer( const Range& r, PtrMapAdapter& from ) // basic 609 { 610 return transfer( boost::begin(r), boost::end(r), from ); 611 } 612 613 #endif 614 615 template< class PtrMapAdapter > transfer(PtrMapAdapter & from)616 size_type transfer( PtrMapAdapter& from ) // basic 617 { 618 return transfer( from.begin(), from.end(), from ); 619 } 620 }; 621 622 ///////////////////////////////////////////////////////////////////////// 623 // ptr_multimap_adapter 624 ///////////////////////////////////////////////////////////////////////// 625 626 template 627 < 628 class T, 629 class VoidPtrMultiMap, 630 class CloneAllocator = heap_clone_allocator, 631 bool Ordered = true 632 > 633 class ptr_multimap_adapter : 634 public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered> 635 { 636 typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered> 637 base_type; 638 639 public: // typedefs 640 typedef BOOST_DEDUCED_TYPENAME base_type::iterator 641 iterator; 642 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator 643 const_iterator; 644 typedef BOOST_DEDUCED_TYPENAME base_type::size_type 645 size_type; 646 typedef BOOST_DEDUCED_TYPENAME base_type::key_type 647 key_type; 648 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference 649 const_reference; 650 typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type 651 mapped_type; 652 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type 653 auto_type; 654 typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type 655 allocator_type; 656 private: 657 safe_insert(const key_type & key,auto_type ptr)658 void safe_insert( const key_type& key, auto_type ptr ) // strong 659 { 660 this->base().insert( 661 std::make_pair( key, ptr.get() ) ); // strong, commit 662 ptr.release(); // nothrow 663 } 664 665 template< typename II > map_basic_clone_and_insert(II first,II last)666 void map_basic_clone_and_insert( II first, II last ) 667 { 668 while( first != last ) 669 { 670 const_reference pair = *first.base(); // nothrow 671 auto_type ptr( this->null_policy_allocate_clone( pair.second ) ); 672 // strong 673 safe_insert( pair.first, 674 boost::ptr_container::move( ptr ) ); 675 // strong, commit 676 ++first; 677 } 678 } 679 680 public: 681 ptr_multimap_adapter()682 ptr_multimap_adapter() 683 { } 684 685 template< class SizeType > ptr_multimap_adapter(SizeType n,ptr_container_detail::unordered_associative_container_tag tag)686 ptr_multimap_adapter( SizeType n, 687 ptr_container_detail::unordered_associative_container_tag tag ) 688 : base_type( n, tag ) 689 { } 690 691 template< class Comp > ptr_multimap_adapter(const Comp & comp,const allocator_type & a)692 explicit ptr_multimap_adapter( const Comp& comp, 693 const allocator_type& a ) 694 : base_type( comp, a ) { } 695 696 template< class Hash, class Pred, class Allocator > ptr_multimap_adapter(const Hash & hash,const Pred & pred,const Allocator & a)697 ptr_multimap_adapter( const Hash& hash, 698 const Pred& pred, 699 const Allocator& a ) 700 : base_type( hash, pred, a ) 701 { } 702 703 template< class InputIterator > ptr_multimap_adapter(InputIterator first,InputIterator last)704 ptr_multimap_adapter( InputIterator first, InputIterator last ) 705 { 706 map_basic_clone_and_insert( first, last ); 707 } 708 709 template< class InputIterator, class Comp > ptr_multimap_adapter(InputIterator first,InputIterator last,const Comp & comp,const allocator_type & a)710 ptr_multimap_adapter( InputIterator first, InputIterator last, 711 const Comp& comp, 712 const allocator_type& a ) 713 : base_type( comp, a ) 714 { 715 map_basic_clone_and_insert( first, last ); 716 } 717 718 template< class InputIterator, class Hash, class Pred, class Allocator > ptr_multimap_adapter(InputIterator first,InputIterator last,const Hash & hash,const Pred & pred,const Allocator & a)719 ptr_multimap_adapter( InputIterator first, InputIterator last, 720 const Hash& hash, 721 const Pred& pred, 722 const Allocator& a ) 723 : base_type( hash, pred, a ) 724 { 725 map_basic_clone_and_insert( first, last ); 726 } 727 ptr_multimap_adapter(const ptr_multimap_adapter & r)728 ptr_multimap_adapter( const ptr_multimap_adapter& r ) 729 { 730 map_basic_clone_and_insert( r.begin(), r.end() ); 731 } 732 733 template< class Key, class U, class CA, bool b > ptr_multimap_adapter(const ptr_multimap_adapter<Key,U,CA,b> & r)734 ptr_multimap_adapter( const ptr_multimap_adapter<Key,U,CA,b>& r ) 735 { 736 map_basic_clone_and_insert( r.begin(), r.end() ); 737 } 738 739 template< class U > ptr_multimap_adapter(std::auto_ptr<U> r)740 explicit ptr_multimap_adapter( std::auto_ptr<U> r ) : base_type( r ) 741 { } 742 operator =(ptr_multimap_adapter r)743 ptr_multimap_adapter& operator=( ptr_multimap_adapter r ) 744 { 745 this->swap( r ); 746 return *this; 747 } 748 749 template< class U > operator =(std::auto_ptr<U> r)750 ptr_multimap_adapter& operator=( std::auto_ptr<U> r ) 751 { 752 base_type::operator=( r ); 753 return *this; 754 } 755 756 using base_type::release; 757 758 private: insert_impl(const key_type & key,mapped_type x)759 iterator insert_impl( const key_type& key, mapped_type x ) // strong 760 { 761 this->enforce_null_policy( x, 762 "Null pointer in 'ptr_multimap_adapter::insert()'" ); 763 auto_type ptr( x ); // nothrow 764 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator 765 res = this->base().insert( std::make_pair( key, x ) ); 766 // strong, commit 767 ptr.release(); // notrow 768 return iterator( res ); 769 } 770 insert_impl(iterator before,const key_type & key,mapped_type x)771 iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong 772 { 773 this->enforce_null_policy( x, 774 "Null pointer in 'ptr_multimap_adapter::insert()'" ); 775 auto_type ptr( x ); // nothrow 776 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator 777 res = this->base().insert( before.base(), 778 std::make_pair( key, x ) ); 779 // strong, commit 780 ptr.release(); // notrow 781 return iterator( res ); 782 } 783 784 public: 785 template< typename InputIterator > insert(InputIterator first,InputIterator last)786 void insert( InputIterator first, InputIterator last ) // basic 787 { 788 map_basic_clone_and_insert( first, last ); 789 } 790 791 template< class Range > insert(const Range & r)792 void insert( const Range& r ) 793 { 794 insert( boost::begin(r), boost::end(r) ); 795 } 796 insert(key_type & key,mapped_type x)797 iterator insert( key_type& key, mapped_type x ) // strong 798 { 799 return insert_impl( key, x ); 800 } 801 802 template< class U > insert(const key_type & key,std::auto_ptr<U> x)803 iterator insert( const key_type& key, std::auto_ptr<U> x ) 804 { 805 return insert_impl( key, x.release() ); 806 } 807 808 template< class F, class S > insert(iterator before,ptr_container_detail::ref_pair<F,S> p)809 iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p ) // strong 810 { 811 this->enforce_null_policy( p.second, 812 "Null pointer in 'ptr_multimap_adapter::insert()'" ); 813 iterator res = insert_impl( before, p.first, 814 this->null_policy_allocate_clone( p.second ) ); 815 return res; 816 } 817 insert(iterator before,key_type & key,mapped_type x)818 iterator insert( iterator before, key_type& key, mapped_type x ) // strong 819 { 820 return insert_impl( before, key, x ); 821 } 822 823 template< class U > insert(iterator before,const key_type & key,std::auto_ptr<U> x)824 iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x ) // strong 825 { 826 return insert_impl( before, key, x.release() ); 827 } 828 829 template< class PtrMapAdapter > transfer(BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,PtrMapAdapter & from)830 void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, 831 PtrMapAdapter& from ) // strong 832 { 833 this->multi_transfer( object, from ); 834 } 835 836 template< class PtrMapAdapter > transfer(BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,PtrMapAdapter & from)837 size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, 838 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, 839 PtrMapAdapter& from ) // basic 840 { 841 return this->multi_transfer( first, last, from ); 842 } 843 844 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) 845 #else 846 847 template< class PtrMapAdapter, class Range > 848 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, 849 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >, 850 size_type >::type transfer(const Range & r,PtrMapAdapter & from)851 transfer( const Range& r, PtrMapAdapter& from ) // basic 852 { 853 return transfer( boost::begin(r), boost::end(r), from ); 854 } 855 856 #endif 857 template< class PtrMapAdapter > transfer(PtrMapAdapter & from)858 void transfer( PtrMapAdapter& from ) // basic 859 { 860 transfer( from.begin(), from.end(), from ); 861 BOOST_ASSERT( from.empty() ); 862 } 863 864 }; 865 866 template< class I, class F, class S > is_null(const ptr_map_iterator<I,F,S> & i)867 inline bool is_null( const ptr_map_iterator<I,F,S>& i ) 868 { 869 return i->second == 0; 870 } 871 872 } // namespace 'boost' 873 874 #endif 875