Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:36

0001 //
0002 // Boost.Pointer Container
0003 //
0004 //  Copyright Thorsten Ottosen 2003-2005. Use, modification and
0005 //  distribution is subject to the Boost Software License, Version
0006 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // For more information, see http://www.boost.org/libs/ptr_container/
0010 //
0011 
0012 #ifndef BOOST_PTR_CONTAINER_PTR_SEQUENCE_ADAPTER_HPP
0013 #define BOOST_PTR_CONTAINER_PTR_SEQUENCE_ADAPTER_HPP
0014 
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018 
0019 
0020 #include <boost/ptr_container/detail/reversible_ptr_container.hpp>
0021 #include <boost/ptr_container/indirect_fun.hpp>
0022 #include <boost/ptr_container/detail/void_ptr_iterator.hpp>
0023 #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
0024 #include <boost/type_traits/remove_pointer.hpp>
0025 #include <boost/type_traits/is_same.hpp>
0026 #include <boost/next_prior.hpp>
0027 
0028 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0029 #pragma GCC diagnostic push
0030 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0031 #endif
0032 
0033 namespace boost
0034 {
0035 namespace ptr_container_detail
0036 {
0037     template
0038     <
0039         class T,
0040         class VoidPtrSeq
0041     >
0042     struct sequence_config
0043     {
0044         typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type
0045                     U;
0046         typedef VoidPtrSeq
0047                     void_container_type;
0048 
0049         typedef BOOST_DEDUCED_TYPENAME VoidPtrSeq::allocator_type
0050                     allocator_type;
0051 
0052         typedef U   value_type;
0053 
0054         typedef void_ptr_iterator<
0055                         BOOST_DEDUCED_TYPENAME VoidPtrSeq::iterator, U >
0056                     iterator;
0057 
0058         typedef void_ptr_iterator<
0059                         BOOST_DEDUCED_TYPENAME VoidPtrSeq::const_iterator, const U >
0060                     const_iterator;
0061 
0062 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0063 
0064         template< class Iter >
0065         static U* get_pointer( Iter i )
0066         {
0067             return static_cast<U*>( *i.base() );
0068         }
0069 
0070 #else
0071         template< class Iter >
0072         static U* get_pointer( void_ptr_iterator<Iter,U> i )
0073         {
0074             return static_cast<U*>( *i.base() );
0075         }
0076 
0077         template< class Iter >
0078         static U* get_pointer( Iter i )
0079         {
0080             return &*i;
0081         }
0082 #endif
0083 
0084 #if defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
0085 
0086         template< class Iter >
0087         static const U* get_const_pointer( Iter i )
0088         {
0089             return static_cast<const U*>( *i.base() );
0090         }
0091 
0092 #else // BOOST_NO_SFINAE
0093 
0094         template< class Iter >
0095         static const U* get_const_pointer( void_ptr_iterator<Iter,U> i )
0096         {
0097             return static_cast<const U*>( *i.base() );
0098         }
0099 
0100         template< class Iter >
0101         static const U* get_const_pointer( Iter i )
0102         {
0103             return &*i;
0104         }
0105 
0106 #endif // BOOST_NO_SFINAE
0107 
0108         BOOST_STATIC_CONSTANT(bool, allow_null = boost::is_nullable<T>::value );
0109     };
0110 
0111 } // ptr_container_detail
0112 
0113 
0114     template< class Iterator, class T >
0115     inline bool is_null( void_ptr_iterator<Iterator,T> i )
0116     {
0117         return *i.base() == 0;
0118     }
0119 
0120 
0121 
0122     template
0123     <
0124         class T,
0125         class VoidPtrSeq,
0126         class CloneAllocator = heap_clone_allocator
0127     >
0128     class ptr_sequence_adapter : public
0129         ptr_container_detail::reversible_ptr_container< ptr_container_detail::sequence_config<T,VoidPtrSeq>,
0130                                             CloneAllocator >
0131     {
0132         typedef ptr_container_detail::reversible_ptr_container< ptr_container_detail::sequence_config<T,VoidPtrSeq>,
0133                                                     CloneAllocator >
0134              base_type;
0135 
0136         typedef ptr_sequence_adapter<T,VoidPtrSeq,CloneAllocator>
0137             this_type;
0138 
0139     protected:
0140         typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter scoped_deleter;
0141 
0142     public:
0143         typedef BOOST_DEDUCED_TYPENAME base_type::value_type  value_type;
0144         typedef BOOST_DEDUCED_TYPENAME base_type::reference   reference;
0145         typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0146                                                               const_reference;
0147         typedef BOOST_DEDUCED_TYPENAME base_type::auto_type   auto_type;
0148         typedef BOOST_DEDUCED_TYPENAME base_type::clone_allocator_type
0149                                                               clone_allocator_type;
0150         typedef BOOST_DEDUCED_TYPENAME base_type::iterator    iterator;
0151         typedef BOOST_DEDUCED_TYPENAME base_type::size_type   size_type;
0152         typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type
0153                                                               allocator_type;
0154 
0155         ptr_sequence_adapter()
0156         { }
0157 
0158         template< class Allocator >
0159         explicit ptr_sequence_adapter( const Allocator& a )
0160           : base_type( a )
0161         { }
0162 
0163         template< class SizeType >
0164         ptr_sequence_adapter( SizeType n,
0165                               ptr_container_detail::fixed_length_sequence_tag tag )
0166           : base_type( n, tag )
0167         { }
0168 
0169         template< class SizeType, class Allocator >
0170         ptr_sequence_adapter( SizeType n, const Allocator& a,
0171                               ptr_container_detail::fixed_length_sequence_tag tag )
0172           : base_type( n, a, tag )
0173         { }
0174 
0175         template< class InputIterator >
0176         ptr_sequence_adapter( InputIterator first, InputIterator last )
0177           : base_type( first, last )
0178         { }
0179 
0180         template< class InputIterator, class Allocator >
0181         ptr_sequence_adapter( InputIterator first, InputIterator last,
0182                               const Allocator& a )
0183           : base_type( first, last, a )
0184         { }
0185 
0186         template< class ForwardIterator >
0187         ptr_sequence_adapter( ForwardIterator first,
0188                               ForwardIterator last,
0189                               ptr_container_detail::fixed_length_sequence_tag tag )
0190           : base_type( first, last,  tag )
0191         { }
0192 
0193         template< class SizeType, class ForwardIterator >
0194         ptr_sequence_adapter( SizeType n,
0195                               ForwardIterator first,
0196                               ForwardIterator last,
0197                               ptr_container_detail::fixed_length_sequence_tag tag )
0198           : base_type( n, first, last,  tag )
0199         { }
0200 
0201         ptr_sequence_adapter( const ptr_sequence_adapter& r )
0202           : base_type( r )
0203         { }
0204 
0205         template< class U >
0206         ptr_sequence_adapter( const ptr_sequence_adapter<U,VoidPtrSeq,CloneAllocator>& r )
0207           : base_type( r )
0208         { }
0209 
0210         ptr_sequence_adapter( const ptr_sequence_adapter& r,
0211                               ptr_container_detail::fixed_length_sequence_tag tag )
0212           : base_type( r, tag )
0213         { }
0214 
0215         template< class U >
0216         ptr_sequence_adapter( const ptr_sequence_adapter<U,VoidPtrSeq,CloneAllocator>& r,
0217                               ptr_container_detail::fixed_length_sequence_tag tag )
0218           : base_type( r, tag )
0219         { }
0220 
0221 #ifndef BOOST_NO_AUTO_PTR
0222         template< class PtrContainer >
0223         explicit ptr_sequence_adapter( std::auto_ptr<PtrContainer> clone )
0224           : base_type( clone )
0225         { }
0226 #endif
0227 #ifndef BOOST_NO_CXX11_SMART_PTR
0228         template< class PtrContainer >
0229         explicit ptr_sequence_adapter( std::unique_ptr<PtrContainer> clone )
0230           : base_type( std::move( clone ) )
0231         { }
0232 #endif
0233 
0234         ptr_sequence_adapter& operator=( const ptr_sequence_adapter r )
0235         {
0236             this->swap( r );
0237             return *this;
0238         }
0239 
0240 #ifndef BOOST_NO_AUTO_PTR
0241         template< class PtrContainer >
0242         ptr_sequence_adapter& operator=( std::auto_ptr<PtrContainer> clone )
0243         {
0244             base_type::operator=( clone );
0245             return *this;
0246         }
0247 #endif
0248 #ifndef BOOST_NO_CXX11_SMART_PTR
0249         template< class PtrContainer >
0250         ptr_sequence_adapter& operator=( std::unique_ptr<PtrContainer> clone )
0251         {
0252             base_type::operator=( std::move( clone ) );
0253             return *this;
0254         }
0255 #endif
0256 
0257         /////////////////////////////////////////////////////////////
0258         // modifiers
0259         /////////////////////////////////////////////////////////////
0260 
0261         void push_back( value_type x )  // strong
0262         {
0263             this->enforce_null_policy( x, "Null pointer in 'push_back()'" );
0264             auto_type ptr( x, *this );    // notrow
0265             this->base().push_back( x );  // strong, commit
0266             ptr.release();                // nothrow
0267         }
0268 
0269 #ifndef BOOST_NO_AUTO_PTR
0270         template< class U >
0271         void push_back( std::auto_ptr<U> x )
0272         {
0273             push_back( x.release() );
0274         }
0275 #endif
0276 #ifndef BOOST_NO_CXX11_SMART_PTR
0277         template< class U >
0278         void push_back( std::unique_ptr<U> x )
0279         {
0280             push_back( x.release() );
0281         }
0282 #endif
0283 
0284         void push_front( value_type x )
0285         {
0286             this->enforce_null_policy( x, "Null pointer in 'push_front()'" );
0287             auto_type ptr( x, *this );    // nothrow
0288             this->base().push_front( x ); // strong, commit
0289             ptr.release();                // nothrow
0290         }
0291 
0292 #ifndef BOOST_NO_AUTO_PTR
0293         template< class U >
0294         void push_front( std::auto_ptr<U> x )
0295         {
0296             push_front( x.release() );
0297         }
0298 #endif
0299 #ifndef BOOST_NO_CXX11_SMART_PTR
0300         template< class U >
0301         void push_front( std::unique_ptr<U> x )
0302         {
0303             push_front( x.release() );
0304         }
0305 #endif
0306 
0307         auto_type pop_back()
0308         {
0309             BOOST_ASSERT( !this->empty() &&
0310                           "'pop_back()' on empty container" );
0311             auto_type ptr( static_cast<value_type>(this->base().back()), *this );
0312                                                        // nothrow
0313             this->base().pop_back();                   // nothrow
0314             return ptr_container_detail::move( ptr );  // nothrow
0315         }
0316 
0317         auto_type pop_front()
0318         {
0319             BOOST_ASSERT( !this->empty() &&
0320                           "'pop_front()' on empty container" );
0321             auto_type ptr( static_cast<value_type>(this->base().front()), *this );
0322                                          // nothrow
0323             this->base().pop_front();    // nothrow
0324             return ptr_container_detail::move( ptr );
0325         }
0326 
0327         reference front()
0328         {
0329             BOOST_ASSERT( !this->empty() &&
0330                           "accessing 'front()' on empty container" );
0331 
0332             BOOST_ASSERT( !::boost::is_null( this->begin() ) );
0333             return *this->begin();
0334         }
0335 
0336         const_reference front() const
0337         {
0338             return const_cast<ptr_sequence_adapter*>(this)->front();
0339         }
0340 
0341         reference back()
0342         {
0343             BOOST_ASSERT( !this->empty() &&
0344                           "accessing 'back()' on empty container" );
0345             BOOST_ASSERT( !::boost::is_null( --this->end() ) );
0346             return *--this->end();
0347         }
0348 
0349         const_reference back() const
0350         {
0351             return const_cast<ptr_sequence_adapter*>(this)->back();
0352         }
0353 
0354     public: // deque/vector inerface
0355 
0356         reference operator[]( size_type n ) // nothrow
0357         {
0358             BOOST_ASSERT( n < this->size() );
0359             BOOST_ASSERT( !this->is_null( n ) );
0360             return *static_cast<value_type>( this->base()[n] );
0361         }
0362 
0363         const_reference operator[]( size_type n ) const // nothrow
0364         {
0365             BOOST_ASSERT( n < this->size() );
0366             BOOST_ASSERT( !this->is_null( n ) );
0367             return *static_cast<value_type>( this->base()[n] );
0368         }
0369 
0370         reference at( size_type n )
0371         {
0372             BOOST_PTR_CONTAINER_THROW_EXCEPTION( n >= this->size(), bad_index,
0373                                                  "'at()' out of bounds" );
0374             BOOST_ASSERT( !this->is_null( n ) );
0375             return (*this)[n];
0376         }
0377 
0378         const_reference at( size_type n ) const
0379         {
0380             BOOST_PTR_CONTAINER_THROW_EXCEPTION( n >= this->size(), bad_index,
0381                                                  "'at()' out of bounds" );
0382             BOOST_ASSERT( !this->is_null( n ) );
0383             return (*this)[n];
0384         }
0385 
0386     public: // vector interface
0387 
0388         size_type capacity() const
0389         {
0390             return this->base().capacity();
0391         }
0392 
0393         void reserve( size_type n )
0394         {
0395             this->base().reserve( n );
0396         }
0397 
0398         void reverse()
0399         {
0400             this->base().reverse();
0401         }
0402 
0403     public: // assign, insert, transfer
0404 
0405         // overhead: 1 heap allocation (very cheap compared to cloning)
0406         template< class InputIterator >
0407         void assign( InputIterator first, InputIterator last ) // strong
0408         {
0409             base_type temp( first, last );
0410             this->swap( temp );
0411         }
0412 
0413         template< class Range >
0414         void assign( const Range& r ) // strong
0415         {
0416             assign( boost::begin(r), boost::end(r ) );
0417         }
0418 
0419     private:
0420         template< class I >
0421         void insert_impl( iterator before, I first, I last, std::input_iterator_tag ) // strong
0422         {
0423             ptr_sequence_adapter temp(first,last);  // strong
0424             transfer( before, temp );               // strong, commit
0425         }
0426 
0427         template< class I >
0428         void insert_impl( iterator before, I first, I last, std::forward_iterator_tag ) // strong
0429         {
0430             if( first == last )
0431                 return;
0432             scoped_deleter sd( *this, first, last );         // strong
0433             this->insert_clones_and_release( sd, before );   // strong, commit
0434         }
0435 
0436     public:
0437 
0438         using base_type::insert;
0439 
0440         template< class InputIterator >
0441         void insert( iterator before, InputIterator first, InputIterator last ) // strong
0442         {
0443             insert_impl( before, first, last, BOOST_DEDUCED_TYPENAME
0444                          iterator_category<InputIterator>::type() );
0445         }
0446 
0447 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0448 #else
0449         template< class Range >
0450         BOOST_DEDUCED_TYPENAME
0451         boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
0452         insert( iterator before, const Range& r )
0453         {
0454             insert( before, boost::begin(r), boost::end(r) );
0455         }
0456 
0457 #endif
0458 
0459         template< class PtrSeqAdapter >
0460         void transfer( iterator before,
0461                        BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator first,
0462                        BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator last,
0463                        PtrSeqAdapter& from ) // strong
0464         {
0465             BOOST_ASSERT( (void*)&from != (void*)this );
0466             if( from.empty() )
0467                 return;
0468             this->base().
0469                 insert( before.base(), first.base(), last.base() ); // strong
0470             from.base().erase( first.base(), last.base() );         // nothrow
0471         }
0472 
0473         template< class PtrSeqAdapter >
0474         void transfer( iterator before,
0475                        BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object,
0476                        PtrSeqAdapter& from ) // strong
0477         {
0478             BOOST_ASSERT( (void*)&from != (void*)this );
0479             if( from.empty() )
0480                 return;
0481             this->base().insert( before.base(), *object.base() ); // strong
0482             from.base().erase( object.base() );                  // nothrow
0483         }
0484 
0485 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0486 #else
0487 
0488         template< class PtrSeqAdapter, class Range >
0489         BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
0490                       BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator > >::type
0491         transfer( iterator before, const Range& r, PtrSeqAdapter& from ) // strong
0492         {
0493             transfer( before, boost::begin(r), boost::end(r), from );
0494         }
0495 
0496 #endif
0497         template< class PtrSeqAdapter >
0498         void transfer( iterator before, PtrSeqAdapter& from ) // strong
0499         {
0500             BOOST_ASSERT( (void*)&from != (void*)this );
0501             if( from.empty() )
0502                 return;
0503             this->base().
0504                 insert( before.base(),
0505                         from.begin().base(), from.end().base() ); // strong
0506             from.base().clear();                                  // nothrow
0507         }
0508 
0509     public: // C-array support
0510 
0511         void transfer( iterator before, value_type* from,
0512                        size_type size, bool delete_from = true ) // strong
0513         {
0514             BOOST_ASSERT( from != 0 );
0515             if( delete_from )
0516             {
0517                 BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
0518                     deleter( *this, from, size );                         // nothrow
0519                 this->base().insert( before.base(), from, from + size );  // strong
0520                 deleter.release();                                        // nothrow
0521             }
0522             else
0523             {
0524                 this->base().insert( before.base(), from, from + size ); // strong
0525             }
0526         }
0527 
0528         value_type* c_array() // nothrow
0529         {
0530             if( this->empty() )
0531                 return 0;
0532             T** res = reinterpret_cast<T**>( &this->begin().base()[0] );
0533             return res;
0534         }
0535 
0536     public: // null functions
0537 
0538         bool is_null( size_type idx ) const
0539         {
0540             BOOST_ASSERT( idx < this->size() );
0541             return this->base()[idx] == 0;
0542         }
0543 
0544     public: // resize
0545 
0546         void resize( size_type size ) // basic
0547         {
0548             size_type old_size = this->size();
0549             if( old_size > size )
0550             {
0551                 this->erase( boost::next( this->begin(), size ), this->end() );
0552             }
0553             else if( size > old_size )
0554             {
0555                 for( ; old_size != size; ++old_size )
0556                     this->push_back( new BOOST_DEDUCED_TYPENAME
0557                                      boost::remove_pointer<value_type>::type() );
0558             }
0559 
0560             BOOST_ASSERT( this->size() == size );
0561         }
0562 
0563         void resize( size_type size, value_type to_clone ) // basic
0564         {
0565             size_type old_size = this->size();
0566             if( old_size > size )
0567             {
0568                 this->erase( boost::next( this->begin(), size ), this->end() );
0569             }
0570             else if( size > old_size )
0571             {
0572                 for( ; old_size != size; ++old_size )
0573                     this->push_back( this->null_policy_allocate_clone( to_clone ) );
0574             }
0575 
0576             BOOST_ASSERT( this->size() == size );
0577         }
0578 
0579         void rresize( size_type size ) // basic
0580         {
0581             size_type old_size = this->size();
0582             if( old_size > size )
0583             {
0584                 this->erase( this->begin(),
0585                              boost::next( this->begin(), old_size - size ) );
0586             }
0587             else if( size > old_size )
0588             {
0589                 for( ; old_size != size; ++old_size )
0590                     this->push_front( new BOOST_DEDUCED_TYPENAME
0591                                       boost::remove_pointer<value_type>::type() );
0592             }
0593 
0594             BOOST_ASSERT( this->size() == size );
0595         }
0596 
0597         void rresize( size_type size, value_type to_clone ) // basic
0598         {
0599             size_type old_size = this->size();
0600             if( old_size > size )
0601             {
0602                 this->erase( this->begin(),
0603                              boost::next( this->begin(), old_size - size ) );
0604             }
0605             else if( size > old_size )
0606             {
0607                 for( ; old_size != size; ++old_size )
0608                     this->push_front( this->null_policy_allocate_clone( to_clone ) );
0609             }
0610 
0611             BOOST_ASSERT( this->size() == size );
0612         }
0613 
0614     public: // algorithms
0615 
0616         void sort( iterator first, iterator last )
0617         {
0618             sort( first, last, std::less<T>() );
0619         }
0620 
0621         void sort()
0622         {
0623             sort( this->begin(), this->end() );
0624         }
0625 
0626         template< class Compare >
0627         void sort( iterator first, iterator last, Compare comp )
0628         {
0629             BOOST_ASSERT( first <= last && "out of range sort()" );
0630             BOOST_ASSERT( this->begin() <= first && "out of range sort()" );
0631             BOOST_ASSERT( last <= this->end() && "out of range sort()" );
0632             // some static assert on the arguments of the comparison
0633             std::sort( first.base(), last.base(),
0634                        void_ptr_indirect_fun<Compare,T>(comp) );
0635         }
0636 
0637         template< class Compare >
0638         void sort( Compare comp )
0639         {
0640             sort( this->begin(), this->end(), comp );
0641         }
0642 
0643         void unique( iterator first, iterator last )
0644         {
0645             unique( first, last, std::equal_to<T>() );
0646         }
0647 
0648         void unique()
0649         {
0650             unique( this->begin(), this->end() );
0651         }
0652 
0653     private:
0654         struct is_not_zero_ptr
0655         {
0656             template< class U >
0657             bool operator()( const U* r ) const
0658             {
0659                 return r != 0;
0660             }
0661         };
0662 
0663     protected:
0664         template< class Fun, class Arg1 >
0665         class void_ptr_delete_if
0666         {
0667             Fun fun;
0668         public:
0669 
0670             void_ptr_delete_if() : fun(Fun())
0671             { }
0672 
0673             void_ptr_delete_if( Fun f ) : fun(f)
0674             { }
0675 
0676             bool operator()( void* r ) const
0677             {
0678                BOOST_ASSERT( r != 0 );
0679                Arg1 arg1 = static_cast<Arg1>(r);
0680                if( fun( *arg1 ) )
0681                {
0682                    clone_allocator_type::deallocate_clone( arg1 );
0683                    return true;
0684                }
0685                return false;
0686             }
0687         };
0688 
0689     private:
0690         void compact_and_erase_nulls( iterator first, iterator last ) // nothrow
0691         {
0692             typename base_type::ptr_iterator p = std::stable_partition(
0693                                                     first.base(),
0694                                                     last.base(),
0695                                                     is_not_zero_ptr() );
0696             this->base().erase( p, this->end().base() );
0697 
0698         }
0699 
0700         void range_check_impl( iterator, iterator,
0701                                std::bidirectional_iterator_tag )
0702         { /* do nothing */ }
0703 
0704         void range_check_impl( iterator first, iterator last,
0705                                std::random_access_iterator_tag )
0706         {
0707             BOOST_ASSERT( first <= last && "out of range unique()/erase_if()" );
0708             BOOST_ASSERT( this->begin() <= first && "out of range unique()/erase_if()" );
0709             BOOST_ASSERT( last <= this->end() && "out of range unique()/erase_if)(" );
0710         }
0711 
0712         void range_check( iterator first, iterator last )
0713         {
0714             range_check_impl( first, last,
0715                               BOOST_DEDUCED_TYPENAME iterator_category<iterator>::type() );
0716         }
0717 
0718     public:
0719 
0720         template< class Compare >
0721         void unique( iterator first, iterator last, Compare comp )
0722         {
0723             range_check(first,last);
0724 
0725             iterator prev = first;
0726             iterator next = first;
0727             ++next;
0728             for( ; next != last; ++next )
0729             {
0730                 BOOST_ASSERT( !::boost::is_null(prev) );
0731                 BOOST_ASSERT( !::boost::is_null(next) );
0732                 if( comp( *prev, *next ) )
0733                 {
0734                     this->remove( next ); // delete object
0735                     *next.base() = 0;     // mark pointer as deleted
0736                 }
0737                 else
0738                 {
0739                     prev = next;
0740                 }
0741                 // ++next
0742             }
0743 
0744             compact_and_erase_nulls( first, last );
0745         }
0746 
0747         template< class Compare >
0748         void unique( Compare comp )
0749         {
0750             unique( this->begin(), this->end(), comp );
0751         }
0752 
0753         template< class Pred >
0754         void erase_if( iterator first, iterator last, Pred pred )
0755         {
0756             range_check(first,last);
0757             this->base().erase( std::remove_if( first.base(), last.base(),
0758                                                 void_ptr_delete_if<Pred,value_type>(pred) ),
0759                                 last.base() );
0760         }
0761 
0762         template< class Pred >
0763         void erase_if( Pred pred )
0764         {
0765             erase_if( this->begin(), this->end(), pred );
0766         }
0767 
0768 
0769         void merge( iterator first, iterator last,
0770                     ptr_sequence_adapter& from )
0771         {
0772              merge( first, last, from, std::less<T>() );
0773         }
0774 
0775         template< class BinPred >
0776         void merge( iterator first, iterator last,
0777                     ptr_sequence_adapter& from, BinPred pred )
0778         {
0779             void_ptr_indirect_fun<BinPred,T>  bin_pred(pred);
0780             size_type                         current_size = this->size();
0781             this->transfer( this->end(), first, last, from );
0782             typename base_type::ptr_iterator middle = this->begin().base();
0783             std::advance(middle,current_size);
0784             std::inplace_merge( this->begin().base(),
0785                                 middle,
0786                                 this->end().base(),
0787                                 bin_pred );
0788         }
0789 
0790         void merge( ptr_sequence_adapter& r )
0791         {
0792             merge( r, std::less<T>() );
0793             BOOST_ASSERT( r.empty() );
0794         }
0795 
0796         template< class BinPred >
0797         void merge( ptr_sequence_adapter& r, BinPred pred )
0798         {
0799             merge( r.begin(), r.end(), r, pred );
0800             BOOST_ASSERT( r.empty() );
0801         }
0802 
0803     };
0804 
0805 
0806 } // namespace 'boost'
0807 
0808 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0809 #pragma GCC diagnostic pop
0810 #endif
0811 
0812 #endif