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