diff --git a/doc/facade-and-adaptor.html b/doc/facade-and-adaptor.html index 59e7262..a179b94 100755 --- a/doc/facade-and-adaptor.html +++ b/doc/facade-and-adaptor.html @@ -693,28 +693,53 @@ template <class Derived, class V, class TC, class R, class D> Derived operator+ (iterator_facade<Derived, V, TC, R, D> const&, typename Derived::difference_type n) -
The iterator_category member of iterator_facade is -facade_iterator_category(CategoryOrTraversal, value_type, -reference), as specified by the following pseudo-code:
+The iterator_category member of iterator_facade is
-facade_iterator_category(C, V, R) = - if (C is convertible to input_iterator_tag or output_iterator_tag) then - return C - else if (C is convertible to incrementable_traversal_tag) then - if (R is a reference type - and C is convertible to forward_traversal_tag) then - if (C is convertible to random_access_traversal_tag) - return a type convertible to random_access_iterator_tag - else if (C is convertible to bidirectional_traversal_tag) - return a type convertible to bidirectional_iterator_tag - else - return a type convertible to forward_iterator_tag - else if (C is convertible to single_pass_traversal_tag - and R is convertible to V) - return a type convertible to input_iterator_tag - else - return C +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 + ) + return C + + else if (C is not convertible to incrementable_traversal_tag) + the program is ill-formed + + else return a type X satisfying the following two constraints: + + 1. X is convertible to X1, and not to any more-derived + type, where X1 is defined by: + + if (R is a reference type + && C is convertible to forward_traversal_tag) + { + if (C is convertible to random_access_traversal_tag) + X1 = random_access_iterator_tag + else if (C is convertible to bidirectional_traversal_tag) + X1 = bidirectional_iterator_tag + else + X1 = forward_iterator_tag + } + else + { + if (C is convertible to single_pass_traversal_tag + && R is convertible to V) + X1 = input_iterator_tag + else + X1 = C + } + + 2. category-to-traversal(X) is convertible to the most + derived traversal tag type to which X is also + convertible, and not to any more-derived traversal tag + type. ++
[Note: the intention is to allow iterator_category to be one of +the five original category tags when convertibility to one of the +traversal tags would add no information]
diff --git a/doc/facade_iterator_category.rst b/doc/facade_iterator_category.rst index 49af535..ea2e538 100755 --- a/doc/facade_iterator_category.rst +++ b/doc/facade_iterator_category.rst @@ -1,24 +1,49 @@ +.. parsed-literal:: + + *iterator-category*\ (C,R,V) := + if (C is convertible to std::input_iterator_tag + || C is convertible to std::output_iterator_tag + ) + return C + else if (C is not convertible to incrementable_traversal_tag) + *the program is ill-formed* -:: + else return a type X satisfying the following two constraints: - facade_iterator_category(C, V, R) = - if (C is convertible to input_iterator_tag or output_iterator_tag) then - return C - else if (C is convertible to incrementable_traversal_tag) then - if (R is a reference type - and C is convertible to forward_traversal_tag) then - if (C is convertible to random_access_traversal_tag) - return a type convertible to random_access_iterator_tag - else if (C is convertible to bidirectional_traversal_tag) - return a type convertible to bidirectional_iterator_tag - else - return a type convertible to forward_iterator_tag - else if (C is convertible to single_pass_traversal_tag - and R is convertible to V) - return a type convertible to input_iterator_tag - else - return C + 1. X is convertible to X1, and not to any more-derived + type, where X1 is defined by: + + if (R is a reference type + && C is convertible to forward_traversal_tag) + { + if (C is convertible to random_access_traversal_tag) + X1 = random_access_iterator_tag + else if (C is convertible to bidirectional_traversal_tag) + X1 = bidirectional_iterator_tag + else + X1 = forward_iterator_tag + } + else + { + if (C is convertible to single_pass_traversal_tag + && R is convertible to V) + X1 = input_iterator_tag + else + X1 = C + } + + 2. |category-to-traversal|_\ (X) is convertible to the most + derived traversal tag type to which X is also + convertible, and not to any more-derived traversal tag + type. + +.. |category-to-traversal| replace:: *category-to-traversal* +.. _`category-to-traversal`: new-iter-concepts.html#category-to-traversal + +[Note: the intention is to allow ``iterator_category`` to be one of +the five original category tags when convertibility to one of the +traversal tags would add no information] .. Copyright David Abrahams 2004. Use, modification and distribution is .. subject to the Boost Software License, Version 1.0. (See accompanying diff --git a/doc/iterator_facade.html b/doc/iterator_facade.html index ff906c1..3ef1219 100644 --- a/doc/iterator_facade.html +++ b/doc/iterator_facade.html @@ -45,43 +45,43 @@ and associated types, to be supplied by a derived iterator class.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 @@ -486,7 +511,7 @@ Iterator
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 @@ -627,7 +652,7 @@ return tmp -= n;
Say we've written a polymorphic linked list node base class:
# include <iostream> @@ -699,7 +724,7 @@ inline std::ostream& operator<<(std::ostream& s, node_base const&a lists.
We will construct a node_iterator class using inheritance from iterator_facade to implement most of the iterator's operations.
@@ -713,24 +738,24 @@ 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 @@ -750,7 +775,7 @@ end up being std::forward_iterator_tag
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 @@ -759,7 +784,7 @@ library's default for this parameter is Va 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. @@ -786,7 +811,7 @@ 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 @@ -831,7 +856,7 @@ default constructor to leave m_node
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
@@ -882,7 +907,7 @@ iterator! For a working example of its use, see
- 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
@@ -993,7 +1018,7 @@ just as you can with std::list<int><
node_const_iterator into the same list, we should be able to
compare them for equality. This expected ability to use two different iterator types together
-is known as interoperability. Achieving interoperability in
+is known as interoperability. Achieving interoperability in
our case is as simple as templatizing the equal function and
adding a templatized converting constructor 3 4: 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.
@@ -1094,7 +1119,7 @@ appropriate: 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
diff --git a/doc/iterator_facade_ref.rst b/doc/iterator_facade_ref.rst
index 420ded1..5353654 100644
--- a/doc/iterator_facade_ref.rst
+++ b/doc/iterator_facade_ref.rst
@@ -97,9 +97,13 @@ __ brackets_
.. _`iterator category`:
-The ``iterator_category`` member of ``iterator_facade`` is
-``facade_iterator_category(CategoryOrTraversal, value_type,
-reference)``, as specified by the following pseudo-code:
+The ``iterator_category`` member of ``iterator_facade`` is
+
+.. parsed-literal::
+
+ *iterator-category*\ (CategoryOrTraversal, value_type, reference)
+
+where *iterator-category* is defined as follows:
.. include:: facade_iterator_category.rst
diff --git a/doc/iterator_facade_tutorial.rst b/doc/iterator_facade_tutorial.rst
index bb96264..10980ed 100755
--- a/doc/iterator_facade_tutorial.rst
+++ b/doc/iterator_facade_tutorial.rst
@@ -388,7 +388,7 @@ just as you can with ``std::list The is_readable_iterator and iterator_traversal class
-templates satisfy the UnaryTypeTrait requirements. The is_readable_iterator class
+template satisfies the UnaryTypeTrait requirements. Given an iterator type X, is_readable_iterator<X>::value
yields true if, for an object a of type X, *a is
convertible to iterator_traits<X>::value_type, and false
otherwise. iterator_traversal<X>::type is defined to be: iterator_traversal<X>::type is where category-to-traversal is defined as followsA constant node_iterator
+A constant node_iterator
Interoperability
+Interoperability
@@ -1056,7 +1081,7 @@ traversal iterator, we'd have had to templatize its
iterators here.
Telling the Truth
+Telling the Truth
Wrap Up
+Wrap Up
Lvalue Iterator Requirements
@@ -659,12 +659,13 @@ Forward Traversal Iterator, the following expressions are valid and
respect the stated semantics.
Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator)
+Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal
+Iterator)
Expression
Return Type
@@ -715,10 +716,10 @@ the stated semantics. In the table below, Distance.
Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator)
@@ -831,9 +832,9 @@ of type X, Distance.
Expression
@@ -872,43 +873,38 @@ constant object of type Distance
@@ -969,27 +961,30 @@ struct random_access_traversal_tag : bidirectional_traversal_tag { };
Expression
Return Type
Operational Semantics
-Assertion/
-Precondition
+Assertion/ Precondition
x < y
convertible to bool
y - x > 0
-< is a total
-ordering relation
+< is a total ordering relation
y < x
convertible to bool
x - y > 0
-< is a total
-ordering relation
+< is a total ordering relation
x > y
convertible to bool
y < x
-> is a total
-ordering relation
+> is a total ordering relation
y > x
convertible to bool
x < y
-> is a total
-ordering relation
+> is a total ordering relation
x >= y
convertible to bool
@@ -933,20 +929,16 @@ ordering relation
y - x
Distance
distance(Y(x),y)
-pre: there exists a
-value n of
-Distance such that
-x + n == y. y
-== x + (y - x).
+pre: there exists a value n of
+Distance such that x + n == y.
+y == x + (y - x).
x - y
Distance
distance(y,Y(x))
-pre: there exists a
-value n of
-Distance such that
-y + n == x. x
-== y + (x - y).
+pre: there exists a value n of
+Distance such that y + n == x.
+x == y + (x - y).
Addition to [lib.iterator.traits]
-
-traversal-category(X) =
- cat = iterator_traits<X>::iterator_category;
- if (cat is convertible to incrementable_traversal_tag)
- return cat;
- else if (cat is convertible to random_access_iterator_tag)
+category-to-traversal(iterator_traits<X>::iterator_category)
+
+
+category-to-traversal(C) =
+ if (C is convertible to incrementable_traversal_tag)
+ return C;
+ else if (C is convertible to random_access_iterator_tag)
return random_access_traversal_tag;
- else if (cat is convertible to bidirectional_iterator_tag)
+ else if (C is convertible to bidirectional_iterator_tag)
return bidirectional_traversal_tag;
- else if (cat is convertible to forward_iterator_tag)
+ else if (C is convertible to forward_iterator_tag)
return forward_traversal_tag;
- else if (cat is convertible to input_iterator_tag)
+ else if (C is convertible to input_iterator_tag)
return single_pass_traversal_tag;
- else if (cat is convertible to output_iterator_tag)
+ else if (C is convertible to output_iterator_tag)
return incrementable_traversal_tag;
else
the program is ill-formed
diff --git a/doc/new-iter-concepts.rst b/doc/new-iter-concepts.rst
index eb5325a..bdac3da 100644
--- a/doc/new-iter-concepts.rst
+++ b/doc/new-iter-concepts.rst
@@ -430,20 +430,20 @@ The *Lvalue Iterator* concept adds the requirement that the return
type of ``operator*`` type be a reference to the value type of the
iterator.
-+---------------------------------------------------------------------------------+
-| Lvalue Iterator Requirements |
-+---------------------------------+-----------+-----------------------------------+
-|Expression |Return Type|Note/Assertion |
-+=================================+===========+===================================+
-|``*a`` | ``T&`` |``T`` is *cv* |
-| | |``iterator_traits