annotate DEPENDENCIES/generic/include/boost/ptr_container/detail/reversible_ptr_container.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //
Chris@16 2 // Boost.Pointer Container
Chris@16 3 //
Chris@16 4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and
Chris@16 5 // distribution is subject to the Boost Software License, Version
Chris@16 6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // For more information, see http://www.boost.org/libs/ptr_container/
Chris@16 10 //
Chris@16 11
Chris@16 12
Chris@16 13 #ifndef BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
Chris@16 14 #define BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
Chris@16 15
Chris@16 16 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
Chris@16 17 # pragma once
Chris@16 18 #endif
Chris@16 19
Chris@16 20 #include <boost/ptr_container/detail/throw_exception.hpp>
Chris@16 21 #include <boost/ptr_container/detail/scoped_deleter.hpp>
Chris@16 22 #include <boost/ptr_container/detail/static_move_ptr.hpp>
Chris@16 23 #include <boost/ptr_container/exception.hpp>
Chris@16 24 #include <boost/ptr_container/clone_allocator.hpp>
Chris@16 25 #include <boost/ptr_container/nullable.hpp>
Chris@16 26
Chris@16 27 #ifdef BOOST_NO_SFINAE
Chris@16 28 #else
Chris@16 29 #include <boost/range/functions.hpp>
Chris@16 30 #endif
Chris@16 31
Chris@16 32 #include <boost/config.hpp>
Chris@16 33 #include <boost/iterator/reverse_iterator.hpp>
Chris@16 34 #include <boost/range/iterator.hpp>
Chris@16 35 #include <boost/utility/enable_if.hpp>
Chris@16 36 #include <boost/type_traits/is_pointer.hpp>
Chris@16 37 #include <boost/type_traits/is_integral.hpp>
Chris@16 38 #include <typeinfo>
Chris@16 39 #include <memory>
Chris@16 40
Chris@16 41 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
Chris@16 42 #pragma warning(push)
Chris@16 43 #pragma warning(disable:4127)
Chris@16 44 #endif
Chris@16 45
Chris@16 46 namespace boost
Chris@16 47 {
Chris@16 48
Chris@16 49 namespace ptr_container_detail
Chris@16 50 {
Chris@16 51 template< class CloneAllocator >
Chris@16 52 struct clone_deleter
Chris@16 53 {
Chris@16 54 template< class T >
Chris@16 55 void operator()( const T* p ) const
Chris@16 56 {
Chris@16 57 CloneAllocator::deallocate_clone( p );
Chris@16 58 }
Chris@16 59 };
Chris@16 60
Chris@16 61 template< class T >
Chris@16 62 struct is_pointer_or_integral
Chris@16 63 {
Chris@16 64 BOOST_STATIC_CONSTANT(bool, value = is_pointer<T>::value || is_integral<T>::value );
Chris@16 65 };
Chris@16 66
Chris@16 67 struct is_pointer_or_integral_tag {};
Chris@16 68 struct is_range_tag {};
Chris@16 69 struct sequence_tag {};
Chris@16 70 struct fixed_length_sequence_tag : sequence_tag {};
Chris@16 71 struct associative_container_tag {};
Chris@16 72 struct ordered_associative_container_tag : associative_container_tag {};
Chris@16 73 struct unordered_associative_container_tag : associative_container_tag {};
Chris@16 74
Chris@16 75
Chris@16 76
Chris@16 77 template
Chris@16 78 <
Chris@16 79 class Config,
Chris@16 80 class CloneAllocator
Chris@16 81 >
Chris@16 82 class reversible_ptr_container
Chris@16 83 {
Chris@16 84 private:
Chris@16 85 BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null );
Chris@16 86
Chris@16 87 typedef BOOST_DEDUCED_TYPENAME Config::value_type Ty_;
Chris@16 88
Chris@16 89 template< bool allow_null_values >
Chris@16 90 struct null_clone_allocator
Chris@16 91 {
Chris@16 92 template< class Iter >
Chris@16 93 static Ty_* allocate_clone_from_iterator( Iter i )
Chris@16 94 {
Chris@16 95 return allocate_clone( Config::get_const_pointer( i ) );
Chris@16 96 }
Chris@16 97
Chris@16 98 static Ty_* allocate_clone( const Ty_* x )
Chris@16 99 {
Chris@16 100 if( allow_null_values )
Chris@16 101 {
Chris@16 102 if( x == 0 )
Chris@16 103 return 0;
Chris@16 104 }
Chris@16 105 else
Chris@16 106 {
Chris@16 107 BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" );
Chris@16 108 }
Chris@16 109
Chris@16 110 Ty_* res = CloneAllocator::allocate_clone( *x );
Chris@16 111 BOOST_ASSERT( typeid(*res) == typeid(*x) &&
Chris@16 112 "CloneAllocator::allocate_clone() does not clone the "
Chris@16 113 "object properly. Check that new_clone() is implemented"
Chris@16 114 " correctly" );
Chris@16 115 return res;
Chris@16 116 }
Chris@16 117
Chris@16 118 static void deallocate_clone( const Ty_* x )
Chris@16 119 {
Chris@16 120 if( allow_null_values )
Chris@16 121 {
Chris@16 122 if( x == 0 )
Chris@16 123 return;
Chris@16 124 }
Chris@16 125
Chris@16 126 CloneAllocator::deallocate_clone( x );
Chris@16 127 }
Chris@16 128 };
Chris@16 129
Chris@16 130 typedef BOOST_DEDUCED_TYPENAME Config::void_container_type Cont;
Chris@16 131 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
Chris@16 132 typedef null_clone_allocator<reversible_ptr_container::allow_null>
Chris@16 133 null_cloner_type;
Chris@16 134 #else
Chris@16 135 typedef null_clone_allocator<allow_null> null_cloner_type;
Chris@16 136 #endif
Chris@16 137 typedef clone_deleter<null_cloner_type> Deleter;
Chris@16 138
Chris@16 139 Cont c_;
Chris@16 140
Chris@16 141 public:
Chris@16 142 Cont& base() { return c_; }
Chris@16 143 protected: // having this public could break encapsulation
Chris@16 144 const Cont& base() const { return c_; }
Chris@16 145
Chris@16 146 public: // typedefs
Chris@16 147 typedef Ty_* value_type;
Chris@16 148 typedef Ty_* pointer;
Chris@16 149 typedef Ty_& reference;
Chris@16 150 typedef const Ty_& const_reference;
Chris@16 151
Chris@16 152 typedef BOOST_DEDUCED_TYPENAME Config::iterator
Chris@16 153 iterator;
Chris@16 154 typedef BOOST_DEDUCED_TYPENAME Config::const_iterator
Chris@16 155 const_iterator;
Chris@16 156 typedef boost::reverse_iterator< iterator >
Chris@16 157 reverse_iterator;
Chris@16 158 typedef boost::reverse_iterator< const_iterator >
Chris@16 159 const_reverse_iterator;
Chris@16 160 typedef BOOST_DEDUCED_TYPENAME Cont::difference_type
Chris@16 161 difference_type;
Chris@16 162 typedef BOOST_DEDUCED_TYPENAME Cont::size_type
Chris@16 163 size_type;
Chris@16 164 typedef BOOST_DEDUCED_TYPENAME Config::allocator_type
Chris@16 165 allocator_type;
Chris@16 166 typedef CloneAllocator clone_allocator_type;
Chris@16 167 typedef ptr_container_detail::static_move_ptr<Ty_,Deleter>
Chris@16 168 auto_type;
Chris@16 169
Chris@16 170 protected:
Chris@16 171
Chris@16 172 typedef ptr_container_detail::scoped_deleter<Ty_,null_cloner_type>
Chris@16 173 scoped_deleter;
Chris@16 174 typedef BOOST_DEDUCED_TYPENAME Cont::iterator
Chris@16 175 ptr_iterator;
Chris@16 176 typedef BOOST_DEDUCED_TYPENAME Cont::const_iterator
Chris@16 177 ptr_const_iterator;
Chris@16 178 private:
Chris@16 179
Chris@16 180 template< class InputIterator >
Chris@16 181 void copy( InputIterator first, InputIterator last )
Chris@16 182 {
Chris@16 183 std::copy( first, last, begin() );
Chris@16 184 }
Chris@16 185
Chris@16 186 void copy( const reversible_ptr_container& r )
Chris@16 187 {
Chris@16 188 copy( r.begin(), r.end() );
Chris@16 189 }
Chris@16 190
Chris@16 191 void copy_clones_and_release( scoped_deleter& sd ) // nothrow
Chris@16 192 {
Chris@16 193 BOOST_ASSERT( size_type( std::distance( sd.begin(), sd.end() ) ) == c_.size() );
Chris@16 194 std::copy( sd.begin(), sd.end(), c_.begin() );
Chris@16 195 sd.release();
Chris@16 196 }
Chris@16 197
Chris@16 198 template< class ForwardIterator >
Chris@16 199 void clone_assign( ForwardIterator first,
Chris@16 200 ForwardIterator last ) // strong
Chris@16 201 {
Chris@16 202 BOOST_ASSERT( first != last );
Chris@16 203 scoped_deleter sd( first, last ); // strong
Chris@16 204 copy_clones_and_release( sd ); // nothrow
Chris@16 205 }
Chris@16 206
Chris@16 207 template< class ForwardIterator >
Chris@16 208 void clone_back_insert( ForwardIterator first,
Chris@16 209 ForwardIterator last )
Chris@16 210 {
Chris@16 211 BOOST_ASSERT( first != last );
Chris@16 212 scoped_deleter sd( first, last );
Chris@16 213 insert_clones_and_release( sd, end() );
Chris@16 214 }
Chris@16 215
Chris@16 216 void remove_all()
Chris@16 217 {
Chris@16 218 remove( begin(), end() );
Chris@16 219 }
Chris@16 220
Chris@16 221 protected:
Chris@16 222
Chris@16 223 void insert_clones_and_release( scoped_deleter& sd,
Chris@16 224 iterator where ) // strong
Chris@16 225 {
Chris@16 226 //
Chris@16 227 // 'c_.insert' always provides the strong guarantee for T* elements
Chris@16 228 // since a copy constructor of a pointer cannot throw
Chris@16 229 //
Chris@16 230 c_.insert( where.base(),
Chris@16 231 sd.begin(), sd.end() );
Chris@16 232 sd.release();
Chris@16 233 }
Chris@16 234
Chris@16 235 void insert_clones_and_release( scoped_deleter& sd ) // strong
Chris@16 236 {
Chris@16 237 c_.insert( sd.begin(), sd.end() );
Chris@16 238 sd.release();
Chris@16 239 }
Chris@16 240
Chris@16 241 template< class U >
Chris@16 242 void remove( U* ptr )
Chris@16 243 {
Chris@16 244 null_policy_deallocate_clone( ptr );
Chris@16 245 }
Chris@16 246
Chris@16 247 template< class I >
Chris@16 248 void remove( I i )
Chris@16 249 {
Chris@16 250 null_policy_deallocate_clone( Config::get_const_pointer(i) );
Chris@16 251 }
Chris@16 252
Chris@16 253 template< class I >
Chris@16 254 void remove( I first, I last )
Chris@16 255 {
Chris@16 256 for( ; first != last; ++first )
Chris@16 257 remove( first );
Chris@16 258 }
Chris@16 259
Chris@16 260 static void enforce_null_policy( const Ty_* x, const char* msg )
Chris@16 261 {
Chris@16 262 if( !allow_null )
Chris@16 263 {
Chris@16 264 BOOST_PTR_CONTAINER_THROW_EXCEPTION( 0 == x && "null not allowed",
Chris@16 265 bad_pointer, msg );
Chris@16 266 }
Chris@16 267 }
Chris@16 268
Chris@16 269 static Ty_* null_policy_allocate_clone( const Ty_* x )
Chris@16 270 {
Chris@16 271 return null_cloner_type::allocate_clone( x );
Chris@16 272 }
Chris@16 273
Chris@16 274 static void null_policy_deallocate_clone( const Ty_* x )
Chris@16 275 {
Chris@16 276 null_cloner_type::deallocate_clone( x );
Chris@16 277 }
Chris@16 278
Chris@16 279 private:
Chris@16 280 template< class ForwardIterator >
Chris@16 281 ForwardIterator advance( ForwardIterator begin, size_type n )
Chris@16 282 {
Chris@16 283 ForwardIterator iter = begin;
Chris@16 284 std::advance( iter, n );
Chris@16 285 return iter;
Chris@16 286 }
Chris@16 287
Chris@16 288 template< class I >
Chris@16 289 void constructor_impl( I first, I last, std::input_iterator_tag ) // basic
Chris@16 290 {
Chris@16 291 while( first != last )
Chris@16 292 {
Chris@16 293 insert( end(), null_cloner_type::allocate_clone_from_iterator(first) );
Chris@16 294 ++first;
Chris@16 295 }
Chris@16 296 }
Chris@16 297
Chris@16 298 template< class I >
Chris@16 299 void constructor_impl( I first, I last, std::forward_iterator_tag ) // strong
Chris@16 300 {
Chris@16 301 if( first == last )
Chris@16 302 return;
Chris@16 303 clone_back_insert( first, last );
Chris@16 304 }
Chris@16 305
Chris@16 306 template< class I >
Chris@16 307 void associative_constructor_impl( I first, I last ) // strong
Chris@16 308 {
Chris@16 309 if( first == last )
Chris@16 310 return;
Chris@16 311
Chris@16 312 scoped_deleter sd( first, last );
Chris@16 313 insert_clones_and_release( sd );
Chris@16 314 }
Chris@16 315
Chris@16 316 public: // foundation! should be protected!
Chris@16 317 reversible_ptr_container()
Chris@16 318 { }
Chris@16 319
Chris@16 320 template< class SizeType >
Chris@16 321 reversible_ptr_container( SizeType n, unordered_associative_container_tag )
Chris@16 322 : c_( n )
Chris@16 323 { }
Chris@16 324
Chris@16 325 template< class SizeType >
Chris@16 326 reversible_ptr_container( SizeType n, fixed_length_sequence_tag )
Chris@16 327 : c_( n )
Chris@16 328 { }
Chris@16 329
Chris@16 330 template< class SizeType >
Chris@16 331 reversible_ptr_container( SizeType n, const allocator_type& a,
Chris@16 332 fixed_length_sequence_tag )
Chris@16 333 : c_( n, a )
Chris@16 334 { }
Chris@16 335
Chris@16 336 explicit reversible_ptr_container( const allocator_type& a )
Chris@16 337 : c_( a )
Chris@16 338 { }
Chris@16 339
Chris@16 340 template< class PtrContainer >
Chris@16 341 explicit reversible_ptr_container( std::auto_ptr<PtrContainer> clone )
Chris@16 342 {
Chris@16 343 swap( *clone );
Chris@16 344 }
Chris@16 345
Chris@16 346 reversible_ptr_container( const reversible_ptr_container& r )
Chris@16 347 {
Chris@16 348 constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() );
Chris@16 349 }
Chris@16 350
Chris@16 351 template< class C, class V >
Chris@16 352 reversible_ptr_container( const reversible_ptr_container<C,V>& r )
Chris@16 353 {
Chris@16 354 constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() );
Chris@16 355 }
Chris@16 356
Chris@16 357 template< class PtrContainer >
Chris@16 358 reversible_ptr_container& operator=( std::auto_ptr<PtrContainer> clone ) // nothrow
Chris@16 359 {
Chris@16 360 swap( *clone );
Chris@16 361 return *this;
Chris@16 362 }
Chris@16 363
Chris@16 364 reversible_ptr_container& operator=( reversible_ptr_container r ) // strong
Chris@16 365 {
Chris@16 366 swap( r );
Chris@16 367 return *this;
Chris@16 368 }
Chris@16 369
Chris@16 370 // overhead: null-initilization of container pointer (very cheap compared to cloning)
Chris@16 371 // overhead: 1 heap allocation (very cheap compared to cloning)
Chris@16 372 template< class InputIterator >
Chris@16 373 reversible_ptr_container( InputIterator first,
Chris@16 374 InputIterator last,
Chris@16 375 const allocator_type& a = allocator_type() ) // basic, strong
Chris@16 376 : c_( a )
Chris@16 377 {
Chris@16 378 constructor_impl( first, last,
Chris@16 379 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
Chris@16 380 #else
Chris@16 381 BOOST_DEDUCED_TYPENAME
Chris@16 382 #endif
Chris@16 383 iterator_category<InputIterator>::type() );
Chris@16 384 }
Chris@16 385
Chris@16 386 template< class Compare >
Chris@16 387 reversible_ptr_container( const Compare& comp,
Chris@16 388 const allocator_type& a )
Chris@16 389 : c_( comp, a ) {}
Chris@16 390
Chris@16 391 template< class ForwardIterator >
Chris@16 392 reversible_ptr_container( ForwardIterator first,
Chris@16 393 ForwardIterator last,
Chris@16 394 fixed_length_sequence_tag )
Chris@16 395 : c_( std::distance(first,last) )
Chris@16 396 {
Chris@16 397 constructor_impl( first, last,
Chris@16 398 std::forward_iterator_tag() );
Chris@16 399 }
Chris@16 400
Chris@16 401 template< class SizeType, class InputIterator >
Chris@16 402 reversible_ptr_container( SizeType n,
Chris@16 403 InputIterator first,
Chris@16 404 InputIterator last,
Chris@16 405 fixed_length_sequence_tag )
Chris@16 406 : c_( n )
Chris@16 407 {
Chris@16 408 constructor_impl( first, last,
Chris@16 409 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
Chris@16 410 #else
Chris@16 411 BOOST_DEDUCED_TYPENAME
Chris@16 412 #endif
Chris@16 413 iterator_category<InputIterator>::type() );
Chris@16 414 }
Chris@16 415
Chris@16 416 template< class Compare >
Chris@16 417 reversible_ptr_container( const Compare& comp,
Chris@16 418 const allocator_type& a,
Chris@16 419 associative_container_tag )
Chris@16 420 : c_( comp, a )
Chris@16 421 { }
Chris@16 422
Chris@16 423 template< class InputIterator >
Chris@16 424 reversible_ptr_container( InputIterator first,
Chris@16 425 InputIterator last,
Chris@16 426 associative_container_tag )
Chris@16 427 {
Chris@16 428 associative_constructor_impl( first, last );
Chris@16 429 }
Chris@16 430
Chris@16 431 template< class InputIterator, class Compare >
Chris@16 432 reversible_ptr_container( InputIterator first,
Chris@16 433 InputIterator last,
Chris@16 434 const Compare& comp,
Chris@16 435 const allocator_type& a,
Chris@16 436 associative_container_tag )
Chris@16 437 : c_( comp, a )
Chris@16 438 {
Chris@16 439 associative_constructor_impl( first, last );
Chris@16 440 }
Chris@16 441
Chris@16 442 explicit reversible_ptr_container( size_type n )
Chris@16 443 : c_( n ) {}
Chris@16 444
Chris@16 445 template< class Hash, class Pred >
Chris@16 446 reversible_ptr_container( const Hash& h,
Chris@16 447 const Pred& pred,
Chris@16 448 const allocator_type& a )
Chris@16 449 : c_( h, pred, a ) {}
Chris@16 450
Chris@16 451 template< class InputIterator, class Hash, class Pred >
Chris@16 452 reversible_ptr_container( InputIterator first,
Chris@16 453 InputIterator last,
Chris@16 454 const Hash& h,
Chris@16 455 const Pred& pred,
Chris@16 456 const allocator_type& a )
Chris@16 457 : c_( h, pred, a )
Chris@16 458 {
Chris@16 459 associative_constructor_impl( first, last );
Chris@16 460 }
Chris@16 461
Chris@16 462 public:
Chris@16 463 ~reversible_ptr_container()
Chris@16 464 {
Chris@16 465 remove_all();
Chris@16 466 }
Chris@16 467
Chris@16 468 public:
Chris@16 469
Chris@16 470 allocator_type get_allocator() const
Chris@16 471 {
Chris@16 472 return c_.get_allocator();
Chris@16 473 }
Chris@16 474
Chris@16 475 public: // container requirements
Chris@16 476 iterator begin()
Chris@16 477 { return iterator( c_.begin() ); }
Chris@16 478 const_iterator begin() const
Chris@16 479 { return const_iterator( c_.begin() ); }
Chris@16 480 iterator end()
Chris@16 481 { return iterator( c_.end() ); }
Chris@16 482 const_iterator end() const
Chris@16 483 { return const_iterator( c_.end() ); }
Chris@16 484
Chris@16 485 reverse_iterator rbegin()
Chris@16 486 { return reverse_iterator( this->end() ); }
Chris@16 487 const_reverse_iterator rbegin() const
Chris@16 488 { return const_reverse_iterator( this->end() ); }
Chris@16 489 reverse_iterator rend()
Chris@16 490 { return reverse_iterator( this->begin() ); }
Chris@16 491 const_reverse_iterator rend() const
Chris@16 492 { return const_reverse_iterator( this->begin() ); }
Chris@16 493
Chris@16 494 const_iterator cbegin() const
Chris@16 495 { return const_iterator( c_.begin() ); }
Chris@16 496 const_iterator cend() const
Chris@16 497 { return const_iterator( c_.end() ); }
Chris@16 498
Chris@16 499 const_reverse_iterator crbegin() const
Chris@16 500 { return const_reverse_iterator( this->end() ); }
Chris@16 501 const_reverse_iterator crend() const
Chris@16 502 { return const_reverse_iterator( this->begin() ); }
Chris@16 503
Chris@16 504 void swap( reversible_ptr_container& r ) // nothrow
Chris@16 505 {
Chris@16 506 c_.swap( r.c_ );
Chris@16 507 }
Chris@16 508
Chris@16 509 size_type size() const // nothrow
Chris@16 510 {
Chris@16 511 return c_.size();
Chris@16 512 }
Chris@16 513
Chris@16 514 size_type max_size() const // nothrow
Chris@16 515 {
Chris@16 516 return c_.max_size();
Chris@16 517 }
Chris@16 518
Chris@16 519 bool empty() const // nothrow
Chris@16 520 {
Chris@16 521 return c_.empty();
Chris@16 522 }
Chris@16 523
Chris@16 524 public: // optional container requirements
Chris@16 525
Chris@16 526 bool operator==( const reversible_ptr_container& r ) const // nothrow
Chris@16 527 {
Chris@16 528 if( size() != r.size() )
Chris@16 529 return false;
Chris@16 530 else
Chris@16 531 return std::equal( begin(), end(), r.begin() );
Chris@16 532 }
Chris@16 533
Chris@16 534 bool operator!=( const reversible_ptr_container& r ) const // nothrow
Chris@16 535 {
Chris@16 536 return !(*this == r);
Chris@16 537 }
Chris@16 538
Chris@16 539 bool operator<( const reversible_ptr_container& r ) const // nothrow
Chris@16 540 {
Chris@16 541 return std::lexicographical_compare( begin(), end(), r.begin(), r.end() );
Chris@16 542 }
Chris@16 543
Chris@16 544 bool operator<=( const reversible_ptr_container& r ) const // nothrow
Chris@16 545 {
Chris@16 546 return !(r < *this);
Chris@16 547 }
Chris@16 548
Chris@16 549 bool operator>( const reversible_ptr_container& r ) const // nothrow
Chris@16 550 {
Chris@16 551 return r < *this;
Chris@16 552 }
Chris@16 553
Chris@16 554 bool operator>=( const reversible_ptr_container& r ) const // nothrow
Chris@16 555 {
Chris@16 556 return !(*this < r);
Chris@16 557 }
Chris@16 558
Chris@16 559 public: // modifiers
Chris@16 560
Chris@16 561 iterator insert( iterator before, Ty_* x )
Chris@16 562 {
Chris@16 563 enforce_null_policy( x, "Null pointer in 'insert()'" );
Chris@16 564
Chris@16 565 auto_type ptr( x ); // nothrow
Chris@16 566 iterator res( c_.insert( before.base(), x ) ); // strong, commit
Chris@16 567 ptr.release(); // nothrow
Chris@16 568 return res;
Chris@16 569 }
Chris@16 570
Chris@16 571 template< class U >
Chris@16 572 iterator insert( iterator before, std::auto_ptr<U> x )
Chris@16 573 {
Chris@16 574 return insert( before, x.release() );
Chris@16 575 }
Chris@16 576
Chris@16 577 iterator erase( iterator x ) // nothrow
Chris@16 578 {
Chris@16 579 BOOST_ASSERT( !empty() );
Chris@16 580 BOOST_ASSERT( x != end() );
Chris@16 581
Chris@16 582 remove( x );
Chris@16 583 return iterator( c_.erase( x.base() ) );
Chris@16 584 }
Chris@16 585
Chris@16 586 iterator erase( iterator first, iterator last ) // nothrow
Chris@16 587 {
Chris@16 588 remove( first, last );
Chris@16 589 return iterator( c_.erase( first.base(),
Chris@16 590 last.base() ) );
Chris@16 591 }
Chris@16 592
Chris@16 593 template< class Range >
Chris@16 594 iterator erase( const Range& r )
Chris@16 595 {
Chris@16 596 return erase( boost::begin(r), boost::end(r) );
Chris@16 597 }
Chris@16 598
Chris@16 599 void clear()
Chris@16 600 {
Chris@16 601 remove_all();
Chris@16 602 c_.clear();
Chris@16 603 }
Chris@16 604
Chris@16 605 public: // access interface
Chris@16 606
Chris@16 607 auto_type release( iterator where )
Chris@16 608 {
Chris@16 609 BOOST_ASSERT( where != end() );
Chris@16 610
Chris@16 611 BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
Chris@16 612 "'release()' on empty container" );
Chris@16 613
Chris@16 614 auto_type ptr( Config::get_pointer( where ) ); // nothrow
Chris@16 615 c_.erase( where.base() ); // nothrow
Chris@16 616 return boost::ptr_container_detail::move( ptr );
Chris@16 617 }
Chris@16 618
Chris@16 619 auto_type replace( iterator where, Ty_* x ) // strong
Chris@16 620 {
Chris@16 621 BOOST_ASSERT( where != end() );
Chris@16 622
Chris@16 623 enforce_null_policy( x, "Null pointer in 'replace()'" );
Chris@16 624
Chris@16 625 auto_type ptr( x );
Chris@16 626
Chris@16 627 BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
Chris@16 628 "'replace()' on empty container" );
Chris@16 629
Chris@16 630 auto_type old( Config::get_pointer( where ) ); // nothrow
Chris@16 631 const_cast<void*&>(*where.base()) = ptr.release();
Chris@16 632 return boost::ptr_container_detail::move( old );
Chris@16 633 }
Chris@16 634
Chris@16 635 template< class U >
Chris@16 636 auto_type replace( iterator where, std::auto_ptr<U> x )
Chris@16 637 {
Chris@16 638 return replace( where, x.release() );
Chris@16 639 }
Chris@16 640
Chris@16 641 auto_type replace( size_type idx, Ty_* x ) // strong
Chris@16 642 {
Chris@16 643 enforce_null_policy( x, "Null pointer in 'replace()'" );
Chris@16 644
Chris@16 645 auto_type ptr( x );
Chris@16 646
Chris@16 647 BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= size(), bad_index,
Chris@16 648 "'replace()' out of bounds" );
Chris@16 649
Chris@16 650 auto_type old( static_cast<Ty_*>( c_[idx] ) ); // nothrow
Chris@16 651 c_[idx] = ptr.release(); // nothrow, commit
Chris@16 652 return boost::ptr_container_detail::move( old );
Chris@16 653 }
Chris@16 654
Chris@16 655 template< class U >
Chris@16 656 auto_type replace( size_type idx, std::auto_ptr<U> x )
Chris@16 657 {
Chris@16 658 return replace( idx, x.release() );
Chris@16 659 }
Chris@16 660
Chris@16 661 }; // 'reversible_ptr_container'
Chris@16 662
Chris@16 663
Chris@16 664 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
Chris@16 665 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
Chris@16 666 typename base_type::auto_type \
Chris@16 667 release( typename base_type::iterator i ) \
Chris@16 668 { \
Chris@16 669 return boost::ptr_container_detail::move(base_type::release(i)); \
Chris@16 670 }
Chris@16 671 #else
Chris@16 672 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
Chris@16 673 using base_type::release;
Chris@16 674 #endif
Chris@16 675
Chris@16 676 //
Chris@16 677 // two-phase lookup of template functions
Chris@16 678 // is buggy on most compilers, so we use a macro instead
Chris@16 679 //
Chris@16 680 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type ) \
Chris@16 681 explicit PC( std::auto_ptr<this_type> r ) \
Chris@16 682 : base_type ( r ) { } \
Chris@16 683 \
Chris@16 684 PC& operator=( std::auto_ptr<this_type> r ) \
Chris@16 685 { \
Chris@16 686 base_type::operator=( r ); \
Chris@16 687 return *this; \
Chris@16 688 } \
Chris@16 689 \
Chris@16 690 std::auto_ptr<this_type> release() \
Chris@16 691 { \
Chris@16 692 std::auto_ptr<this_type> ptr( new this_type );\
Chris@16 693 this->swap( *ptr ); \
Chris@16 694 return ptr; \
Chris@16 695 } \
Chris@16 696 BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
Chris@16 697 \
Chris@16 698 std::auto_ptr<this_type> clone() const \
Chris@16 699 { \
Chris@16 700 return std::auto_ptr<this_type>( new this_type( this->begin(), this->end() ) ); \
Chris@16 701 }
Chris@16 702
Chris@16 703 #define BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type ) \
Chris@16 704 \
Chris@16 705 template< class U > \
Chris@16 706 PC( const PC<U>& r ) : base_type( r ) { } \
Chris@16 707 \
Chris@16 708 PC& operator=( PC r ) \
Chris@16 709 { \
Chris@16 710 this->swap( r ); \
Chris@16 711 return *this; \
Chris@16 712 } \
Chris@16 713
Chris@16 714
Chris@16 715 #define BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \
Chris@16 716 typedef BOOST_DEDUCED_TYPENAME base_type::iterator iterator; \
Chris@16 717 typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type; \
Chris@16 718 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference const_reference; \
Chris@16 719 typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type allocator_type; \
Chris@16 720 PC() {} \
Chris@16 721 explicit PC( const allocator_type& a ) : base_type(a) {} \
Chris@16 722 template< class InputIterator > \
Chris@16 723 PC( InputIterator first, InputIterator last ) : base_type( first, last ) {} \
Chris@16 724 template< class InputIterator > \
Chris@16 725 PC( InputIterator first, InputIterator last, \
Chris@16 726 const allocator_type& a ) : base_type( first, last, a ) {}
Chris@16 727
Chris@16 728 #define BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \
Chris@16 729 BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \
Chris@16 730 BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type )
Chris@16 731
Chris@16 732 #define BOOST_PTR_CONTAINER_DEFINE_SEQEUENCE_MEMBERS( PC, base_type, this_type ) \
Chris@16 733 BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \
Chris@16 734 BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type )
Chris@16 735
Chris@16 736 } // namespace 'ptr_container_detail'
Chris@16 737
Chris@16 738 //
Chris@16 739 // @remark: expose movability of internal move-pointer
Chris@16 740 //
Chris@16 741 namespace ptr_container
Chris@16 742 {
Chris@16 743 using ptr_container_detail::move;
Chris@16 744 }
Chris@16 745
Chris@16 746 } // namespace 'boost'
Chris@16 747
Chris@16 748 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
Chris@16 749 #pragma warning(pop)
Chris@16 750 #endif
Chris@16 751
Chris@16 752 #endif