[iterator] Combining traversal_tags with iterator_tags

Hi, In MultiArray I would like use iterator_facade to create an iterator that can satisfy random_access_traversal, input_iterator_tag, and output_iterator_tag. I see that in the file boost/iterator/detail/facade_iterator_category.hpp, at line 138 there is a class in the boost::detail namespace declared template <class Category, class Traversal> struct iterator_category_with_traversal So it looks like passing: boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag> as the CategoryOrTraversal would be what I want. However, two components above are in the detail namespace, so I am not sure if they are meant to be used by other libraries. Is this a safe operation? Thanks, Ron Side Notes: In my searches, I found a few buggy bits in the docs and code comments: - In boost/iterator/detail/facade_iterator_category.hpp, line 76, there's a comment: // If writability has been disabled per the above metafunction, the // result will not be convertible to output_iterator_tag. This comment corresponds to behavior that was removed in changeset: https://svn.boost.org/trac/boost/changeset/21683 Now the result will never be convertible to output_iterator_tag. - In the documentation for iterator_facade, there's a bit of a booboo where the function is first written: iterator-category(CategoryOrTraversal, value_type, reference) Then defined as: iterator-category(C,R,V) So I think the argument order is flipped.

on Sat Jan 07 2012, Ronald Garcia <rxg-AT-cs.cmu.edu> wrote:
Hi,
In MultiArray I would like use iterator_facade to create an iterator that can satisfy random_access_traversal, input_iterator_tag, and output_iterator_tag. I see that in the file boost/iterator/detail/facade_iterator_category.hpp, at line 138 there is a class in the boost::detail namespace declared
template <class Category, class Traversal> struct iterator_category_with_traversal
So it looks like passing: boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag>
as the CategoryOrTraversal would be what I want. However, two components above are in the detail namespace, so I am not sure if they are meant to be used by other libraries. Is this a safe operation?
Using things in detail namespaces is never really "safe" unless you own the surrounding namespace.
Side Notes: In my searches, I found a few buggy bits in the docs and code comments:
- In boost/iterator/detail/facade_iterator_category.hpp, line 76, there's a comment: // If writability has been disabled per the above metafunction, the // result will not be convertible to output_iterator_tag.
This comment corresponds to behavior that was removed in changeset: https://svn.boost.org/trac/boost/changeset/21683
Now the result will never be convertible to output_iterator_tag.
- In the documentation for iterator_facade, there's a bit of a booboo where the function is first written: iterator-category(CategoryOrTraversal, value_type, reference)
Then defined as:
iterator-category(C,R,V)
So I think the argument order is flipped.
Please open Trac tickets for any of these that don't already have them. Thanks! -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Hi Dave, On Jan 7, 2012, at 4:56 PM, Dave Abrahams wrote:
So it looks like passing: boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag>
as the CategoryOrTraversal would be what I want. However, two components above are in the detail namespace, so I am not sure if they are meant to be used by other libraries. Is this a safe operation?
Using things in detail namespaces is never really "safe" unless you own the surrounding namespace.
Definitely. Let me rephrase then: it seems as though these two items, input_output_iterator_tag and iterator_category_with_traversal, could be elevated out of boost::detail and be part of the public interface of the iterator library. As far as I can tell, neither is ever used in the implementation of the library, which makes them currently dead code. However, I don't know enough about the iterator library to know if this makes sense. So: does it make sense for these two classes to appear as part of the iterator library interface, or are there some aspects of the library design or existing interface that would preclude this? If there is no such problem, then I would be happy to file a feature request via Trac, and possibly even propose some patches to make it so. Best, Ron

Ronald Garcia wrote:
In MultiArray I would like use iterator_facade to create an iterator that can satisfy random_access_traversal, input_iterator_tag, and output_iterator_tag. [snip] So it looks like passing: boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag>
as the CategoryOrTraversal would be what I want.
This is a very good idea. The advantage of this "idea" over my ideas how to fix the problem is that you neither need to modify Boost.Iterator, nor to "lie" to the compiler. However, I would just declare the required iterator_tag class locally, so that you don't depend on implementation details of Boost.Iterator: struct random_access_traversal_input_output_iterator_tag : boost::random_access_traversal_tag, std::input_iterator_tag { operator std::output_iterator_tag() const { return std::output_iterator_tag(); } }; The attached patch for multi_array/iterator.hpp does exactly that. You should be able to apply it directly, without any need to wait for changes to Boost.Iterator. Independently, you can still pursue your feature request for Boost.Iterator (if you want). Regards, Thomas

On Sun, Jan 8, 2012 at 2:34 PM, Thomas Klimpel <Thomas.Klimpel@synopsys.com>wrote:
In MultiArray I would like use iterator_facade to create an iterator
Ronald Garcia wrote: that can satisfy
random_access_traversal, input_iterator_tag, and output_iterator_tag. [snip] So it looks like passing:
boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag>
as the CategoryOrTraversal would be what I want.
This is a very good idea. The advantage of this "idea" over my ideas how to fix the problem is that you neither need to modify Boost.Iterator, nor to "lie" to the compiler. However, I would just declare the required iterator_tag class locally, so that you don't depend on implementation details of Boost.Iterator:
struct random_access_traversal_input_output_iterator_tag : boost::random_access_traversal_tag, std::input_iterator_tag { operator std::output_iterator_tag() const { return std::output_iterator_tag(); } };
The attached patch for multi_array/iterator.hpp does exactly that. You should be able to apply it directly, without any need to wait for changes to Boost.Iterator. Independently, you can still pursue your feature request for Boost.Iterator (if you want).
I agree, I think the thing to do here is to be explicit about what tag you want to use, rather than pulling this out of Boost.Iterator's detail namespace; e.g., the above prefers conversions to std::input_iterator_tag over std::output_iterator_tag, which could have subtle effects in some situations. - Jeff

Hello Jeff, Since input_iterator and output_iterator are orthogonal concepts, I can't imagine what piece of sensible code would cause subtle effects due to preferring input_iterator over output_iterator. Do you have an example in mind? Thanks, Ron On Jan 8, 2012, at 6:32 PM, Jeffrey Lee Hellrung, Jr. wrote:
I agree, I think the thing to do here is to be explicit about what tag you want to use, rather than pulling this out of Boost.Iterator's detail namespace; e.g., the above prefers conversions to std::input_iterator_tag over std::output_iterator_tag, which could have subtle effects in some situations.
- Jeff
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

[reordering] On Sun, Jan 8, 2012 at 8:45 PM, Ronald Garcia <rxg@cs.cmu.edu> wrote:
On Jan 8, 2012, at 6:32 PM, Jeffrey Lee Hellrung, Jr. wrote:
I agree, I think the thing to do here is to be explicit about what tag you want to use, rather than pulling this out of Boost.Iterator's detail namespace; e.g., the above prefers conversions to std::input_iterator_tag over std::output_iterator_tag, which could have subtle effects in some situations.
- Jeff
Hello Jeff,
Since input_iterator and output_iterator are orthogonal concepts, I can't imagine what piece of sensible code would cause subtle effects due to preferring input_iterator over output_iterator. Do you have an example in mind?
Thanks, Ron
Nope, nothing in particular in mind. I would say, if you really think that traversal_with_category (I think that's what it's called...) should be pulled out to the public API, file a trac ticket and I'll look more closely at it once I find time to familiarize myself with the boost development process (I've found wiki's with lots of information, just haven't parsed through them yet). In the meantime, though, this can be a change made entirely locally to whatever component you need it in (I'm sorry, I've since forgotten the context). - Jeff

Hello Thomas, Thank you for the offered patch. Unfortunately this is not quite right because it would result in const_iterators being declared as output iterators as well. Cheers, Ron On Jan 8, 2012, at 5:34 PM, Thomas Klimpel wrote:
Ronald Garcia wrote:
In MultiArray I would like use iterator_facade to create an iterator that can satisfy random_access_traversal, input_iterator_tag, and output_iterator_tag. [snip] So it looks like passing: boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag>
as the CategoryOrTraversal would be what I want.
This is a very good idea. The advantage of this "idea" over my ideas how to fix the problem is that you neither need to modify Boost.Iterator, nor to "lie" to the compiler. However, I would just declare the required iterator_tag class locally, so that you don't depend on implementation details of Boost.Iterator:
struct random_access_traversal_input_output_iterator_tag : boost::random_access_traversal_tag, std::input_iterator_tag { operator std::output_iterator_tag() const { return std::output_iterator_tag(); } };
The attached patch for multi_array/iterator.hpp does exactly that. You should be able to apply it directly, without any need to wait for changes to Boost.Iterator. Independently, you can still pursue your feature request for Boost.Iterator (if you want).
Regards, Thomas<multi_array_iterator.patch> _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hello Thomas, Thank you for the offered patch. Unfortunately this is not quite right because it would result in const_iterators being declared as output iterators as well. Cheers, Ron On Jan 8, 2012, at 5:34 PM, Thomas Klimpel wrote:
Ronald Garcia wrote:
In MultiArray I would like use iterator_facade to create an iterator that can satisfy random_access_traversal, input_iterator_tag, and output_iterator_tag. [snip] So it looks like passing: boost::detail::iterator_category_with_traversal<boost::detail::input_output_iterator_tag,boost::random_traversal_tag>
as the CategoryOrTraversal would be what I want.
This is a very good idea. The advantage of this "idea" over my ideas how to fix the problem is that you neither need to modify Boost.Iterator, nor to "lie" to the compiler. However, I would just declare the required iterator_tag class locally, so that you don't depend on implementation details of Boost.Iterator:
struct random_access_traversal_input_output_iterator_tag : boost::random_access_traversal_tag, std::input_iterator_tag { operator std::output_iterator_tag() const { return std::output_iterator_tag(); } };
The attached patch for multi_array/iterator.hpp does exactly that. You should be able to apply it directly, without any need to wait for changes to Boost.Iterator. Independently, you can still pursue your feature request for Boost.Iterator (if you want).
Regards, Thomas<multi_array_iterator.patch> _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (4)
-
Dave Abrahams
-
Jeffrey Lee Hellrung, Jr.
-
Ronald Garcia
-
Thomas Klimpel