- Four types of objects are currently supported by the library:
-
-
- standard-like containers
-
-
- std::pair<iterator,iterator>
-
-
- null terminated strings (this includes char[],wchar_t[],
- char*, and wchar_t*)
-
- Warning: support for null-terminated strings is deprecated and will
- disappear in the next Boost release (1.34).
-
-
-
-
- built-in arrays
-
-
-
- Even though the behavior of the primary templates are exactly such that standard
- containers will be supported by default, the requirements are much lower than
- the standard container requirements. For example, the utility class iterator_range implements
- the minimal interface required to make the
- class a Forward Range.
-
+ Four types of objects are currently supported by the library:
+
+
+ standard-like containers
+
+ std::pair<iterator,iterator>
+
+ null terminated strings (this includes char[],wchar_t[],
+ char*, and wchar_t*)
+
+ Warning: support for null-terminated strings is deprecated and will
+ disappear in the next Boost release (1.34).
+
+
+ built-in arrays
+
+
+ Even though the behavior of the primary templates are exactly such that
+ standard containers will be supported by default, the requirements are much
+ lower than the standard container requirements. For example, the utility class
+ iterator_range implements the minimal
+ interface required to make the class a Forward
+ Range
+ .
+
+
+ Please notice in tables below that when four lines appear in a cell, the first
+ line will describe the primary template, the second line pairs of iterators,
+ the third line arrays and the last line null-terminated strings.
+
+
Metafunctions
+
+
+
+
+ Expression
+
+ Return type
+
+ Complexity
+
+
+
+
range_value<X>::type
+
T::value_type
+ boost::iterator_value<P::first_type>::type
+ A
+ Char
+
+ The special metafunctions range_result_iterator and range_reverse_result_iterator
+ are not part of any Range concept, but they are very useful when implementing
+ certain Range classes like sub_range
+ because of their ability to select iterators based on constness.
+
+
Functions
+
+
+
+
+ Expression
+
+ Return type
+
+ Returns
+
+ Complexity
+
+
+
+
begin(x)
+
range_result_iterator<X>::type
+
+ p.first if p is of type std::pair<T>
+ a if a is an array
+ s if s is a string literal
+ boost_range_begin(x) if that expression would invoke a function found by ADL
+ t.begin() otherwise
+
+
constant time
+
+
+
+
end(x)
+
range_result_iterator<X>::type
+
+ p.second if p is of type std::pair<T>
+ a + sz if a is an array of size sz
+ s + std::char_traits<X>::length( s ) if s is a Char*
+
+ s + sz - 1 if s is a string literal of size sz
+
+ boost_range_end(x) if that expression would invoke a function found by ADL
+ t.end() otherwise
+
+
linear if X is Char*
+
+ constant time otherwise
+
+
+
+
empty(x)
+
bool
+
begin(x) == end( x )
+
linear if X is Char*
+
+ constant time otherwise
+
+
+
+
+
size(x)
+
range_size<X>::type
+
+ std::distance(p.first,p.second) if p is of type std::pair<T>
+ sz if a is an array of size sz
+ end(s) - s if s is a string literal or a Char*
+ boost_range_size(x) if that expression would invoke a function found by ADL
+ t.size() otherwise
+
linear if X is Char*
+
+ or if std::distance() is linear
+
+ constant time otherwise
+ The special const functions are not part of any Range concept, but
+ are very useful when you want to document clearly that your code is read-only.
+
Method 1: provide member functions and nested types
+
+
+ This procedure assumes that you have control over the types that should be made
+ conformant to a Range concept. If not, see method 2.
+
+
+
+ The primary templates in this library are implemented such that standard
+ containers will work automatically and so will boost::array.
+ Below is given an overview of which member functions and member types a class
+ must specify to be useable as a certain Range concept.
+
+ Again one should notice that member types reverse_iterator and const_reverse_iterator
+ are not needed.
+
+
+
Method 2: provide free-standing functions and specialize metafunctions
-
- Please notice in tables below that when four lines appear in a cell, the first
- line will describe the primary template, the second line pairs of iterators, the
- third line arrays and the last line null-terminated strings.
-
-
Metafunctions
-
-
-
-
Expression
-
Return type
-
Complexity
-
-
-
-
range_value<X>::type
-
T::value_type
- boost::iterator_value<P::first_type>::type
- A
- Char
-
+ This procedure assumes that you cannot (or do not wish to) change the types that should be made
+ conformant to a Range concept. If this is not true, see method 1.
+
+
+
+ The primary templates in this library are implemented such that
+ certain functions are found via argument-dependent-lookup (ADL).
+ Below is given an overview of which free-standing functions a class
+ must specify to be useable as a certain Range concept.
+ Let x be a variable (const or mutable)
+ of the class in question.
+
+#include<boost/range.hpp>
+#include<iterator>// for std::iterator_traits, std::distance()
+namespaceFoo
+{
+ //
+ // Our sample UDT. A 'Pair'
+ // will work as a range when the stored
+ // elements are iterators.
+ //
+ template<classT>
+ structPair
+ {
+ Tfirst,last;
+ };
-
-
-
- The special metafunctions range_result_iterator and range_reverse_result_iterator
- are not part of any Range concept, but they are very useful when implementing
- certain Range classes like sub_range because of their
- ability to select iterators based on constness.
-
+}// namespace 'Foo'
-
Functions
-
-
-
-
Expression
-
Return type
-
Returns
-
Complexity
-
-
-
-
begin(x)
-
range_result_iterator<X>::type
-
t.begin()
- p.first
- a
- s
-
constant time
-
-
-
-
end(x)
-
range_result_iterator<X>::type
-
t.end()
- p.second
- a + sz
- s + std::char_traits<X>::length( s ) if X is Char*
-
- s + sz - 1 if X is Char[sz]
+namespaceboost
+{
+ //
+ // Specialize metafunctions. We must include the range.hpp header.
+ // We must open the 'boost' namespace.
+ //
+ template<classT>
+ structrange_iterator<Foo::Pair<T>>
+ {
+ typedefTtype;
+ };
-
linear if X is Char*
- constant time otherwise
-
-
-
-
empty(x)
-
bool
-
begin(x) == end( x )
-
linear if X is Char*
- constant time otherwise
-
-
-
-
-
size(x)
-
range_size<X>::type
-
t.size()
- std::distance(p.first,p.second)
- sz
- end(s) - s
+ template<classT>
+ structrange_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.
+ //
+ typedefTtype;
+ };
-
linear if X is Char*
- or if std::distance() is linear
- constant time otherwise
- The special const functions are not part of any Range concept,
- but are very useful when you want to document clearly that your code is
- read-only.
-
+ typedefstd::size_ttype;
+ };
-
-
Extending the library
-
- The primary templates in this library are implemented such that standard
- containers will work automatically and so will boost::array. Below is given an overview of
- which member functions and member types a class must specify to
-be useable as a certain Range concept.
-
- Again one should notice that member types reverse_iterator and
- const_reverse_iterator are not needed.
-
-
-
-
- (C) Copyright Thorsten Ottosen 2003-2004
-
+namespaceFoo
+{
+ //
+ // The required functions. These should be defined in
+ // the same namespace as 'Pair', in this case
+ // in namespace 'Foo'.
+ //
+
+ template<classT>
+ inlineTboost_range_begin(Pair<T>&x)
+ {
+ returnx.first;
+ }
-
-
-
-
-
-
-
-
-
-
-
-
+ template<classT>
+ inlineTboost_range_begin(constPair<T>&x)
+ {
+ returnx.first;
+ }
+ template<classT>
+ inlineTboost_range_end(Pair<T>&x)
+ {
+ returnx.last;
+ }
-
+ template<classT>
+ inlineTboost_range_end(constPair<T>&x)
+ {
+ returnx.last;
+ }
+
+ template<classT>
+ inlinetypenameboost::range_size<Pair<T>>::type
+ boost_range_size(constPair<T>&x)
+ {
+ returnstd::distance(x.first,x.last);
+ }
+
+}// namespace 'Foo'
+
+#include<vector>
+
+intmain()
+{
+ typedefstd::vector<int>::iteratoriter;
+ std::vector<int>vec;
+ Foo::Pair<iter>pair={vec.begin(),vec.end()};
+ constFoo::Pair<iter>&cpair=pair;
+ //
+ // Notice that we call 'begin' etc with qualification.
+ //
+ iteri=boost::begin(pair);
+ itere=boost::end(pair);
+ i=boost::begin(cpair);
+ e=boost::end(cpair);
+ boost::range_size<Foo::Pair<iter>>::types=boost::size(pair);
+ s=boost::size(cpair);
+ boost::range_const_reverse_iterator<Foo::Pair<iter>>::type
+ ri=boost::rbegin(cpair),
+ re=boost::rend(cpair);
+}
+
+
+
+
+
+ (C) Copyright Thorsten Ottosen 2003-2004
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/example.cpp b/doc/example.cpp
new file mode 100644
index 0000000..afe448f
--- /dev/null
+++ b/doc/example.cpp
@@ -0,0 +1,141 @@
+#include
+#include // 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 >
+ {
+ typedef typename std::iterator_traits::value_type type;
+ };
+ */
+
+ template< class T >
+ struct range_iterator< Foo::Pair >
+ {
+ typedef T type;
+ };
+
+ template< class T >
+ struct range_const_iterator< Foo::Pair >
+ {
+ //
+ // 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 >
+ {
+ typedef typename std::iterator_traits::difference_type type;
+ };
+ */
+
+ template< class T >
+ struct range_size< Foo::Pair >
+ {
+ int static_assertion[ sizeof( std::size_t ) >=
+ sizeof( typename range_difference< Foo::Pair >::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& x )
+ {
+ return x.first;
+ }
+
+ template< class T >
+ inline T boost_range_begin( const Pair& x )
+ {
+ return x.first;
+ }
+
+ template< class T >
+ inline T boost_range_end( Pair& x )
+ {
+ return x.last;
+ }
+
+ template< class T >
+ inline T boost_range_end( const Pair& x )
+ {
+ return x.last;
+ }
+
+ template< class T >
+ inline typename boost::range_size< Pair >::type
+ boost_range_size( const Pair& x )
+ {
+ return std::distance(x.first,x.last);
+ }
+
+} // namespace 'Foo'
+
+#include
+
+int main()
+{
+ typedef std::vector::iterator iter;
+ std::vector vec;
+ vec.push_back( 42 );
+ Foo::Pair pair = { vec.begin(), vec.end() };
+ const Foo::Pair& 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 >::type s = boost::size( pair );
+ s = boost::size( cpair );
+ boost::range_const_reverse_iterator< Foo::Pair >::type
+ ri = boost::rbegin( cpair ),
+ re = boost::rend( cpair );
+
+ //
+ // Test metafunctions
+ //
+
+ boost::range_value< Foo::Pair >::type
+ v = *boost::begin(pair);
+
+ boost::range_difference< Foo::Pair >::type
+ d = boost::end(pair) - boost::begin(pair);
+}
+
diff --git a/doc/intro.html b/doc/intro.html
index 0161f42..444b4ca 100755
--- a/doc/intro.html
+++ b/doc/intro.html
@@ -87,7 +87,7 @@ free-standing functions so syntactic and/or semantic differences can be removed.
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
-
+
template< class ForwardReadableRange, class T >
inline typename boost::range_const_iterator< ForwardReadableRange >::type
@@ -95,7 +95,7 @@ class=identifier>ForwardReadableRange >::{
return std::find( boost::begin( c ), boost::end( c ), value );
}
-
+
//
// replace first value and return its index
//
@@ -104,7 +104,7 @@ class=identifier>ForwardReadableRange >::my_generic_replace( ForwardReadableWriteableRange& c, const T& value, const T& replacement )
{
typename boost::range_iterator< ForwardReadableWriteableRange >::type found = find( c, value );
-
+
if( found != boost::end( c ) )
*found = replacement;
return std::distance( boost::begin( c ), found );
@@ -115,30 +115,30 @@ class=identifier>ForwardReadableRange >::const int N = 5;
std::vector<int> my_vector;
- int values[] = { 1,2,3,4,5,6,7,8,9 };
+ int values[] = { 1,2,3,4,5,6,7,8,9 };
- my_vector.my_vector.assign( values, boost::end( values ) );typedef std::vector<int>::iterator iterator;
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
boost::begin( my_vector ) + N );
char str_val[] = "a string";
char* str = str_val;
-
- std::cout << my_generic_replace( my_vector, 4, 2 )
- << my_generic_replace( my_view, 4, 2 )
- << my_generic_replace( str, 'a', 'b' );
+
+ std::cout << my_generic_replace( my_vector, 4, 2 );
+ std::cout << my_generic_replace( my_view, 4, 2 );
+ std::cout << my_generic_replace( str, 'a', 'b' );
// prints '3', '5' and '0'
- By using the free-standing functions and metafunctions, the code automatically
- works for all the types supported by this library; now and in the future.
+ By using the free-standing functions and metafunctions, the code automatically
+ works for all the types supported by this library; now and in the future.
Notice that we have to
- provide two version of find() since we cannot forward a non-const
- rvalue with reference arguments (see this article about The
+ provide two version of find() since we cannot forward a non-const
+ rvalue with reference arguments (see this article about The
Forwarding Problem ).
diff --git a/doc/range.html b/doc/range.html
index b2f907c..13b5ad4 100755
--- a/doc/range.html
+++ b/doc/range.html
@@ -386,7 +386,7 @@ VAlign="top">boost::range_const_reverse_iterator<X>::type
Beginning of range
-
rboost::begin(a)
+
boost::rbegin(a)
boost::range_reverse_iterator<X>::type if
a is mutable, boost::range_const_reverse_iterator<X>::type
otherwise.
boost::range_reverse_iterator<X>::type if
a is mutable, boost::range_const_reverse_iterator<X>::type
otherwise.
@@ -405,7 +405,7 @@ otherwise.
Complexity guarantees
- rboost::begin(a) has the same complexity as boost::end(a) and rboost::end(a)
+ boost::rbegin(a) has the same complexity as boost::end(a) and boost::rend(a)
has the same complexity as boost::begin(a) from Forward Range.
@@ -414,13 +414,13 @@ otherwise.
Valid reverse range
-
For any Bidirectional Range a, [rboost::begin(a),rboost::end(a))
- is a valid range, that is, rboost::end(a) is reachable from rboost::begin(a)
+
For any Bidirectional Range a, [boost::rbegin(a),boost::rend(a))
+ is a valid range, that is, boost::rend(a) is reachable from boost::rbegin(a)
in a finite number of increments.
Completeness
-
An algorithm that iterates through the range [rboost::begin(a),rboost::end(a))
+
An algorithm that iterates through the range [boost::rbegin(a),boost::rend(a))
will pass through every element of a.