epoc32/include/stdapis/boost/range/iterator_range.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 // Boost.Range library
     2 //
     3 //  Copyright Thorsten Ottosen & Pavol Droba 2003-2004. Use, modification and
     4 //  distribution is subject to the Boost Software License, Version
     5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
     6 //  http://www.boost.org/LICENSE_1_0.txt)
     7 //
     8 // For more information, see http://www.boost.org/libs/range/
     9 //
    10 
    11 #ifndef BOOST_RANGE_ITERATOR_RANGE_HPP
    12 #define BOOST_RANGE_ITERATOR_RANGE_HPP
    13 
    14 // From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for Cray X1 patch.
    15 #include <boost/config.hpp> // Define __STL_CONFIG_H, if appropriate.
    16 #ifndef BOOST_OLD_IOSTREAMS 
    17 # if defined(__STL_CONFIG_H) && \
    18     !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \
    19     /**/
    20 #  define BOOST_OLD_IOSTREAMS
    21 # endif
    22 #endif // #ifndef BOOST_OLD_IOSTREAMS
    23 
    24 #include <boost/detail/workaround.hpp>
    25 #include <boost/range/functions.hpp>
    26 #include <boost/range/result_iterator.hpp>
    27 #include <boost/range/difference_type.hpp>
    28 #include <boost/iterator/iterator_traits.hpp>    
    29 #include <boost/assert.hpp>
    30 #include <iterator>
    31 #include <algorithm>
    32 #ifndef BOOST_OLD_IOSTREAMS
    33 # include <ostream>
    34 #else
    35 # include <ostream.h>
    36 #endif
    37 #include <cstddef>
    38 
    39 
    40 /*! \file
    41     Defines the \c iterator_class and related functions. 
    42     \c iterator_range is a simple wrapper of iterator pair idiom. It provides
    43     a rich subset of Container interface.
    44 */
    45 
    46 
    47 namespace boost 
    48 {
    49     namespace iterator_range_detail
    50     {
    51         //
    52         // The functions adl_begin and adl_end are implemented in a separate
    53         // class for gcc-2.9x
    54         //
    55         template<typename IteratorT>
    56         struct iterator_range_impl {
    57             template< class ForwardRange >
    58             static IteratorT adl_begin( ForwardRange& r )
    59             {
    60                 return IteratorT( boost::begin( r ) );
    61             }
    62             
    63             template< class ForwardRange >
    64             static IteratorT adl_end( ForwardRange& r )
    65             {
    66                 return IteratorT( boost::end( r ) );
    67             }
    68         };
    69  
    70         template< class Left, class Right >
    71         inline bool equal( const Left& l, const Right& r )
    72         {
    73             typedef BOOST_DEDUCED_TYPENAME boost::range_size<Left>::type sz_type;
    74 
    75             sz_type l_size = boost::size( l ),
    76                     r_size = boost::size( r );
    77 
    78             if( l_size != r_size )
    79                 return false;
    80 
    81             return std::equal( boost::begin(l), boost::end(l), 
    82                                boost::begin(r) );                
    83         }
    84 
    85         template< class Left, class Right >
    86         inline bool less_than( const Left& l, const Right& r )
    87         {                
    88             return std::lexicographical_compare( boost::begin(l), 
    89                                                  boost::end(l), 
    90                                                  boost::begin(r), 
    91                                                  boost::end(r) );                
    92         }
    93            
    94         struct range_tag { };
    95         struct const_range_tag { };
    96 
    97     }
    98 
    99 //  iterator range template class -----------------------------------------//
   100 
   101         //! iterator_range class
   102         /*!
   103             An \c iterator_range delimits a range in a sequence by beginning and ending iterators. 
   104             An iterator_range can be passed to an algorithm which requires a sequence as an input. 
   105             For example, the \c toupper() function may be used most frequently on strings, 
   106             but can also be used on iterator_ranges: 
   107             
   108             \code
   109                 boost::tolower( find( s, "UPPERCASE STRING" ) );
   110             \endcode
   111 
   112             Many algorithms working with sequences take a pair of iterators, 
   113             delimiting a working range, as an arguments. The \c iterator_range class is an 
   114             encapsulation of a range identified by a pair of iterators. 
   115             It provides a collection interface, 
   116             so it is possible to pass an instance to an algorithm requiring a collection as an input. 
   117         */
   118         template<typename IteratorT> 
   119         class iterator_range
   120         {
   121         protected: // Used by sub_range
   122             //! implementation class
   123             typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
   124         public:
   125 
   126             //! this type
   127             typedef iterator_range<IteratorT> type;
   128             //BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type);
   129         
   130             //! Encapsulated value type
   131             typedef BOOST_DEDUCED_TYPENAME 
   132                 iterator_value<IteratorT>::type value_type;
   133 
   134             //! Difference type
   135             typedef BOOST_DEDUCED_TYPENAME 
   136                 iterator_difference<IteratorT>::type difference_type;
   137             
   138             //! Size type
   139             typedef std::size_t size_type; // note: must be unsigned
   140 
   141             //! This type
   142             typedef iterator_range<IteratorT> this_type;
   143 
   144             //! Refence type
   145             //
   146             // Needed because value-type is the same for 
   147             // const and non-const iterators
   148             //
   149             typedef BOOST_DEDUCED_TYPENAME
   150                 iterator_reference<IteratorT>::type reference;
   151             
   152             //! const_iterator type
   153             /*! 
   154                 There is no distinction between const_iterator and iterator.
   155                 These typedefs are provides to fulfill container interface
   156             */ 
   157             typedef IteratorT const_iterator;
   158             //! iterator type
   159             typedef IteratorT iterator;
   160 
   161             iterator_range() : m_Begin( iterator() ), m_End( iterator() ), 
   162                                singular( true )
   163             { }
   164 /*
   165 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))  
   166             iterator_range( this_type r ) :
   167             : m_Begin(r.begin()), m_End(r.end())
   168             { }
   169 
   170             this_type& operator=( this_type r )
   171             {
   172                 m_Begin = r.begin();
   173                 m_End   = r.end();
   174                 return *this;
   175             }
   176 #endif
   177 */            
   178             //! Constructor from a pair of iterators
   179             template< class Iterator >
   180             iterator_range( Iterator Begin, Iterator End ) : 
   181                 m_Begin(Begin), m_End(End), singular(false) {}
   182 
   183             //! Constructor from a Range
   184             template< class Range >
   185             iterator_range( const Range& r ) : 
   186                 m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) ), 
   187                 singular(false) {}
   188 
   189             //! Constructor from a Range
   190             template< class Range >
   191             iterator_range( Range& r ) : 
   192                 m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) ), 
   193                 singular(false) {}
   194 
   195             //! Constructor from a Range
   196             template< class Range >
   197             iterator_range( const Range& r, iterator_range_detail::const_range_tag ) : 
   198                 m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) ), 
   199                 singular(false) {}
   200 
   201             //! Constructor from a Range
   202             template< class Range >
   203             iterator_range( Range& r, iterator_range_detail::range_tag ) : 
   204                 m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) ), 
   205                 singular(false) {}
   206 
   207             #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   208             this_type& operator=( const this_type& r )    
   209             {
   210                 m_Begin  = r.begin(); 
   211                 m_End    = r.end();
   212                 //
   213                 // remark: this need not necessarily be true, but it does no harm
   214                 //
   215                 singular = r.singular;
   216                 return *this;
   217             }
   218             #endif
   219                 
   220             template< class Iterator >
   221             iterator_range& operator=( const iterator_range<Iterator>& r )    
   222             {
   223                 m_Begin  = r.begin(); 
   224                 m_End    = r.end();
   225                 //
   226                 // remark: this need not necessarily be true, but it does no harm
   227                 //
   228                 singular = r.empty();
   229                 return *this;
   230             }
   231                                       
   232             template< class ForwardRange >
   233             iterator_range& operator=( ForwardRange& r )
   234             {
   235                 m_Begin  = impl::adl_begin( r ); 
   236                 m_End    = impl::adl_end( r );
   237                 singular = false;
   238                 return *this;
   239             }
   240 
   241             template< class ForwardRange >
   242             iterator_range& operator=( const ForwardRange& r )
   243             {
   244                 m_Begin  = impl::adl_begin( r ); 
   245                 m_End    = impl::adl_end( r );
   246                 singular = false;
   247                 return *this;
   248             }
   249 
   250             IteratorT begin() const 
   251             { 
   252                 return m_Begin; 
   253             }
   254 
   255             IteratorT end() const 
   256             { 
   257                 return m_End; 
   258             } 
   259 
   260             size_type size() const
   261             { 
   262                 if( singular )
   263                     return 0;
   264 
   265 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   266                 return std::distance<IteratorT>( m_Begin, m_End );
   267 #else                
   268                 return std::distance( m_Begin, m_End );
   269 #endif                
   270             }
   271             
   272             bool empty() const
   273             {
   274                 if( singular )
   275                     return true;
   276                 
   277                 return m_Begin == m_End;
   278             }
   279 
   280 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))  
   281             operator bool() const
   282             {
   283                 return !empty();
   284             }                                    
   285 #else            
   286             typedef iterator (iterator_range::*unspecified_bool_type) () const;
   287             operator unspecified_bool_type() const
   288             {
   289                 return empty() ? 0: &iterator_range::end;
   290             }
   291 #endif
   292 
   293             bool equal( const iterator_range& r ) const
   294             {
   295                 return singular == r.singular && m_Begin == r.m_Begin && m_End == r.m_End;
   296             }
   297 
   298 
   299 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   300 
   301             bool operator==( const iterator_range& r ) const
   302             {
   303                 return iterator_range_detail::equal( *this, r );
   304             }
   305 
   306             bool operator!=( const iterator_range& r ) const
   307             {
   308                 return !operator==(r);
   309             }
   310 
   311            bool operator<( const iterator_range& r ) const
   312            {
   313                 return iterator_range_detail::less_than( *this, r );
   314            }
   315 
   316 #endif            
   317 
   318         public: // convenience
   319            reference front() const
   320            {
   321                BOOST_ASSERT( !empty() );
   322                return *m_Begin;
   323            }
   324     
   325            reference back() const
   326            {
   327                BOOST_ASSERT( !empty() );
   328                IteratorT last( m_End );
   329                return *--last;
   330            }
   331     
   332            reference operator[]( size_type sz ) const
   333            {
   334                //BOOST_STATIC_ASSERT( is_random_access );
   335                BOOST_ASSERT( sz < size() );
   336                return m_Begin[sz];
   337            }
   338 
   339            iterator_range& advance_begin( difference_type n )
   340            {
   341                std::advance( m_Begin, n );
   342                return *this;
   343            }
   344            
   345            iterator_range& advance_end( difference_type n )
   346            {
   347                std::advance( m_End, n );
   348                return *this;
   349            }
   350            
   351         private:
   352             // begin and end iterators
   353             IteratorT m_Begin;
   354             IteratorT m_End;
   355             bool      singular;
   356         };
   357 
   358 //  iterator range free-standing operators ---------------------------//
   359 
   360 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   361 #else
   362         template< class Iterator >
   363         inline bool empty( const iterator_range<Iterator>& r )
   364         {
   365             //
   366             // this will preserve the well-defined empty() even 
   367             // though 'r' is singular.
   368             //
   369             return r.empty();
   370         }
   371 #endif
   372 
   373 #ifndef BOOST_OLD_IOSTREAMS   
   374 
   375         //! iterator_range output operator
   376         /*!
   377             Output the range to an ostream. Elements are outputed
   378             in a sequence without separators.
   379         */
   380         template< typename IteratorT, typename Elem, typename Traits >
   381         inline std::basic_ostream<Elem,Traits>& operator<<( 
   382                     std::basic_ostream<Elem, Traits>& Os,
   383                     const iterator_range<IteratorT>& r )
   384         {
   385             std::copy( r.begin(), r.end(), 
   386                        std::ostream_iterator< BOOST_DEDUCED_TYPENAME 
   387                                             iterator_value<IteratorT>::type, 
   388                                               Elem, Traits>(Os) );
   389             return Os;
   390         }
   391 
   392 #else
   393 
   394         //! iterator_range output operator
   395         /*!
   396             Output the range to an ostream. Elements are outputed
   397             in a sequence without separators.
   398         */
   399         template< typename IteratorT >
   400         inline std::ostream& operator<<( 
   401                     std::ostream& Os,
   402                     const iterator_range<IteratorT>& r )
   403         {
   404             std::copy( r.begin(), r.end(), std::ostream_iterator<char>(Os));
   405             return Os;
   406         }
   407 
   408 #endif
   409 
   410         /////////////////////////////////////////////////////////////////////
   411         // comparison operators
   412         /////////////////////////////////////////////////////////////////////
   413 
   414         template< class IteratorT, class ForwardRange >
   415         inline bool operator==( const ForwardRange& l, 
   416                                 const iterator_range<IteratorT>& r )
   417         {
   418             return iterator_range_detail::equal( l, r );
   419         }
   420 
   421         template< class IteratorT, class ForwardRange >
   422         inline bool operator!=( const ForwardRange& l, 
   423                                 const iterator_range<IteratorT>& r )
   424         {
   425             return !iterator_range_detail::equal( l, r );
   426         }
   427 
   428         template< class IteratorT, class ForwardRange >
   429         inline bool operator<( const ForwardRange& l, 
   430                                const iterator_range<IteratorT>& r )
   431         {
   432             return iterator_range_detail::less_than( l, r );
   433         }
   434 
   435 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   436 #else
   437         template< class Iterator1T, class Iterator2T >
   438         inline bool operator==( const iterator_range<Iterator1T>& l, 
   439                                 const iterator_range<Iterator2T>& r )
   440         {
   441             return iterator_range_detail::equal( l, r );
   442         }
   443 
   444         template< class IteratorT, class ForwardRange >
   445         inline bool operator==( const iterator_range<IteratorT>& l, 
   446                                 const ForwardRange& r )
   447         {
   448             return iterator_range_detail::equal( l, r );
   449         }
   450 
   451 
   452         template< class Iterator1T, class Iterator2T >
   453         inline bool operator!=( const iterator_range<Iterator1T>& l, 
   454                                 const iterator_range<Iterator2T>& r )
   455         {
   456             return !iterator_range_detail::equal( l, r );
   457         }
   458         
   459         template< class IteratorT, class ForwardRange >
   460         inline bool operator!=( const iterator_range<IteratorT>& l, 
   461                                 const ForwardRange& r )
   462         {
   463             return !iterator_range_detail::equal( l, r );
   464         }
   465 
   466         
   467         template< class Iterator1T, class Iterator2T >
   468         inline bool operator<( const iterator_range<Iterator1T>& l, 
   469                                const iterator_range<Iterator2T>& r )
   470         {
   471             return iterator_range_detail::less_than( l, r );
   472         }
   473 
   474         template< class IteratorT, class ForwardRange >
   475         inline bool operator<( const iterator_range<IteratorT>& l, 
   476                                const ForwardRange& r )
   477         {            
   478             return iterator_range_detail::less_than( l, r );
   479         }
   480 
   481 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   482                     
   483 //  iterator range utilities -----------------------------------------//
   484 
   485         //! iterator_range construct helper 
   486         /*!
   487             Construct an \c iterator_range from a pair of iterators
   488 
   489             \param Begin A begin iterator
   490             \param End An end iterator
   491             \return iterator_range object
   492         */
   493         template< typename IteratorT >
   494         inline iterator_range< IteratorT > 
   495         make_iterator_range( IteratorT Begin, IteratorT End ) 
   496         {   
   497             return iterator_range<IteratorT>( Begin, End );
   498         }
   499                      
   500 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   501 
   502         template< typename Range >
   503         inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
   504         make_iterator_range( Range& r ) 
   505         {   
   506             return iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
   507                 ( boost::begin( r ), boost::end( r ) );
   508         }
   509         
   510 #else
   511         //! iterator_range construct helper
   512         /*!
   513             Construct an \c iterator_range from a \c Range containing the begin
   514             and end iterators.
   515         */
   516         template< class ForwardRange >
   517         inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
   518         make_iterator_range( ForwardRange& r ) 
   519         {   
   520            return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
   521                 ( r, iterator_range_detail::range_tag() );
   522         }
   523 
   524         template< class ForwardRange >
   525         inline iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<ForwardRange>::type >
   526         make_iterator_range( const ForwardRange& r ) 
   527         {   
   528            return iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<ForwardRange>::type >
   529                 ( r, iterator_range_detail::const_range_tag() );
   530         }
   531 
   532 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   533 
   534         namespace iterator_range_detail
   535         {    
   536             template< class Range >
   537             inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
   538             make_range_impl( Range& r, 
   539                              BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
   540                              BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
   541             {
   542                 if( advance_begin == 0 && advance_end == 0 )
   543                     return make_iterator_range( r );
   544 
   545                 BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type 
   546                     new_begin = boost::begin( r ),
   547                     new_end   = boost::end( r );
   548                 std::advance( new_begin, advance_begin );
   549                 std::advance( new_end, advance_end );
   550                 return make_iterator_range( new_begin, new_end );
   551             }
   552         }
   553         
   554 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   555 
   556         template< class Range >
   557         inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
   558         make_iterator_range( Range& r, 
   559                     BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
   560                     BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
   561         {
   562             //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
   563             return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
   564         }
   565 
   566 #else
   567 
   568         template< class Range >
   569         inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
   570         make_iterator_range( Range& r, 
   571                     BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
   572                     BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
   573         {
   574             //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
   575             return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
   576         }
   577 
   578         template< class Range >
   579         inline iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<Range>::type >
   580         make_iterator_range( const Range& r, 
   581                     BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
   582                     BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
   583         {
   584             //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
   585             return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
   586         }
   587 
   588 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   589 
   590         //! copy a range into a sequence
   591         /*!
   592             Construct a new sequence of the specified type from the elements
   593             in the given range
   594 
   595             \param Range An input range
   596             \return New sequence
   597         */
   598         template< typename SeqT, typename Range >
   599         inline SeqT copy_range( const Range& r )
   600         {
   601             return SeqT( boost::begin( r ), boost::end( r ) );
   602         }
   603 
   604 } // namespace 'boost'
   605 
   606 #undef BOOST_OLD_IOSTREAMS
   607 
   608 #endif