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