forked from boostorg/range
added discussion on extension mechanism
[SVN r30854]
This commit is contained in:
1012
doc/boost_range.html
1012
doc/boost_range.html
File diff suppressed because it is too large
Load Diff
125
doc/example.cpp
Normal file
125
doc/example.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include <boost/range.hpp>
|
||||||
|
#include <iterator> // for std::iterator_traits, std::distance()
|
||||||
|
|
||||||
|
namespace Foo
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Our sample UDT. A 'Pair'
|
||||||
|
// will work as a range when the stored
|
||||||
|
// elements are iterators.
|
||||||
|
//
|
||||||
|
template< class T >
|
||||||
|
struct Pair
|
||||||
|
{
|
||||||
|
T first, last;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace 'Foo'
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Specialize metafunctions. We must include the range.hpp header.
|
||||||
|
// We must open the 'boost' namespace.
|
||||||
|
//
|
||||||
|
template< class T >
|
||||||
|
struct range_value< Foo::Pair<T> >
|
||||||
|
{
|
||||||
|
typedef typename std::iterator_traits<T>::value_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct range_iterator< Foo::Pair<T> >
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct range_const_iterator< Foo::Pair<T> >
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Remark: this is defined similar to 'range_iterator'
|
||||||
|
// because the 'Pair' type does not distinguish
|
||||||
|
// between an iterator and a const_iterator.
|
||||||
|
//
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct range_difference< Foo::Pair<T> >
|
||||||
|
{
|
||||||
|
typedef typename std::iterator_traits<T>::difference_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
struct range_size< Foo::Pair<T> >
|
||||||
|
{
|
||||||
|
int static_assertion[ sizeof( std::size_t ) >=
|
||||||
|
sizeof( typename range_difference< Foo::Pair<T> >::type ) ];
|
||||||
|
typedef std::size_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace 'boost'
|
||||||
|
|
||||||
|
namespace Foo
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// The required functions. These should be defined in
|
||||||
|
// the same namespace as 'Pair', in this case
|
||||||
|
// in namespace 'Foo'.
|
||||||
|
//
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline T boost_range_begin( Pair<T>& x )
|
||||||
|
{
|
||||||
|
return x.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline T boost_range_begin( const Pair<T>& x )
|
||||||
|
{
|
||||||
|
return x.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline T boost_range_end( Pair<T>& x )
|
||||||
|
{
|
||||||
|
return x.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline T boost_range_end( const Pair<T>& x )
|
||||||
|
{
|
||||||
|
return x.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
inline typename boost::range_size< Pair<T> >::type
|
||||||
|
boost_range_size( const Pair<T>& x )
|
||||||
|
{
|
||||||
|
return std::distance(x.first,x.last);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace 'Foo'
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
typedef std::vector<int>::iterator iter;
|
||||||
|
std::vector<int> vec;
|
||||||
|
Foo::Pair<iter> pair = { vec.begin(), vec.end() };
|
||||||
|
const Foo::Pair<iter>& cpair = pair;
|
||||||
|
//
|
||||||
|
// Notice that we call 'begin' etc with qualification.
|
||||||
|
//
|
||||||
|
iter i = boost::begin( pair );
|
||||||
|
iter e = boost::end( pair );
|
||||||
|
i = boost::begin( cpair );
|
||||||
|
e = boost::end( cpair );
|
||||||
|
boost::range_size< Foo::Pair<iter> >::type s = boost::size( pair );
|
||||||
|
s = boost::size( cpair );
|
||||||
|
boost::range_const_reverse_iterator< Foo::Pair<iter> >::type
|
||||||
|
ri = boost::rbegin( cpair ),
|
||||||
|
re = boost::rend( cpair );
|
||||||
|
}
|
@ -386,7 +386,7 @@ VAlign="top"><code>boost::range_const_reverse_iterator<X>::type</code></TD>
|
|||||||
</TR>
|
</TR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD VAlign="top">Beginning of range</TD>
|
<TD VAlign="top">Beginning of range</TD>
|
||||||
<TD VAlign="top"><code>rboost::begin(a)</code></TD>
|
<TD VAlign="top"><code>boost::rbegin(a)</code></TD>
|
||||||
<TD VAlign="top"><code>boost::range_reverse_iterator<X>::type</code> if
|
<TD VAlign="top"><code>boost::range_reverse_iterator<X>::type</code> if
|
||||||
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
||||||
otherwise.</TD>
|
otherwise.</TD>
|
||||||
@ -394,7 +394,7 @@ otherwise.</TD>
|
|||||||
<code>boost::range_reverse_iterator<X>::type(boost::end(a))</code>.</TD> </TR>
|
<code>boost::range_reverse_iterator<X>::type(boost::end(a))</code>.</TD> </TR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD VAlign="top">End of range</TD>
|
<TD VAlign="top">End of range</TD>
|
||||||
<TD VAlign="top"><code>rboost::end(a)</code></TD>
|
<TD VAlign="top"><code>boost::rend(a)</code></TD>
|
||||||
<TD VAlign="top"><code>boost::range_reverse_iterator<X>::type</code> if
|
<TD VAlign="top"><code>boost::range_reverse_iterator<X>::type</code> if
|
||||||
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
||||||
otherwise.</TD>
|
otherwise.</TD>
|
||||||
@ -405,7 +405,7 @@ otherwise.</TD>
|
|||||||
|
|
||||||
<h3>Complexity guarantees</h3>
|
<h3>Complexity guarantees</h3>
|
||||||
|
|
||||||
<code>rboost::begin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>rboost::end(a)</code>
|
<code>boost::rbegin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>boost::rend(a)</code>
|
||||||
has the same complexity as <code>boost::begin(a)</code> from <a
|
has the same complexity as <code>boost::begin(a)</code> from <a
|
||||||
href="#forward_range">Forward Range</a>.
|
href="#forward_range">Forward Range</a>.
|
||||||
|
|
||||||
@ -414,13 +414,13 @@ otherwise.</TD>
|
|||||||
<Table border="1" cellpadding="5">
|
<Table border="1" cellpadding="5">
|
||||||
<TR>
|
<TR>
|
||||||
<TD VAlign="top">Valid reverse range</TD>
|
<TD VAlign="top">Valid reverse range</TD>
|
||||||
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[rboost::begin(a),rboost::end(a))</code>
|
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[boost::rbegin(a),boost::rend(a))</code>
|
||||||
is a valid range, that is, <code>rboost::end(a)</code> is reachable from <code>rboost::begin(a)</code>
|
is a valid range, that is, <code>boost::rend(a)</code> is reachable from <code>boost::rbegin(a)</code>
|
||||||
in a finite number of increments.</TD>
|
in a finite number of increments.</TD>
|
||||||
</TR>
|
</TR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD VAlign="top">Completeness</TD>
|
<TD VAlign="top">Completeness</TD>
|
||||||
<TD VAlign="top">An algorithm that iterates through the range <code>[rboost::begin(a),rboost::end(a))</code>
|
<TD VAlign="top">An algorithm that iterates through the range <code>[boost::rbegin(a),boost::rend(a))</code>
|
||||||
will pass through every element of <code>a</code>.</TD>
|
will pass through every element of <code>a</code>.</TD>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
Reference in New Issue
Block a user