ptr_sequence_adapter.hpp 26 KB

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