RE: [boost] [iterators] request for utility iterator

you can easily achieve this using (make_)transform_iterator and boost bind: make_transform_iterator( map.begin(), boost::bind( &MAP_TYPE::value_type::first, _1 ) ) (give or take a typename before MAP_TYPE::...) I think it's so simple that you don't really need a utility class for it. I'm also quite sure that boost bind takes better care of const/mutable return type and any other bad things that you may stumble across when trying to implement this functor youself (same goes for boost.lambda). eyal. -----Original Message----- From: Thorsten Ottosen [mailto:nesotto@cs.auc.dk] Sent: Monday, February 14, 2005 4:19 AM To: boost@lists.boost.org Subject: [boost] [iterators] request for utility iterator Hi all, I often want to iterate over just the values of a map or perhaps just the keys of a map. Therefore I would like to see the following iterator adapters in the iterator library: template< class Map > struct map_key_iterator; template< class Map > struct map_value_iterator; template< class Map > struct map_const_value_iterator; I have outlined an implementation in the attached file, but basically it just a wrapper around transform_iterator<typename Map::iterator>. Comments? br Thorsten

"Eyal Farago" <eyal.farago@actimize.com> wrote in message news:BC29F2A417B44F44BD3AA1AD9868CEDC034244@ilexchange.adrembi.com... | you can easily achieve this using (make_)transform_iterator and boost bind: | | make_transform_iterator( | map.begin(), | boost::bind( &MAP_TYPE::value_type::first, _1 ) | ) | | (give or take a typename before MAP_TYPE::...) | I think it's so simple that you don't really need a utility class for it. well, I cannot use that when I want to write a manual loop. yes, it is simple, but also frequently used. And we also have to think about less experienced users IMO. -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Eyal Farago" <eyal.farago@actimize.com> wrote in message news:BC29F2A417B44F44BD3AA1AD9868CEDC034244@ilexchange.adrembi.com... | you can easily achieve this using (make_)transform_iterator and boost bind: | | make_transform_iterator( | map.begin(), | boost::bind( &MAP_TYPE::value_type::first, _1 ) | ) | | (give or take a typename before MAP_TYPE::...) | I think it's so simple that you don't really need a utility class for it.
well, I cannot use that when I want to write a manual loop.
yes, it is simple, but also frequently used. And we also have to think about less experienced users IMO.
Both of you make good points. There's a third point I should bring up: Thorsten, your iterator isn't legal. Hint: what is the return type of its operator++? It has been pointed out that this sort of thing would be very much easier if, like iterator_facade and iterator_adaptor, all the specialized adapters could accept one more optional parameter that specifies the most-derived iterator class. I think that's a good idea, but I'm not sure how to do it without making the interface overly complicated. Ideas? I don't want to go back to the "bad old days" of named template parameters. In fact, the way default types are calculated and specified in the iterators library is just too complicated and needs to be re-examined. The whole iterators library needs some attention, but there just hasn't been time for me recently. Jeremy is working on his PhD, and Thomas has allowed his professional life to get the better of him ;-). I hope to get to it somewhere along the path of my work on the MTL (http://www.boost-consulting.com/projects/mtl). -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | | > "Eyal Farago" <eyal.farago@actimize.com> wrote in message | > news:BC29F2A417B44F44BD3AA1AD9868CEDC034244@ilexchange.adrembi.com... | > | you can easily achieve this using (make_)transform_iterator and boost bind: [snip] | > well, I cannot use that when I want to write a manual loop. | > | > yes, it is simple, but also frequently used. And we also | > have to think about less experienced users IMO. | | Both of you make good points. There's a third point I should bring | up: Thorsten, your iterator isn't legal. Hint: what is the return | type of its operator++? yes, there are lots of trouple with it...for example, I don't think it is good to base it on the container type when basing it on an iterator type would be more flexible. | It has been pointed out that this sort of thing would be very much | easier if, like iterator_facade and iterator_adaptor, all the | specialized adapters could accept one more optional parameter that | specifies the most-derived iterator class. perhaps, but so much interested in the actual implementation...as a user I just wished the functionality was there to use...just like I don't have to code an indirect iterator, but can use boost::indirect_iterator. If there is agreement that the two iterators would be a good idea, I don't mind adding a proper implementation. -Thorsten

Dave, Thorsten, David Abrahams wrote:
"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
It has been pointed out that this sort of thing would be very much easier if, like iterator_facade and iterator_adaptor, all the specialized adapters could accept one more optional parameter that specifies the most-derived iterator class. I think that's a good idea, but I'm not sure how to do it without making the interface overly complicated. Ideas? I don't want to go back to the "bad old days" of named template parameters.
I can see this being usefull, but deriving from an iterator is such a no-no that creating a optonally derivable iterator somehow seems wrong to me. We could add another level of indirection and introduce xxx_iterator_base<Derived, ...> types. And no I don't consider this a very bright idea either. With respect to iterator lib maintenance. Me personally I don't feel confident in making changes as I don't have a good feeling on what is really needed or what the correct solution will be.
In fact, the way default types are calculated and specified in the iterators library is just too complicated and needs to be re-examined.
This directly relates to what I said before. The whole area of iterator categories is so murky currently. IIRC there are outstanding DRs and issues that where never really resolved. In general I do agree.
The whole iterators library needs some attention, but there just hasn't been time for me recently. Jeremy is working on his PhD, and Thomas has allowed his professional life to get the better of him ;-).
Yeah having to work for a living really makes your live miserable ;-). Seriously I will have more time to deal with these things starting now. I.e. I am open to input I just currently don't have any good ideas on how to improve the whole thing. With respect to map_xxx iterators I always felt that something like this is sorely lacking. IN going ahaed I would much rather like to see an iterator_adaptor that iterates over a single/multiple index in a collection of tuples than a map iterator. Thomas -- Thomas Witt witt@acm.org

Thomas Witt <witt@acm.org> writes:
Dave, Thorsten,
David Abrahams wrote:
"Thorsten Ottosen" <nesotto@cs.auc.dk> writes: It has been pointed out that this sort of thing would be very much easier if, like iterator_facade and iterator_adaptor, all the specialized adapters could accept one more optional parameter that specifies the most-derived iterator class. I think that's a good idea, but I'm not sure how to do it without making the interface overly complicated. Ideas? I don't want to go back to the "bad old days" of named template parameters.
I can see this being usefull, but deriving from an iterator is such a no-no that creating a optonally derivable iterator somehow seems wrong to me.
What you're saying is that giving people a way to do it correctly will encourage them to do it incorrectly, and therefore we shouldn't?
We could add another level of indirection and introduce xxx_iterator_base<Derived, ...> types. And no I don't consider this a very bright idea either.
The problem is that the previous version of the library using the policy adaptor pattern _had_ this capability, because you could grab the policies class that each adaptor published as part of its public interface, and derive a new policies class from it.
With respect to iterator lib maintenance. Me personally I don't feel confident in making changes as I don't have a good feeling on what is really needed or what the correct solution will be.
But you know what you _don't_ like ;-)
In fact, the way default types are calculated and specified in the iterators library is just too complicated and needs to be re-examined.
This directly relates to what I said before. The whole area of iterator categories is so murky currently. IIRC there are outstanding DRs
DRs? Do you mean against C++03 iterators in the standard?
and issues that where never really resolved. In general I do agree.
The whole iterators library needs some attention, but there just hasn't been time for me recently. Jeremy is working on his PhD, and Thomas has allowed his professional life to get the better of him ;-).
Yeah having to work for a living really makes your live miserable ;-). Seriously I will have more time to deal with these things starting now. I.e. I am open to input I just currently don't have any good ideas on how to improve the whole thing.
Well, maybe we need to return to policy adaptors, with a hybrid approach: class my_iterator : public iterator_facade<my_iterator, my_policies> { // c'tors here }; But ultimately, I think we do need some way to allow users to conveniently refine the existing adaptors, and we need to do it *before* template aliases show up in their compilers! -- Dave Abrahams Boost Consulting www.boost-consulting.com

Dave, David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
I can see this being usefull, but deriving from an iterator is such a no-no that creating a optonally derivable iterator somehow seems wrong to me.
What you're saying is that giving people a way to do it correctly will encourage them to do it incorrectly, and therefore we shouldn't?
What I was trying to say was that I'd prefer to see a solution that provides the desired functionality without having the user derive from what otherwise is a valid iterator.
We could add another level of indirection and introduce xxx_iterator_base<Derived, ...> types. And no I don't consider this a very bright idea either.
The problem is that the previous version of the library using the policy adaptor pattern _had_ this capability, because you could grab the policies class that each adaptor published as part of its public interface, and derive a new policies class from it.
Well that's actually more like deriving from xxx_iterator_base.
But you know what you _don't_ like ;-)
Yep. I just try to be unhelpfull in a sophisticated way ;-).
This directly relates to what I said before. The whole area of iterator categories is so murky currently. IIRC there are outstanding DRs
DRs? Do you mean against C++03 iterators in the standard?
I am mostly referring to iterator_categories here. IIRC not all issues that came up during the iterator adaptor discussions are resolved yet.
Well, maybe we need to return to policy adaptors, with a hybrid approach:
class my_iterator : public iterator_facade<my_iterator, my_policies> { // c'tors here };
Wasn't that one of the original design ideas that was ruled out due to ... ? If only I could remember what the rationale was.
But ultimately, I think we do need some way to allow users to conveniently refine the existing adaptors, and we need to do it *before* template aliases show up in their compilers!
Agreed Thomas -- Thomas Witt witt@acm.org

Thomas Witt <witt@acm.org> writes:
Dave,
David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
I can see this being usefull, but deriving from an iterator is such a no-no that creating a optonally derivable iterator somehow seems wrong to me.
What you're saying is that giving people a way to do it correctly will encourage them to do it incorrectly, and therefore we shouldn't?
What I was trying to say was that I'd prefer to see a solution that provides the desired functionality without having the user derive from what otherwise is a valid iterator.
Well, of course it wouldn't be a valid iterator. transform_iterator<derived_is<whatever>, ... > // using named param syntax isn't a valid iterator by itself.
We could add another level of indirection and introduce xxx_iterator_base<Derived, ...> types. And no I don't consider this a very bright idea either.
The problem is that the previous version of the library using the policy adaptor pattern _had_ this capability, because you could grab the policies class that each adaptor published as part of its public interface, and derive a new policies class from it.
Well that's actually more like deriving from xxx_iterator_base.
Yes, I was only talking about the capability -- not the means for getting it -- and saying why we need to do _something_.
But you know what you _don't_ like ;-)
Yep. I just try to be unhelpfull in a sophisticated way ;-).
Ever the urbane sophisticate, ain'tcha?
This directly relates to what I said before. The whole area of iterator categories is so murky currently. IIRC there are outstanding DRs
DRs? Do you mean against C++03 iterators in the standard?
I am mostly referring to iterator_categories here. IIRC not all issues that came up during the iterator adaptor discussions are resolved yet.
So you don't mean DRs. That's a whole other ball-o'-wax.
Well, maybe we need to return to policy adaptors, with a hybrid approach: class my_iterator : public iterator_facade<my_iterator, my_policies> { // c'tors here };
Wasn't that one of the original design ideas that was ruled out due to ... ? If only I could remember what the rationale was.
I honestly don't know. I think it's quite possible that we never distinguished the use of policies in the old design from the problems caused by not using CRTP.
But ultimately, I think we do need some way to allow users to conveniently refine the existing adaptors, and we need to do it *before* template aliases show up in their compilers!
Agreed
Well, at least we agree there's a real problem. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
I honestly don't know. I think it's quite possible that we never distinguished the use of policies in the old design from the problems caused by not using CRTP.
I had a look at my archived emails. Unfortunately they represent only a small part of the discussion. IIRC that my initial design proposal was indeed policy based and we decided that it added complexity for very little benefit. One problem being constructor signatures. In order to shield the user from dealing with policies directly an iterator author had to provide a policy and a class derived from the policy wrapper (iterator_adaptor/iterator_facade). Thomas -- Thomas Witt witt@acm.org
participants (4)
-
David Abrahams
-
Eyal Farago
-
Thomas Witt
-
Thorsten Ottosen