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