Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Class iterator_range

The intention of the iterator_range class is to encapsulate two iterators so they fulfill the Forward Range concept. A few other functions are also provided for convenience.

If the template argument is not a model of Forward Traversal Iterator, one can still use a subset of the interface. In particular, size() requires Random Access Traversal Iterators whereas empty() only requires Single Pass Iterators.

Recall that many default constructed iterators are singular and hence can only be assigned, but not compared or incremented or anything. However, if one creates a default constructed iterator_range, then one can still call all its member functions. This design decision avoids the iterator_range imposing limitations upon ranges of iterators that are not singular. Any singularity limitation is simply propogated from the underlying iterator type.

Synopsis

namespace boost
{
    template< class ForwardTraversalIterator >
    class iterator_range
    {
    public: // Forward Range types
        typedef ForwardTraversalIterator   iterator;
        typedef ForwardTraversalIterator   const_iterator;
        typedef iterator_difference<iterator>::type difference_type;

    public: // construction, assignment
        template< class ForwardTraversalIterator2 >
        iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
                    
        template< class ForwardRange >
        iterator_range( ForwardRange& r );
  
        template< class ForwardRange >
        iterator_range( const ForwardRange& r );
        
        template< class ForwardRange >
        iterator_range& operator=( ForwardRange& r );

        template< class ForwardRange >
        iterator_range& operator=( const ForwardRange& r );
    
    public: // Forward Range functions
        iterator  begin() const;
        iterator  end() const;
        
    public: // convenience
        operator    unspecified_bool_type() const;
        bool        equal( const iterator_range& ) const;
        value_type& front() const;
        value_type& back() const;
        iterator_range& advance_begin(difference_type n);
        iterator_range& advance_end(difference_type n);
        bool      empty() const;
        // for Random Access Range only: 
        reference operator[]( difference_type at ) const;
        value_type operator()( difference_type at ) const;
        size_type size() const;
    };
    
    // stream output
    template< class ForwardTraversalIterator, class T, class Traits >
    std::basic_ostream<T,Traits>& 
    operator<<( std::basic_ostream<T,Traits>& Os,
                const iterator_range<ForwardTraversalIterator>& r );

    // comparison
    template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
    bool operator==( const iterator_range<ForwardTraversalIterator>& l, 
                     const iterator_range<ForwardTraversalIterator2>& r );

    template< class ForwardTraversalIterator, class ForwardRange >
    bool operator==( const iterator_range<ForwardTraversalIterator>& l, 
                     const ForwardRange& r );

    template< class ForwardTraversalIterator, class ForwardRange >
    bool operator==( const ForwardRange& l,
                     const iterator_range<ForwardTraversalIterator>& r );

    template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
    bool operator!=( const iterator_range<ForwardTraversalIterator>& l, 
                     const iterator_range<ForwardTraversalIterator2>& r );

    template< class ForwardTraversalIterator, class ForwardRange >
    bool operator!=( const iterator_range<ForwardTraversalIterator>& l, 
                     const ForwardRange& r );

    template< class ForwardTraversalIterator, class ForwardRange >
    bool operator!=( const ForwardRange& l,
                     const iterator_range<ForwardTraversalIterator>& r );

    template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
    bool operator<( const iterator_range<ForwardTraversalIterator>& l, 
                    const iterator_range<ForwardTraversalIterator2>& r );

    template< class ForwardTraversalIterator, class ForwardRange >
    bool operator<( const iterator_range<ForwardTraversalIterator>& l, 
                    const ForwardRange& r );

    template< class ForwardTraversalIterator, class ForwardRange >
    bool operator<( const ForwardRange& l,
                    const iterator_range<ForwardTraversalIterator>& r );
 
    // external construction
    template< class ForwardTraversalIterator >
    iterator_range< ForwardTraversalIterator >
    make_iterator_range( ForwardTraversalIterator Begin, 
                         ForwardTraversalIterator End );
       
    template< class ForwardRange >
    iterator_range< typename range_iterator<ForwardRange>::type >
    make_iterator_range( ForwardRange& r );

    template< class ForwardRange >
    iterator_range< typename range_iterator<const ForwardRange>::type >
    make_iterator_range( const ForwardRange& r );
    
    template< class Range >
    iterator_range< typename range_iterator<Range>::type >
    make_iterator_range( Range& r,
                         typename range_difference<Range>::type advance_begin,
                         typename range_difference<Range>::type advance_end );
    
    template< class Range >
    iterator_range< typename range_iterator<const Range>::type >
    make_iterator_range( const Range& r, 
                         typename range_difference<const Range>::type advance_begin,
                         typename range_difference<const Range>::type advance_end );
    
    // convenience
    template< class Sequence, class ForwardRange >
    Sequence copy_range( const ForwardRange& r );
    
} // namespace 'boost'

If an instance of iterator_range is constructed by a client with two iterators, the client must ensure that the two iterators delimit a valid closed-open range [begin,end).

It is worth noticing that the templated constructors and assignment operators allow conversion from iterator_range<iterator> to iterator_range<const_iterator>. Similarly, since the comparison operators have two template arguments, we can compare ranges whenever the iterators are comparable; for example when we are dealing with const and non-const iterators from the same container.

Details member functions

operator unspecified_bool_type() const;

Returns !empty();

bool equal( iterator_range& r ) const;

Returns begin() == r.begin() && end() == r.end();

Details functions

bool operator==( const ForwardRange1& l, const ForwardRange2& r );

Returns size(l) != size(r) ? false : std::equal( begin(l), end(l), begin(r) );

bool operator!=( const ForwardRange1& l, const ForwardRange2& r );

Returns !( l == r );

bool operator<( const ForwardRange1& l, const ForwardRange2& r );

Returns std::lexicographical_compare( begin(l), end(l), begin(r), end(r) );

iterator_range make_iterator_range( Range& r,
                                    typename range_difference<Range>::type advance_begin, 
                                    typename range_difference<Range>::type advance_end );

Effects:

iterator new_begin = begin( r ),
iterator new_end   = end( r );
std::advance( new_begin, advance_begin );
std::advance( new_end, advance_end );
return make_iterator_range( new_begin, new_end );

Sequence copy_range( const ForwardRange& r );

Returns Sequence( begin(r), end(r) );


PrevUpHomeNext