[29] | 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/static_assert.hpp> |
---|
| 22 | #include <boost/range/iterator_range.hpp> |
---|
| 23 | |
---|
| 24 | namespace boost |
---|
| 25 | { |
---|
| 26 | namespace ptr_container_detail |
---|
| 27 | { |
---|
| 28 | |
---|
| 29 | template |
---|
| 30 | < |
---|
| 31 | class T, |
---|
| 32 | class VoidPtrMap |
---|
| 33 | > |
---|
| 34 | struct map_config |
---|
| 35 | { |
---|
| 36 | typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type |
---|
| 37 | U; |
---|
| 38 | typedef VoidPtrMap |
---|
| 39 | void_container_type; |
---|
| 40 | |
---|
| 41 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type |
---|
| 42 | allocator_type; |
---|
| 43 | |
---|
| 44 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_compare |
---|
| 45 | key_compare; |
---|
| 46 | |
---|
| 47 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::value_compare |
---|
| 48 | value_compare; |
---|
| 49 | |
---|
| 50 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type |
---|
| 51 | key_type; |
---|
| 52 | |
---|
| 53 | typedef U value_type; |
---|
| 54 | |
---|
| 55 | typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const > |
---|
| 56 | iterator; |
---|
| 57 | |
---|
| 58 | typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const> |
---|
| 59 | const_iterator; |
---|
| 60 | |
---|
| 61 | template< class Iter > |
---|
| 62 | static U* get_pointer( Iter i ) |
---|
| 63 | { |
---|
| 64 | return i->second; |
---|
| 65 | } |
---|
| 66 | |
---|
| 67 | template< class Iter > |
---|
| 68 | static const U* get_const_pointer( Iter i ) |
---|
| 69 | { |
---|
| 70 | return i->second; |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable<T>::value ); |
---|
| 74 | }; |
---|
| 75 | |
---|
| 76 | |
---|
| 77 | |
---|
| 78 | template |
---|
| 79 | < |
---|
| 80 | class T, |
---|
| 81 | class VoidPtrMap, |
---|
| 82 | class CloneAllocator |
---|
| 83 | > |
---|
| 84 | class ptr_map_adapter_base : |
---|
| 85 | public ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap>, |
---|
| 86 | CloneAllocator > |
---|
| 87 | { |
---|
| 88 | typedef ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap>, |
---|
| 89 | CloneAllocator > |
---|
| 90 | base_type; |
---|
| 91 | |
---|
| 92 | typedef map_config<T,VoidPtrMap> config; |
---|
| 93 | |
---|
| 94 | typedef ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator> this_type; |
---|
| 95 | |
---|
| 96 | public: |
---|
| 97 | |
---|
| 98 | typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type |
---|
| 99 | allocator_type; |
---|
| 100 | typedef BOOST_DEDUCED_TYPENAME base_type::iterator |
---|
| 101 | iterator; |
---|
| 102 | typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator |
---|
| 103 | const_iterator; |
---|
| 104 | typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
---|
| 105 | size_type; |
---|
| 106 | typedef BOOST_DEDUCED_TYPENAME base_type::key_type |
---|
| 107 | key_type; |
---|
| 108 | typedef BOOST_DEDUCED_TYPENAME base_type::auto_type |
---|
| 109 | auto_type; |
---|
| 110 | typedef BOOST_DEDUCED_TYPENAME base_type::value_type |
---|
| 111 | mapped_type; |
---|
| 112 | typedef BOOST_DEDUCED_TYPENAME base_type::reference |
---|
| 113 | mapped_reference; |
---|
| 114 | typedef BOOST_DEDUCED_TYPENAME base_type::const_reference |
---|
| 115 | const_mapped_reference; |
---|
| 116 | typedef BOOST_DEDUCED_TYPENAME iterator_value<iterator>::type |
---|
| 117 | value_type; |
---|
| 118 | typedef value_type |
---|
| 119 | reference; |
---|
| 120 | typedef BOOST_DEDUCED_TYPENAME iterator_value<const_iterator>::type |
---|
| 121 | const_reference; |
---|
| 122 | typedef value_type |
---|
| 123 | pointer; |
---|
| 124 | typedef const_reference |
---|
| 125 | const_pointer; |
---|
| 126 | |
---|
| 127 | private: |
---|
| 128 | const_mapped_reference lookup( const key_type& key ) const |
---|
| 129 | { |
---|
| 130 | const_iterator i = this->find( key ); |
---|
| 131 | if( i != this->end() ) |
---|
| 132 | return *i->second; |
---|
| 133 | else |
---|
| 134 | BOOST_PTR_CONTAINER_THROW_EXCEPTION( true, bad_ptr_container_operation, |
---|
| 135 | "'ptr_map/multimap::at()' could" |
---|
| 136 | " not find key" ); |
---|
| 137 | } |
---|
| 138 | |
---|
| 139 | struct eraser // scope guard |
---|
| 140 | { |
---|
| 141 | bool released_; |
---|
| 142 | VoidPtrMap* m_; |
---|
| 143 | const key_type& key_; |
---|
| 144 | |
---|
| 145 | eraser( VoidPtrMap* m, const key_type& key ) |
---|
| 146 | : released_(false), m_(m), key_(key) |
---|
| 147 | {} |
---|
| 148 | |
---|
| 149 | ~eraser() |
---|
| 150 | { |
---|
| 151 | if( !released_ ) |
---|
| 152 | m_->erase(key_); |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | void release() { released_ = true; } |
---|
| 156 | }; |
---|
| 157 | |
---|
| 158 | mapped_reference insert_lookup( const key_type& key ) |
---|
| 159 | { |
---|
| 160 | void*& ref = this->c_private()[key]; |
---|
| 161 | if( ref ) |
---|
| 162 | { |
---|
| 163 | return *static_cast<mapped_type>(ref); |
---|
| 164 | } |
---|
| 165 | else |
---|
| 166 | { |
---|
| 167 | eraser e(&this->c_private(),key); // nothrow |
---|
| 168 | mapped_type res = new T(); // strong |
---|
| 169 | ref = res; // nothrow |
---|
| 170 | e.release(); // nothrow |
---|
| 171 | return *res; |
---|
| 172 | } |
---|
| 173 | } |
---|
| 174 | |
---|
| 175 | public: |
---|
| 176 | |
---|
| 177 | ptr_map_adapter_base( const allocator_type& a = allocator_type() ) |
---|
| 178 | : base_type(a) |
---|
| 179 | { } |
---|
| 180 | |
---|
| 181 | template< class InputIterator > |
---|
| 182 | ptr_map_adapter_base( InputIterator first, InputIterator last, |
---|
| 183 | const allocator_type& a = allocator_type() ) |
---|
| 184 | : base_type( first, last, a ) |
---|
| 185 | { } |
---|
| 186 | |
---|
| 187 | template< class Compare, class Allocator > |
---|
| 188 | explicit ptr_map_adapter_base( const Compare& comp, |
---|
| 189 | const Allocator& a ) |
---|
| 190 | : base_type( comp, a ) |
---|
| 191 | { } |
---|
| 192 | |
---|
| 193 | template< class PtrContainer > |
---|
| 194 | ptr_map_adapter_base( std::auto_ptr<PtrContainer> clone ) |
---|
| 195 | : base_type( clone ) |
---|
| 196 | { } |
---|
| 197 | |
---|
| 198 | template< typename PtrContainer > |
---|
| 199 | void operator=( std::auto_ptr<PtrContainer> clone ) |
---|
| 200 | { |
---|
| 201 | base_type::operator=( clone ); |
---|
| 202 | } |
---|
| 203 | |
---|
| 204 | iterator find( const key_type& x ) |
---|
| 205 | { |
---|
| 206 | return iterator( this->c_private().find( x ) ); |
---|
| 207 | } |
---|
| 208 | |
---|
| 209 | const_iterator find( const key_type& x ) const |
---|
| 210 | { |
---|
| 211 | return const_iterator( this->c_private().find( x ) ); |
---|
| 212 | } |
---|
| 213 | |
---|
| 214 | size_type count( const key_type& x ) const |
---|
| 215 | { |
---|
| 216 | return this->c_private().count( x ); |
---|
| 217 | } |
---|
| 218 | |
---|
| 219 | iterator lower_bound( const key_type& x ) |
---|
| 220 | { |
---|
| 221 | return iterator( this->c_private().lower_bound( x ) ); |
---|
| 222 | } |
---|
| 223 | |
---|
| 224 | const_iterator lower_bound( const key_type& x ) const |
---|
| 225 | { |
---|
| 226 | return const_iterator( this->c_private().lower_bound( x ) ); |
---|
| 227 | } |
---|
| 228 | |
---|
| 229 | iterator upper_bound( const key_type& x ) |
---|
| 230 | { |
---|
| 231 | return iterator( this->c_private().upper_bound( x ) ); |
---|
| 232 | } |
---|
| 233 | |
---|
| 234 | const_iterator upper_bound( const key_type& x ) const |
---|
| 235 | { |
---|
| 236 | return const_iterator( this->c_private().upper_bound( x ) ); |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | iterator_range<iterator> equal_range( const key_type& x ) |
---|
| 240 | { |
---|
| 241 | std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator, |
---|
| 242 | BOOST_DEDUCED_TYPENAME base_type::ptr_iterator> |
---|
| 243 | p = this->c_private().equal_range( x ); |
---|
| 244 | return make_iterator_range( iterator( p.first ), iterator( p.second ) ); |
---|
| 245 | } |
---|
| 246 | |
---|
| 247 | iterator_range<const_iterator> equal_range( const key_type& x ) const |
---|
| 248 | { |
---|
| 249 | std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator, |
---|
| 250 | BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator> |
---|
| 251 | p = this->c_private().equal_range( x ); |
---|
| 252 | return make_iterator_range( const_iterator( p.first ), |
---|
| 253 | const_iterator( p.second ) ); |
---|
| 254 | } |
---|
| 255 | |
---|
| 256 | mapped_reference at( const key_type& key ) |
---|
| 257 | { |
---|
| 258 | return const_cast<mapped_reference>( lookup( key ) ); |
---|
| 259 | } |
---|
| 260 | |
---|
| 261 | const_mapped_reference at( const key_type& key ) const |
---|
| 262 | { |
---|
| 263 | return lookup( key ); |
---|
| 264 | } |
---|
| 265 | |
---|
| 266 | mapped_reference operator[]( const key_type& key ) |
---|
| 267 | { |
---|
| 268 | return insert_lookup( key ); |
---|
| 269 | } |
---|
| 270 | |
---|
| 271 | auto_type replace( iterator where, mapped_type x ) // strong |
---|
| 272 | { |
---|
| 273 | BOOST_ASSERT( where != this->end() ); |
---|
| 274 | |
---|
| 275 | this->enforce_null_policy( x, "Null pointer in 'replace()'" ); |
---|
| 276 | |
---|
| 277 | auto_type ptr( x ); |
---|
| 278 | |
---|
| 279 | BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(), |
---|
| 280 | bad_ptr_container_operation, |
---|
| 281 | "'replace()' on empty container" ); |
---|
| 282 | |
---|
| 283 | auto_type old( where->second ); // nothrow |
---|
| 284 | where.base()->second = ptr.release(); // nothrow, commit |
---|
| 285 | return move( old ); |
---|
| 286 | } |
---|
| 287 | |
---|
| 288 | template< class U > |
---|
| 289 | auto_type replace( iterator where, std::auto_ptr<U> x ) |
---|
| 290 | { |
---|
| 291 | return replace( where, x.release() ); |
---|
| 292 | } |
---|
| 293 | |
---|
| 294 | public: // serialization |
---|
| 295 | |
---|
| 296 | template< class Archive > |
---|
| 297 | void save( Archive& ar, const unsigned ) const |
---|
| 298 | { |
---|
| 299 | ar & ptr_container_detail::serialize_as_const( this->size() ); |
---|
| 300 | |
---|
| 301 | const_iterator i = this->begin(), e = this->end(); |
---|
| 302 | for( ; i != e; ++i ) |
---|
| 303 | { |
---|
| 304 | ar & i->first; |
---|
| 305 | ar & ptr_container_detail::serialize_as_const( i->second ); |
---|
| 306 | } |
---|
| 307 | } |
---|
| 308 | }; |
---|
| 309 | |
---|
| 310 | } // ptr_container_detail |
---|
| 311 | |
---|
| 312 | ///////////////////////////////////////////////////////////////////////// |
---|
| 313 | // ptr_map_adapter |
---|
| 314 | ///////////////////////////////////////////////////////////////////////// |
---|
| 315 | |
---|
| 316 | template |
---|
| 317 | < |
---|
| 318 | class T, |
---|
| 319 | class VoidPtrMap, |
---|
| 320 | class CloneAllocator = heap_clone_allocator |
---|
| 321 | > |
---|
| 322 | class ptr_map_adapter : |
---|
| 323 | public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator> |
---|
| 324 | { |
---|
| 325 | typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator> |
---|
| 326 | base_type; |
---|
| 327 | |
---|
| 328 | public: |
---|
| 329 | typedef BOOST_DEDUCED_TYPENAME base_type::iterator |
---|
| 330 | iterator; |
---|
| 331 | typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator |
---|
| 332 | const_iterator; |
---|
| 333 | typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
---|
| 334 | size_type; |
---|
| 335 | typedef BOOST_DEDUCED_TYPENAME base_type::key_type |
---|
| 336 | key_type; |
---|
| 337 | typedef BOOST_DEDUCED_TYPENAME base_type::const_reference |
---|
| 338 | const_reference; |
---|
| 339 | typedef BOOST_DEDUCED_TYPENAME base_type::auto_type |
---|
| 340 | auto_type; |
---|
| 341 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_compare |
---|
| 342 | key_compare; |
---|
| 343 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type |
---|
| 344 | allocator_type; |
---|
| 345 | typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type |
---|
| 346 | mapped_type; |
---|
| 347 | private: |
---|
| 348 | |
---|
| 349 | void safe_insert( const key_type& key, auto_type ptr ) // strong |
---|
| 350 | { |
---|
| 351 | std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> |
---|
| 352 | res = |
---|
| 353 | this->c_private().insert( std::make_pair( key, ptr.get() ) ); // strong, commit |
---|
| 354 | if( res.second ) // nothrow |
---|
| 355 | ptr.release(); // nothrow |
---|
| 356 | } |
---|
| 357 | |
---|
| 358 | template< class II > |
---|
| 359 | void map_basic_clone_and_insert( II first, II last ) |
---|
| 360 | { |
---|
| 361 | while( first != last ) |
---|
| 362 | { |
---|
| 363 | if( this->find( first->first ) == this->end() ) |
---|
| 364 | { |
---|
| 365 | const_reference p = *first.base(); // nothrow |
---|
| 366 | auto_type ptr( this->null_policy_allocate_clone( p.second ) ); |
---|
| 367 | // strong |
---|
| 368 | this->safe_insert( p.first, ptr_container_detail:: |
---|
| 369 | move( ptr ) );// strong, commit |
---|
| 370 | } |
---|
| 371 | ++first; |
---|
| 372 | } |
---|
| 373 | } |
---|
| 374 | |
---|
| 375 | public: |
---|
| 376 | |
---|
| 377 | explicit ptr_map_adapter( const key_compare& comp = key_compare(), |
---|
| 378 | const allocator_type& a = allocator_type() ) |
---|
| 379 | : base_type( comp, a ) { } |
---|
| 380 | |
---|
| 381 | template< class InputIterator > |
---|
| 382 | ptr_map_adapter( InputIterator first, InputIterator last, |
---|
| 383 | const key_compare& comp = key_compare(), |
---|
| 384 | const allocator_type& a = allocator_type() ) |
---|
| 385 | : base_type( comp, a ) |
---|
| 386 | { |
---|
| 387 | map_basic_clone_and_insert( first, last ); |
---|
| 388 | } |
---|
| 389 | |
---|
| 390 | template< class U > |
---|
| 391 | ptr_map_adapter( std::auto_ptr<U> r ) : base_type( r ) |
---|
| 392 | { } |
---|
| 393 | |
---|
| 394 | template< class U > |
---|
| 395 | void operator=( std::auto_ptr<U> r ) |
---|
| 396 | { |
---|
| 397 | base_type::operator=( r ); |
---|
| 398 | } |
---|
| 399 | |
---|
| 400 | using base_type::release; |
---|
| 401 | |
---|
| 402 | template< typename InputIterator > |
---|
| 403 | void insert( InputIterator first, InputIterator last ) // basic |
---|
| 404 | { |
---|
| 405 | map_basic_clone_and_insert( first, last ); |
---|
| 406 | } |
---|
| 407 | |
---|
| 408 | template< class Range > |
---|
| 409 | void insert( const Range& r ) |
---|
| 410 | { |
---|
| 411 | insert( boost::begin(r), boost::end(r) ); |
---|
| 412 | } |
---|
| 413 | |
---|
| 414 | private: |
---|
| 415 | std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x ) // strong |
---|
| 416 | { |
---|
| 417 | this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" ); |
---|
| 418 | auto_type ptr( x ); // nothrow |
---|
| 419 | |
---|
| 420 | std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> |
---|
| 421 | res = this->c_private().insert( std::make_pair( key, x ) ); // strong, commit |
---|
| 422 | if( res.second ) // nothrow |
---|
| 423 | ptr.release(); // nothrow |
---|
| 424 | return std::make_pair( iterator( res.first ), res.second ); // nothrow |
---|
| 425 | } |
---|
| 426 | |
---|
| 427 | public: |
---|
| 428 | |
---|
| 429 | std::pair<iterator,bool> insert( key_type& key, mapped_type x ) |
---|
| 430 | { |
---|
| 431 | return insert_impl( key, x ); |
---|
| 432 | } |
---|
| 433 | |
---|
| 434 | template< class U > |
---|
| 435 | std::pair<iterator,bool> insert( const key_type& key, std::auto_ptr<U> x ) |
---|
| 436 | { |
---|
| 437 | return insert_impl( key, x.release() ); |
---|
| 438 | } |
---|
| 439 | |
---|
| 440 | template< class PtrMapAdapter > |
---|
| 441 | bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, |
---|
| 442 | PtrMapAdapter& from ) // strong |
---|
| 443 | { |
---|
| 444 | return this->single_transfer( object, from ); |
---|
| 445 | } |
---|
| 446 | |
---|
| 447 | template< class PtrMapAdapter > |
---|
| 448 | size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, |
---|
| 449 | BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, |
---|
| 450 | PtrMapAdapter& from ) // basic |
---|
| 451 | { |
---|
| 452 | return this->single_transfer( first, last, from ); |
---|
| 453 | } |
---|
| 454 | |
---|
| 455 | #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) |
---|
| 456 | #else |
---|
| 457 | |
---|
| 458 | template< class PtrMapAdapter, class Range > |
---|
| 459 | BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, |
---|
| 460 | BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >, |
---|
| 461 | size_type >::type |
---|
| 462 | transfer( const Range& r, PtrMapAdapter& from ) // basic |
---|
| 463 | { |
---|
| 464 | return transfer( boost::begin(r), boost::end(r), from ); |
---|
| 465 | } |
---|
| 466 | |
---|
| 467 | #endif |
---|
| 468 | |
---|
| 469 | template< class PtrMapAdapter > |
---|
| 470 | size_type transfer( PtrMapAdapter& from ) // basic |
---|
| 471 | { |
---|
| 472 | return transfer( from.begin(), from.end(), from ); |
---|
| 473 | } |
---|
| 474 | |
---|
| 475 | public: // serialization |
---|
| 476 | |
---|
| 477 | template< class Archive > |
---|
| 478 | void load( Archive& ar, const unsigned ) // strong |
---|
| 479 | { |
---|
| 480 | this->clear(); |
---|
| 481 | size_type n; |
---|
| 482 | ar & n; |
---|
| 483 | |
---|
| 484 | for( size_type i = 0u; i != n; ++i ) |
---|
| 485 | { |
---|
| 486 | key_type key; |
---|
| 487 | T* value; |
---|
| 488 | ar & key; |
---|
| 489 | ar & value; |
---|
| 490 | std::pair<iterator,bool> p = this->insert( key, value ); |
---|
| 491 | ar.reset_object_address( &p.first->first, &key ); |
---|
| 492 | } |
---|
| 493 | } |
---|
| 494 | |
---|
| 495 | BOOST_SERIALIZATION_SPLIT_MEMBER() |
---|
| 496 | |
---|
| 497 | }; |
---|
| 498 | |
---|
| 499 | ///////////////////////////////////////////////////////////////////////// |
---|
| 500 | // ptr_multimap_adapter |
---|
| 501 | ///////////////////////////////////////////////////////////////////////// |
---|
| 502 | |
---|
| 503 | template |
---|
| 504 | < |
---|
| 505 | class T, |
---|
| 506 | class VoidPtrMultiMap, |
---|
| 507 | class CloneAllocator = heap_clone_allocator |
---|
| 508 | > |
---|
| 509 | class ptr_multimap_adapter : |
---|
| 510 | public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator> |
---|
| 511 | { |
---|
| 512 | typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator> |
---|
| 513 | base_type; |
---|
| 514 | |
---|
| 515 | public: // typedefs |
---|
| 516 | typedef BOOST_DEDUCED_TYPENAME base_type::iterator |
---|
| 517 | iterator; |
---|
| 518 | typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator |
---|
| 519 | const_iterator; |
---|
| 520 | typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
---|
| 521 | size_type; |
---|
| 522 | typedef BOOST_DEDUCED_TYPENAME base_type::key_type |
---|
| 523 | key_type; |
---|
| 524 | typedef BOOST_DEDUCED_TYPENAME base_type::const_reference |
---|
| 525 | const_reference; |
---|
| 526 | typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type |
---|
| 527 | mapped_type; |
---|
| 528 | typedef BOOST_DEDUCED_TYPENAME base_type::auto_type |
---|
| 529 | auto_type; |
---|
| 530 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::key_compare |
---|
| 531 | key_compare; |
---|
| 532 | typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type |
---|
| 533 | allocator_type; |
---|
| 534 | private: |
---|
| 535 | |
---|
| 536 | void safe_insert( const key_type& key, auto_type ptr ) // strong |
---|
| 537 | { |
---|
| 538 | this->c_private().insert( |
---|
| 539 | std::make_pair( key, ptr.get() ) ); // strong, commit |
---|
| 540 | ptr.release(); // nothrow |
---|
| 541 | } |
---|
| 542 | |
---|
| 543 | template< typename II > |
---|
| 544 | void map_basic_clone_and_insert( II first, II last ) |
---|
| 545 | { |
---|
| 546 | while( first != last ) |
---|
| 547 | { |
---|
| 548 | const_reference pair = *first.base(); // nothrow |
---|
| 549 | auto_type ptr( this->null_policy_allocate_clone( pair.second ) ); |
---|
| 550 | // strong |
---|
| 551 | safe_insert( pair.first, ptr_container_detail:: |
---|
| 552 | move( ptr ) ); // strong, commit |
---|
| 553 | ++first; |
---|
| 554 | } |
---|
| 555 | } |
---|
| 556 | |
---|
| 557 | public: |
---|
| 558 | |
---|
| 559 | explicit ptr_multimap_adapter( const key_compare& comp = key_compare(), |
---|
| 560 | const allocator_type& a = allocator_type() ) |
---|
| 561 | : base_type( comp, a ) { } |
---|
| 562 | |
---|
| 563 | template< class InputIterator > |
---|
| 564 | ptr_multimap_adapter( InputIterator first, InputIterator last, |
---|
| 565 | const key_compare& comp = key_compare(), |
---|
| 566 | const allocator_type& a = allocator_type() ) |
---|
| 567 | : base_type( comp, a ) |
---|
| 568 | { |
---|
| 569 | map_basic_clone_and_insert( first, last ); |
---|
| 570 | } |
---|
| 571 | |
---|
| 572 | template< class U > |
---|
| 573 | ptr_multimap_adapter( std::auto_ptr<U> r ) : base_type( r ) |
---|
| 574 | { } |
---|
| 575 | |
---|
| 576 | template< class U > |
---|
| 577 | void operator=( std::auto_ptr<U> r ) |
---|
| 578 | { |
---|
| 579 | base_type::operator=( r ); |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | using base_type::release; |
---|
| 583 | |
---|
| 584 | template< typename InputIterator > |
---|
| 585 | void insert( InputIterator first, InputIterator last ) // basic |
---|
| 586 | { |
---|
| 587 | map_basic_clone_and_insert( first, last ); |
---|
| 588 | } |
---|
| 589 | |
---|
| 590 | template< class Range > |
---|
| 591 | void insert( const Range& r ) |
---|
| 592 | { |
---|
| 593 | insert( boost::begin(r), boost::end(r) ); |
---|
| 594 | } |
---|
| 595 | |
---|
| 596 | iterator insert( key_type& key, mapped_type x ) // strong |
---|
| 597 | { |
---|
| 598 | this->enforce_null_policy( x, |
---|
| 599 | "Null pointer in 'ptr_multimap_adapter::insert()'" ); |
---|
| 600 | |
---|
| 601 | auto_type ptr( x ); // nothrow |
---|
| 602 | BOOST_DEDUCED_TYPENAME base_type::ptr_iterator |
---|
| 603 | res = this->c_private().insert( std::make_pair( key, x ) ); |
---|
| 604 | // strong, commit |
---|
| 605 | ptr.release(); // notrow |
---|
| 606 | return iterator( res ); |
---|
| 607 | } |
---|
| 608 | |
---|
| 609 | template< class U > |
---|
| 610 | iterator insert( key_type& key, std::auto_ptr<U> x ) |
---|
| 611 | { |
---|
| 612 | return insert( key, x.release() ); |
---|
| 613 | } |
---|
| 614 | |
---|
| 615 | template< class PtrMapAdapter > |
---|
| 616 | void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, |
---|
| 617 | PtrMapAdapter& from ) // strong |
---|
| 618 | { |
---|
| 619 | this->multi_transfer( object, from ); |
---|
| 620 | } |
---|
| 621 | |
---|
| 622 | template< class PtrMapAdapter > |
---|
| 623 | size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, |
---|
| 624 | BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, |
---|
| 625 | PtrMapAdapter& from ) // basic |
---|
| 626 | { |
---|
| 627 | return this->multi_transfer( first, last, from ); |
---|
| 628 | } |
---|
| 629 | |
---|
| 630 | #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) |
---|
| 631 | #else |
---|
| 632 | |
---|
| 633 | template< class PtrMapAdapter, class Range > |
---|
| 634 | BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, |
---|
| 635 | BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >, |
---|
| 636 | size_type >::type |
---|
| 637 | transfer( const Range& r, PtrMapAdapter& from ) // basic |
---|
| 638 | { |
---|
| 639 | return transfer( boost::begin(r), boost::end(r), from ); |
---|
| 640 | } |
---|
| 641 | |
---|
| 642 | #endif |
---|
| 643 | template< class PtrMapAdapter > |
---|
| 644 | void transfer( PtrMapAdapter& from ) // basic |
---|
| 645 | { |
---|
| 646 | transfer( from.begin(), from.end(), from ); |
---|
| 647 | BOOST_ASSERT( from.empty() ); |
---|
| 648 | } |
---|
| 649 | |
---|
| 650 | public: // serialization |
---|
| 651 | |
---|
| 652 | template< class Archive > |
---|
| 653 | void load( Archive& ar, const unsigned ) // basic |
---|
| 654 | { |
---|
| 655 | this->clear(); |
---|
| 656 | size_type n; |
---|
| 657 | ar & n; |
---|
| 658 | |
---|
| 659 | for( size_type i = 0u; i != n; ++i ) |
---|
| 660 | { |
---|
| 661 | key_type key; |
---|
| 662 | T* value; |
---|
| 663 | ar & key; |
---|
| 664 | ar & value; |
---|
| 665 | iterator p = this->insert( key, value ); |
---|
| 666 | ar.reset_object_address( &p->first, &key ); |
---|
| 667 | } |
---|
| 668 | } |
---|
| 669 | |
---|
| 670 | BOOST_SERIALIZATION_SPLIT_MEMBER() |
---|
| 671 | |
---|
| 672 | }; |
---|
| 673 | |
---|
| 674 | template< class I, class F, class S > |
---|
| 675 | inline bool is_null( const ptr_map_iterator<I,F,S>& i ) |
---|
| 676 | { |
---|
| 677 | return i->second == 0; |
---|
| 678 | } |
---|
| 679 | |
---|
| 680 | } // namespace 'boost' |
---|
| 681 | |
---|
| 682 | #endif |
---|