ptr_sequence_adapter.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  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. #ifndef BOOST_PTR_CONTAINER_PTR_SEQUENCE_ADAPTER_HPP
  12. #define BOOST_PTR_CONTAINER_PTR_SEQUENCE_ADAPTER_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <boost/ptr_container/detail/reversible_ptr_container.hpp>
  17. #include <boost/ptr_container/indirect_fun.hpp>
  18. #include <boost/ptr_container/detail/void_ptr_iterator.hpp>
  19. #include <boost/type_traits/remove_pointer.hpp>
  20. #include <boost/type_traits/is_same.hpp>
  21. namespace boost
  22. {
  23. namespace ptr_container_detail
  24. {
  25. template
  26. <
  27. class T,
  28. class VoidPtrSeq
  29. >
  30. struct sequence_config
  31. {
  32. typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type
  33. U;
  34. typedef VoidPtrSeq
  35. void_container_type;
  36. typedef BOOST_DEDUCED_TYPENAME VoidPtrSeq::allocator_type
  37. allocator_type;
  38. typedef U value_type;
  39. typedef void_ptr_iterator<
  40. BOOST_DEDUCED_TYPENAME VoidPtrSeq::iterator, U >
  41. iterator;
  42. typedef void_ptr_iterator<
  43. BOOST_DEDUCED_TYPENAME VoidPtrSeq::const_iterator, const U >
  44. const_iterator;
  45. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  46. template< class Iter >
  47. static U* get_pointer( Iter i )
  48. {
  49. return static_cast<U*>( *i.base() );
  50. }
  51. #else
  52. template< class Iter >
  53. static U* get_pointer( void_ptr_iterator<Iter,U> i )
  54. {
  55. return static_cast<U*>( *i.base() );
  56. }
  57. template< class Iter >
  58. static U* get_pointer( Iter i )
  59. {
  60. return &*i;
  61. }
  62. #endif
  63. #if defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
  64. template< class Iter >
  65. static const U* get_const_pointer( Iter i )
  66. {
  67. return static_cast<const U*>( *i.base() );
  68. }
  69. #else // BOOST_NO_SFINAE
  70. #if BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
  71. template< class Iter >
  72. static const U* get_const_pointer( void_ptr_iterator<Iter,U> i )
  73. {
  74. return static_cast<const U*>( *i.base() );
  75. }
  76. #else // BOOST_WORKAROUND
  77. template< class Iter >
  78. static const U* get_const_pointer( void_ptr_iterator<Iter,const U> i )
  79. {
  80. return static_cast<const U*>( *i.base() );
  81. }
  82. #endif // BOOST_WORKAROUND
  83. template< class Iter >
  84. static const U* get_const_pointer( Iter i )
  85. {
  86. return &*i;
  87. }
  88. #endif // BOOST_NO_SFINAE
  89. BOOST_STATIC_CONSTANT(bool, allow_null = boost::is_nullable<T>::value );
  90. };
  91. } // ptr_container_detail
  92. template< class Iterator, class T >
  93. inline bool is_null( void_ptr_iterator<Iterator,T> i )
  94. {
  95. return *i.base() == 0;
  96. }
  97. template
  98. <
  99. class T,
  100. class VoidPtrSeq,
  101. class CloneAllocator = heap_clone_allocator
  102. >
  103. class ptr_sequence_adapter : public
  104. ptr_container_detail::reversible_ptr_container< ptr_container_detail::sequence_config<T,VoidPtrSeq>,
  105. CloneAllocator >
  106. {
  107. typedef ptr_container_detail::reversible_ptr_container< ptr_container_detail::sequence_config<T,VoidPtrSeq>,
  108. CloneAllocator >
  109. base_type;
  110. typedef ptr_sequence_adapter<T,VoidPtrSeq,CloneAllocator>
  111. this_type;
  112. protected:
  113. typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter scoped_deleter;
  114. public:
  115. typedef BOOST_DEDUCED_TYPENAME base_type::value_type value_type;
  116. typedef BOOST_DEDUCED_TYPENAME base_type::reference reference;
  117. typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
  118. const_reference;
  119. typedef BOOST_DEDUCED_TYPENAME base_type::auto_type auto_type;
  120. typedef BOOST_DEDUCED_TYPENAME base_type::clone_allocator_type
  121. clone_allocator_type;
  122. typedef BOOST_DEDUCED_TYPENAME base_type::iterator iterator;
  123. typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type;
  124. typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type
  125. allocator_type;
  126. ptr_sequence_adapter()
  127. { }
  128. template< class Allocator >
  129. explicit ptr_sequence_adapter( const Allocator& a )
  130. : base_type( a )
  131. { }
  132. template< class SizeType >
  133. ptr_sequence_adapter( SizeType n,
  134. ptr_container_detail::fixed_length_sequence_tag tag )
  135. : base_type( n, tag )
  136. { }
  137. template< class SizeType, class Allocator >
  138. ptr_sequence_adapter( SizeType n, const Allocator& a,
  139. ptr_container_detail::fixed_length_sequence_tag tag )
  140. : base_type( n, a, tag )
  141. { }
  142. template< class InputIterator >
  143. ptr_sequence_adapter( InputIterator first, InputIterator last )
  144. : base_type( first, last )
  145. { }
  146. template< class InputIterator, class Allocator >
  147. ptr_sequence_adapter( InputIterator first, InputIterator last,
  148. const Allocator& a )
  149. : base_type( first, last, a )
  150. { }
  151. template< class ForwardIterator >
  152. ptr_sequence_adapter( ForwardIterator first,
  153. ForwardIterator last,
  154. ptr_container_detail::fixed_length_sequence_tag tag )
  155. : base_type( first, last, tag )
  156. { }
  157. template< class SizeType, class ForwardIterator >
  158. ptr_sequence_adapter( SizeType n,
  159. ForwardIterator first,
  160. ForwardIterator last,
  161. ptr_container_detail::fixed_length_sequence_tag tag )
  162. : base_type( n, first, last, tag )
  163. { }
  164. ptr_sequence_adapter( const ptr_sequence_adapter& r )
  165. : base_type( r )
  166. { }
  167. template< class U >
  168. ptr_sequence_adapter( const ptr_sequence_adapter<U,VoidPtrSeq,CloneAllocator>& r )
  169. : base_type( r )
  170. { }
  171. ptr_sequence_adapter( const ptr_sequence_adapter& r,
  172. ptr_container_detail::fixed_length_sequence_tag tag )
  173. : base_type( r, tag )
  174. { }
  175. template< class U >
  176. ptr_sequence_adapter( const ptr_sequence_adapter<U,VoidPtrSeq,CloneAllocator>& r,
  177. ptr_container_detail::fixed_length_sequence_tag tag )
  178. : base_type( r, tag )
  179. { }
  180. template< class PtrContainer >
  181. explicit ptr_sequence_adapter( std::auto_ptr<PtrContainer> clone )
  182. : base_type( clone )
  183. { }
  184. ptr_sequence_adapter& operator=( const ptr_sequence_adapter r )
  185. {
  186. this->swap( r );
  187. return *this;
  188. }
  189. template< class PtrContainer >
  190. ptr_sequence_adapter& operator=( std::auto_ptr<PtrContainer> clone )
  191. {
  192. base_type::operator=( clone );
  193. return *this;
  194. }
  195. /////////////////////////////////////////////////////////////
  196. // modifiers
  197. /////////////////////////////////////////////////////////////
  198. void push_back( value_type x ) // strong
  199. {
  200. this->enforce_null_policy( x, "Null pointer in 'push_back()'" );
  201. auto_type ptr( x ); // notrow
  202. this->base().push_back( x ); // strong, commit
  203. ptr.release(); // nothrow
  204. }
  205. template< class U >
  206. void push_back( std::auto_ptr<U> x )
  207. {
  208. push_back( x.release() );
  209. }
  210. void push_front( value_type x )
  211. {
  212. this->enforce_null_policy( x, "Null pointer in 'push_front()'" );
  213. auto_type ptr( x ); // nothrow
  214. this->base().push_front( x ); // strong, commit
  215. ptr.release(); // nothrow
  216. }
  217. template< class U >
  218. void push_front( std::auto_ptr<U> x )
  219. {
  220. push_front( x.release() );
  221. }
  222. auto_type pop_back()
  223. {
  224. BOOST_ASSERT( !this->empty() &&
  225. "'pop_back()' on empty container" );
  226. auto_type ptr( static_cast<value_type>( this->base().back() ) );
  227. // nothrow
  228. this->base().pop_back(); // nothrow
  229. return ptr_container_detail::move( ptr ); // nothrow
  230. }
  231. auto_type pop_front()
  232. {
  233. BOOST_ASSERT( !this->empty() &&
  234. "'pop_front()' on empty container" );
  235. auto_type ptr( static_cast<value_type>( this->base().front() ) );
  236. // nothrow
  237. this->base().pop_front(); // nothrow
  238. return ptr_container_detail::move( ptr );
  239. }
  240. reference front()
  241. {
  242. BOOST_ASSERT( !this->empty() &&
  243. "accessing 'front()' on empty container" );
  244. BOOST_ASSERT( !::boost::is_null( this->begin() ) );
  245. return *this->begin();
  246. }
  247. const_reference front() const
  248. {
  249. return const_cast<ptr_sequence_adapter*>(this)->front();
  250. }
  251. reference back()
  252. {
  253. BOOST_ASSERT( !this->empty() &&
  254. "accessing 'back()' on empty container" );
  255. BOOST_ASSERT( !::boost::is_null( --this->end() ) );
  256. return *--this->end();
  257. }
  258. const_reference back() const
  259. {
  260. return const_cast<ptr_sequence_adapter*>(this)->back();
  261. }
  262. public: // deque/vector inerface
  263. reference operator[]( size_type n ) // nothrow
  264. {
  265. BOOST_ASSERT( n < this->size() );
  266. BOOST_ASSERT( !this->is_null( n ) );
  267. return *static_cast<value_type>( this->base()[n] );
  268. }
  269. const_reference operator[]( size_type n ) const // nothrow
  270. {
  271. BOOST_ASSERT( n < this->size() );
  272. BOOST_ASSERT( !this->is_null( n ) );
  273. return *static_cast<value_type>( this->base()[n] );
  274. }
  275. reference at( size_type n )
  276. {
  277. BOOST_PTR_CONTAINER_THROW_EXCEPTION( n >= this->size(), bad_index,
  278. "'at()' out of bounds" );
  279. BOOST_ASSERT( !this->is_null( n ) );
  280. return (*this)[n];
  281. }
  282. const_reference at( size_type n ) const
  283. {
  284. BOOST_PTR_CONTAINER_THROW_EXCEPTION( n >= this->size(), bad_index,
  285. "'at()' out of bounds" );
  286. BOOST_ASSERT( !this->is_null( n ) );
  287. return (*this)[n];
  288. }
  289. public: // vector interface
  290. size_type capacity() const
  291. {
  292. return this->base().capacity();
  293. }
  294. void reserve( size_type n )
  295. {
  296. this->base().reserve( n );
  297. }
  298. void reverse()
  299. {
  300. this->base().reverse();
  301. }
  302. public: // assign, insert, transfer
  303. // overhead: 1 heap allocation (very cheap compared to cloning)
  304. template< class InputIterator >
  305. void assign( InputIterator first, InputIterator last ) // strong
  306. {
  307. base_type temp( first, last );
  308. this->swap( temp );
  309. }
  310. template< class Range >
  311. void assign( const Range& r ) // strong
  312. {
  313. assign( boost::begin(r), boost::end(r ) );
  314. }
  315. private:
  316. template< class I >
  317. void insert_impl( iterator before, I first, I last, std::input_iterator_tag ) // strong
  318. {
  319. ptr_sequence_adapter temp(first,last); // strong
  320. transfer( before, temp ); // strong, commit
  321. }
  322. template< class I >
  323. void insert_impl( iterator before, I first, I last, std::forward_iterator_tag ) // strong
  324. {
  325. if( first == last )
  326. return;
  327. scoped_deleter sd( first, last ); // strong
  328. this->insert_clones_and_release( sd, before ); // strong, commit
  329. }
  330. public:
  331. using base_type::insert;
  332. template< class InputIterator >
  333. void insert( iterator before, InputIterator first, InputIterator last ) // strong
  334. {
  335. insert_impl( before, first, last, BOOST_DEDUCED_TYPENAME
  336. iterator_category<InputIterator>::type() );
  337. }
  338. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  339. #else
  340. template< class Range >
  341. BOOST_DEDUCED_TYPENAME
  342. boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
  343. insert( iterator before, const Range& r )
  344. {
  345. insert( before, boost::begin(r), boost::end(r) );
  346. }
  347. #endif
  348. template< class PtrSeqAdapter >
  349. void transfer( iterator before,
  350. BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator first,
  351. BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator last,
  352. PtrSeqAdapter& from ) // strong
  353. {
  354. BOOST_ASSERT( (void*)&from != (void*)this );
  355. if( from.empty() )
  356. return;
  357. this->base().
  358. insert( before.base(), first.base(), last.base() ); // strong
  359. from.base().erase( first.base(), last.base() ); // nothrow
  360. }
  361. template< class PtrSeqAdapter >
  362. void transfer( iterator before,
  363. BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object,
  364. PtrSeqAdapter& from ) // strong
  365. {
  366. BOOST_ASSERT( (void*)&from != (void*)this );
  367. if( from.empty() )
  368. return;
  369. this->base().insert( before.base(), *object.base() ); // strong
  370. from.base().erase( object.base() ); // nothrow
  371. }
  372. #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  373. #else
  374. template< class PtrSeqAdapter, class Range >
  375. BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
  376. BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator > >::type
  377. transfer( iterator before, const Range& r, PtrSeqAdapter& from ) // strong
  378. {
  379. transfer( before, boost::begin(r), boost::end(r), from );
  380. }
  381. #endif
  382. template< class PtrSeqAdapter >
  383. void transfer( iterator before, PtrSeqAdapter& from ) // strong
  384. {
  385. BOOST_ASSERT( (void*)&from != (void*)this );
  386. if( from.empty() )
  387. return;
  388. this->base().
  389. insert( before.base(),
  390. from.begin().base(), from.end().base() ); // strong
  391. from.base().clear(); // nothrow
  392. }
  393. public: // C-array support
  394. void transfer( iterator before, value_type* from,
  395. size_type size, bool delete_from = true ) // strong
  396. {
  397. BOOST_ASSERT( from != 0 );
  398. if( delete_from )
  399. {
  400. BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
  401. deleter( from, size ); // nothrow
  402. this->base().insert( before.base(), from, from + size ); // strong
  403. deleter.release(); // nothrow
  404. }
  405. else
  406. {
  407. this->base().insert( before.base(), from, from + size ); // strong
  408. }
  409. }
  410. value_type* c_array() // nothrow
  411. {
  412. if( this->empty() )
  413. return 0;
  414. T** res = reinterpret_cast<T**>( &this->begin().base()[0] );
  415. return res;
  416. }
  417. public: // null functions
  418. bool is_null( size_type idx ) const
  419. {
  420. BOOST_ASSERT( idx < this->size() );
  421. return this->base()[idx] == 0;
  422. }
  423. public: // resize
  424. void resize( size_type size ) // basic
  425. {
  426. size_type old_size = this->size();
  427. if( old_size > size )
  428. {
  429. this->erase( boost::next( this->begin(), size ), this->end() );
  430. }
  431. else if( size > old_size )
  432. {
  433. for( ; old_size != size; ++old_size )
  434. this->push_back( new BOOST_DEDUCED_TYPENAME
  435. boost::remove_pointer<value_type>::type() );
  436. }
  437. BOOST_ASSERT( this->size() == size );
  438. }
  439. void resize( size_type size, value_type to_clone ) // basic
  440. {
  441. size_type old_size = this->size();
  442. if( old_size > size )
  443. {
  444. this->erase( boost::next( this->begin(), size ), this->end() );
  445. }
  446. else if( size > old_size )
  447. {
  448. for( ; old_size != size; ++old_size )
  449. this->push_back( this->null_policy_allocate_clone( to_clone ) );
  450. }
  451. BOOST_ASSERT( this->size() == size );
  452. }
  453. void rresize( size_type size ) // basic
  454. {
  455. size_type old_size = this->size();
  456. if( old_size > size )
  457. {
  458. this->erase( this->begin(),
  459. boost::next( this->begin(), old_size - size ) );
  460. }
  461. else if( size > old_size )
  462. {
  463. for( ; old_size != size; ++old_size )
  464. this->push_front( new BOOST_DEDUCED_TYPENAME
  465. boost::remove_pointer<value_type>::type() );
  466. }
  467. BOOST_ASSERT( this->size() == size );
  468. }
  469. void rresize( size_type size, value_type to_clone ) // basic
  470. {
  471. size_type old_size = this->size();
  472. if( old_size > size )
  473. {
  474. this->erase( this->begin(),
  475. boost::next( this->begin(), old_size - size ) );
  476. }
  477. else if( size > old_size )
  478. {
  479. for( ; old_size != size; ++old_size )
  480. this->push_front( this->null_policy_allocate_clone( to_clone ) );
  481. }
  482. BOOST_ASSERT( this->size() == size );
  483. }
  484. public: // algorithms
  485. void sort( iterator first, iterator last )
  486. {
  487. sort( first, last, std::less<T>() );
  488. }
  489. void sort()
  490. {
  491. sort( this->begin(), this->end() );
  492. }
  493. template< class Compare >
  494. void sort( iterator first, iterator last, Compare comp )
  495. {
  496. BOOST_ASSERT( first <= last && "out of range sort()" );
  497. BOOST_ASSERT( this->begin() <= first && "out of range sort()" );
  498. BOOST_ASSERT( last <= this->end() && "out of range sort()" );
  499. // some static assert on the arguments of the comparison
  500. std::sort( first.base(), last.base(),
  501. void_ptr_indirect_fun<Compare,T>(comp) );
  502. }
  503. template< class Compare >
  504. void sort( Compare comp )
  505. {
  506. sort( this->begin(), this->end(), comp );
  507. }
  508. void unique( iterator first, iterator last )
  509. {
  510. unique( first, last, std::equal_to<T>() );
  511. }
  512. void unique()
  513. {
  514. unique( this->begin(), this->end() );
  515. }
  516. private:
  517. struct is_not_zero_ptr
  518. {
  519. template< class U >
  520. bool operator()( const U* r ) const
  521. {
  522. return r != 0;
  523. }
  524. };
  525. protected:
  526. template< class Fun, class Arg1 >
  527. class void_ptr_delete_if
  528. {
  529. Fun fun;
  530. public:
  531. void_ptr_delete_if() : fun(Fun())
  532. { }
  533. void_ptr_delete_if( Fun f ) : fun(f)
  534. { }
  535. bool operator()( void* r ) const
  536. {
  537. BOOST_ASSERT( r != 0 );
  538. Arg1 arg1 = static_cast<Arg1>(r);
  539. if( fun( *arg1 ) )
  540. {
  541. clone_allocator_type::deallocate_clone( arg1 );
  542. return true;
  543. }
  544. return false;
  545. }
  546. };
  547. private:
  548. void compact_and_erase_nulls( iterator first, iterator last ) // nothrow
  549. {
  550. typename base_type::ptr_iterator p = std::stable_partition(
  551. first.base(),
  552. last.base(),
  553. is_not_zero_ptr() );
  554. this->base().erase( p, this->end().base() );
  555. }
  556. void range_check_impl( iterator first, iterator last,
  557. std::bidirectional_iterator_tag )
  558. { /* do nothing */ }
  559. void range_check_impl( iterator first, iterator last,
  560. std::random_access_iterator_tag )
  561. {
  562. BOOST_ASSERT( first <= last && "out of range unique()/erase_if()" );
  563. BOOST_ASSERT( this->begin() <= first && "out of range unique()/erase_if()" );
  564. BOOST_ASSERT( last <= this->end() && "out of range unique()/erase_if)(" );
  565. }
  566. void range_check( iterator first, iterator last )
  567. {
  568. range_check_impl( first, last,
  569. BOOST_DEDUCED_TYPENAME iterator_category<iterator>::type() );
  570. }
  571. public:
  572. template< class Compare >
  573. void unique( iterator first, iterator last, Compare comp )
  574. {
  575. range_check(first,last);
  576. iterator prev = first;
  577. iterator next = first;
  578. ++next;
  579. for( ; next != last; ++next )
  580. {
  581. BOOST_ASSERT( !::boost::is_null(prev) );
  582. BOOST_ASSERT( !::boost::is_null(next) );
  583. if( comp( *prev, *next ) )
  584. {
  585. this->remove( next ); // delete object
  586. *next.base() = 0; // mark pointer as deleted
  587. }
  588. else
  589. {
  590. prev = next;
  591. }
  592. // ++next
  593. }
  594. compact_and_erase_nulls( first, last );
  595. }
  596. template< class Compare >
  597. void unique( Compare comp )
  598. {
  599. unique( this->begin(), this->end(), comp );
  600. }
  601. template< class Pred >
  602. void erase_if( iterator first, iterator last, Pred pred )
  603. {
  604. range_check(first,last);
  605. this->base().erase( std::remove_if( first.base(), last.base(),
  606. void_ptr_delete_if<Pred,value_type>(pred) ),
  607. last.base() );
  608. }
  609. template< class Pred >
  610. void erase_if( Pred pred )
  611. {
  612. erase_if( this->begin(), this->end(), pred );
  613. }
  614. void merge( iterator first, iterator last,
  615. ptr_sequence_adapter& from )
  616. {
  617. merge( first, last, from, std::less<T>() );
  618. }
  619. template< class BinPred >
  620. void merge( iterator first, iterator last,
  621. ptr_sequence_adapter& from, BinPred pred )
  622. {
  623. void_ptr_indirect_fun<BinPred,T> bin_pred(pred);
  624. size_type current_size = this->size();
  625. this->transfer( this->end(), first, last, from );
  626. typename base_type::ptr_iterator middle = this->begin().base();
  627. std::advance(middle,current_size);
  628. std::inplace_merge( this->begin().base(),
  629. middle,
  630. this->end().base(),
  631. bin_pred );
  632. }
  633. void merge( ptr_sequence_adapter& r )
  634. {
  635. merge( r, std::less<T>() );
  636. BOOST_ASSERT( r.empty() );
  637. }
  638. template< class BinPred >
  639. void merge( ptr_sequence_adapter& r, BinPred pred )
  640. {
  641. merge( r.begin(), r.end(), r, pred );
  642. BOOST_ASSERT( r.empty() );
  643. }
  644. };
  645. } // namespace 'boost'
  646. #endif