mirror of
https://github.com/boostorg/utility.git
synced 2025-08-02 14:24:30 +02:00
changes for new policies interface
[SVN r11510]
This commit is contained in:
@@ -26,6 +26,37 @@
|
|||||||
"../../more/generic_programming.html#adaptors">adaptors</a> which apply
|
"../../more/generic_programming.html#adaptors">adaptors</a> which apply
|
||||||
specific useful behaviors to arbitrary base iterators.
|
specific useful behaviors to arbitrary base iterators.
|
||||||
|
|
||||||
|
<h2>Backward Compatibility Note</h2>
|
||||||
|
|
||||||
|
<p>The library's interface has changed since it was first released, breaking
|
||||||
|
backward compatibility:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
|
||||||
|
<li><a href="#policies">Policies classes</a> now operate on instances of the
|
||||||
|
whole <tt>iterator_adaptor</tt> object, rather than just operating on the
|
||||||
|
<tt>Base</tt> object. This change not only gives the policies class access
|
||||||
|
to both members of a pair of interacting iterators, but also eliminates the
|
||||||
|
need for the ugly <tt>type<Reference></tt> and
|
||||||
|
<tt>type<Difference></tt> parameters to various policy functions.
|
||||||
|
|
||||||
|
<li>The <a href="#named_template_parameters">Named Template Parameter</a>
|
||||||
|
interface has been made simpler, easier to use, and compatible with more
|
||||||
|
compilers.
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>Other Documentation</h2>
|
||||||
|
|
||||||
|
<p><a href="iterator_adaptors.pdf">``Policy Adaptors and the Boost Iterator
|
||||||
|
Adaptor Library''</a> is a technical paper describing this library and the
|
||||||
|
powerful design pattern on which it is based. It was presented at the <a
|
||||||
|
href="http://www.oonumerics.org/tmpw01">C++ Template Workshop</a> at OOPSLA
|
||||||
|
2001; the slides from the talk are available <a
|
||||||
|
href="iterator_adaptors.ppt">here</a>. Please note that while the slides
|
||||||
|
incorporate the minor interface changes described in the previous section,
|
||||||
|
the paper does not.
|
||||||
|
|
||||||
<h2>Table of Contents</h2>
|
<h2>Table of Contents</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@@ -385,40 +416,40 @@ typedef iterator_adaptor<foo_iterator, foo_policies,
|
|||||||
<pre>
|
<pre>
|
||||||
struct <a name="default_iterator_policies">default_iterator_policies</a>
|
struct <a name="default_iterator_policies">default_iterator_policies</a>
|
||||||
{
|
{
|
||||||
template <class BaseType>
|
// Some of these members were defined static, but Borland got confused
|
||||||
void initialize(BaseType&)
|
// and thought they were non-const. Also, Sun C++ does not like static
|
||||||
{ }
|
// function templates.
|
||||||
|
|
||||||
template <class Reference, class BaseType>
|
template <class Base>
|
||||||
Reference dereference(type<Reference>, const BaseType& x) const
|
void initialize(Base&)
|
||||||
{ return *x; }
|
{ }
|
||||||
|
|
||||||
template <class BaseType>
|
template <class IteratorAdaptor>
|
||||||
void increment(BaseType& x)
|
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const
|
||||||
{ ++x; }
|
{ return *x.base(); }
|
||||||
|
|
||||||
template <class BaseType1, class BaseType2>
|
template <class IteratorAdaptor>
|
||||||
bool equal(const BaseType1& x, const BaseType2& y) const
|
void increment(IteratorAdaptor& x)
|
||||||
{ return x == y; }
|
{ ++x.base(); }
|
||||||
|
|
||||||
template <class BaseType>
|
template <class IteratorAdaptor>
|
||||||
void decrement(BaseType& x)
|
void decrement(IteratorAdaptor& x)
|
||||||
{ --x; }
|
{ --x.base(); }
|
||||||
|
|
||||||
template <class BaseType, class DifferenceType>
|
template <class IteratorAdaptor, class DifferenceType>
|
||||||
void advance(BaseType& x, DifferenceType n)
|
void advance(IteratorAdaptor& x, DifferenceType n)
|
||||||
{ x += n; }
|
{ x.base() += n; }
|
||||||
|
|
||||||
template <class Difference, class BaseType1, class BaseType2>
|
template <class IteratorAdaptor1, class IteratorAdaptor2>
|
||||||
Difference distance(type<Difference>, const BaseType1& x, const BaseType2& y) const
|
typename IteratorAdaptor1::difference_type
|
||||||
{ return y - x; }
|
distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
|
||||||
|
{ return y.base() - x.base(); }
|
||||||
|
|
||||||
template <class BaseType1, class BaseType2>
|
template <class IteratorAdaptor1, class IteratorAdaptor2>
|
||||||
bool less(const BaseType1& x, const BaseType2& y) const
|
bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
|
||||||
{ return x < y; }
|
{ return x.base() == y.base(); }
|
||||||
};
|
};
|
||||||
</pre>
|
</pre></blockquote>
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<p>Template member functions are used throughout
|
<p>Template member functions are used throughout
|
||||||
<tt>default_iterator_policies</tt> so that it can be employed with a wide
|
<tt>default_iterator_policies</tt> so that it can be employed with a wide
|
||||||
@@ -451,7 +482,7 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
|
|||||||
iterator_adaptor(const
|
iterator_adaptor(const
|
||||||
iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)</tt>
|
iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)</tt>
|
||||||
<br><br>
|
<br><br>
|
||||||
This constructor allows for conversion from non-<tt>const</tt> to
|
This constructor allows for conversion from mutable to
|
||||||
constant adapted iterators. See <a href=
|
constant adapted iterators. See <a href=
|
||||||
"#iterator_interactions">below</a> for more details.<br>
|
"#iterator_interactions">below</a> for more details.<br>
|
||||||
Requires: <tt>B</tt> is convertible to <tt>Base</tt>.
|
Requires: <tt>B</tt> is convertible to <tt>Base</tt>.
|
||||||
@@ -483,34 +514,31 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
|
|||||||
|
|
||||||
<p>To implement a transform iterator we will only change one of the base
|
<p>To implement a transform iterator we will only change one of the base
|
||||||
iterator's behaviors, so the <tt>transform_iterator_policies</tt> class can
|
iterator's behaviors, so the <tt>transform_iterator_policies</tt> class can
|
||||||
inherit the rest from <tt>default_iterator_policies</tt>. We will define
|
inherit the rest from <tt>default_iterator_policies</tt>. We will define the
|
||||||
the <tt>dereference()</tt> member function, which is used to implement
|
<tt>dereference()</tt> member function, which is used to implement
|
||||||
<tt>operator*()</tt> of the adapted iterator. The implementation will
|
<tt>operator*()</tt> of the adapted iterator. The implementation will
|
||||||
dereference the base iterator and apply the function object. The
|
dereference the base iterator and apply the function object. The complete
|
||||||
<tt>type<Reference></tt> parameter is used to convey the appropriate
|
code for <tt>transform_iterator_policies</tt> is:<br>
|
||||||
return type. The complete code for <tt>transform_iterator_policies</tt>
|
|
||||||
is:<br>
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<blockquote><pre>
|
||||||
<blockquote>
|
template <class AdaptableUnaryFunction>
|
||||||
<pre>
|
struct transform_iterator_policies : public default_iterator_policies
|
||||||
template <class AdaptableUnaryFunction>
|
{
|
||||||
struct transform_iterator_policies : public default_iterator_policies
|
|
||||||
{
|
|
||||||
transform_iterator_policies() { }
|
transform_iterator_policies() { }
|
||||||
|
|
||||||
transform_iterator_policies(const AdaptableUnaryFunction& f)
|
transform_iterator_policies(const AdaptableUnaryFunction& f)
|
||||||
: m_f(f) { }
|
: m_f(f) { }
|
||||||
|
|
||||||
template <class Reference, class BaseIterator>
|
template <class IteratorAdaptor>
|
||||||
Reference dereference(type<Reference>, const BaseIterator& i) const
|
typename IteratorAdaptor::reference
|
||||||
{ return m_f(*i); }
|
dereference(const IteratorAdaptor& iter) const
|
||||||
|
{ return m_f(*iter.base()); }
|
||||||
|
|
||||||
AdaptableUnaryFunction m_f;
|
AdaptableUnaryFunction m_f;
|
||||||
};
|
};
|
||||||
</pre>
|
|
||||||
</blockquote>
|
</pre></blockquote>
|
||||||
|
|
||||||
<p>The next step is to use the <tt>iterator_adaptor</tt> template to
|
<p>The next step is to use the <tt>iterator_adaptor</tt> template to
|
||||||
construct the transform iterator type. The nicest way to package the
|
construct the transform iterator type. The nicest way to package the
|
||||||
@@ -546,7 +574,7 @@ public:
|
|||||||
|
|
||||||
<p>As a finishing touch, we will create an <a href=
|
<p>As a finishing touch, we will create an <a href=
|
||||||
"../../more/generic_programming.html#object_generator">object generator</a>
|
"../../more/generic_programming.html#object_generator">object generator</a>
|
||||||
for the transform iterator. This is a function that makes it more
|
for the transform iterator. Our object generator makes it more
|
||||||
convenient to create a transform iterator.<br>
|
convenient to create a transform iterator.<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -785,12 +813,12 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
|
|||||||
<tt>reference</tt> types for all <a href=
|
<tt>reference</tt> types for all <a href=
|
||||||
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterators</a> are
|
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterators</a> are
|
||||||
<tt>const T*</tt> and <tt>const T&</tt>, respectively. Stripping the
|
<tt>const T*</tt> and <tt>const T&</tt>, respectively. Stripping the
|
||||||
<tt>const</tt>-ness of <tt>Value</tt> allows you to easily
|
<tt>const</tt>-ness of <tt>Value</tt> allows you to easily make a constant
|
||||||
make a <tt>const</tt> iterator adaptor by supplying a <tt>const</tt> type
|
iterator by supplying a <tt>const</tt> type for <tt>Value</tt>, and allowing
|
||||||
for <tt>Value</tt>, and allowing the defaults for the <tt>Pointer</tt> and
|
the defaults for the <tt>Pointer</tt> and <tt>Reference</tt> parameters to
|
||||||
<tt>Reference</tt> parameters to take effect. Although compilers that don't
|
take effect. Although compilers that don't support partial specialization
|
||||||
support partial specialization won't strip <tt>const</tt> for you, having a
|
won't strip <tt>const</tt> for you, having a <tt>const value_type</tt> is
|
||||||
<tt>const value_type</tt> is often harmless in practice.
|
often harmless in practice.
|
||||||
|
|
||||||
<p><a name="2">[2]</a> If your compiler does not support partial
|
<p><a name="2">[2]</a> If your compiler does not support partial
|
||||||
specialization and the base iterator is a builtin pointer type, you
|
specialization and the base iterator is a builtin pointer type, you
|
||||||
|
Reference in New Issue
Block a user