From 66feb4567660567219a5abad3782c688f70c2788 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Tue, 16 Dec 2003 20:43:27 +0000 Subject: [PATCH] finished adding all the issues form the reflector [SVN r21292] --- doc/iter-issue-list.rst | 781 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 777 insertions(+), 4 deletions(-) diff --git a/doc/iter-issue-list.rst b/doc/iter-issue-list.rst index 8b0198e..664a3d0 100644 --- a/doc/iter-issue-list.rst +++ b/doc/iter-issue-list.rst @@ -17,15 +17,342 @@ .. _`Boost Consulting`: http://www.boost-consulting.com +.. contents:: Table of Contents + + +problem with is_writable, is_swappable +====================================== + +See the separate writeup_. + +.. _writeup: ./issues.html + + reference requirements in readable iterator -------------------------------------------- +=========================================== The DR has been submitted. This is a placeholder for updating our proposals with respects to the resolution of that DR. +Subject: N1550: iterator_access overspecified? +============================================== +Date: Fri, 07 Nov 2003 10:25:45 -0500 +Message c++std-lib-12262 + +The proposal includes: + +enum iterator_access { readable_iterator = 1, writable_iterator = 2, +swappable_iterator = 4, lvalue_iterator = 8 }; + +In general, the standard specifies thing like this as a bitmask type with a +list of defined names, and specifies neither the exact type nor the +specific values. Is there a reason for iterator_access to be more specific? + + +Resolution +---------- + The iterator_access enum has been removed, so this is no longer an issue. + + + + +N1530: Minor Issues +=================== +Message c++std-lib-12299 +Date: Tue, 11 Nov 2003 10:30:36 -0500 + +1. operators of iterator_facade overspecified. In general, we've provided +operational semantics for things like operator++. That is, we've said that +++iter must work, without requiring either a member function or a +non-member function. iterator_facade specifies most operators as member +functions. There's no inherent reason for these to be members, so we should +remove this requirement. Similarly, some operations are specified as +non-member functions but could be implemented as members. Again, the +standard doesn't make either of these choices, and TR1 shouldn't, either. +So: operator*(), operator++(), operator++(int), operator--(), +operator--(int), operator+=, operator-=, operator-(difference_type), +operator-(iterator_facade instance), and operator+ should be specified with +operational semantics and not explicitly required to be members or non-members. + +2. enable_if_interoperable needs standardese. The only discussion of what +this means is in a note, so is non-normative. Further, the note seems to be +incorrect. It says that enable_if_interoperable only works for types that +"are interoperable, by which we mean they are convertible to each other." +This requirement is too strong: it should be that one of the types is +convertible to the other. + +3. iterator_adaptor has an extraneous 'bool' at the start of the template +definition. + +4. iterator_adaptor has a private member named m_iterator. Presumably this +is for exposition only, since it's an implementation detail. It needs to be +marked as such. + +5. iterator_adaptor operations specifications are a bit inconsistent. +iterator_adpator() has a Requires clause, that Base must be default +constructible. iterator_adaptor(Base) has no Requires clause, although the +Returns clause says that the Base member is copy construced from the +argument (this may actually be an oversight in N1550, which doesn't require +iterators to be copy constructible or assignable). + +6. similar to 2, "Specialized Adaptors" has a note describing +enable_if_convertible. This should be normative text. + +7. reverse iterator "flips the direction of the base iterator's motion". +This needs to be more formal, as in the current standard. Something like: +"iterates through the controlled sequence in the opposite direction" + +8. reverse_iterator::dereference is specified as calling a function named +'prior' which has no specification. + +9. Transform iterator has a two-part specification: it does this, in other +words, it does that. "In other words" always means "I didn't say it right, +so I'll try again." We need to say it once. + +10. similar to 4, transform_iterator has a private member named 'm_f' which +should be marked "exposition only." + +11. The description of Counting iterator is unclear. "The counting iterator +adaptor implements dereference by returning a reference to the base object. +The other operations are implemented by the base m_iterator, as per the +inheritance from iterator_adaptor." + +12. Counting iterator has the following note: + +[Note: implementers are encouraged to provide an implementation of +distance_to and a difference_type that avoids overflows in the cases when +the Incrementable type is a numeric type.] + +I'm not sure what this means. The user provides a template argument named +Difference, but there's no difference_type. I assume this is just a glitch +in the wording. But if implementors are encouraged to ignore this argument +if it won't work right, why is it there? + + +Subject: N1550: iterator_facade Derived template argument underspecified +======================================================================== +Message c++std-lib-12302, +Date: Wed, 12 Nov 2003 11:16:49 -0500 + +The first template argument to iterator_facade is named Derived, and the +proposal says: + + The Derived template parameter must be a class derived from iterator_facade. + +First, iterator_facade is a template, so cannot be derived from. Rather, +the class must be derived from a specialization of iterator_facade. More +important, isn't Derived required to be the class that is being defined? +That is, if I understand it right, the definition of D here this is not valid: + +class C : public iterator_facade { ... }; + +class D : public iterator_facade { ... }; + +In the definition of D, the Derived argument to iterator_facade is a class +derived from a specialization of iterator_facade, so the requirement is +met. Shouldn't the requirement be more like "when using iterator_facade to +define an iterator class Iter, the class Iter must be derived from a +specialization of iterator_facade whose first template argument is Iter." +That's a bit awkward, but at the moment I don't see a better way of +phrasing it. + + +Subject: N1550: return type of Iterator difference for iterator facade +====================================================================== +Date: Wed, 12 Nov 2003 12:20:26 -0500 +Message c++std-lib-12303 + +The proposal says: + +>template class Dr2, class V2, class AC2, class TC2, class R2, class D2> +>typename enable_if_interoperable::type +>operator -(iterator_facade const& lhs, +> iterator_facade const& rhs); + +Shouldn't the return type be one of the two iterator types? Which one? The +idea is that if one of the iterator types can be converted to the other +type, then the subtraction is okay. Seems like the return type should then +be the type that was converted to. Is that right? + + + +Subject: N1550: Minor Wording Issue +=================================== +Date: Wed, 12 Nov 2003 13:19:07 -0500 +From: Pete Becker +Message c++std-lib-12305 + +In the table that lists the required (sort of) member functions of iterator +types that are based on iterator_facade, the entry for c.equal(y) says: + +>true iff c and y refer to the same position. Implements c == y and c != y. + +The second sentence is inside out. c.equal(y) does not implement either of +these operations. It is used to implement them. Same thing in the +description of c.distance_to(z). + + +Subject: N1530: Problems in iterator facade operations +====================================================== +Date: Wed, 12 Nov 2003 13:52:55 -0500 +From: Pete Becker +Message c++std-lib-12308 + +1. Several of the descriptions use the name X without defining it. This +seems to be a carryover from the table immediately above this section, but +the text preceding that table says "In the table below, X is the derived +iterator type." Looks like the X:: qualifiers aren't really needed; +X::reference can simply be reference, since that's defined by the +iterator_facade specialization itself. + +2. Several of the member functions return a Derived object or a Derived&. +Their Effects clauses end with + +:: + + return *this; + +This should be + +:: + + return *(Derived*)this; + + +3. The returns clause for operator[](difference_type n) const says + +:: + + Returns: an object convertible to X::reference and holding a copy p of a+n + such that, for a constant object v of type X::value_type, + X::reference(a[n] = v) is equivalent to p = v. + +This needs to define 'a', but assuming it's supposed to be *this (or +maybe *(Derived*)this), it still isn't clear what this +says. Presumably, the idea is that you can index off of an iterator +and assign to the result. But why the requirement that it hold a copy +of a+n? Granted, that's probably how it's implemented, but it seems +over-constrained. And the last phrase seems wrong. p is an iterator; +there's no requirement that you can assign a value_type object to +it. Should that be *p = v? But why the cast in reference(a[n] = v)? + +4. operator- has both an effects clause and a returns clause. Looks like +the returns clause should be removed. + + +Subject: N1530: Problems in indirect_iterator operations +======================================================== +Date: Wed, 12 Nov 2003 14:49:44 -0500 +From: Pete Becker +Message c++std-lib-12310 + +1. The default constructor returns "An instance of indirect_iterator with a +default constructed base object", but the constructor that takes an +Iterator object returns "An instance of indirect_iterator with the +iterator_adaptor subobject copy constructed from x." The latter is the +correct form, since it does not reach inside the base class for its +semantics. So the default constructor shoudl return "An instance of +indirect_iterator with a default-constructed iterator_adaptor subobject." + +2. The templated constructor that takes an indirect_iterator with a +different set of template arguments says that it returns "An instance of +indirect_iterator that is a copy of [the argument]". But the type of the +argument is different from the type of the object being constructed, and +there is no description of what a "copy" means. The Iterator template +parameter for the argument must be convertible to the Iterator template +parameter for the type being constructed, which suggests that the +argument's contained Iterator object should be converted to the target +type's Iterator type. Is that what's meant here? + + +Subject: N1530: enable_if_convertible conflicts with requires +============================================================= +Date: Wed, 12 Nov 2003 15:09:48 -0500 +From: Pete Becker +Message c++std-lib-12312 + +In every place where enable_if_convertible is used it's used like this +(simplified): + +template +struct C +{ +template +C(T1, enable_if_convertible::type* = 0); +}; + +The idea being that this constructor won't compile if T1 isn't convertible +to T. As a result, the constructor won't be considered as a possible +overload when constructing from an object x where the type of x isn't +convertible to T. In addition, however, each of these constructors has a +requires clause that requires convertibility, so the behavior of a program +that attempts such a construction is undefined. Seems like the +enable_if_convertible part is irrelevant, and should be removed. + + +Subject: N1530: transform_iterator argument irregularity +======================================================== +Date: Wed, 12 Nov 2003 15:22:58 -0500 +From: Pete Becker +Message c++std-lib-12315 + +The specialized adaptors that take both a Value and a Reference template +argument all take them in that order, i.e. Value precedes Reference in the +template argument list, with the exception of transform_iterator, where +Reference precedes Value. This seems like a possible source of confusion. +Is there a reason why this order is prefereable? + + +Subject: N1530: function_output_iterator +======================================== +Date: Wed, 12 Nov 2003 15:52:37 -0500 +From: Pete Becker +Message c++std-lib-12318 + +1. function_output_iterator requirements says: "The UnaryFunction must be +Assignable, Copy Constructible, and the expression f(x) must be valid, +where f is an object of type UnaryFunction and x is an object of a type +accepted by f." + +Everything starting with "and," somewhat reworded, is actually a constraint +on output_proxy::operator=. All that's needed to create a +function_output_iterator object is that the UnaryFunction type be +Assignable and CopyConstructible. That's also sufficient to dereference and +to increment such an object. It's only when you try to assign through a +dereferenced iterator that f(x) has to work, and then only for the +particular function object that the iterator holds and for the particular +value that is being assigned. + +2. Should output_proxy really be a named type? This means someone can store +an output_proxy object for later use, whatever that means. It also +constrains output_proxy to hold a copy of the function object, rather than +a pointer to the iterator object. Is all this mechanism really necessary? + + + +N1550: istreambuf_iterator isn't a Readable Iterator +==================================================== +Date: Thu, 13 Nov 2003 08:24:39 -0500 +From: Pete Becker +Message c++std-lib-12333 + +N1550 requires that for a Readable Iterator a of type X, *a returns an +object of type iterator_traits::reference. +istreambuf_iterator::operator* returns charT, but +istreambuf_iterator::reference is charT&. So am I overlooking something, or +is istreambuf_iterator not Readable? + + + + +Subject: N1530: iterator_facade free functions unspecified +========================================================== +Date: Tue, 02 Dec 2003 14:44:05 -0500 +From: Pete Becker Message c++std-lib-12562 ------------------------- + The template functions operator==, operator!=, operator<, operator<=, operator>, operator>=, and operator- that take two arguments that are @@ -34,8 +361,14 @@ function operator+ that takes an argument that is a specialization of iterator_facade and an argument of type difference_type has no specification. + + +Subject: N1530, iterator_facade: too many equals? +================================================= +Date: Tue, 02 Dec 2003 17:24:55 -0500 +From: Pete Becker Message c++std-lib-12563 ------------------------- + The table listing the functions required for types derived from iterator_facade has two functions named equal and two named distance_to:: @@ -57,7 +390,7 @@ Are the 'b' versions needed? Message c++std-lib-12566 ------------------------- +======================== The footnote says: @@ -67,3 +400,443 @@ The footnote says: This is not correct. We had a vague discussion of this in Kona and agreed in principle, but at the time there was no formal proposal. It's in the issues list as a new issue. + + +Subject: Re: Proposed revision of N1550 +======================================= +Date: Fri, 5 Dec 2003 15:09:32 -0500 +From: Howard Hinnant +Message c++std-lib-12585 + +I'm wading thru + +http://boost-consulting.com/boost/libs/iterator/doc/new-iter-concepts.html + +and due to my desire to plow through this in a sequential manner, I'm +having trouble getting past one spot. I've skimmed through the +previous discussions and didn't see that this issue was addressed +(sorry if I missed it). + +Readable Iterator Requirements says:: + + a->m U& pre: (*a).m is well-defined. Equivalent to (*a).m + +Do we mean to outlaw iterators with proxy references from meeting the +readable requirements? + +Consider:: + + template + class proxy_pointer + { + public: + proxy_pointer(T* t) : t_(t) {} + + T* operator->() {return t_;} + private: + T* t_; + }; + + template + class proxy_reference + { + public: + proxy_reference(T& t) : t_(&t) {} + + proxy_reference& operator=(const T& t) + { + *t_ = t; + return *this; + } + + proxy_reference& operator=(const proxy_reference& p) + { + *t_ = p->t_; + return *this; + } + + operator T() const {return *t_;} + + proxy_pointer operator&() const {return proxy_pointer(t_);} + private: + T* t_; + }; + + template + class iterator + { + public: + typedef proxy_reference reference; + typedef proxy_pointer pointer; + + iterator(T* t) : t_(t) {} + reference operator*() const {return reference(*t_);} + pointer operator->() const {return pointer(t_);} + private: + T* t_; + }; + + int main() + { + typedef std::pair T; + T p(1, 2); + iterator r(&p); + int i = (*r).first; // error + int j = r->first; // ok + } + +Would it be better for the requirements to read static_cast(*a).m +instead of (*a).m ? + + +Subject: N1530: counting_iterator Traversal argument unspecified +================================================================ +Date: Tue, 09 Dec 2003 10:09:15 -0500 +From: Pete Becker +Message c++std-lib-12635 + +counting_iterator takes an argument for its Traversal type, with a default +value of use_default. It is derived from an instance of iterator_adaptor, +where the argument passed for the Traversal type is described as "/* see +details for traversal category */". The details for counting_iterator +describe constraints on the Incrementable type imposed by various traversal +categories. There is no description of what the argument to +iterator_adaptor should be. + + +Subject: N1530: iterator_facade function requirements +===================================================== +Date: Tue, 09 Dec 2003 10:47:40 -0500 +From: Pete Becker +Message c++std-lib-12636 + +The table that lists required functions for the derived type X passed to +iterator_facade lists, among others: + +for a single pass iterator: +c.equal(b) +c.equal(y) + +where b and c are const X objects, and y is a const object of a single pass +iterator that is interoperable with X. Since X is interoperable with +itself, c.equal(b) is redundant. There is a difference in their +descriptions, but its meaning isn't clear. The first is "true iff b and c +are equivalent", and the second is "true iff c and y refer to the same +position." Is there a difference between the undefined term "equivalent" +and "refer to the same position"? + +Similarly, for a random access traversal iterator: +c.distance_to(b) +c.distance_to(z) + +where z is a constant object of a random access traversal iterator that is +interoperable with X. Again, X is interoperable with itself, so +c.distance_to(b) is redundant. + +Also, the specification for c.distance_to(z) isn't valid. It's written as +"equivalent to distance(c, z)". The template function distance takes two +arguments of the same type, so distance(c, z) isn't valid if c and z are +different types. Should it be distance(c, (X)z)? + + + +Subject: N1530: iterator_facade requirements muddled +==================================================== +Date: Tue, 09 Dec 2003 11:20:00 -0500 +From: Pete Becker +Message c++std-lib-12638 + +Sorry for the title. The problem is that the section entitled +"iterator_facade requirements" mixes specification of the implementation +with specification of constraints on user-supplied types. The specification +of the implementation isn't really need, though. Paragraph by paragraph: + +>Some of the constraints on template parameters to iterator_facade are +>expressed in terms of resulting nested types and should be viewed in the +>context of their impact on iterator_traits. + +This isn't really true, once we go through the rest. Remove it. + +>The Derived template parameter must be a class derived from iterator_facade. + +There's already an open issue on the wording here. No other changes needed. + +>The nested ::value_type type will be the same as remove_cv::type, +>so the Value parameter must be an (optionally const-qualified) +>non-reference type. + +The first clause repeats what's already said in the definition of the +template. The second clause is the important part. Rewrite as: + +The Value parameter shall be an optionally const-qualified non-reference type. + +>AccessCategory must be an unsigned value which uses no more bits than the +>greatest value of iterator_access. + +There's an open issue in N1550 about the specification of access +categories. The standard defines "bitmask type" for this purpose. Using it +removes the problem of determining what "uses no more bits" means. + +>The nested ::reference will be the same as the Reference parameter; it +>must be a suitable reference type for the resulting iterator. The default +>for the Reference parameter is Value&. + +The first clause repeats what's already said in the definition of the +template. The second clause has no technical meaning. The last sentence is +part of the specification of the template, and should be moved to the +definition of the template. Remove this paragraph, and change the template +argument in the definition of iterator_facade from + + class Reference = /* see below */ + +to + + class Reference = Value&; + +Finally, something that isn't quite as clearcut: + +>Depending on the resulting iterator's iterator_category, a subset of the +>expressions listed in the table are required to be valid. + +Is it meaningful to have an iterator that is neither readable nor writable? +If not, then this can be phrased as "Depending on the template argument +TraversalCategory", and the first line of the following table can be +removed from the table and stated as an overall requirement. + + + + + +Subject: N1530: iterator_adaptor issues +======================================= +Date: Tue, 09 Dec 2003 12:36:44 -0500 +From: Pete Becker +Message c++std-lib-12639 + + +1. The Derived argument seems to be underspecified. Same problem as +described in N1541, 9.21 for iterator_facade. + +2. The name Base for the iterator that's being adapted (and in the member +functions base() and base_reference()) is confusing, since it's not a base +in the sense that the term is used in C++. The templates indirect_iterator +and reverse_iterator both name their iterator argument Iterator. We should +do the same here. + +3. The clause entitled "iterator_adaptor requirements" talks about +iterator_traits::iterator_category. The base iterator_facade +defines iterator_category, so it would seem more natural to simply use +that. Unless, of course, Derived is permitted to provide its own definition +of iterator_category which is different from the one in the base, or that +iterator_traits can be specialized to provide a differnt one. That +doesn't seem reasonable, since the type in the base is determined by the +Access and Traversal arguments that the user passed to iterator_adaptor. +Why would the user want to define it differently? + +4. The clause entitled "iterator_adaptor requirements" sets out +requirements in terms of the typedefs defined in iterator_facade. It would +be clearer to specify the arguments that should be passed to iterator_facade: + +Value argument to iterator_facade:: + + if (Value != use_default) + Value + else + iterator_traits::value_type + +But note that the default here is slightly different from the default +specified in the paper. The latter can't be implemented correctly with an +argument to iterator_facade, since iterator_traits::value_type might +be cv-qualified, and iterator_facade strips the cv-qualifier. The approch +I've given strips the cv-qualifier, too. In order to implement what the +paper says, iterator_adaptor would have to provide its own version of +value_type. + +AccessCategory argument to iterator_facade:: + + if (Access != use_default) + Access + else if (is_const) + access_category::value & ~writable_iterator + else + access_category::value + +This assumes (as does the paper) that there is a suitable definition of +access_category somewhere (N1550 doesn't specify it). + +TraversalCategory argument to iterator_facade:: + + if (Traversal != use_default) + Traversal + else + traversal_category::type + +This assumes (as does the paper) that there is a suitable definition of +traversal_category somewhere (N1550 doesn't specify it). + +iterator_category is redundant and should be removed. + +Reference argument to iterator_facade:: + + if (Reference != use_default) + Reference + else if (Value != use_default) + Value& + else + iterator_traits::reference + +The Difference argument to iterator_facade isn't specified here. Needs to +be added. By analogy, should it be this?:: + + if (Difference != use_default) + Difference + else + iterator_traits::difference_type + + + + + +Subject: N1530: indirect_iterator requirements muddled +====================================================== +Date: Tue, 09 Dec 2003 13:35:20 -0500 +From: Pete Becker +Message c++std-lib-12640 + +>The value_type of the Iterator template parameter should itself be +>dereferenceable. The return type of the operator* for the value_type must +>be the same type as the Reference template parameter. + +I'd say this a bit differently, to emphasize what's required: + +iterator_traits::value_type must be dereferenceable. + +The Reference template parameter must be the same type as +*iterator_traits::value_type(). + +>The Value template parameter will be the value_type for the +>indirect_iterator, unless Value is const. If Value is const X, then +>value_type will be non- const X. + +Also non-volatile, right? In other words, if Value isn't use_default, it +just gets passed as the Value argument for iterator_adaptor. + +>The default for Value is +> +>iterator_traits< iterator_traits::value_type >::value_type +> +>If the default is used for Value, then there must be a valid +>specialization of iterator_traits for the value type of the base iterator. + +The earlier requirement is that iterator_traits::value_type must +be dereferenceable. Now it's being treated as an iterator. Is this just a +pun, or is iterator_traits::value_type required to be some form +of iterator? If it's the former we need to find a different way to say it. +If it's the latter we need to say so. + +>The Reference parameter will be the reference type of the +>indirect_iterator. The default is Value&. + +That is, the Reference parameter is passed unchanged as the Reference +argument to iterator_adaptor. Which is what it should say, instead of +repeating what iterator_adaptor does. + +>The Access and Traversal parameters are passed unchanged to the +>corresponding parameters of the iterator_adaptor base class, and the +>Iterator parameter is passed unchanged as the Base parameter to the +>iterator_adaptor base class. + +Okay, but wordy. We should put it in the template definition: + +template< + class Iterator, + class Value = use_default, + class Access = use_default_access, + class Traversal = use_default, + class Reference = use_default, + clsas Difference = use_default> +class indirect_iterator + : public iterator_adaptor< + indirect_iterator, + Iterator, + /* Value = see below */, + Access, + Traversal, + Reference, + Difference> + +>The indirect iterator will model the most refined standard traversal +>concept that is modeled by the Iterator type. The indirect iterator will +>model the most refined standard access concept that is modeled by the +>value type of Iterator. + +That's not strictly true. The Access and Traversal arguments can be more +restrictive than the Iterator, in which case the operations needed for the +most refined types are available, but iterator_traits::iterator_category +won't reflect those capabilities. + + + +Subject: N1530: transform_iterator requirements +=============================================== +Date: Tue, 09 Dec 2003 13:42:49 -0500 +From: Pete Becker +Message c++std-lib-12641 + +>The reference type of transform_iterator is +>result_of::reference)>::type. The +>value_type is remove_cv >::type. + +These are the defaults, right? If the user supplies their own types that's +what gets passed to iterator_adaptor. And again, the specification should +be in terms of the specialization of iterator_adaptor, and not in terms of +the result: + +Reference argument to iterator_adaptor:: + + if (Reference != use_default) + Reference + else + result_of::reference)>::type + +Value argument to iterator_adaptor:: + + if (Value != use_default) + Value + else if (Reference != use_default) + remove_reference::type + else + remove_reference::reference)>::type>::type + +There's probably a better way to specify that last alternative, but I've +been at this too long, and it's all turning into a maze of twisty passages, +all alike. + + + +Subject: N1530: filter_iterator details unspecified +=================================================== +Date: Tue, 09 Dec 2003 13:52:21 -0500 +From: Pete Becker +Message c++std-lib-12642 + +The paper says:: + + template + class filter_iterator + : public iterator_adaptor< + filter_iterator, + Iterator, + use_default, + /* see details */ > + +That comment covers the Access, Traversal, Reference, and Difference +arguments. The only specification for any of these in the details is: + +>The access category of the filter_iterator will be the same as the access +>category of Iterator. + +Needs more. + +