diff --git a/doc/boost_range.html b/doc/boost_range.html index 7ee54ee..41f4e81 100644 --- a/doc/boost_range.html +++ b/doc/boost_range.html @@ -1,112 +1,128 @@ -
![]() |
|
This library makes it possible to treat different types as if they have
- implemented a subset of the container requirements
- (see §23.1of the C++ standard). Formally, that subset is defined by
- the CollectionConcept.
- The subset deals mostly with
- iterator returning functions and nested typedef
s.
- The main goal is to treat built-in arrays, standard containers,
- pairs of iterators and some iterators uniformly. Formally, this library is an implementation
- of the ExternalCollectionConcept (see also this explanation of External Concepts ).
The main advantages are
Below are given a small example (the complete example can be found here ):
- // - // Example: extracting bounds in generic algorithms - // - - template< typename ExternalCollection, typename T > - inline typename boost::iterator_of<ExternalCollection>::type - find( ExternalCollection& c, const T& value ) - { - return std::find( boost::begin( c ), boost::end( c ), value ); - } + + + +By using the free-standing functions and type-generators, the code automatically - works for all the types supported by this library. Notice that we have to provide - two version ofBoost.Range Range Implementation + + - template< typename ExternalCollection, typename T > - inline typename boost::const_iterator_of<ExternalCollection>::type - find( const ExternalCollection& c, const T& value ) - { - return std::find( boost::begin( c ), boost::end( c ), value ); - } - - // - // replace first value and return its index - // - template< typename EC, typename T > - inline typename boost::size_type_of< EC >::type - my_generic_replace( EC& c, const T& value, const T& replacement ) - { - typename boost::const_iterator_of<EC>::type found = find( c, value ); - *found = replacement; - return std::distance( boost::begin( c ), found ); - } - - // - // usage - // - std::vector<int> my_vector; - typedef vector<int>::iterator iterator; - std::pair<iterator,iterator> my_view( my_vector.begin(), my_vector.begin() + N ); - char str[] = "a string"; - // ... - std::cout << my_generic_replace( my_vector, 4, 2 ) - << my_generic_replace( my_view, 4, 2 ) - << my_generic_replace( str, 'a', 'b' ); -
find()
since we cannot
- forward a non-const rvalue with reference arguments (see this article about The Forwarding Problem ).#include <boost/collection_traits.hpp>
Five types of objects are currently supported by the library:
char[]
,wchar_t[]
,char*
, and wchar_t*
)std::pair<iterator,iterator>
boost::array<>
- anyway). Also note that arrays and pointers of char
or whar_t
are treated special because of their use in string algorithms.The concept is defined by the type-generators and the
- functions below. Even though these functions are defined in
- namespace boost
, there is no such general requirement, that is,
- if one wants to extend the list of supported types, it can be done in any
- namespace.
- namespace boost + + + + +
![]() |
+
|
+
+Five types of objects are currently supported by the library: +
char[]
,wchar_t[]
,
+ char*
, and wchar_t*
)
+ std::pair<iterator,iterator>
+ boost::array<>
anyway). Also note
+that arrays and pointers of char
or whar_t
are
+treated special because of their use in string algorithms.
+
+
+The concept is defined by the type-generators and the functions below. Even
+though these functions are defined in namespace boost
, there is no
+such general requirement, that is, if one wants to extend the list of supported
+types, it can be done in any namespace.
+
+
+ namespace boost { - // + // // type generators - // + // - template< typename EC > + template< typename EC > struct value_type_of { - typedef ... type; // type of stored objects + typedef ... type; // type of stored objects }; - template< typename EC > - struct iterator_of + template< typename EC > + struct iterator_of { typedef ... type; // iterator over stored objects }; - template< typename EC > - struct const_iterator_of + template< typename EC > + struct const_iterator_of { - typedef ... type; // iterator over immutable stored objects + typedef ... type; // iterator over immutable stored objects }; - template< typename EC > + template< typename EC > struct difference_type_of { - typedef ... type; + typedef ... type; BOOST_STATIC_ASSERT( boost::is_signed< type >::value ); // - // remark: if std::iterator_traits<> works for the type, this assertion must hold + // remark: if std::iterator_traits<> works for the type, this assertion must + hold // - BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename - iterator_of< EC >::type >::difference_type>::value ); + BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename + iterator_of< EC >::type >::difference_type>::value ); }; - template< typename EC > + template< typename EC > struct size_type_of { typedef ... type; BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value ); - BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( difference_type_of< EC >::type ) ); + BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( + difference_type_of< EC >::type ) ); }; - template< typename EC > - struct result_iterator_of + template< typename EC > + struct result_iterator_of { - typedef ... type; - // iterator_of< EC >::type if EC is non-const, const_iterator_of< EC >::type otherwise + typedef ... type; + // iterator_of< EC >::type if EC is non-const, + const_iterator_of< EC >::type otherwise }; // @@ -115,15 +131,15 @@ template< typename EC > inline typename iterator_of::type - begin( EC& c ); + begin( EC& c ); template< typename EC > inline typename const_iterator_of< EC >::type - begin( const EC& c ); + begin( const EC& c ); template< typename EC > inline typename iterator_of< EC >::type - end( EC& c ); + end( EC& c ); template< typename EC > inline typename const_iterator_of< EC >::type @@ -131,38 +147,230 @@ template< typename EC > inline bool - empty( const EC& c ); + empty( const EC& c ); template< typename EC > inline typename size_type_of< EC >::type size( const EC& c ); - } // namespace 'boost'
Header | Includes |
---|---|
<boost/collection_traits.hpp> | everything |
<boost/collection_traits/types.hpp> | every type-generator |
<boost/collection_traits/functions.hpp> | every function |
<boost/collection_traits/value_type.hpp> | value_type_of |
<boost/collection_traits/iterator.hpp> | iterator_of |
<boost/collection_traits/const_iterator.hpp> | const_iterator_of |
<boost/collection_traits/difference_type.hpp> | difference_type_of |
<boost/collection_traits/size_type.hpp> | size_type_of |
<boost/collection_traits/result_iterator.hpp> | result_iterator_of |
<boost/collection_traits/begin.hpp> | begin |
<boost/collection_traits/end.hpp> | end |
<boost/collection_traits/empty.hpp> | empty |
<boost/collection_traits/size.hpp> | size |
In the table C
is a type that conforms to the ExternalCollectionConcept and c
is an object of that type. SC
will denote a standard
- container, T[sz]
will denote an array of type T
of size sz
, P
will denote std::pair<>
, I
means an iterator which default construction
- denotes the end of the range and sc,t,p,i
are objects of these types,
- respectively. Special cases for char*
and wchar_t*
are described explicitly.
Please note that char*
,whar_t*
,char[]
, and wchar_t[]
behaves differently from
- normal arrays only for size()
and end()
.
- Note that the null pointer is allowed as an argument in these cases.
Some examples are given in the accompanying test - files:
iterator.cpp
std::copy()
that works with std::ifstream_iterator<>.
string.cpp
std::find()
that works with char[],wchar_t[],char*,wchar_t*.
algorithm_example.cpp
Full support for built-in arrays require that the - compiler supports class template partial specialization.
Notice that some compilers cannot do function template ordering
- properly. In that case one cannot rely of result_iterator_of<>
and a single function definition; instead one needs to supply
- a function overloaded for const and non-const arguments if it is required.
Full support for iterators like std::istream_iterator<>
depends very
- much on a conforming standard library.
Most of the tests have been run successfully on these compilers
iterator_of<C>::type
and const_iterator_of<C>::type
for std::pair<iterator,iterator>
or iterators which default construction denotes the end of the range?In general it is not possible nor desirable to find a corresponding const_iterator
. When it is possible to come up with
- one, the client might choose to
- construct a std::pair<const_iterator,const_iterator>
object.
The traits class have been kept small because its current interface - will serve most purposes. If and when a genuine need arises for - more functionality, it can be implemented.
One should always start with a generic algorithm that takes two iterators as input. Then use the - collection traits to build handier versions on top of the base algorithm.
The library have been under way for a long time. Dietmar Kühl originally
- intended to submit an array_traits<>
class template which had most
- of the functionality present now, but only for arrays and standard containers.
- Meanwhile work on container algorithms
- in various context showed the need for handling pairs of iterators, and
- string libraries needed special treatment of character arrays.
- Thorsten Ottosen wrote everything from the ground up including the first
- work-around for missing partial template specialization. Pavol Droba helped to
- improve the work-around for handicapped compilers and the special character support.
- The naming scheme of type-generators was suggested by Peter Dimov.
© Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk). - Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied warranty, and with no - claim as to its suitability for any purpose.
+In the table C
is a type that conforms to the
+ExternalCollectionConcept and c
is an object of that type.
+SC
+will denote a standard container, T[sz]
will denote an array of
+type T
of size sz
, P
will denote
+std::pair<>
,
+I
means an iterator which default construction denotes the end of
+the range and sc,t,p,i
are objects of these types, respectively.
+Special cases for char*
and wchar_t*
are described
+explicitly.
+
+Please note that char*
,whar_t*
,char[]
,
+and wchar_t[]
behaves differently from normal arrays only for
+size()
+and end()
. Note that the null pointer is allowed as an argument
+in these cases.
+
+Some examples are given in the accompanying test files: +
+iterator.cpp
+ std::copy()
that
+ works with std::ifstream_iterator<>.
+ string.cpp
+ std::find()
that
+ works with char[],wchar_t[],char*,wchar_t*.
+ algorithm_example.cpp
+
+ + (C) Copyright Thorsten Ottosen 2003-2004 +
+ +![]() |
+ Boost.Range |
+
+
iterator_of<C>::type
and const_iterator_of<C>::type
+ for std::pair<iterator, iterator>
.
+
+ In general it is not possible nor desirable to find a corresponding const_iterator
.
+ When it is possible to come up with one, the client might choose to construct a std::pair<const_iterator,const_iterator>
+ object.
+
+ The library have been kept small because its current interface will serve + most purposes. If and when a genuine need arises for more functionality, it can + be implemented. +
++ One should always start with a generic algorithm that takes two + iterators (or more) as + input. Then use Boost.Range to build handier versions on top of the + iterator based algorithm. Please notice that once the range version + of the algorithm is done, it makes sense not to expose the + iterator version in the public interface. +
++ (C) Copyright Thorsten Ottosen 2003-2004 +
+ +![]() |
+ Boost.Range |
+
+
Header | +Includes | +
---|---|
<boost/range.hpp> |
+ everything | +
<boost/range/types.hpp> |
+ every meta-function | +
<boost/range/functions.hpp> |
+ every function | +
<boost/range/value_type.hpp> |
+ value_type_of | +
<boost/range/iterator.hpp> |
+ iterator_of | +
<boost/range/const_iterator.hpp> |
+ const_iterator_of | +
<boost/range/difference_type.hpp> |
+ difference_type_of | +
<boost/range/size_type.hpp> |
+ size_type_of | +
<boost/range/result_iterator.hpp> |
+ result_iterator_of | +
<boost/range/reverse_iterator.hpp> |
+ reverse_iterator_of | +
<boost/range/const_reverse_iterator.hpp> |
+ const_reverse_iterator_of | +
<boost/range/reverse_result_iterator.hpp> |
+ reverse_result_iterator_of | +
<boost/range/begin.hpp> |
+ begin | +
<boost/range/end.hpp> |
+ end | +
<boost/range/empty.hpp> |
+ empty | +
<boost/range/size.hpp> |
+ size | +
<boost/range/rbegin.hpp> |
+ rbegin | +
<boost/range/rend.hpp> |
+ rend | +
<boost/range/iterator_range.hpp> |
+ iterator_range | +
<boost/range/sub_range.hpp> |
+ sub_range | +
+ (C) Copyright Thorsten Ottosen 2003-2004 +
+ +![]() |
+ Boost.Range |
+
+ The library have been under way for a long time. Dietmar Kühl originally
+ intended to submit an array_traits<>
class template which
+ had most of the functionality present now, but only for arrays and standard
+ containers.
+
+ Meanwhile work on container algorithms in various context showed the + need for handling pairs of iterators, and string libraries needed special + treatment of character arrays. +
+ ++ Special thanks goes to +
+ (C) Copyright Thorsten Ottosen 2003-2004 +
+ +![]() |
+ Boost.Range |
+
+ This library makes it possible to treat different types as if they have
+ implemented a subset of the container requirements (see §23.1of the C++
+ standard). Formally, that subset is defined by the Range concept. The subset deals mostly with iterator
+ returning functions and nested typedef
s. The main goal is to treat
+ built-in arrays, standard containers, pairs of iterators and some iterators
+ uniformly.
+
+ The main advantages are +
+ Below are given a small example (the complete example can be found here + ): +
+ + // + // Example: extracting bounds in generic algorithms + // + + template< typename XRange, typename T > + inline typename boost::iterator_of<XRange>::type + find( XRange& c, const T& value ) + { + return std::find( boost::begin( c ), boost::end( c ), value ); + } + + template< typename XRange, typename T > + inline typename boost::const_iterator_of<XRange>::type + find( const XRange& c, const T& value ) + { + return std::find( boost::begin( c ), boost::end( c ), value ); + } + + // + // replace first value and return its index + // + template< typename EC, typename T > + inline typename boost::size_type_of< EC >::type + my_generic_replace( EC& c, const T& value, const T& replacement ) + { + typename boost::const_iterator_of<EC>::type found = find( c, value ); + *found = replacement; + return std::distance( boost::begin( c ), found ); + } + + // + // usage + // + std::vector<int> my_vector; + typedef vector<int>::iterator iterator; + std::pair<iterator,iterator> my_view( my_vector.begin(), my_vector.begin( + ) + N ); + char str[] = "a string"; + // ... + std::cout << my_generic_replace( my_vector, 4, 2 ) + << my_generic_replace( my_view, 4, 2 ) + << my_generic_replace( str, 'a', 'b' ); ++ + By using the free-standing functions and type-generators, the code automatically + works for all the types supported by this library. 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
+ Forwarding Problem ).
+
+
+
+
+ + (C) Copyright Thorsten Ottosen 2003-2004 +
+ +![]() |
+ Boost.Range |
+
+ Full support for built-in arrays require that the compiler supports class + template partial specialization. For non-conforming compilers there might + be a change that it works anyway thanks to workarounds in the type traits + library.
+
+ Notice that some compilers cannot do function template ordering properly. In
+ that case one must rely of result_iterator_of<>
and a
+ single function definition instead of
+ overloaded versions for const and non-const arguments.
+
+
+ So if one cares about old compilers, one should not pass rvalues
+ to the functions.
+
+ A huge effort has been made to port the library to as many compilers as + possible. The results of the test-suites can be found + here. +
+ ++ (C) Copyright Thorsten Ottosen 2003-2004 +
+ +![]() |
+ Boost.Range |
+
-X - | --A type that is a model of Range. - | -
-a, b - | --Object of type X. - | -
-T - | --The value type of X. - | -
X | +A type that is a model of Range. | +
a, b | +Object of type X. | +
T | +The value type of X. | +
-Value type - | --X::value_type - | --The type of the object stored in a Range. - - | -|
-Iterator type - | --X::iterator - | --The type of iterator used to iterate through a Range's - elements. The iterator's value type is expected to be the - Range's value type. A conversion - from the iterator type to the const iterator type must exist. - The iterator type must at least be an InputIterator. - | -|
-Const iterator type - | --X::const_iterator - | --A type of iterator that may be used to examine, but not to modify, - a Range's elements. - | -|
-Reference type - | --X::reference - | --A type that behaves like a reference to the Range's value type. -[1] - | -|
-Distance type - | --X::difference_type - | --A signed integral type used to represent the distance between two - of the Range's iterators. This type must be the same as - the iterator's distance type. - | -|
-Size type - | --X::size_type - | --An unsigned integral type that can represent any nonnegative value - of the Range's distance type. - | -
Value type | +value_type_of<X>::type | +The type of the object stored in a Range. + |
Iterator type | +iterator_of<X>::type | +The type of iterator used to iterate through a Range's elements. + The iterator's value type is expected to be the Range's value type. A + conversion from the iterator type to the const iterator type must exist. The + iterator type must at least be an InputIterator. | +
Const iterator type | +const_iterator_of<X>::type | +A type of iterator that may be used to examine, but not to + modify, a Range's elements. | +
Reference type | +reference_of<X>::type | +A type that behaves like a reference to the Range's value type. [1] | +
Distance type | +difference_type_of<>::type | +A signed integral type used to represent the distance between + two of the Range's iterators. This type must be the same as the iterator's + distance type. | +
Size type | +size_type_of<X>::type | +An unsigned integral type that can represent any nonnegative + value of the Range's distance type. | +
-
-Name - | --Expression - | --Return type - | -|
---|---|---|---|
-Beginning of range - | --a.begin() - | --iterator if a is mutable, const_iterator otherwise - | -|
-End of range - | --a.end() - | --iterator if a is mutable, const_iterator otherwise - | -|
-Size - | --a.size() - | --size_type - | --Empty range - | --a.empty() - | --Convertible to bool - | - -
Name | +Expression | +Return type | +
---|---|---|
Beginning of range | +begin(a) | +iterator if a is mutable, const_iterator + otherwise | +
End of range | +end(a) | +iterator if a is mutable, const_iterator + otherwise | +
Size of range | +size(a) | +size_type | +Is range empty? | +empty(a) | +Convertible to bool | + +
-Name - | --Expression - | --Semantics - | --Postcondition - | -- |
---|---|---|---|
-Beginning of range - | --a.begin() - | --Returns an iterator pointing to the first element in the Range. - | --a.begin() is either dereferenceable or past-the-end. It is - past-the-end if and only if a.size() == 0. - | -
-End of range - | --a.end() - | --Returns an iterator pointing one past the last element in the - Range. - | --a.end() is past-the-end. - | -
-Size - | --a.size() - | --Returns the size of the Collection, that is, its number of elements. - | --a.size() >= 0 - | -
-Empty Collection - | --a.empty() - | --Equivalent to a.size() == 0. (But possibly faster.) - | -- - | -
Expression | +Semantics | +Postcondition | ++ |
begin(a) | +Returns an iterator pointing to the first element in the Range. | +begin(a) is either dereferenceable or +past-the-end. It is past-the-end if and only if size(a) == 0. | +|
end(a) | +Returns an iterator pointing one past the last element in the + Range. | +end(a) is past-the-end. | +|
size(a) | +Returns the size of the Collection, that is, its number of + elements. | +size(a) >= 0 | +|
empty(a) | +Equivalent to size(a) == 0. (But +possibly faster.) | - | +
-Valid range - | --For any Range a, [a.begin(), a.end()) is a valid - range. - | -
-Range size - | --a.size() is equal to the distance from a.begin() to a.end(). - | -
-Completeness - | --An algorithm that iterates through the range [a.begin(), a.end()) - will pass through every element of a. - | -
Valid range | +For any Range a, [begin(a),end(a)) is a
+ valid range, that is, end(a) is reachable from begin(a)
+ in a finite number of increments. |
+
Range size | +size(a) is equal to the distance from +begin(a) to end(a). | +
Completeness | +An algorithm that iterates through the range +[begin(a),end(a)) will pass through every element of a. | +
All models of Container
+ -Reverse Iterator type - | --X::reverse_iterator - | --The type of iterator used to iterate through a Range's - elements in reverse order. The iterator's value type is expected to be the - Range's value type. A conversion - from the reverse iterator type to the const reverse iterator type must exist. - The iterator type must at least be a BidirectionalIterator. - | -
-Const reverse iterator type - | --X::const_reverse_iterator - | --A type of reverse iterator that may be used to examine, but not to modify, - a Range's elements. - | -
Reverse Iterator type | +X::reverse_iterator | +The type of iterator used to iterate through a Range's elements + in reverse order. The iterator's value type is expected to be the Range's value + type. A conversion from the reverse iterator type to the const reverse iterator + type must exist. The iterator type must at least be a BidirectionalIterator. | +
Const reverse iterator type | +X::const_reverse_iterator | +A type of reverse iterator that may be used to examine, but not + to modify, a Range's elements. | +
-Name - | --Expression - | --Return type - | --Semantics - | -
---|---|---|---|
-Beginning of range - | --a.rbegin() - | --reverse_iterator if a is mutable, -const_reverse_iterator otherwise. - | --Equivalent to X::reverse_iterator(a.end()). - | -
-End of range - | --a.rend() - | --reverse_iterator if a is mutable, -const_reverse_iterator otherwise. - | --Equivalent to X::reverse_iterator(a.begin()). - | -
Name | +Expression | +Return type | +Semantics | +
Beginning of range | +rbegin(a) | +reverse_iterator if a is mutable, const_reverse_iterator + otherwise. | +Equivalent to X::reverse_iterator(end(a)). |
End of range | +rend(a) | +reverse_iterator if a is mutable, const_reverse_iterator + otherwise. | +Equivalent to +X::reverse_iterator(begin(a)). |
[1] +
+[1]
-The reference type does not have to be a real C++ reference. The
-requirements of the reference type depend on the context within which
-the Range is being used. Specifically it depends on the
-requirements the context places on the value type of the Range.
-The reference type of the Range must meet the same requirements
-as the value type. In addition, the reference objects must be
-equivalent to the value type objects in the Range (which is
-trivially true if they are the same). Also, in a mutable Range,
-an assignment to the reference object must result in an assignment to
-the object in the Range (again, which is trivially true if they
-are the same object, but non-trivial if the reference type is a proxy
-class).
+The reference type does not have to be a real C++ reference. The requirements of
+the reference type is that it behaves like a real reference. Hence the
+reference type must be convertible to the value_type and assignment through
-
-
+
+
Copyright © 2000 | -Jeremy Siek, Univ.of Notre Dame and C++ Library & Compiler Group/SGI (jsiek@engr.sgi.com) - |
Copyright © 2004 | -Thorsten Ottosen. + |
Copyright © 2000 | +Jeremy Siek + |
Copyright © 2004 | +Thorsten Ottosen. |