Compare commits

...

15 Commits

Author SHA1 Message Date
a54b608635 This commit was manufactured by cvs2svn to create tag
'Version_1_33_1'.

[SVN r31916]
2005-12-05 14:04:06 +00:00
32847c6b64 More cleanups
[SVN r31860]
2005-12-01 15:00:34 +00:00
bd34ecb841 Changed - output statement at end of example. cout << a << b << c; does
NOT guarantee left to right evaluation.


[SVN r31755]
2005-11-23 16:03:02 +00:00
99378979c2 *** empty log message ***
[SVN r31520]
2005-10-31 23:11:00 +00:00
848c11831e Re-enable broken compiler workarounds (they cause regressions if not present).
[SVN r31512]
2005-10-31 13:29:56 +00:00
823d513129 *** empty log message ***
[SVN r30988]
2005-09-14 17:05:05 +00:00
21c1285cd0 *** empty log message ***
[SVN r30927]
2005-09-12 20:08:14 +00:00
a47b8664f7 simplified metafunctions interface
[SVN r30889]
2005-09-09 16:11:29 +00:00
19d2d83d29 added remove_const to parameters to avoid common instantiations errors
[SVN r30855]
2005-09-07 16:13:23 +00:00
06e624858b added discussion on extension mechanism
[SVN r30854]
2005-09-07 16:12:03 +00:00
43a83f500e added test for extension mechanism
[SVN r30815]
2005-09-05 19:44:09 +00:00
9b66041b25 *** empty log message ***
[SVN r30508]
2005-08-08 20:58:56 +00:00
b4f01b66bb *** empty log message ***
[SVN r30490]
2005-08-05 15:16:37 +00:00
59f118601a fixed broken links
[SVN r30421]
2005-08-03 19:43:36 +00:00
d0f9bf8cc0 This commit was manufactured by cvs2svn to create branch 'RC_1_33_0'.
[SVN r30300]
2005-07-28 18:22:24 +00:00
17 changed files with 1145 additions and 592 deletions

File diff suppressed because it is too large Load Diff

141
doc/example.cpp Normal file
View File

@ -0,0 +1,141 @@
#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;
vec.push_back( 42 );
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 );
//
// Test metafunctions
//
boost::range_value< Foo::Pair<iter> >::type
v = *boost::begin(pair);
boost::range_difference< Foo::Pair<iter> >::type
d = boost::end(pair) - boost::begin(pair);
}

View File

@ -24,8 +24,13 @@
<li >
<a href="../test/string.cpp" target="_self" ><code >string.cpp</code></a>
</li>
shows how to implement a container version of <code >std::find()</code> that
shows how to implement a container version of <code >std::find()</code> that
works with <code >char[],wchar_t[],char*,wchar_t*.</code>
<p>
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i>
</p>
<li >
<a href="../test/algorithm_example.cpp" target="_self" ><code >algorithm_example.cpp</code></a>

View File

@ -20,36 +20,36 @@
<h2 >FAQ</h2> <a name="FAQ" ></a>
<ol >
<li >
<i>Why is there no difference between <code >range_iterator&lt;C&gt;::type</code>
<i>Why is there no difference between <code >range_iterator&lt;C&gt;::type</code>
and <code >range_const_iterator&lt;C&gt;::type</code> for <code>std::pair&lt;iterator, iterator&gt;</code></i>.
</li>
<p >
In general it is not possible nor desirable to find a corresponding <code >const_iterator</code>.
When it is possible to come up with one, the client might choose to construct a <code >std::pair&lt;const_iterator,const_iterator&gt;</code>
In general it is not possible nor desirable to find a corresponding <code >const_iterator</code>.
When it is possible to come up with one, the client might choose to construct a <code >std::pair&lt;const_iterator,const_iterator&gt;</code>
object.
</p>
<p>
Note that an <a href="utility_class.html#iter_range">iterator_range</a>
is somewhat more convenient than a <code>pair</code> and that a <a
href="utility_class.html#sub_range"><code>sub_range</code></a> do
Note that an <a href="utility_class.html#iter_range">iterator_range</a>
is somewhat more convenient than a <code>pair</code> and that a <a
href="utility_class.html#sub_range"><code>sub_range</code></a> does
propagate const-ness. </p>
<li >
<i>Why is there not supplied more types or more functions?</i>
<p >
The library has been kept small because its current interface will
The library has been kept small because its current interface will
serve most
purposes. If and when a genuine need arises for more functionality, it can be
purposes. If and when a genuine need arises for more functionality, it can be
implemented.
</p>
</li>
<li >
<i>How should I implement generic algorithms for ranges?</i>
<p >
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 <i>not</i> to expose the iterator version in
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 <i>not</i> to expose the iterator version in
the public interface.
</p>
</li>
@ -57,59 +57,59 @@
<i>Why is there no Incrementable Range concept?</i>
<p>
Even though we speak of incrementable iterators, it would not make
much sense for ranges; for example, we cannot determine the size and
emptiness of a range since we cannot even compare
its iterators.
much sense for ranges; for example, we cannot determine the size and
emptiness of a range since we cannot even compare
its iterators.
</p>
<p>
Note also that incrementable iterators are derived from output
Note also that incrementable iterators are derived from output
iterators and so there exist no output range.
</p>
</li>
</li>
<!--
<li>
<i>Should I use qualified syntax, for example
<blockquote><pre>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>); </span>
</pre></blockquote>
instead of
instead of
<blockquote>
<pre><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>;</span>
<span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>)</span></pre></blockquote>
when calling functions in this library? If so, can I still rely on argument
when calling functions in this library? If so, can I still rely on argument
dependent lookup (ADL) to kick in?</i>
<p>
The answer to the first question is that "it's up to you". The
answer to the second question is Yes. Normally qualified syntax
disables ADL, but the functions are implemented in a special
manner that preserves ADL properties. The trick was explained by
Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and
The answer to the first question is that "it's up to you". The
answer to the second question is Yes. Normally qualified syntax
disables ADL, but the functions are implemented in a special
manner that preserves ADL properties. The trick was explained by
Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and
it is best explained by some code: <blockquote>
<pre>
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=keyword>namespace </span><span class=identifier>range_detail
</span><span class=keyword>namespace </span><span class=identifier>range_detail
</span><span class=special>{
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;:</span><span class=identifier>type </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>)
</span><span class=special>{ </span><span class=comment>/* normal implementation */ </span><span class=special>}
</span><span class=special>}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=special>}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>)
</span><span class=special>{
</span><span class=comment>//
</span><span class=comment>//
// Create ADL hook
//
</span><span class=keyword>using </span><span class=identifier>range_detail</span><span class=special>::</span><span class=identifier>begin</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>);
//
</span><span class=keyword>using </span><span class=identifier>range_detail</span><span class=special>::</span><span class=identifier>begin</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>);
</span><span class=special>}</span>
<span class=special>} </span>
<span class=special>} </span>
</pre>
</blockquote>
Cool indeed!
</blockquote>
Cool indeed!
</p>
-->
-->
</ol>

View File

@ -18,36 +18,36 @@
<h2>Introduction</h2>
<p>
Generic algorithms have so far been specified in terms of two or more
iterators. Two iterators would together form a range of values that the
Generic algorithms have so far been specified in terms of two or more
iterators. Two iterators would together form a range of values that the
algorithm could work on. This leads to a very general interface, but also
to a somewhat clumsy use of the algorithms with redundant specification
of container names. Therefore we would like to raise the abstraction level
for algorithms so they specify their interface in terms of <a
for algorithms so they specify their interface in terms of <a
href=range.html>Ranges</a> as much as possible.
</p>
<p>
The most common form of ranges we are used to work with is standard library
The most common form of ranges we are used to work with is standard library
containers. However, one
often finds it desirable to extend that code to work with other types that
often finds it desirable to extend that code to work with other types that
offer
enough functionality to satisfy the needs of the generic code
<i>if a suitable layer of indirection is applied </i>. For
enough functionality to satisfy the needs of the generic code
<i>if a suitable layer of indirection is applied </i>. For
example, raw arrays are often suitable for use with generic code that
works with containers, provided a suitable adapter is used. Likewise, null
terminated strings can be treated as containers of characters, if suitably
adapted.
</p>
works with containers, provided a suitable adapter is used. Likewise, null
terminated strings can be treated as containers of characters, if suitably
adapted.
</p>
<p>
This library therefore provides the means to adapt standard-like
This library therefore provides the means to adapt standard-like
containers,
null terminated strings, <code>std::pairs</code> of iterators, and raw
arrays (and more), such that the same generic code can work with them all.
The basic idea is to add another layer of indirection using <a
href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and
free-standing functions so syntactic and/or semantic differences can be removed.
null terminated strings, <code>std::pairs</code> of iterators, and raw
arrays (and more), such that the same generic code can work with them all.
The basic idea is to add another layer of indirection using <a
href="../../mpl/doc/refmanual/metafunction.html">metafunctions</a> and
free-standing functions so syntactic and/or semantic differences can be removed.
</p>
<p >
@ -61,15 +61,19 @@ free-standing functions so syntactic and/or semantic differences can be removed.
</li>
<li >
correct handling of null-terminated strings
<p>
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i>
</p>
</li>
<li >
safe use of built-in arrays (for legacy code; why else would you use
safe use of built-in arrays (for legacy code; why else would you use
built-in arrays?) </li>
</ul>
</p>
<p >
Below are given a small example (the complete example can be found <a href="../test/algorithm_example.cpp" target="_self" >here</a>
Below are given a small example (the complete example can be found <a href="../test/algorithm_example.cpp" target="_self" >here</a>
):
<blockquote>
<pre >
@ -83,7 +87,7 @@ free-standing functions so syntactic and/or semantic differences can be removed.
</span><span class=special>{
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
</span><span class=special>}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_const_iterator</span><span class=special>&lt; </span><span
class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><span class=identifier>type
@ -91,7 +95,7 @@ class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><s
</span><span class=special>{
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
</span><span class=special>}
</span><span class=comment>//
// replace first value and return its index
//
@ -100,7 +104,7 @@ class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><s
</span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>replacement </span><span class=special>)
</span><span class=special>{
</span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_iterator</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>found </span><span class=special>= </span><span class=identifier>find</span><span class=special>( </span><span class=identifier>c</span><span class=special>, </span><span class=identifier>value </span><span class=special>);
</span><span class=keyword>if</span><span class=special>( </span><span class=identifier>found </span><span class=special>!= </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>) </span><span class=special>)
</span><span class=special>*</span><span class=identifier>found </span><span class=special>= </span><span class=identifier>replacement</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>distance</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>found </span><span class=special>);
@ -111,30 +115,30 @@ class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><s
//
</span><span class=keyword>const </span><span class=keyword>int </span><span class=identifier>N </span><span class=special>= </span><span class=number>5</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=identifier>my_vector</span><span class=special>;
</span><span class=keyword>int </span><span class=identifier>values</span><span class=special>[] </span><span class=special>= </span><span class=special>{ </span><span class=number>1</span><span class=special>,</span><span class=number>2</span><span class=special>,</span><span class=number>3</span><span class=special>,</span><span class=number>4</span><span class=special>,</span><span class=number>5</span><span class=special>,</span><span class=number>6</span><span class=special>,</span><span class=number>7</span><span class=special>,</span><span class=number>8</span><span class=special>,</span><span class=number>9 </span><span class=special>};
</span><span class=keyword>int </span><span class=identifier>values</span><span class=special>[] </span><span class=special>= </span><span class=special>{ </span><span class=number>1</span><span class=special>,</span><span class=number>2</span><span class=special>,</span><span class=number>3</span><span class=special>,</span><span class=number>4</span><span class=special>,</span><span class=number>5</span><span class=special>,</span><span class=number>6</span><span class=special>,</span><span class=number>7</span><span class=special>,</span><span class=number>8</span><span class=special>,</span><span class=number>9 </span><span class=special>};
</span>
<span class=identifier>my_vector</span><span class=special>.</span><span
<span class=identifier>my_vector</span><span class=special>.</span><span
class=identifier>assign</span><span class=special>( </span><span class=identifier>values</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>values </span><span class=special>) </span><span class=special>);</span>
</span><span class=keyword>typedef </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;::</span><span class=identifier>iterator </span><span class=identifier>iterator</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt; </span><span class=identifier>my_view</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>my_vector </span><span class=special>),
</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>my_vector </span><span class=special>) </span><span class=special>+ </span><span class=identifier>N </span><span class=special>);
</span><span class=keyword>char </span><span class=identifier>str_val</span><span class=special>[] </span><span class=special>= </span><span class=string>&quot;a string&quot;</span><span class=special>;
</span><span class=keyword>char</span><span class=special>* </span><span class=identifier>str </span><span class=special>= </span><span class=identifier>str_val</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_vector</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>)
</span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_view</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>)
</span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=literal>'a'</span><span class=special>, </span><span class=literal>'b' </span><span class=special>);
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_vector</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>);
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_view</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>);
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=literal>'a'</span><span class=special>, </span><span class=literal>'b' </span><span class=special>);
</span>
<span class=comment>// prints '3', '5' and '0' </span>
</pre>
</blockquote>
By using the free-standing functions and <a
href="../../mpl/doc/index.html#metafunctions">metafunctions</a>, the code automatically
works for all the types supported by this library; now and in the future.
By using the free-standing functions and <a
href="../../mpl/doc/refmanual/metafunction.html">metafunctions</a>, 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 <code >find()</code> since we cannot forward a non-const
rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The
provide two version of <code >find()</code> since we cannot forward a non-const
rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The
Forwarding Problem</a> ).
</p>

View File

@ -44,16 +44,16 @@
<p>
A Range is a <i>concept</i> similar to the STL <a
href="http://www.sgi.com/Technology/STL/Container.html">Container</a> concept. A
href="http://www.sgi.com/Technology/STL/Container.html">Container</a> concept. A
Range provides iterators for accessing a half-open range
<code>[first,one_past_last)</code> of elements and provides
information about the number of elements in the Range. However, a Range has
fewer requirements than a Container.
</p>
information about the number of elements in the Range. However, a Range has
fewer requirements than a Container.
</p>
<p>
The motivation for the Range concept is
that there are many useful Container-like types that do not meet the full
requirements of Container, and many algorithms that can be written with this
The motivation for the Range concept is
that there are many useful Container-like types that do not meet the full
requirements of Container, and many algorithms that can be written with this
reduced set of requirements. In particular, a Range does not necessarily
<ul>
@ -67,25 +67,25 @@
-->
</ul>
Because of the second requirement, a Range object must be passed by
Because of the second requirement, a Range object must be passed by
(const or non-const) reference in generic code.
</p>
<p>
The operations that can be performed on a Range is dependent on the
<a href="../../iterator/doc/new-iter-concepts.html#iterator-traversal-concepts-lib-iterator-traversal">traversal
The operations that can be performed on a Range is dependent on the
<a href="../../iterator/doc/new-iter-concepts.html#iterator-traversal-concepts-lib-iterator-traversal">traversal
category</a> of the underlying iterator type. Therefore
the range concepts are named to reflect which traversal category its
the range concepts are named to reflect which traversal category its
iterators support. See also <a href="style.html">terminology and style guidelines.</a>
for more information about naming of ranges.</p>
<p> The concepts described below specifies associated types as
<a href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and all
<a href="../../mpl/doc/refmanual/metafunction.html">metafunctions</a> and all
functions as free-standing functions to allow for a layer of indirection. </p>
<p><i>Notice that these metafunctions must be defined in namespace </i>
<code>boost</code></p>
<!--<p><i>Notice that these metafunctions must be defined in namespace </i>
<code>boost</code></p>-->
<hr>
<a name="single_pass_range">
@ -103,10 +103,10 @@ functions as free-standing functions to allow for a layer of indirection. </p>
</TR>
</table>
<h3>Description</h3>
<p>
A range X where <code>range_iterator&lt;X>::type</code> is a model of <a
A range X where <code>boost::range_iterator&lt;X>::type</code> is a model of <a
href="../../iterator/doc/new-iter-concepts.html#single-pass-iterators-lib-single-pass-iterators">
Single Pass Iterator</a>
@ -118,20 +118,20 @@ Single Pass Iterator</a>
<table border="1" cellpadding="5">
<TR>
<TD VAlign="top">Value type</TD>
<TD VAlign="top"><code>range_value&lt;X>::type</code></TD>
<TD VAlign="top"><code>boost::range_value&lt;X>::type</code></TD>
<TD VAlign="top">The type of the object stored in a Range.
</TR>
<TR>
<TD VAlign="top">Iterator type</TD>
<TD VAlign="top"><code>range_iterator&lt;X>::type</code></TD>
<TD VAlign="top">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
<TD VAlign="top"><code>boost::range_iterator&lt;X>::type</code></TD>
<TD VAlign="top">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.
</TR>
<TR>
<TD VAlign="top">Const iterator type</TD>
<TD VAlign="top"><code>range_const_iterator&lt;X>::type</code></TD>
<TD VAlign="top">A type of iterator that may be used to examine, but not to
<TD VAlign="top"><code>boost::range_const_iterator&lt;X>::type</code></TD>
<TD VAlign="top">A type of iterator that may be used to examine, but not to
modify, a Range's elements.</TD>
</TR>
<!--
@ -157,20 +157,20 @@ Single Pass Iterator</a>
</TR>
<TR>
<TD VAlign="top">Beginning of range</TD>
<TD VAlign="top"><code>begin(a)</code></TD>
<TD VAlign="top"><code>range_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>range_const_iterator&lt;X>::type</code>
<TD VAlign="top"><code>boost::begin(a)</code></TD>
<TD VAlign="top"><code>boost::range_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_iterator&lt;X>::type</code>
otherwise</TD> </TR>
<TR>
<TD VAlign="top">End of range</TD>
<TD VAlign="top"><code>end(a)</code></TD>
<TD VAlign="top"><code>range_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>range_const_iterator&lt;X>::type</code>
<TD VAlign="top"><code>boost::end(a)</code></TD>
<TD VAlign="top"><code>boost::range_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_iterator&lt;X>::type</code>
otherwise</TD>
</TR>
<tr>
<TD VAlign="top">Is range empty?</TD>
<TD VAlign="top"><code>empty(a)</code></TD>
<TD VAlign="top"><code>boost::empty(a)</code></TD>
<TD VAlign="top">Convertible to <code>bool</code></TD>
</TR>
</table>
@ -183,20 +183,20 @@ otherwise</TD>
<TH>Postcondition</TH>
</TR>
<TR>
<TD VAlign="top"><code>begin(a)</code></TD>
<TD VAlign="top"><code>boost::begin(a)</code></TD>
<TD VAlign="top">Returns an iterator pointing to the first element in the Range.</TD>
<TD VAlign="top"><code>begin(a)</code> is either dereferenceable or past-the-end.
It is past-the-end if and only if <code>size(a) == 0</code>.</TD>
<TD VAlign="top"><code>boost::begin(a)</code> is either dereferenceable or past-the-end.
It is past-the-end if and only if <code>boost::size(a) == 0</code>.</TD>
</TR>
<TR>
<TD VAlign="top"><code>end(a)</code></TD>
<TD VAlign="top"><code>boost::end(a)</code></TD>
<TD VAlign="top">Returns an iterator pointing one past the last element in the
Range.</TD>
<TD VAlign="top"><code>end(a)</code> is past-the-end.</TD>
<TD VAlign="top"><code>boost::end(a)</code> is past-the-end.</TD>
</TR>
<TR>
<TD VAlign="top"><code>empty(a)</code></TD>
<TD VAlign="top">Equivalent to <code>begin(a) == end(a)</code>. (But possibly
<TD VAlign="top"><code>boost::empty(a)</code></TD>
<TD VAlign="top">Equivalent to <code>boost::begin(a) == boost::end(a)</code>. (But possibly
faster.)</TD>
<TD VAlign="top">&nbsp;-&nbsp;</TD>
</TR>
@ -205,20 +205,20 @@ otherwise</TD>
<h3>Complexity guarantees</h3>
All three functions are at most amortized linear time. For most practical
purposes, one can expect <code>begin(a)</code>, <code>end(a)</code> and <code>empty(a)</code>
purposes, one can expect <code>boost::begin(a)</code>, <code>boost::end(a)</code> and <code>boost::empty(a)</code>
to be amortized constant time.
<h3>Invariants</h3>
<Table border>
<TR>
<TD VAlign="top">Valid range</TD>
<TD VAlign="top">For any Range <code>a</code>, <code>[begin(a),end(a))</code> is
a valid range, that is, <code>end(a)</code> is reachable from <code>begin(a)</code>
<TD VAlign="top">For any Range <code>a</code>, <code>[boost::begin(a),boost::end(a))</code> is
a valid range, that is, <code>boost::end(a)</code> is reachable from <code>boost::begin(a)</code>
in a finite number of increments.</TD>
</TR>
<TR>
<TD VAlign="top">Completeness</TD>
<TD VAlign="top">An algorithm that iterates through the range <code>[begin(a),end(a))</code>
<TD VAlign="top">An algorithm that iterates through the range <code>[boost::begin(a),boost::end(a))</code>
will pass through every element of <code>a</code>.</TD>
</tr>
</table>
@ -228,7 +228,7 @@ otherwise</TD>
<p>
<A href="http://www.sgi.com/Technology/STL/Container.html">Container</A>
</p>
<p> <a href="boost_range.html#range_value">implementation of
<p> <a href="boost_range.html#boost::range_value">implementation of
metafunctions </a></p>
<p> <a href="boost_range.html#begin">implementation of
@ -251,7 +251,7 @@ otherwise</TD>
<h3>Description</h3>
<p>
A range <code>X</code> where <code>range_iterator&lt;X>::type</code> is a model
A range <code>X</code> where <code>boost::range_iterator&lt;X>::type</code> is a model
of <a
href="../../iterator/doc/new-iter-concepts.html#forward-traversal-iterators-lib-forward-traversal-iterators">Forward Traversal Iterator</a>
</p>
@ -264,14 +264,14 @@ Range</a>
<table cellpadding="5" border="1">
<TR>
<TD VAlign="top">Distance type</TD>
<TD VAlign="top"><code>range_difference&lt;X>::type</code></TD>
<TD VAlign="top"><code>boost::range_difference&lt;X>::type</code></TD>
<TD VAlign="top">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.</TD>
</TR>
<TR>
<TD VAlign="top">Size type</TD>
<TD VAlign="top"><code>range_size&lt;X>::type</code></TD>
<TD VAlign="top"><code>boost::range_size&lt;X>::type</code></TD>
<TD VAlign="top">An unsigned integral type that can represent any nonnegative
value of the Range's distance type.</TD>
</tr>
@ -287,8 +287,8 @@ Range</a>
</tr>
<TR>
<TD VAlign="top">Size of range</TD>
<TD VAlign="top"><code>size(a)</code></TD>
<TD VAlign="top"><code>range_size&lt;X>::type</code></TD>
<TD VAlign="top"><code>boost::size(a)</code></TD>
<TD VAlign="top"><code>boost::range_size&lt;X>::type</code></TD>
</TR>
</table>
@ -301,29 +301,29 @@ Range</a>
<TH>Postcondition</TH>
</TR>
<tr>
<TD VAlign="top"><code>size(a)</code></TD>
<TD VAlign="top"><code>boost::size(a)</code></TD>
<TD VAlign="top">Returns the size of the Range, that is, its number
of elements. Note <code>size(a) == 0u</code> is equivalent to
<code>empty(a).</code></TD>
<TD VAlign="top"><code>size(a) &gt;= 0</TD>
of elements. Note <code>boost::size(a) == 0u</code> is equivalent to
<code>boost::empty(a).</code></TD>
<TD VAlign="top"><code>boost::size(a) &gt;= 0</TD>
</TR>
</table>
<h3>Complexity guarantees</h3>
<p><code>size(a)</code> is at most amortized linear time.</p>
<p><code>boost::size(a)</code> is at most amortized linear time.</p>
<h3>Invariants</h3>
<p>
<Table border="1" cellpadding="5">
<TR>
<TD VAlign="top">Range size</TD>
<TD VAlign="top"><code>size(a)</code> is equal to the distance from <code>begin(a)</code>
to <code>end(a)</code>.</TD> </table>
<TD VAlign="top"><code>boost::size(a)</code> is equal to the distance from <code>boost::begin(a)</code>
to <code>boost::end(a)</code>.</TD> </table>
</p>
<h3>See also</h3>
<p> <a href="boost_range.html#range_difference">implementation of
<p> <a href="boost_range.html#boost::range_difference">implementation of
metafunctions </a></p>
<p> <a href="boost_range.html#size">implementation of
@ -347,7 +347,7 @@ of elements. Note <code>size(a) == 0u</code> is equivalent to
<h3>Description</h3> This concept provides access to iterators that traverse in
both directions (forward and reverse). The
<code>range_iterator&lt;X>::type</code> iterator must meet all of the requirements
<code>boost::range_iterator&lt;X>::type</code> iterator must meet all of the requirements
of <a
href="../../iterator/doc/new-iter-concepts.html#bidirectional-traversal-iterator
s-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterator.</a>
@ -359,7 +359,7 @@ s-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterator.</a>
<Table border>
<TR>
<TD VAlign="top">Reverse Iterator type</TD>
<TD VAlign="top"><code>range_reverse_iterator&lt;X>::type</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code></TD>
<TD VAlign="top">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
@ -368,7 +368,7 @@ s-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterator.</a>
<TR>
<TD VAlign="top">Const reverse iterator type</TD>
<TD
VAlign="top"><code>range_const_reverse_iterator&ltX>::type</code></TD>
VAlign="top"><code>boost::range_const_reverse_iterator&ltX>::type</code></TD>
<TD VAlign="top">A type of reverse iterator that may be used to examine, but not
to modify, a Range's elements.</TD>
</TR>
@ -386,27 +386,27 @@ VAlign="top"><code>range_const_reverse_iterator&ltX>::type</code></TD>
</TR>
<TR>
<TD VAlign="top">Beginning of range</TD>
<TD VAlign="top"><code>rbegin(a)</code></TD>
<TD VAlign="top"><code>range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>range_const_reverse_iterator&lt;X>::type</code>
<TD VAlign="top"><code>boost::rbegin(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
<TD VAlign="top">Equivalent to
<code>range_reverse_iterator&lt;X>::type(end(a))</code>.</TD> </TR>
<code>boost::range_reverse_iterator&lt;X>::type(boost::end(a))</code>.</TD> </TR>
<TR>
<TD VAlign="top">End of range</TD>
<TD VAlign="top"><code>rend(a)</code></TD>
<TD VAlign="top"><code>range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>range_const_reverse_iterator&lt;X>::type</code>
<TD VAlign="top"><code>boost::rend(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
<TD VAlign="top">Equivalent to
<code>range_reverse_iterator&lt;X>::type(begin(a))</code>.</TD> </tr>
<code>boost::range_reverse_iterator&lt;X>::type(boost::begin(a))</code>.</TD> </tr>
</table>
<h3>Complexity guarantees</h3>
<code>rbegin(a)</code> has the same complexity as <code>end(a)</code> and <code>rend(a)</code>
has the same complexity as <code>begin(a)</code> from <a
<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
href="#forward_range">Forward Range</a>.
<h3>Invariants</h3>
@ -414,20 +414,20 @@ otherwise.</TD>
<Table border="1" cellpadding="5">
<TR>
<TD VAlign="top">Valid reverse range</TD>
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[rbegin(a),rend(a))</code>
is a valid range, that is, <code>rend(a)</code> is reachable from <code>rbegin(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>boost::rend(a)</code> is reachable from <code>boost::rbegin(a)</code>
in a finite number of increments.</TD>
</TR>
<TR>
<TD VAlign="top">Completeness</TD>
<TD VAlign="top">An algorithm that iterates through the range <code>[rbegin(a),rend(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>
</tr>
</table>
</p>
<h3>See also</h3>
<p> <a href="boost_range.html#range_reverse_iterator">implementation of metafunctions </a></p>
<p> <a href="boost_range.html#boost::range_reverse_iterator">implementation of metafunctions </a></p>
<p> <a href="boost_range.html#rbegin">implementation of
functions </a></p>
@ -436,7 +436,7 @@ otherwise.</TD>
<a name=random_access_range><h2>Random Access Range</h2> <h3>Description</h3>
<p>
A range <code>X</code> where <code>range_iterator&lt;X>::type</code> is a model
A range <code>X</code> where <code>boost::range_iterator&lt;X>::type</code> is a model
of <a
href="../../iterator/doc/new-iter-concepts.html#random-access-traversal-iterators

View File

@ -19,7 +19,7 @@
<h2>Terminology and style guidelines </h2>
<p>
The use of a consistent terminology is as important for <a href="range.html#range">Range</a>s
The use of a consistent terminology is as important for <a href="range.html">Range</a>s
and range-based algorithms as it is for iterators and iterator-based algorithms.
If a conventional set of names are adopted, we can avoid misunderstandings and
write generic function prototypes that are <i>self-documenting</i>.

View File

@ -15,6 +15,7 @@
# pragma once
#endif
#include <boost/type_traits/remove_const.hpp>
#include <boost/range/config.hpp>
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
@ -46,7 +47,8 @@ namespace range_detail
}
template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<C>::type >::type
boost_range_begin( C& c )
{
return c.begin();
@ -140,7 +142,8 @@ namespace range_detail
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<T>::type >::type begin( T& r )
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \

View File

@ -16,12 +16,25 @@
#endif
#include <boost/range/config.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/difference_type.hpp>
#else
#include <boost/range/const_iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace boost
{
template< class T >
struct range_difference
{
typedef BOOST_DEDUCED_TYPENAME iterator_difference<
BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type >::type
type;
};
}
//#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//#include <boost/range/detail/difference_type.hpp>
//#else
/*
#include <cstddef>
#include <utility>
@ -30,13 +43,13 @@ namespace boost
//////////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////////
template< typename C >
struct range_difference
{
typedef BOOST_DEDUCED_TYPENAME C::difference_type type;
};
//////////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////////
@ -44,14 +57,14 @@ namespace boost
template< typename Iterator >
struct range_difference< std::pair<Iterator,Iterator> >
{
typedef BOOST_DEDUCED_TYPENAME
typedef BOOST_DEDUCED_TYPENAME
iterator_difference<Iterator>::type type;
};
template< typename Iterator >
struct range_difference< const std::pair<Iterator,Iterator> >
{
typedef BOOST_DEDUCED_TYPENAME
typedef BOOST_DEDUCED_TYPENAME
iterator_difference<Iterator>::type type;
};
@ -127,5 +140,6 @@ namespace boost
} // namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
*/
#endif

View File

@ -15,6 +15,7 @@
# pragma once
#endif
#include <boost/type_traits/remove_const.hpp>
#include <boost/range/config.hpp>
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
@ -25,34 +26,35 @@
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
namespace boost
namespace boost
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \
/**/
/**/
namespace range_detail
{
#endif
#endif
//////////////////////////////////////////////////////////////////////
// primary template
//////////////////////////////////////////////////////////////////////
template< typename C >
inline BOOST_DEDUCED_TYPENAME range_const_iterator<C>::type
boost_range_end( const C& c )
{
return c.end();
}
template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<C>::type >::type
boost_range_end( C& c )
{
return c.end();
}
//////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////
@ -62,13 +64,13 @@ namespace range_detail
{
return p.second;
}
template< typename Iterator >
inline Iterator boost_range_end( std::pair<Iterator,Iterator>& p )
{
return p.second;
}
//////////////////////////////////////////////////////////////////////
// array
//////////////////////////////////////////////////////////////////////
@ -76,13 +78,13 @@ namespace range_detail
template< typename T, std::size_t sz >
inline const T* boost_range_end( const T (&array)[sz] )
{
return range_detail::array_end<T,sz>( array );
return range_detail::array_end<T,sz>( array );
}
template< typename T, std::size_t sz >
inline T* boost_range_end( T (&array)[sz] )
{
return range_detail::array_end<T,sz>( array );
return range_detail::array_end<T,sz>( array );
}
//////////////////////////////////////////////////////////////////////
@ -134,18 +136,19 @@ namespace range_detail
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \
/**/
/**/
} // namespace 'range_detail'
#endif
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<T>::type >::type end( T& r )
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \
/**/
using namespace range_detail;
#endif
#endif
return boost_range_end( r );
}
@ -156,7 +159,7 @@ inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type end( const T& r )
!BOOST_WORKAROUND(__GNUC__, < 3) \
/**/
using namespace range_detail;
#endif
#endif
return boost_range_end( r );
}

View File

@ -26,7 +26,7 @@ namespace boost
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type
rbegin( C& c )
{
return BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type( end( c ) );
@ -35,16 +35,18 @@ rbegin( C& c )
#else
template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
rbegin( C& c )
{
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
iter_type;
return iter_type( end( c ) );
}
template< class C >
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
rbegin( const C& c )
{
typedef BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type

View File

@ -22,29 +22,31 @@
namespace boost
{
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type
rend( C& c )
{
return BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type( begin( c ) );
}
#else
template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
rend( C& c )
{
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
iter_type;
return iter_type( begin( c ) );
}
template< class C >
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
rend( const C& c )
{
typedef BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type

View File

@ -16,6 +16,54 @@
#endif
#include <boost/range/config.hpp>
/*
#include <boost/range/difference_type.hpp>
namespace boost
{
namespace range_detail
{
template< class T >
struct add_unsigned;
template<>
struct add_unsigned<short>
{
typedef unsigned short type;
};
template<>
struct add_unsigned<int>
{
typedef unsigned int type;
};
template<>
struct add_unsigned<long>
{
typedef unsigned long type;
};
#ifdef BOOST_HAS_LONG_LONG
template<>
struct add_unsigned<long long>
{
typedef unsigned long long type;
};
#endif
}
template< class T >
struct range_size
{
typedef BOOST_DEDUCED_TYPENAME range_detail::add_unsigned<
BOOST_DEDUCED_TYPENAME range_difference<T>::type >::type
type;
};
}
*/
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/size_type.hpp>
@ -29,13 +77,13 @@ namespace boost
//////////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////////
template< typename C >
struct range_size
{
typedef BOOST_DEDUCED_TYPENAME C::size_type type;
};
//////////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////////
@ -45,7 +93,7 @@ namespace boost
{
typedef std::size_t type;
};
template< typename Iterator >
struct range_size< const std::pair<Iterator,Iterator> >
{
@ -124,4 +172,5 @@ namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif

View File

@ -16,12 +16,26 @@
#endif
#include <boost/range/config.hpp>
#include <boost/range/iterator.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/value_type.hpp>
#else
#include <boost/iterator/iterator_traits.hpp>
namespace boost
{
template< class T >
struct range_value
{
typedef BOOST_DEDUCED_TYPENAME iterator_value<
BOOST_DEDUCED_TYPENAME range_iterator<T>::type >::type
type;
};
}
/*
#include <cstddef>
#include <utility>
@ -31,13 +45,13 @@ namespace boost
//////////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////////
template< typename C >
struct range_value
{
typedef BOOST_DEDUCED_TYPENAME C::value_type type;
};
//////////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////////
@ -45,15 +59,15 @@ namespace boost
template< typename Iterator >
struct range_value< std::pair<Iterator,Iterator> >
{
typedef BOOST_DEDUCED_TYPENAME
typedef BOOST_DEDUCED_TYPENAME
iterator_value<Iterator>::type type;
};
template< typename Iterator >
struct range_value< const std::pair<Iterator,Iterator> >
{
typedef BOOST_DEDUCED_TYPENAME
typedef BOOST_DEDUCED_TYPENAME
iterator_value<Iterator>::type type;
};
@ -72,7 +86,7 @@ namespace boost
{
typedef const T type;
};
//////////////////////////////////////////////////////////////////////////
// string
//////////////////////////////////////////////////////////////////////////
@ -126,7 +140,7 @@ namespace boost
};
} // namespace boost
*/
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif

View File

@ -39,11 +39,11 @@
<li><a href="doc/range.html">Range concepts:</a>
<ul>
<li> <a href="doc/range.html#single_pass_range">SinglePassRange</a>
<li> <a href="doc/range.html#range">ForwardRange</a>
<li> <a href="doc/range.html#forward_range">ForwardRange</a>
<li> <a href="doc/range.html#bidirectional_range">BidirectionalRange</a>
<li> <a href="doc/range.html#random_access_range">RandomAccessRange</a> </ul>
<li> <a href="doc/boost_range.html">Synopsis and Reference</a>
<li> <a href="doc/boost_range.html">Reference</a>
<li> <a href="doc/utility_class.html"> Utilities:</a>
<ul>
<li> Class <a href="doc/utility_class.html#iter_range"><code>iterator_range</code></a>

View File

@ -35,6 +35,7 @@ test-suite range :
[ range-test algorithm_example ]
[ range-test reversible_range ]
[ range-test const_ranges ]
[ range-test extension_mechanism ]
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
;

112
test/extension_mechanism.cpp Executable file
View File

@ -0,0 +1,112 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# pragma warn -8091 // supress warning in Boost.Test
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
//
// Generic range algorithm
//
template< class Rng >
typename boost::range_result_iterator<Rng>::type foo_algo( Rng& r )
{
//
// This will only compile for Rng = UDT if the qualified calls
// find boost_range_XXX via ADL.
//
return boost::size(r) == 0u ? boost::begin(r) : boost::end(r);
}
namespace Foo
{
//
// Our sample UDT
//
struct X
{
typedef std::vector<int> data_t;
typedef data_t::iterator iterator;
typedef data_t::const_iterator const_iterator;
typedef data_t::size_type size_type;
data_t vec;
void push_back( int i )
{ vec.push_back(i); }
};
//
// The required functions. No type-traits need
// to be defined because X defines the proper set of
// nested types.
//
inline X::iterator boost_range_begin( X& x )
{
return x.vec.begin();
}
inline X::const_iterator boost_range_begin( const X& x )
{
return x.vec.begin();
}
inline X::iterator boost_range_end( X& x )
{
return x.vec.end();
}
inline X::const_iterator boost_range_end( const X& x )
{
return x.vec.end();
}
inline X::size_type boost_range_size( const X& x )
{
return x.vec.size();
}
}
void check_extension()
{
Foo::X x;
x.push_back(3);
const Foo::X x2;
foo_algo( x );
foo_algo( x2 );
}
using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_extension ) );
return test;
}