| Home | Libraries | People | FAQ | More

### 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) );`