diff --git a/doc/BidirectionalTraversal.html b/doc/BidirectionalTraversal.html index 9de555e..5bc8342 100644 --- a/doc/BidirectionalTraversal.html +++ b/doc/BidirectionalTraversal.html @@ -3,48 +3,333 @@
- +A class or built-in type X models the Bidirectional Traversal -concept if, in addition to X meeting the requirements of Forward +
A class or built-in type X models the Bidirectional Traversal +concept if, in addition to X meeting the requirements of Forward Traversal Iterator, the following expressions are valid and respect the stated semantics.
-Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal + | ||
---|---|---|
Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator) | ||
Expression | -Return Type | -Assertion/Semantics / + |
Expression | +Return Type | +Assertion/Semantics / Pre-/Post-condition |
--r | -X& | +|
--r | +X& | pre: there exists -s such that r +s such that r == ++s. post: -s is +s is dereferenceable. ---(++r) == r. ---r == --s -implies r == -s. &r == &--r. | +--(++r) == r. +--r == --s +implies r == +s. &r == &--r.
r-- | -convertible to const X& | +|
r-- | +convertible to const X& | { X tmp = r; @@ -54,18 +339,13 @@ implies r == |
iterator_traversal<X>::type | +||
iterator_traversal<X>::type | Convertible to -bidirectional_traversal_tag | +bidirectional_traversal_tag
A class or built-in type X models the Forward Traversal -concept if, in addition to X meeting the requirements of Default +
A class or built-in type X models the Forward Traversal +concept if, in addition to X meeting the requirements of Default Constructible and Single Pass Iterator, the following expressions are valid and respect the stated semantics.
-Forward Traversal Iterator Requirements (in addition to Default Constructible and Single Pass Iterator) | +||
---|---|---|
Forward Traversal Iterator Requirements (in addition to Default Constructible and Single Pass Iterator) | ||
Expression | -Return Type | -Assertion/Note | +
Expression | +Return Type | +Assertion/Note |
X u; | -X& | -note: u may have a + |
X u; | +X& | +note: u may have a singular value. |
++r | -X& | -r == s and r is + |
++r | +X& | +r == s and r is dereferenceable implies -++r == ++s. | +++r == ++s.
iterator_traits<X>::difference_type | +||
iterator_traits<X>::difference_type | A signed integral type representing the distance between iterators | |
iterator_traversal<X>::type | +||
iterator_traversal<X>::type | Convertible to -forward_traversal_tag | +forward_traversal_tag
A class or built-in type X models the Incrementable Iterator -concept if, in addition to X being Assignable and Copy +
A class or built-in type X models the Incrementable Iterator +concept if, in addition to X being Assignable and Copy Constructible, the following expressions are valid and respect the stated semantics.
-Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible) | +||
---|---|---|
Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible) | ||
Expression | -Return Type | -Assertion/Semantics | +
Expression | +Return Type | +Assertion/Semantics |
++r | -X& | -&r == &++r | +
++r | +X& | +&r == &++r |
r++ | -X | +|
r++ | +X | { X tmp = r; @@ -44,18 +329,13 @@ stated semantics. |
iterator_traversal<X>::type | +||
iterator_traversal<X>::type | Convertible to -incrementable_traversal_tag | +incrementable_traversal_tag
The Lvalue Iterator concept adds the requirement that the return -type of operator* type be a reference to the value type of the +type of operator* type be a reference to the value type of the iterator.
-Lvalue Iterator Requirements | +||
---|---|---|
Lvalue Iterator Requirements | ||
Expression | -Return Type | -Note/Assertion | +
Expression | +Return Type | +Note/Assertion |
*a | -T& | -T is cv -iterator_traits<X>::value_type + |
*a | +T& | +T is cv +iterator_traits<X>::value_type where cv is an optional cv-qualification. -pre: a is -dereferenceable. If a -== b then *a is -equivalent to *b. | +pre: a is +dereferenceable. If a +== b then *a is +equivalent to *b.
A class or built-in type X models the Random Access Traversal +
A class or built-in type X models the Random Access Traversal concept if the following expressions are valid and respect the stated -semantics. In the table below, Distance is -iterator_traits<X>::difference_type and n represents a -constant object of type Distance.
-Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal) | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Expression | -Return Type | -Operational Semantics | -Assertion/ + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Expression | +Return Type | +Operational Semantics | +Assertion/ Precondition | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
r += n | -X& | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
r += n | +X& | { Distance m = n; @@ -50,80 +335,75 @@ Precondition |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
a + n, n + a | -X | -{ X tmp = a; return tmp
+a + n, n + a |
+X |
+{ X tmp = a; return tmp
+= n; } |
|
r -= n |
-X& |
-return r += -n |
+r -= n |
+X& |
+return r += -n |
|
a - n |
-X |
-{ X tmp = a; return tmp
+ | a - n |
+X |
+{ X tmp = a; return tmp
-= n; } |
|
b - a |
-Distance |
-a < b ? distance(a,b)
+ | b - a |
+Distance |
+a < b ? distance(a,b)
: -distance(b,a) |
pre: there exists a
-value n of
-Distance such that
-a + n == b. b
+value n of
+Distance such that
+a + n == b. b
== a + (b - a). |
a[n] |
+a[n] |
convertible to T |
-*(a + n) |
+*(a + n) |
pre: a is a Readable
Iterator |
a[n] = v |
+a[n] = v |
convertible to T |
-*(a + n) = v |
+*(a + n) = v |
pre: a is a Writable
iterator |
a < b |
-convertible to bool |
-b - a > 0 |
-< is a total
+ | a < b |
+convertible to bool |
+b - a > 0 |
+< is a total
ordering relation |
a > b |
-convertible to bool |
-b < a |
-> is a total
+ | a > b |
+convertible to bool |
+b < a |
+> is a total
ordering relation |
a >= b |
-convertible to bool |
-!(a < b) |
+a >= b |
+convertible to bool |
+!(a < b) |
|
a <= b |
-convertible to bool |
-!(a > b) |
+a <= b |
+convertible to bool |
+!(a > b) |
|
iterator_traversal<X>::type |
+iterator_traversal<X>::type |
Convertible to
-random_access_traversal_tag |
+random_access_traversal_tag
|
|
|
A class or built-in type X models the Readable Iterator concept -for value type T if, in addition to X being Assignable and +
A class or built-in type X models the Readable Iterator concept +for value type T if, in addition to X being Assignable and Copy Constructible, the following expressions are valid and respect -the stated semantics. U is the type of any specified member of -type T.
-Readable Iterator Requirements (in addition to Assignable and Copy Constructible) | +|||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Readable Iterator Requirements (in addition to Assignable and Copy Constructible) | |||||||||||
Expression | -Return Type | -Note/Precondition | +|||||||||
Expression | +Return Type | +Note/Precondition | |||||||||
iterator_traits<X>::value_type | -T | +||||||||||
iterator_traits<X>::value_type | +T | Any non-reference, non-cv-qualified type | |||||||||
*a | -Convertible to T | -
*a |
+Convertible to T |
+
a->m |
-U& |
-pre: pre: (*a).m is well-defined. Equivalent to (*a).m. |
+a->m |
+U& |
+pre: pre: (*a).m is well-defined. Equivalent to (*a).m. |
|
A class or built-in type X models the Single Pass Iterator +
A class or built-in type X models the Single Pass Iterator concept if the following expressions are valid and respect the stated semantics.
-Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality + | ||
---|---|---|
Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable) | ||
Expression | -Return Type | -Assertion/Semantics / + |
Expression | +Return Type | +Assertion/Semantics / Pre-/Post-condition |
++r | -X& | -pre: r is + |
++r | +X& | +pre: r is dereferenceable; post: -r is dereferenceable or -r is past-the-end | +r is dereferenceable or +r is past-the-end
a == b | -convertible to bool | -== is an equivalence + |
a == b | +convertible to bool | +== is an equivalence relation over its domain |
a != b | -convertible to bool | -!(a == b) | +
a != b | +convertible to bool | +!(a == b) |
iterator_traversal<X>::type | +||
iterator_traversal<X>::type | Convertible to -single_pass_traversal_tag | +single_pass_traversal_tag
A class or built-in type X models the Swappable Iterator concept -if, in addition to X being Copy Constructible, the following +
A class or built-in type X models the Swappable Iterator concept +if, in addition to X being Copy Constructible, the following expressions are valid and respect the stated semantics.
-Swappable Iterator Requirements (in addition to Copy Constructible) | +||
---|---|---|
Swappable Iterator Requirements (in addition to Copy Constructible) | ||
Expression | -Return Type | -Postcondition | +
Expression | +Return Type | +Postcondition |
iter_swap(a, b) | -void | +|
iter_swap(a, b) | +void | the pointed to values are exchanged |
A class or built-in type X models the Writable Iterator concept -if, in addition to X being Copy Constructible, the following +
A class or built-in type X models the Writable Iterator concept +if, in addition to X being Copy Constructible, the following expressions are valid and respect the stated semantics. Writable Iterators have an associated set of value types.
-Writable Iterator Requirements (in addition to Copy Constructible) | +|||
---|---|---|---|
Writable Iterator Requirements (in addition to Copy Constructible) | |||
Expression | -Return Type | -Precondition | +|
Expression | +Return Type | +Precondition | |
*a = o | +|||
*a = o | - | pre: The type of o + | pre: The type of o is in the set of -value types of X | +value types of X
template < class Incrementable @@ -102,7 +393,7 @@ else if (numeric_limits<Incrementable>::is_specialized) random_access_traversal_tag, Incrementable, const Incrementable&) else return iterator-category( - iterator_traversal<Incrementable>::type, + iterator_traversal<Incrementable>::type, Incrementable, const Incrementable&)
The Incrementable argument shall be Copy Constructible and Assignable.
If iterator_category is convertible to forward_iterator_tag or forward_traversal_tag, the following must be well-formed:
@@ -138,8 +429,8 @@ n = i - j; i < j;Specializations of counting_iterator model Readable Lvalue Iterator. In addition, they model the concepts corresponding to the iterator tags to which their iterator_category is convertible. @@ -154,8 +445,8 @@ concepts modeled by Incrementable counting_iterator<Y,C2,D2> if and only if X is interoperable with Y.
In addition to the operations required by the concepts modeled by counting_iterator, counting_iterator provides the following operations.
@@ -228,6 +519,9 @@ operations.
template <class Incrementable>
counting_iterator<Incrementable> make_counting_iterator(Incrementable x);
@@ -241,9 +535,12 @@ with current construc
This example fills an array with numbers and a second array with pointers into the first array, using counting_iterator for both tasks. Finally indirect_iterator is used to print out the numbers @@ -261,7 +558,7 @@ std::copy(boost::make_counting_iterator(numbers.begin()), boost::make_counting_iterator(numbers.end()), std::back_inserter(pointers)); -std::cout << "indirectly printing out the numbers from 0 to " +std::cout << "indirectly printing out the numbers from 0 to " << N << std::endl; std::copy(boost::make_indirect_iterator(pointers.begin()), boost::make_indirect_iterator(pointers.end()), @@ -271,15 +568,10 @@ std::cout << std::endl;
The output is:
indirectly printing out the numbers from 0 to 7 -0 1 2 3 4 5 6 +0 1 2 3 4 5 6
The source code for this example can be found here.
Iterators play an important role in modern C++ programming. The iterator is the central abstraction of the algorithms of the Standard Library, allowing algorithms to be re-used in in a wide variety of @@ -225,16 +510,16 @@ of more specialized adaptors, such as the
This proposal is purely an addition to the C++ standard library. However, note that this proposal relies on the proposal for New Iterator Concepts.
This proposal is formulated in terms of the new iterator concepts as proposed in n1550, since user-defined and especially adapted iterators suffer from the well known categorization problems that are @@ -243,8 +528,8 @@ inherent to the current iterator categories.
is a direct mapping between new and old categories. This proposal could be reformulated using this mapping if n1550 was not accepted.The question of iterator interoperability is poorly addressed in the current standard. There are currently two defect reports that are concerned with interoperability issues.
@@ -263,11 +548,14 @@ reverse iterator types. The proposed new reverse_iterator template fixes the issues raised in 280. It provides the desired interoperability without introducing unwanted overloads.While the iterator interface is rich, there is a core subset of the interface that is necessary for all the functionality. We have identified the following core behaviors for iterators:
@@ -307,8 +595,8 @@ iterators, and a separate iterato impossible. -The user of iterator_facade derives his iterator class from a specialization of iterator_facade and passes the derived iterator class as iterator_facade's first template parameter. @@ -331,8 +619,8 @@ requirements.
iterator_facade and the operator implementations need to be able to access the core member functions in the derived class. Making the core member functions public would expose an implementation detail to @@ -395,7 +683,7 @@ provided, a class that acts as a gateway to the core member functions in the derived iterator class. The author of the derived class only needs to grant friendship to iterator_core_access to make his core member functions available to the library.
- +iterator_core_access will be typically implemented as an empty class containing only private static member functions which invoke the @@ -405,8 +693,8 @@ standardize the gateway protocol. Note that even if open a safety loophole, as every core member function preserves the invariants of the iterator.
The indexing operator for a generalized iterator presents special challenges. A random access iterator's operator[] is only required to return something convertible to its value_type. @@ -428,8 +716,8 @@ the implementation of her iterator is free to implement an class; it will hide the one supplied by iterator_facade from clients of her iterator.
The reference type of a readable iterator (and today's input iterator) need not in fact be a reference, so long as it is convertible to the iterator's value_type. When the value_type @@ -450,11 +738,14 @@ Patterns, C++ Report, February 1995, pp. 24-27.
The iterator_adaptor class template adapts some Base [3] type to create a new iterator. Instantiations of iterator_adaptor are derived from a corresponding instantiation of iterator_facade @@ -491,8 +782,8 @@ template parameter may not always be identical to the iterator's reference type, and will keep users from making mistakes based on that assumption.
This proposal also contains several examples of specialized adaptors which were easily implemented using iterator_adaptor:
struct use_default; @@ -593,16 +884,22 @@ template <class UnaryFunction> class function_output_iterator;
iterator_facade is a base class template that implements the interface of standard iterators in terms of a few core functions and associated types, to be supplied by a derived iterator class.
-template < class Derived @@ -686,12 +983,12 @@ template <class Dr, class V, class TC, class R, class D> Derived operator+ (typename Derived::difference_type n, iterator_facade<Dr,V,TC,R,D> const&);-
The iterator_category member of iterator_facade is
+The iterator_category member of iterator_facade is
iterator-category(CategoryOrTraversal, value_type, reference)
where iterator-category is defined as follows:
-+iterator-category(C,R,V) := if (C is convertible to std::input_iterator_tag || C is convertible to std::output_iterator_tag @@ -738,10 +1035,10 @@ traversal tags would add no information]The enable_if_interoperable template used above is for exposition purposes. The member operators should only be in an overload set -provided the derived types Dr1 and Dr2 are interoperable, +provided the derived types Dr1 and Dr2 are interoperable, meaning that at least one of the types is convertible to the other. The enable_if_interoperable approach uses SFINAE to take the operators -out of the overload set when the types are not interoperable. +out of the overload set when the types are not interoperable. The operators should behave as-if enable_if_interoperable were defined to be:
@@ -760,8 +1057,8 @@ struct enable_if_interoperable {};
The following table describes the typical valid expressions on iterator_facade's Derived parameter, depending on the iterator concept(s) it will model. The operations in the first @@ -774,8 +1071,8 @@ object of type X, X, and z is a constant object of a random access traversal iterator type interoperable with X.
-iterator_facade Core Operations
+iterator_facade Core Operations
Expression | -Return Type | -Assertion/Note | -Used to implement Iterator + |
---|---|---|---|
Expression | +Return Type | +Assertion/Note | +Used to implement Iterator Concept(s) |
The operations in this section are described in terms of operations on the core interface of Derived which may be inaccessible (i.e. private). The implementation should access these operations @@ -859,14 +1156,14 @@ of type pointer equal
&static_cast<Derived const*>(this)->dereference()-
Otherwise returns an object of unspecified type such that, +
Otherwise returns an object of unspecified type such that, (*static_cast<Derived const*>(this))->m is equivalent to (w = **static_cast<Derived const*>(this), w.m) for some temporary object w of type value_type.
unspecified operator[](difference_type n) const;
+unspecified operator[](difference_type n) const;
Returns: | if is_convertible<Dr2,Dr1>::value
|
---|---|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
+template <class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2> typename enable_if_interoperable<Dr1,Dr2,difference>::type @@ -1138,23 +1447,27 @@ operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,Return Type: if is_convertible<Dr2,Dr1>::value
-+-
- then
-- difference shall be -iterator_traits<Dr1>::difference_type.
-- Otherwise
-- difference shall be iterator_traits<Dr2>::difference_type
+- then
+- +
difference shall be +iterator_traits<Dr1>::difference_type.
+- Otherwise
+difference shall be iterator_traits<Dr2>::difference_type
+@@ -1162,11 +1475,14 @@ operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs, Returns: if is_convertible<Dr2,Dr1>::value
-
- then
-- -((Dr1 const&)lhs).distance_to((Dr2 const&)rhs).
-- Otherwise,
-- ((Dr2 const&)rhs).distance_to((Dr1 const&)lhs).
+- then
+- +
-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs).
+- Otherwise,
+((Dr2 const&)rhs).distance_to((Dr1 const&)lhs).
+
Each specialization of the iterator_adaptor class template is derived from a specialization of iterator_facade. The core interface functions expected by iterator_facade are implemented in terms of the @@ -1177,11 +1493,14 @@ Whether the derived class models any of the standard iterator concepts depends on the operations supported by the Base type and which core interface functions of iterator_facade are redefined in the Derived class.
-template < class Derived @@ -1191,7 +1510,7 @@ template < , class Reference = use_default , class Difference = use_default > -class iterator_adaptor +class iterator_adaptor : public iterator_facade<Derived, V', C', R', D'> // see details { friend class iterator_core_access; @@ -1204,12 +1523,12 @@ class iterator_adaptor typedef iterator_adaptor iterator_adaptor_; Base const& base_reference() const; Base& base_reference(); - private: // Core iterator interface for iterator_facade. + private: // Core iterator interface for iterator_facade. typename iterator_adaptor::reference dereference() const; template < class OtherDerived, class OtherIterator, class V, class C, class R, class D - > + > bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const; void advance(typename iterator_adaptor::difference_type n); @@ -1218,7 +1537,7 @@ class iterator_adaptor template < class OtherDerived, class OtherIterator, class V, class C, class R, class D - > + > typename iterator_adaptor::difference_type distance_to( iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const; @@ -1227,13 +1546,13 @@ class iterator_adaptor };
static_cast<Derived*>(iterator_adaptor*) shall be well-formed. The Base argument shall be Assignable and Copy Constructible.
The V', C', R', and D' parameters of the iterator_facade used as a base class in the summary of iterator_adaptor above are defined as follows:
@@ -1273,8 +1592,8 @@ expression involving ``Derived`` in those concepts' requirements. -->iterator_adaptor();
Requires: | The Base type must be Default Constructible. |
---|---|
Returns: | An instance of iterator_adaptor with + |
Returns: | An instance of iterator_adaptor with m_iterator default constructed. |
Base const& base_reference() const;
typename iterator_adaptor::reference dereference() const;
The enable_if_convertible<X,Y>::type expression used in this section is for exposition purposes. The converting constructors for specialized adaptors should be only be in an overload set provided that an object of type X is implicitly convertible to an object of -type Y. +type Y. The signatures involving enable_if_convertible should behave as-if enable_if_convertible were defined to be:
@@ -1424,10 +1743,13 @@ of enable_if_convertible diagnostic required.[Note: The enable_if_convertible approach uses SFINAE to take the constructor out of the overload set when the types are not -implicitly convertible. +implicitly convertible. ]
--Indirect iterator
++Indirect iterator
+ + +indirect_iterator adapts an iterator by applying an extra dereference inside of operator*(). For example, this iterator adaptor makes it possible to view a container of pointers @@ -1436,8 +1758,8 @@ iterator adaptor makes it possible to view a container of pointers auxiliary traits, pointee and indirect_reference, to provide support for underlying iterators whose value_type is not an iterator.
--Class template pointee
++-Class template pointee
@@ -1480,8 +1802,8 @@ else }-Class template indirect_reference
++-Class template indirect_reference
@@ -1515,8 +1837,11 @@ else std::iterator_traits<Dereferenceable>::reference-Class template indirect_iterator
++-Class template indirect_iterator
+ + +template < class Iterator @@ -1573,9 +1898,9 @@ if (Reference is use_default) then else typedef Reference reference; -if (Value is use_default) then +if (Value is use_default) then typedef pointee<V>::type* pointer; -else +else typedef Value* pointer; if (Difference is use_default) @@ -1593,8 +1918,8 @@ else ) iterator_category;-indirect_iterator requirements
++-indirect_iterator requirements
The expression *v, where v is an object of iterator_traits<Iterator>::value_type, shall be valid expression and convertible to reference. Iterator shall @@ -1607,8 +1932,8 @@ the requirements indicated by ite parameter is not use_default, as implied by the algorithm for deducing the default for the value_type member.]
-indirect_iterator models
++-indirect_iterator models
In addition to the concepts indicated by iterator_category and by iterator_traversal<indirect_iterator>::type, a specialization of indirect_iterator models the following @@ -1628,8 +1953,8 @@ expression (where t i indirect_iterator<Y,V2,C2,R2,D2> if and only if X is interoperable with Y.
-indirect_iterator operations
++indirect_iterator operations
In addition to the operations required by the concepts described above, specializations of indirect_iterator provide the following operations.
@@ -1640,7 +1965,7 @@ following operations.- Requires: Iterator must be Default Constructible. Effects: Constructs an instance of indirect_iterator with + @@ -1673,7 +1998,7 @@ indirect_iterator( Effects: Constructs an instance of indirect_iterator with a default-constructed m_iterator. - Requires: Iterator2 is implicitly convertible to Iterator. Effects: Constructs an instance of indirect_iterator whose + @@ -1720,12 +2045,18 @@ indirect_iterator( Effects: Constructs an instance of indirect_iterator whose m_iterator subobject is constructed from y.base().
The reverse iterator adaptor iterates through the adapted iterator range in the opposite direction.
-
template <class Iterator>
class reverse_iterator
@@ -1761,14 +2092,14 @@ Lvalue Iterator, then iterator_ca
bidirectional_iterator_tag. Otherwise, iterator_category is
convertible to input_iterator_tag.
Iterator must be a model of Bidirectional Traversal Iterator. The type iterator_traits<Iterator>::reference must be the type of *i, where i is an object of type Iterator.
A specialization of reverse_iterator models the same iterator traversal and iterator access concepts modeled by its Iterator argument. In addition, it may model old iterator concepts @@ -1779,8 +2110,8 @@ specified in the following table:
In addition to the operations required by the concepts modeled by reverse_iterator, reverse_iterator provides the following operations.
@@ -1818,7 +2149,7 @@ operations.The transform iterator adapts an iterator by modifying the operator* to apply a function object to the result of dereferencing the iterator and returning the result.
-
template <class UnaryFunction,
- class Iterator,
- class Reference = use_default,
+ class Iterator,
+ class Reference = use_default,
class Value = use_default>
class transform_iterator
{
@@ -1955,8 +2292,8 @@ convertible to forward_iterator_t
model Readable Lvalue Iterator then iterator_category is
convertible to input_iterator_tag.
The type UnaryFunction must be Assignable, Copy Constructible, and the expression f(*i) must be valid where f is an object of type UnaryFunction, i is an object of type Iterator, and @@ -1964,8 +2301,8 @@ where the type of f(*i)result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type.
The argument Iterator shall model Readable Iterator.
The resulting transform_iterator models the most refined of the following that is also modeled by Iterator.
@@ -1986,8 +2323,8 @@ the Iterator argument- If Iterator models -then transform_iterator models +@@ -2011,8 +2348,8 @@ mutable iterator (as defined in the old iterator requirements). transform_iterator<F2, Y, R2, V2> if and only if X is interoperable with Y. - If Iterator models +then transform_iterator models -transform_iterator operations
++transform_iterator operations
In addition to the operations required by the concepts modeled by transform_iterator, transform_iterator provides the following operations.
@@ -2107,8 +2444,11 @@ initialized to t.functor()
The filter iterator adaptor creates a view of an iterator range in which some elements of the range are skipped. A predicate function object controls which elements are skipped. When the predicate is @@ -2119,12 +2459,12 @@ adaptor to know when to stop so as to avoid going past the end of the underlying range. A filter iterator is therefore constructed with pair of iterators indicating the range of elements in the unfiltered sequence to be traversed.
-template <class Predicate, class Iterator> class filter_iterator @@ -2157,15 +2497,15 @@ private:
If Iterator models Readable Lvalue Iterator and Bidirectional Traversal Iterator then iterator_category is convertible to -std::bidirectional_iterator_tag. +std::bidirectional_iterator_tag. Otherwise, if Iterator models Readable Lvalue Iterator and Forward Traversal Iterator then iterator_category is convertible to -std::forward_iterator_tag. +std::forward_iterator_tag. Otherwise iterator_category is convertible to std::input_iterator_tag.
The Iterator argument shall meet the requirements of Readable Iterator and Single Pass Iterator or it shall meet the requirements of Input Iterator.
@@ -2175,8 +2515,8 @@ the expression p(x) m iterator_traits<Iterator>::value_type, and where the type of p(x) must be convertible to bool.The concepts that filter_iterator models are dependent on which concepts the Iterator argument models, as specified in the following tables.
@@ -2186,8 +2526,8 @@ following tables.filter_iterator<P1, X> is interoperable with filter_iterator<P2, Y> +
filter_iterator<P1, X> is interoperable with filter_iterator<P2, Y> if and only if X is interoperable with Y.
In addition to those operations required by the concepts that filter_iterator models, filter_iterator provides the following operations.
@@ -2264,7 +2604,7 @@ operations.counting_iterator adapts an object by adding an operator* that returns the current value of the object. All other iterator operations are forwarded to the adapted object.
-template < class Incrementable @@ -2409,7 +2755,7 @@ else if (numeric_limits<Incrementable>::is_specialized) random_access_traversal_tag, Incrementable, const Incrementable&) else return iterator-category( - iterator_traversal<Incrementable>::type, + iterator_traversal<Incrementable>::type, Incrementable, const Incrementable&)
The Incrementable argument shall be Copy Constructible and Assignable.
If iterator_category is convertible to forward_iterator_tag or forward_traversal_tag, the following must be well-formed:
@@ -2445,8 +2791,8 @@ n = i - j; i < j;Specializations of counting_iterator model Readable Lvalue Iterator. In addition, they model the concepts corresponding to the iterator tags to which their iterator_category is convertible. @@ -2461,8 +2807,8 @@ concepts modeled by Incrementable counting_iterator<Y,C2,D2> if and only if X is interoperable with Y.
In addition to the operations required by the concepts modeled by counting_iterator, counting_iterator provides the following operations.
@@ -2537,8 +2883,11 @@ operations.The function output iterator adaptor makes it easier to create custom output iterators. The adaptor takes a unary function and creates a model of Output Iterator. Each item assigned to the output iterator is @@ -2546,11 +2895,14 @@ passed as an argument to the unary function. The motivation for this iterator is that creating a conforming output iterator is non-trivial, particularly because the proper implementation usually requires a proxy object.
-#include <boost/function_output_iterator.hpp>@@ -2576,23 +2928,23 @@ private: };
UnaryFunction must be Assignable and Copy Constructible.
function_output_iterator is a model of the Writable and Incrementable Iterator concepts.
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
Effects: | Constructs an instance of function_output_iterator + | ||
---|---|---|---|
Effects: | Constructs an instance of function_output_iterator with m_f constructed from f. |
Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. |
abstract: | The filter iterator adaptor creates a view of an iterator range in + |
---|---|
abstract: | + + +The filter iterator adaptor creates a view of an iterator range in which some elements of the range are skipped. A predicate function object controls which elements are skipped. When the predicate is -applied to an element, if it returns true then the element is -retained and if it returns false then the element is skipped +applied to an element, if it returns true then the element is +retained and if it returns false then the element is skipped over. When skipping over elements, it is necessary for the filter adaptor to know when to stop so as to avoid going past the end of the underlying range. A filter iterator is therefore constructed with pair @@ -49,22 +337,22 @@ sequence to be traversed. |
template <class Predicate, class Iterator> class filter_iterator @@ -95,39 +383,39 @@ private: Iterator m_end; // exposition only };-
If Iterator models Readable Lvalue Iterator and Bidirectional Traversal -Iterator then iterator_category is convertible to -std::bidirectional_iterator_tag. -Otherwise, if Iterator models Readable Lvalue Iterator and Forward Traversal -Iterator then iterator_category is convertible to -std::forward_iterator_tag. -Otherwise iterator_category is -convertible to std::input_iterator_tag.
+If Iterator models Readable Lvalue Iterator and Bidirectional Traversal +Iterator then iterator_category is convertible to +std::bidirectional_iterator_tag. +Otherwise, if Iterator models Readable Lvalue Iterator and Forward Traversal +Iterator then iterator_category is convertible to +std::forward_iterator_tag. +Otherwise iterator_category is +convertible to std::input_iterator_tag.
The Iterator argument shall meet the requirements of Readable +
The Iterator argument shall meet the requirements of Readable Iterator and Single Pass Iterator or it shall meet the requirements of Input Iterator.
-The Predicate argument must be Assignable, Copy Constructible, and -the expression p(x) must be valid where p is an object of type -Predicate, x is an object of type -iterator_traits<Iterator>::value_type, and where the type of -p(x) must be convertible to bool.
+The Predicate argument must be Assignable, Copy Constructible, and +the expression p(x) must be valid where p is an object of type +Predicate, x is an object of type +iterator_traits<Iterator>::value_type, and where the type of +p(x) must be convertible to bool.
The concepts that filter_iterator models are dependent on which -concepts the Iterator argument models, as specified in the +
The concepts that filter_iterator models are dependent on which +concepts the Iterator argument models, as specified in the following tables.
-If Iterator models | -then filter_iterator models | +
---|---|
If Iterator models | +then filter_iterator models |
If Iterator models | -then filter_iterator models | +
---|---|
If Iterator models | +then filter_iterator models |
If Iterator models | -then filter_iterator models | +
---|---|
If Iterator models | +then filter_iterator models |
filter_iterator<P1, X> is interoperable with filter_iterator<P2, Y> -if and only if X is interoperable with Y.
+filter_iterator<P1, X> is interoperable with filter_iterator<P2, Y> +if and only if X is interoperable with Y.
-In addition to those operations required by the concepts that -filter_iterator models, filter_iterator provides the following +filter_iterator models, filter_iterator provides the following operations.
-filter_iterator();
-Requires: | Predicate and Iterator must be Default Constructible. | +
---|---|
Requires: | Predicate and Iterator must be Default Constructible. |
Effects: | Constructs a filter_iterator whose``m_pred``, m_iter, and m_end + |
Effects: | Constructs a filter_iterator whose``m_pred``, m_iter, and m_end members are a default constructed. |
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
-Effects: | Constructs a filter_iterator where m_iter is either -the first position in the range [x,end) such that f(*m_iter) == true -or else``m_iter == end``. The member m_pred is constructed from -f and m_end from end. | +
---|---|
Effects: | Constructs a filter_iterator where m_iter is either +the first position in the range [x,end) such that f(*m_iter) == true +or else``m_iter == end``. The member m_pred is constructed from +f and m_end from end. |
filter_iterator(Iterator x, Iterator end = Iterator());
-Requires: | Predicate must be Default Constructible and -Predicate is a class type (not a function pointer). | +
---|---|
Requires: | Predicate must be Default Constructible and +Predicate is a class type (not a function pointer). |
Effects: | Constructs a filter_iterator where m_iter is either -the first position in the range [x,end) such that m_pred(*m_iter) == true -or else``m_iter == end``. The member m_pred is default constructed. | +
Effects: | Constructs a filter_iterator where m_iter is either +the first position in the range [x,end) such that m_pred(*m_iter) == true +or else``m_iter == end``. The member m_pred is default constructed. |
Requires: | OtherIterator is implicitly convertible to Iterator. | +
---|---|
Requires: | OtherIterator is implicitly convertible to Iterator. |
Effects: | Constructs a filter iterator whose members are copied from t. | +
Effects: | Constructs a filter iterator whose members are copied from t. |
Predicate predicate() const;
-Returns: | m_pred | +
---|---|
Returns: | m_pred |
Iterator end() const;
-Returns: | m_end | +
---|---|
Returns: | m_end |
Iterator const& base() const;
-Returns: | m_iterator | +
---|---|
Returns: | m_iterator |
reference operator*() const;
-Returns: | *m_iter | +
---|---|
Returns: | *m_iter |
filter_iterator& operator++();
-Effects: | Increments m_iter and then continues to -increment m_iter until either m_iter == m_end -or m_pred(*m_iter) == true. | +
---|---|
Effects: | Increments m_iter and then continues to +increment m_iter until either m_iter == m_end +or m_pred(*m_iter) == true. |
Returns: | *this | +
Returns: | *this |
template <class Predicate, class Iterator> filter_iterator<Predicate,Iterator> make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());-
This example uses filter_iterator and then -make_filter_iterator to output only the positive integers from an -array of integers. Then make_filter_iterator is is used to output -the integers greater than -2.
+This example uses filter_iterator and then +make_filter_iterator to output only the positive integers from an +array of integers. Then make_filter_iterator is is used to output +the integers greater than -2.
struct is_positive_number { bool operator()(int x) { return 0 < x; } @@ -384,17 +678,12 @@ int main()
The output is:
-4 5 8 -4 5 8 -0 -1 4 5 8 +4 5 8 +4 5 8 +0 -1 4 5 8
The source code for this example can be found here.
abstract: | The function output iterator adaptor makes it easier to create custom + |
---|---|
abstract: | + + +The function output iterator adaptor makes it easier to create custom output iterators. The adaptor takes a unary function and creates a model of Output Iterator. Each item assigned to the output iterator is passed as an argument to the unary function. The motivation for this @@ -46,8 +334,8 @@ proxy object. |
#include <boost/function_output_iterator.hpp>@@ -83,23 +374,23 @@ private: };
UnaryFunction must be Assignable and Copy Constructible.
function_output_iterator is a model of the Writable and Incrementable Iterator concepts.
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
Effects: | Constructs an instance of function_output_iterator + |
---|---|
Effects: | Constructs an instance of function_output_iterator with m_f constructed from f. |
struct string_appender { @@ -159,7 +453,7 @@ int main(int, char*[]) x.push_back("!"); std::string s = ""; - std::copy(x.begin(), x.end(), + std::copy(x.begin(), x.end(), boost::make_function_output_iterator(string_appender(s))); std::cout << s << std::endl; @@ -169,10 +463,5 @@ int main(int, char*[])
The iterator categories defined in C++98 are extremely limiting because they bind together two orthogonal concepts: traversal and element access. For example, because a random access iterator is @@ -85,8 +370,8 @@ concepts, see our
Standard Proposal For New-Style Iterators (PDF)
Writing standard-conforming iterators is tricky, but the need comes up often. In order to ease the implementation of new iterators, the Boost.Iterator library provides the iterator_facade class template, @@ -112,8 +397,8 @@ and accepted into the first C++ technical report; see our
Standard Proposal For Iterator Facade and Adaptor (PDF)for more details.
The iterator library supplies a useful suite of standard-conforming iterator templates based on the Boost iterator facade and adaptor.
If you have been using the old Boost Iterator Adaptor library to +
If you have been using the old Boost Iterator Adaptor library to implement iterators, you probably wrote a Policies class which captures the core operations of your iterator. In the new library design, you'll move those same core operations into the body of the @@ -190,8 +475,8 @@ template argument, if explicitly specified) is a true reference type, transform_iterator will behave like projection_iterator used to.
In 2000 Dave Abrahams was writing an iterator for a container of pointers, which would access the pointed-to elements when dereferenced. Naturally, being a library writer, he decided to @@ -232,10 +517,5 @@ LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
abstract: | indirect_iterator adapts an iterator by applying an + |
---|---|
abstract: | + + +indirect_iterator adapts an iterator by applying an extra dereference inside of operator*(). For example, this iterator adaptor makes it possible to view a container of pointers (e.g. list<foo*>) as if it were a container of the pointed-to type @@ -47,8 +335,8 @@ not an iterator. |
template < class Iterator @@ -115,9 +406,9 @@ if (Reference is use_default) then else typedef Reference reference; -if (Value is use_default) then +if (Value is use_default) then typedef pointee<V>::type* pointer; -else +else typedef Value* pointer; if (Difference is use_default) @@ -135,8 +426,8 @@ else ) iterator_category;
The expression *v, where v is an object of iterator_traits<Iterator>::value_type, shall be valid expression and convertible to reference. Iterator shall @@ -149,8 +440,8 @@ the requirements indicated by ite parameter is not use_default, as implied by the algorithm for deducing the default for the value_type member.]
In addition to the concepts indicated by iterator_category and by iterator_traversal<indirect_iterator>::type, a specialization of indirect_iterator models the following @@ -170,8 +461,8 @@ expression (where t i indirect_iterator<Y,V2,C2,R2,D2> if and only if X is interoperable with Y.
In addition to the operations required by the concepts described above, specializations of indirect_iterator provide the following operations.
@@ -182,7 +473,7 @@ following operations.This example prints an array of characters, using indirect_iterator to access the array of characters through an array of pointers. Next indirect_iterator is used with the @@ -309,7 +603,7 @@ std::cout << std::endl; // Example of using make_indirect_iterator() -std::copy(boost::make_indirect_iterator(pointers_to_chars), +std::copy(boost::make_indirect_iterator(pointers_to_chars), boost::make_indirect_iterator(pointers_to_chars + N), std::ostream_iterator<char>(std::cout, ",")); std::cout << std::endl; @@ -323,10 +617,5 @@ a,b,c,d,e,f,g,
The source code for this example can be found here.
template < class Iterator @@ -48,9 +333,9 @@ private: Iterator m_iterator; // exposition };-
The member types of indirect_iterator are defined according to -the following pseudo-code, where V is -iterator_traits<Iterator>::value_type
+The member types of indirect_iterator are defined according to +the following pseudo-code, where V is +iterator_traits<Iterator>::value_type
if (Value is use_default) then typedef remove_const<pointee<V>::type>::type value_type; @@ -65,9 +350,9 @@ if (Reference is use_default) then else typedef Reference reference; -if (Value is use_default) then +if (Value is use_default) then typedef pointee<V>::type* pointer; -else +else typedef Value* pointer; if (Difference is use_default) @@ -84,65 +369,65 @@ else CategoryOrTraversal,``reference``,``value_type`` ) iterator_category;-
The expression *v, where v is an object of -iterator_traits<Iterator>::value_type, shall be valid -expression and convertible to reference. Iterator shall -model the traversal concept indicated by iterator_category. -Value, Reference, and Difference shall be chosen so -that value_type, reference, and difference_type meet -the requirements indicated by iterator_category.
+The expression *v, where v is an object of +iterator_traits<Iterator>::value_type, shall be valid +expression and convertible to reference. Iterator shall +model the traversal concept indicated by iterator_category. +Value, Reference, and Difference shall be chosen so +that value_type, reference, and difference_type meet +the requirements indicated by iterator_category.
[Note: there are further requirements on the -iterator_traits<Iterator>::value_type if the Value -parameter is not use_default, as implied by the algorithm for -deducing the default for the value_type member.]
+iterator_traits<Iterator>::value_type if the Value +parameter is not use_default, as implied by the algorithm for +deducing the default for the value_type member.]In addition to the concepts indicated by iterator_category -and by iterator_traversal<indirect_iterator>::type, a -specialization of indirect_iterator models the following -concepts, Where v is an object of -iterator_traits<Iterator>::value_type:
+In addition to the concepts indicated by iterator_category +and by iterator_traversal<indirect_iterator>::type, a +specialization of indirect_iterator models the following +concepts, Where v is an object of +iterator_traits<Iterator>::value_type:
--
- Readable Iterator if reference(*v) is convertible to -value_type.
-- Writable Iterator if reference(*v) = t is a valid -expression (where t is an object of type -indirect_iterator::value_type)
-- Lvalue Iterator if reference is a reference type.
+- Readable Iterator if reference(*v) is convertible to +value_type.
+- Writable Iterator if reference(*v) = t is a valid +expression (where t is an object of type +indirect_iterator::value_type)
+- Lvalue Iterator if reference is a reference type.
indirect_iterator<X,V1,C1,R1,D1> is interoperable with -indirect_iterator<Y,V2,C2,R2,D2> if and only if X is -interoperable with Y.
+indirect_iterator<X,V1,C1,R1,D1> is interoperable with +indirect_iterator<Y,V2,C2,R2,D2> if and only if X is +interoperable with Y.
In addition to the operations required by the concepts described -above, specializations of indirect_iterator provide the +above, specializations of indirect_iterator provide the following operations.
-indirect_iterator();
-Requires: | Iterator must be Default Constructible. | +
---|---|
Requires: | Iterator must be Default Constructible. |
Effects: | Constructs an instance of indirect_iterator with -a default-constructed m_iterator. | +
Effects: | Constructs an instance of indirect_iterator with +a default-constructed m_iterator. |
indirect_iterator(Iterator x);
-Effects: | Constructs an instance of indirect_iterator with -m_iterator copy constructed from x. | +
---|---|
Effects: | Constructs an instance of indirect_iterator with +m_iterator copy constructed from x. |
Requires: | Iterator2 is implicitly convertible to Iterator. | +
---|---|
Requires: | Iterator2 is implicitly convertible to Iterator. |
Effects: | Constructs an instance of indirect_iterator whose -m_iterator subobject is constructed from y.base(). | +
Effects: | Constructs an instance of indirect_iterator whose +m_iterator subobject is constructed from y.base(). |
Iterator const& base() const;
-Returns: | m_iterator | +
---|---|
Returns: | m_iterator |
reference operator*() const;
-Returns: | **m_iterator | +
---|---|
Returns: | **m_iterator |
indirect_iterator& operator++();
-Effects: | ++m_iterator | +
---|---|
Effects: | ++m_iterator |
Returns: | *this | +
Returns: | *this |
indirect_iterator& operator--();
-Effects: | --m_iterator | +
---|---|
Effects: | --m_iterator |
Returns: | *this | +
Returns: | *this |
Author: | David Abrahams and Jeremy Siek | -
---|---|
Contact: | dave@boost-consulting.com, jsiek@osl.iu.edu | -
Organization: | Boost Consulting, Indiana University Bloomington | -
date: | $Date$ | -
Copyright: | Copyright David Abrahams, Jeremy Siek 2003. Use, modification and + |
Author: | +David Abrahams and Jeremy Siek |
Contact: | +dave@boost-consulting.com, jsiek@osl.iu.edu |
Organization: | +Boost Consulting, Indiana University Bloomington |
Date: | +2003-11-19 |
Copyright: | +Copyright David Abrahams, Jeremy Siek 2003. 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) | -
The is_writable and is_swappable traits classes in N1550 +
The is_writable and is_swappable traits classes in N1550 provide a mechanism for determining at compile time if an iterator type is a model of the new Writable Iterator and Swappable Iterator -concepts, analogous to iterator_traits<X>::iterator_category +concepts, analogous to iterator_traits<X>::iterator_category for the old iterator concepts. For backward compatibility, -is_writable and is_swappable not only work with new +is_writable and is_swappable not only work with new iterators, but they also are intended to work for old iterators (iterators that meet the requirements for one of the iterator concepts in the current standard). In the case of old iterators, the writability and swapability is deduced based on the -iterator_category and also the reference type. The +iterator_category and also the reference type. The specification for this deduction gives false positives for forward iterators that have non-assignable value types.
-To review, the part of the is_writable trait definition which +
To review, the part of the is_writable trait definition which applies to old iterators is:
if (cat is convertible to output_iterator_tag) return true; else if (cat is convertible to forward_iterator_tag - and iterator_traits<Iterator>::reference is a + and iterator_traits<Iterator>::reference is a mutable reference) return true; else return false;-
Suppose the value_type of the iterator It has a private +
Suppose the value_type of the iterator It has a private assignment operator:
class B { @@ -74,31 +360,31 @@ private: B& operator=(const B&); };-
and suppose the reference type of the iterator is B&. In -that case, is_writable<It>::value will be true when in fact -attempting to write into B will cause an error.
-The same problem applies to is_swappable.
+and suppose the reference type of the iterator is B&. In +that case, is_writable<It>::value will be true when in fact +attempting to write into B will cause an error.
+The same problem applies to is_swappable.
Remove the is_writable and is_swappable traits, and remove the +
Remove the is_writable and is_swappable traits, and remove the requirements in the Writable Iterator and Swappable Iterator concepts that require their models to support these traits.
Change the is_readable specification to be: -is_readable<X>::type is true_type if the -result type of X::operator* is convertible to -iterator_traits<X>::value_type and is false_type -otherwise. Also, is_readable is required to satisfy +
Change the is_readable specification to be: +is_readable<X>::type is true_type if the +result type of X::operator* is convertible to +iterator_traits<X>::value_type and is false_type +otherwise. Also, is_readable is required to satisfy the requirements for the UnaryTypeTrait concept (defined in the type traits proposal).
-Remove the requirement for support of the is_readable trait from +
Remove the requirement for support of the is_readable trait from the Readable Iterator concept.
Remove the iterator_tag class.
+Remove the iterator_tag class.
Change the specification of traversal_category to:
+Change the specification of traversal_category to:
traversal-category(Iterator) = let cat = iterator_traits<Iterator>::iterator_category @@ -120,14 +406,14 @@ traversal-category(Iterator) =
Each specialization of the iterator_adaptor class template is derived from a specialization of iterator_facade. The core interface functions expected by iterator_facade are implemented in terms of the @@ -53,8 +341,8 @@ Whether the derived class models any of the standard iterator concepts depends on the operations supported by the Base type and which core interface functions of iterator_facade are redefined in the Derived class.
-The iterator_adaptor class template adapts some Base [1] type to create a new iterator. Instantiations of iterator_adaptor are derived from a corresponding instantiation of iterator_facade @@ -109,11 +400,14 @@ template parameter may not always be identical to the iterator's reference type, and will keep users from making mistakes based on that assumption.
template < class Derived @@ -123,7 +417,7 @@ template < , class Reference = use_default , class Difference = use_default > -class iterator_adaptor +class iterator_adaptor : public iterator_facade<Derived, V', C', R', D'> // see details { friend class iterator_core_access; @@ -136,12 +430,12 @@ class iterator_adaptor typedef iterator_adaptor iterator_adaptor_; Base const& base_reference() const; Base& base_reference(); - private: // Core iterator interface for iterator_facade. + private: // Core iterator interface for iterator_facade. typename iterator_adaptor::reference dereference() const; template < class OtherDerived, class OtherIterator, class V, class C, class R, class D - > + > bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const; void advance(typename iterator_adaptor::difference_type n); @@ -150,7 +444,7 @@ class iterator_adaptor template < class OtherDerived, class OtherIterator, class V, class C, class R, class D - > + > typename iterator_adaptor::difference_type distance_to( iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const; @@ -158,13 +452,13 @@ class iterator_adaptor Base m_iterator; // exposition only };-
static_cast<Derived*>(iterator_adaptor*) shall be well-formed. The Base argument shall be Assignable and Copy Constructible.
-The V', C', R', and D' parameters of the iterator_facade used as a base class in the summary of iterator_adaptor above are defined as follows:
@@ -204,8 +498,8 @@ expression involving ``Derived`` in those concepts' requirements. -->iterator_adaptor();
Requires: | The Base type must be Default Constructible. |
---|---|
Returns: | An instance of iterator_adaptor with + |
Returns: | An instance of iterator_adaptor with m_iterator default constructed. |
Base const& base_reference() const;
typename iterator_adaptor::reference dereference() const;
template < class Derived @@ -21,7 +306,7 @@ template < , class Reference = use_default , class Difference = use_default > -class iterator_adaptor +class iterator_adaptor : public iterator_facade<Derived, V', C', R', D'> // see details { friend class iterator_core_access; @@ -34,12 +319,12 @@ class iterator_adaptor typedef iterator_adaptor iterator_adaptor_; Base const& base_reference() const; Base& base_reference(); - private: // Core iterator interface for iterator_facade. + private: // Core iterator interface for iterator_facade. typename iterator_adaptor::reference dereference() const; template < class OtherDerived, class OtherIterator, class V, class C, class R, class D - > + > bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const; void advance(typename iterator_adaptor::difference_type n); @@ -48,7 +333,7 @@ class iterator_adaptor template < class OtherDerived, class OtherIterator, class V, class C, class R, class D - > + > typename iterator_adaptor::difference_type distance_to( iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const; @@ -56,13 +341,13 @@ class iterator_adaptor Base m_iterator; // exposition only };-
static_cast<Derived*>(iterator_adaptor*) shall be well-formed. The Base argument shall be Assignable and Copy Constructible.
The V', C', R', and D' parameters of the iterator_facade used as a base class in the summary of iterator_adaptor above are defined as follows:
@@ -102,8 +387,8 @@ expression involving ``Derived`` in those concepts' requirements. -->iterator_adaptor();
Requires: | The Base type must be Default Constructible. |
---|---|
Returns: | An instance of iterator_adaptor with + |
Returns: | An instance of iterator_adaptor with m_iterator default constructed. |
Base const& base_reference() const;
typename iterator_adaptor::reference dereference() const;
namespace iterator_archetypes { @@ -88,8 +373,8 @@ class iterator_archetype };
The access category types provided correspond to the following standard iterator access concept combinations:
@@ -114,27 +399,27 @@ writeable_lvalue_iterator_t := Readable Iterator & Writeable Iterator & Swappable Iterator & Lvalue Iterator
The AccessCategory argument must be one of the predefined access category tags. The TraversalCategory must be one of the standard traversal tags. The Value type must satisfy the requirements of the iterator concept specified by AccessCategory and TraversalCategory as implied by the nested traits types.
iterator_archetype models the iterator concepts specified by the AccessCategory and TraversalCategory arguments. iterator_archetype does not model any other access concepts or any more derived traversal concepts.
The nested trait types are defined as follows:
if (AccessCategory == readable_iterator_t) - + value_type = Value reference = Value pointer = Value* @@ -152,7 +437,7 @@ else if (AccessCategory == readable_writable_iterator_t) reference := A type X that is convertible to Value for which the following - expression is valid. Given an object x of type X and v of type + expression is valid. Given an object x of type X and v of type Value. x = v @@ -160,13 +445,13 @@ else if (AccessCategory == readable_writable_iterator_t) pointer = Value* else if (AccessCategory == readable_lvalue_iterator_t) - + value_type = Value reference = Value const& pointer = Value const* else if (AccessCategory == writable_lvalue_iterator_t) - + value_type = Value reference = Value& pointer = Value* @@ -180,7 +465,7 @@ else difference_type := unspecified type -iterator_category := +iterator_category := A type X satisfying the following two constraints: @@ -211,10 +496,5 @@ iterator_category :=
For an introduction to using concept checking classes, see the documentation for the boost::concept_check library.
-namespace boost_concepts { @@ -114,10 +399,5 @@ namespace boost_concepts {
abstract: | iterator_facade is a base class template that implements the + |
---|---|
abstract: | + + +iterator_facade is a base class template that implements the interface of standard iterators in terms of a few core functions and associated types, to be supplied by a derived iterator class. |
While the iterator interface is rich, there is a core subset of the interface that is necessary for all the functionality. We have identified the following core behaviors for iterators:
@@ -124,8 +415,8 @@ iterators, and a separate iterato impossible. -The user of iterator_facade derives his iterator class from a specialization of iterator_facade and passes the derived iterator class as iterator_facade's first template parameter. @@ -148,8 +439,8 @@ requirements.
iterator_facade and the operator implementations need to be able to access the core member functions in the derived class. Making the core member functions public would expose an implementation detail to @@ -212,7 +503,7 @@ provided, a class that acts as a gateway to the core member functions in the derived iterator class. The author of the derived class only needs to grant friendship to iterator_core_access to make his core member functions available to the library.
- +iterator_core_access will be typically implemented as an empty class containing only private static member functions which invoke the @@ -222,8 +513,8 @@ standardize the gateway protocol. Note that even if open a safety loophole, as every core member function preserves the invariants of the iterator.
The indexing operator for a generalized iterator presents special challenges. A random access iterator's operator[] is only required to return something convertible to its value_type. @@ -245,8 +536,8 @@ the implementation of her iterator is free to implement an class; it will hide the one supplied by iterator_facade from clients of her iterator.
The reference type of a readable iterator (and today's input iterator) need not in fact be a reference, so long as it is convertible to the iterator's value_type. When the value_type @@ -267,11 +558,14 @@ Patterns, C++ Report, February 1995, pp. 24-27.
template < class Derived @@ -355,12 +649,12 @@ template <class Dr, class V, class TC, class R, class D> Derived operator+ (typename Derived::difference_type n, iterator_facade<Dr,V,TC,R,D> const&);-
The iterator_category member of iterator_facade is
+The iterator_category member of iterator_facade is
iterator-category(CategoryOrTraversal, value_type, reference)
where iterator-category is defined as follows:
-+iterator-category(C,R,V) := if (C is convertible to std::input_iterator_tag || C is convertible to std::output_iterator_tag @@ -407,10 +701,10 @@ traversal tags would add no information]The enable_if_interoperable template used above is for exposition purposes. The member operators should only be in an overload set -provided the derived types Dr1 and Dr2 are interoperable, +provided the derived types Dr1 and Dr2 are interoperable, meaning that at least one of the types is convertible to the other. The enable_if_interoperable approach uses SFINAE to take the operators -out of the overload set when the types are not interoperable. +out of the overload set when the types are not interoperable. The operators should behave as-if enable_if_interoperable were defined to be:
@@ -428,8 +722,8 @@ struct enable_if_interoperable > {};--iterator_facade Requirements
++iterator_facade Requirements
The following table describes the typical valid expressions on iterator_facade's Derived parameter, depending on the iterator concept(s) it will model. The operations in the first @@ -442,8 +736,8 @@ object of type X, X, and z is a constant object of a random access traversal iterator type interoperable with X.
---iterator_facade Core Operations
++iterator_facade Core Operations
- @@ -452,10 +746,10 @@ interoperable with X. Expression -Return Type -Assertion/Note -Used to implement Iterator + @@ -502,8 +796,8 @@ Iterator Expression +Return Type +Assertion/Note +Used to implement Iterator Concept(s) -iterator_facade operations
++iterator_facade operations
The operations in this section are described in terms of operations on the core interface of Derived which may be inaccessible (i.e. private). The implementation should access these operations @@ -527,14 +821,14 @@ of type pointer equal
&static_cast<Derived const*>(this)->dereference()-Otherwise returns an object of unspecified type such that, +
Otherwise returns an object of unspecified type such that, (*static_cast<Derived const*>(this))->m is equivalent to (w = **static_cast<Derived const*>(this), w.m) for some temporary object w of type value_type.
unspecified operator[](difference_type n) const;
+unspecified operator[](difference_type n) const;
Returns: | if is_convertible<Dr2,Dr1>::value
|
---|---|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
Returns: | if is_convertible<Dr2,Dr1>::value
|
+template <class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2> typename enable_if_interoperable<Dr1,Dr2,difference>::type @@ -806,23 +1112,27 @@ operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,Return Type: if is_convertible<Dr2,Dr1>::value
-+-
- then
-- difference shall be -iterator_traits<Dr1>::difference_type.
-- Otherwise
-- difference shall be iterator_traits<Dr2>::difference_type
+- then
+- +
difference shall be +iterator_traits<Dr1>::difference_type.
+- Otherwise
+difference shall be iterator_traits<Dr2>::difference_type
+@@ -830,8 +1140,8 @@ operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs, Returns: if is_convertible<Dr2,Dr1>::value
-
- then
-- -((Dr1 const&)lhs).distance_to((Dr2 const&)rhs).
-- Otherwise,
-- ((Dr2 const&)rhs).distance_to((Dr1 const&)lhs).
+- then
+- +
-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs).
+- Otherwise,
+((Dr2 const&)rhs).distance_to((Dr1 const&)lhs).
+
Say we've written a polymorphic linked list node base class:
# include <iostream> @@ -858,16 +1168,16 @@ struct node_base // print to the stream virtual void print(std::ostream& s) const = 0; - + // double the value virtual void double_me() = 0; void append(node_base* p) { - if (m_next) - m_next->append(p); + if (m_next) + m_next->append(p); else - m_next = p; + m_next = p; } private: @@ -902,8 +1212,8 @@ inline std::ostream& operator<<(std::ostream& s, node_base const&aOur first challenge is to build an appropriate iterator over these lists.
We will construct a node_iterator class using inheritance from iterator_facade to implement most of the iterator's operations.
@@ -916,25 +1226,25 @@ class node_iterator ... };-
iterator_facade has several template parameters, so we must decide what types to use for the arguments. The parameters are Derived, Value, CategoryOrTraversal, Reference, and Difference.
-Because iterator_facade is meant to be used with the CRTP [Cop95] the first parameter is the iterator class name itself, node_iterator.
The Value parameter determines the node_iterator's value_type. In this case, we are iterating over node_base objects, so Value will be node_base.
Now we have to determine which iterator traversal concept our node_iterator is going to model. Singly-linked lists only have forward links, so our iterator can't can't be a bidirectional @@ -953,8 +1263,8 @@ end up being std::forward_iterato
The Reference argument becomes the type returned by node_iterator's dereference operation, and will also be the same as std::iterator_traits<node_iterator>::reference. The @@ -962,8 +1272,8 @@ library's default for this parameter is node_base& is a good choice for the iterator's reference type, we can omit this argument, or pass use_default.
The Difference argument determines how the distance between two node_iterators will be measured and will also be the same as std::iterator_traits<node_iterator>::difference_type. @@ -989,8 +1299,8 @@ class node_iterator
Next we need to decide how to represent the iterator's position. This representation will take the form of data members, so we'll also need to write constructors to initialize them. The @@ -1034,8 +1344,8 @@ default constructor to leave m_no
The last step is to implement the core operations required by the concepts we want our iterator to model. Referring to the table, we can see that the first three rows are applicable @@ -1085,8 +1395,8 @@ class node_iterator iterator! For a working example of its use, see this program.
Our const_node_iterator works perfectly well on its own, but taken together with node_iterator it doesn't quite meet expectations. For example, we'd like to be able to pass a @@ -1226,7 +1536,7 @@ class node_iter template <class OtherValue> bool equal(node_iter<OtherValue> const& other) const - { + { return this->m_node == other.m_node; } @@ -1259,8 +1569,8 @@ traversal iterator, we'd have had to templatize its
You can see an example program which exercises our interoperable iterators here.
Now node_iterator and node_const_iterator behave exactly as you'd expect... almost. We can compare them and we can convert in one direction: from node_iterator to node_const_iterator. @@ -1286,7 +1596,7 @@ appropriate:
... -private: +private: struct enabler {}; public: @@ -1301,8 +1611,8 @@ public: : m_node(other.m_node) {}This concludes our iterator_facade tutorial, but before you stop reading we urge you to take a look at iterator_adaptor. There's another way to approach writing these iterators which might @@ -1310,10 +1620,5 @@ even be superior.
abstract: | Header <boost/iterator/iterator_traits.hpp> provides the ability to access an iterator's associated types using -MPL-compatible metafunctions. | +MPL-compatible metafunctions.
---|
std::iterator_traits provides access to five associated types of any iterator: its value_type, reference, pointer, iterator_category, and difference_type. Unfortunately, such a "multi-valued" traits template can be difficult to use in a metaprogramming context. <boost/iterator/iterator_traits.hpp> -provides access to these types using a standard metafunctions.
+provides access to these types using a standard metafunctions.Header <boost/iterator/iterator_traits.hpp>:
template <class Iterator> struct iterator_value { - typedef typename - std::iterator_traits<Iterator>::value_type + typedef typename + std::iterator_traits<Iterator>::value_type type; }; template <class Iterator> struct iterator_reference { - typedef typename + typedef typename std::iterator_traits<Iterator>::reference type; }; @@ -73,8 +358,8 @@ struct iterator_reference template <class Iterator> struct iterator_pointer { - typedef typename - std::iterator_traits<Iterator>::pointer + typedef typename + std::iterator_traits<Iterator>::pointer type; }; @@ -95,14 +380,14 @@ struct iterator_category };
Because of workarounds in Boost, you may find that these -metafunctions actually work better than the facilities provided by +metafunctions actually work better than the facilities provided by your compiler's standard library.
On compilers that don't support partial specialization, such as Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke -BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION on the +BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION on the value_type of pointers that are passed to these metafunctions.
Because of bugs in the implementation of GCC-2.9x, the name of iterator_category is changed to iterator_category_ on that @@ -111,10 +396,5 @@ either iterator_category appropriate to the platform, is provided for portability.
template <class Predicate, class Iterator> filter_iterator<Predicate,Iterator> make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());-
abstract: | The permutation iterator adaptor provides a permuted view of a given + |
---|---|
abstract: | + + +The permutation iterator adaptor provides a permuted view of a given range. That is, the view includes every element of the given range but in a potentially different order. |
The adaptor takes two arguments:
@@ -74,8 +365,11 @@ to be unique. In this same context, it must be noted that the past the end permutation iterator is completely defined by means of the past-the-end iterator to the indices.
template< class ElementIterator , class IndexIterator @@ -104,28 +398,28 @@ private: }; template <class ElementIterator, class IndexIterator> -permutation_iterator<ElementIterator, IndexIterator> +permutation_iterator<ElementIterator, IndexIterator> make_permutation_iterator( ElementIterator e, IndexIterator i);-
ElementIterator shall model Random Access Traversal Iterator. IndexIterator shall model Readable Iterator. The value type of the IndexIterator must be convertible to the difference type of ElementIterator.
permutation_iterator models the same iterator traversal concepts as IndexIterator and the same iterator access concepts as ElementIterator.
-If IndexIterator models Single Pass Iterator and +
If IndexIterator models Single Pass Iterator and ElementIterator models Readable Iterator then permutation_iterator models Input Iterator.
-If IndexIterator models Forward Traversal Iterator and +
If IndexIterator models Forward Traversal Iterator and ElementIterator models Readable Lvalue Iterator then permutation_iterator models Forward Iterator.
-If IndexIterator models Bidirectional Traversal Iterator and +
If IndexIterator models Bidirectional Traversal Iterator and ElementIterator models Readable Lvalue Iterator then permutation_iterator models Bidirectional Iterator.
If IndexIterator models Random Access Traversal Iterator and @@ -136,8 +430,8 @@ with permutation_iterator<E2,< X is interoperable with Y and E1 is convertible to E2.
In addition to those operations required by the concepts that permutation_iterator models, permutation_iterator provides the following operations.
@@ -207,7 +501,7 @@ permutation_iterator(template <class ElementIterator, class IndexIterator> -permutation_iterator<ElementIterator, IndexIterator> +permutation_iterator<ElementIterator, IndexIterator> make_permutation_iterator(ElementIterator e, IndexIterator i);
using namespace boost; int i = 0; @@ -237,7 +534,7 @@ for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.en *el_it = std::distance(elements.begin(), el_it); index_type indices( index_size ); -for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it ) +for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it ) *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it); std::reverse( indices.begin(), indices.end() ); @@ -276,20 +573,15 @@ std::cout << "\n";
The output is:
-The original range is : 0 1 2 3 4 5 6 7 8 9 -The reindexing scheme is : 9 8 7 6 -The permutated range is : 9 8 7 6 -Elements at even indices in the permutation : 9 7 -Permutation backwards : 6 7 8 9 -Iterate backward with stride 2 : 6 8 +The original range is : 0 1 2 3 4 5 6 7 8 9 +The reindexing scheme is : 9 8 7 6 +The permutated range is : 9 8 7 6 +Elements at even indices in the permutation : 9 7 +Permutation backwards : 6 7 8 9 +Iterate backward with stride 2 : 6 8
The source code for this example can be found here.
Have you ever wanted to write a generic function that can operate on any kind of dereferenceable object? If you have, you've probably run into the problem of how to determine the type that the @@ -53,8 +338,8 @@ void f(Dereferenceable p) ... } -
It turns out to be impossible to come up with a fully-general algorithm to do determine what-goes-here directly, but it is possible to require that pointee<Dereferenceable>::type is @@ -75,8 +360,8 @@ namespace boost }
indirect_reference<T>::type is rather more specialized than pointee, and is meant to be used to forward the result of dereferencing an object of its argument type. Most dereferenceable @@ -87,10 +372,10 @@ information is needed, call on in indirect_iterator.
Author: | David Abrahams and Jeremy Siek | -
---|---|
Contact: | dave@boost-consulting.com, jsiek@osl.iu.edu | -
Organization: | Boost Consulting, Indiana University Bloomington | -
date: | $Date$ | -
Copyright: | Copyright David Abrahams, Jeremy Siek 2003. Use, modification and + |
Author: | +David Abrahams and Jeremy Siek |
Contact: | +dave@boost-consulting.com, jsiek@osl.iu.edu |
Organization: | +Boost Consulting, Indiana University Bloomington |
Date: | +2003-11-17 |
Copyright: | +Copyright David Abrahams, Jeremy Siek 2003. 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) | -
The new iterator categories are intended to correspond to the old iterator categories, as specified in a diagram in N1550. For example, an iterator categorized as a mutable Forward Iterator under the old scheme is now a Writable, Lvalue, and Foward Traversal iterator. However, there is a problem with this correspondance, the new iterator -categories place requirements on the iterator_traits<X>::reference +categories place requirements on the iterator_traits<X>::reference type whereas the standard iterator requirements say nothing about the -reference type . In particular, the new Readable Iterator -requirements say that the return type of *a must be -iterator_traits<X>::reference and the Lvalue Iterator requirements -says that iterator_traits<X>::reference must be T& or const +reference type . In particular, the new Readable Iterator +requirements say that the return type of *a must be +iterator_traits<X>::reference and the Lvalue Iterator requirements +says that iterator_traits<X>::reference must be T& or const T&.
Change the standard requirements to match the requirements of the new iterators. (more details to come)
The lack of specification in the standard of the reference type is +
The lack of specification in the standard of the reference type is certainly a defect. Without specification, it is entirely useless in a generic function. The current practice in the community is generally -to assume there are requirements on the reference type, such as +to assume there are requirements on the reference type, such as those proposed in the new iterator categories.
There is some danger in adding requirements to existing concepts. This will mean that some existing iterator types will no longer meet the iterator requirements. However, we feel that the impact of this is small enough to warrant going ahead with this change.
An alternative solution would be to leave the standard requirements as -is, and to remove the requirements for the reference type in the +is, and to remove the requirements for the reference type in the new iterator concepts. We are not in favor of this approach because it extends what we see as a defect further into the future.
abstract: | The reverse iterator adaptor iterates through the adapted iterator + |
---|---|
abstract: | + + +The reverse iterator adaptor iterates through the adapted iterator range in the opposite direction. |
template <class Iterator>
class reverse_iterator
@@ -88,14 +379,14 @@ Lvalue Iterator, then iterator_ca
bidirectional_iterator_tag. Otherwise, iterator_category is
convertible to input_iterator_tag.
Iterator must be a model of Bidirectional Traversal Iterator. The type iterator_traits<Iterator>::reference must be the type of *i, where i is an object of type Iterator.
A specialization of reverse_iterator models the same iterator traversal and iterator access concepts modeled by its Iterator argument. In addition, it may model old iterator concepts @@ -106,8 +397,8 @@ specified in the following table:
In addition to the operations required by the concepts modeled by reverse_iterator, reverse_iterator provides the following operations.
@@ -145,7 +436,7 @@ operations.
template <class BidirectionalIterator>
reverse_iterator<BidirectionalIterator>n
@@ -236,9 +530,12 @@ with a current constr
abstract: | The transform iterator adapts an iterator by modifying the + |
---|---|
abstract: | + + +The transform iterator adapts an iterator by modifying the operator* to apply a function object to the result of dereferencing the iterator and returning the result. |
template <class UnaryFunction,
- class Iterator,
- class Reference = use_default,
+ class Iterator,
+ class Reference = use_default,
class Value = use_default>
class transform_iterator
{
@@ -105,8 +396,8 @@ convertible to forward_iterator_t
model Readable Lvalue Iterator then iterator_category is
convertible to input_iterator_tag.
The type UnaryFunction must be Assignable, Copy Constructible, and the expression f(*i) must be valid where f is an object of type UnaryFunction, i is an object of type Iterator, and @@ -114,8 +405,8 @@ where the type of f(*i)result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type.
The argument Iterator shall model Readable Iterator.
The resulting transform_iterator models the most refined of the following that is also modeled by Iterator.
@@ -136,8 +427,8 @@ the Iterator argument- If Iterator models -then transform_iterator models +@@ -161,8 +452,8 @@ mutable iterator (as defined in the old iterator requirements). transform_iterator<F2, Y, R2, V2> if and only if X is interoperable with Y. - If Iterator models +then transform_iterator models -transform_iterator operations
++transform_iterator operations
In addition to the operations required by the concepts modeled by transform_iterator, transform_iterator provides the following operations.
@@ -255,6 +546,9 @@ initialized to t.functor()
template <class UnaryFunction, class Iterator>
transform_iterator<UnaryFunction, Iterator>
@@ -283,9 +577,12 @@ default constructed and m_iterato
This is a simple example of using the transform_iterators class to generate iterators that multiply (or add to) the value returned by dereferencing the iterator. It would be cooler to use lambda library @@ -314,17 +611,12 @@ std::cout << std::endl;
The output is:
multiplying the array by 2: -2 4 6 8 10 12 14 16 +2 4 6 8 10 12 14 16 adding 4 to each element in the array: 5 6 7 8 9 10 11 12
The source code for this example can be found here.
abstract: | The zip iterator provides the ability to parallel-iterate -over several controlled sequences simultaneously. A zip + |
---|---|
abstract: | + + +The zip iterator provides the ability to parallel-iterate +over several controlled sequences simultaneously. A zip iterator is constructed from a tuple of iterators. Moving the zip iterator moves all the iterators in parallel. Dereferencing the zip iterator returns a tuple that contains @@ -43,8 +331,8 @@ the results of dereferencing the individual iterators. |
template<typename IteratorTuple> class zip_iterator -{ +{ public: typedef /* see below */ reference; @@ -84,8 +375,8 @@ private: IteratorTuple m_iterator_tuple; // exposition only }; -template<typename IteratorTuple> -zip_iterator<IteratorTuple> +template<typename IteratorTuple> +zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t);
The reference member of zip_iterator is the type of the tuple @@ -96,22 +387,22 @@ of the first of the iterator types in the The iterator_category member of zip_iterator is convertible to the minimum of the traversal categories of the iterator types in the IteratorTuple argument. For example, if the zip_iterator holds only vector -iterators, then iterator_category is convertible to +iterators, then iterator_category is convertible to boost::random_access_traversal_tag. If you add a list iterator, then iterator_category will be convertible to boost::bidirectional_traversal_tag, but no longer to boost::random_access_traversal_tag.
All iterator types in the argument IteratorTuple shall model Readable Iterator.
The resulting zip_iterator models Readable Iterator.
-The fact that the zip_iterator models only Readable Iterator does not +
The fact that the zip_iterator models only Readable Iterator does not prevent you from modifying the values that the individual iterators point -to. The tuple returned by the zip_iterator's operator* is a tuple -constructed from the reference types of the individual iterators, not +to. The tuple returned by the zip_iterator's operator* is a tuple +constructed from the reference types of the individual iterators, not their value types. For example, if zip_it is a zip_iterator whose first member iterator is an std::vector<double>::iterator, then the following line will modify the value which the first member iterator of @@ -121,14 +412,14 @@ zip_it->get<0>() = 42.0;
Consider the set of standard traversal concepts obtained by taking the most refined standard traversal concept modeled by each individual -iterator type in the IteratorTuple argument.The zip_iterator +iterator type in the IteratorTuple argument.The zip_iterator models the least refined standard traversal concept in this set.
zip_iterator<IteratorTuple1> is interoperable with zip_iterator<IteratorTuple2> if and only if IteratorTuple1 is interoperable with IteratorTuple2.
In addition to the operations required by the concepts modeled by zip_iterator, zip_iterator provides the following operations.
@@ -213,8 +504,8 @@ zip_iterator(-template<typename IteratorTuple> -zip_iterator<IteratorTuple> +template<typename IteratorTuple> +zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t);
-template<typename IteratorTuple> -zip_iterator<IteratorTuple> +template<typename IteratorTuple> +zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t);
There are two main types of applications of the zip_iterator. The first one concerns runtime efficiency: If one has several controlled sequences -of the same length that must be somehow processed, e.g., with the +of the same length that must be somehow processed, e.g., with the for_each algorithm, then it is more efficient to perform just -one parallel-iteration rather than several individual iterations. For an +one parallel-iteration rather than several individual iterations. For an example, assume that vect_of_doubles and vect_of_ints are two vectors of equal length containing doubles and ints, respectively, and consider the following two iterations:
@@ -274,7 +571,7 @@ std::for_each(A non-generic implementation of zip_func could look as follows:
-struct zip_func : +struct zip_func : public std::unary_function<const boost::tuple<const double&, const int&>&, void> { void operator()(const boost::tuple<const double&, const int&>& t) const @@ -294,14 +591,14 @@ that parallel-iterates over several controlled sequences and, upon dereferencing, returns the result of applying a functor to the values of the sequences at the respective positions. This can now be achieved by using the zip_iterator in conjunction with the transform_iterator. -Suppose, for example, that you have two vectors of doubles, say +
Suppose, for example, that you have two vectors of doubles, say vect_1 and vect_2, and you need to expose to a client -a controlled sequence containing the products of the elements of +a controlled sequence containing the products of the elements of vect_1 and vect_2. Rather than placing these products in a third vector, you can use a combining iterator that calculates the products on the fly. Let us assume that tuple_multiplies is a functor that works like std::multiplies, except that it takes -its two arguments packaged in a tuple. Then the two iterators +its two arguments packaged in a tuple. Then the two iterators it_begin and it_end defined below delimit a controlled sequence containing the products of the elements of vect_1 and vect_2:
@@ -342,10 +639,5 @@ the_transform_iterator it_end(