ptr_sequence_adapter.hpp 25 KB

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