Home | Libraries | People | FAQ | More |
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.
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.
operator unspecified_bool_type() const;
Returns
!empty();
bool equal( iterator_range& r ) const;
Returns
begin() == r.begin() && end() == r.end();
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) );