
OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly: vertex_iterator pv, ve; tie(pv, ve) = vertices(g); // unpack the pair returned by vertices for (; pv != pe; ++pv) { ... } However, we can make it much nicer, e.g.: for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... } My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas? --- -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams-3 wrote:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
unpack or expand perhaps. Best Regards, Johan Torp www.johantorp.com -- View this message in context: http://www.nabble.com/tie-alternative--tp20181162p20182634.html Sent from the Boost - Dev mailing list archive at Nabble.com.

on Mon Oct 27 2008, Johan Torp <johan.torp-AT-gmail.com> wrote:
David Abrahams-3 wrote:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
unpack or expand perhaps.
Yeah, but that's a bit too long and not quite evocative enough. I'm setting the first argument (an out parameter) to the first element of the pair and returning the second one. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams skrev:
OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly:
vertex_iterator pv, ve; tie(pv, ve) = vertices(g); // unpack the pair returned by vertices for (; pv != pe; ++pv) { ... }
However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
What is the usecase here? I'm curious on why it isn't covered by BOOST_FOREACH and if that case really is common enough for a special solution like this. / Jonas

on Mon Oct 27 2008, Jonas Persson <l.j.persson-AT-gmail.com> wrote:
David Abrahams skrev:
OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly:
vertex_iterator pv, ve; tie(pv, ve) = vertices(g); // unpack the pair returned by vertices for (; pv != pe; ++pv) { ... }
However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
What is the usecase here?
Iterating over a range returned as a std::pair. But that should be obvious from what I wrote, so I guess I don't understand the question.
I'm curious on why it isn't covered by BOOST_FOREACH
BOOST_FOREACH doesn't give you access to the iterator value, for what that's worth. Also some people don't like to use macros.
and if that case really is common enough for a special solution like this.
I can't comment on that, I'm afraid. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams skrev:
I'm curious on why it isn't covered by BOOST_FOREACH
BOOST_FOREACH doesn't give you access to the iterator value, for what that's worth. Also some people don't like to use macros.
Ok. Dislike for macros is hard to argue against. But if the reason mainly is about accessing iterators, perhaps an indirection wrapper on vertices and BOOST_FOREACH is a more readable alternative. BOOST_FOREACH(vertex_iterator vi, keep_iterators(vertices(g))) { / Jonas

Quoting Mathias Gaunard <mathias.gaunard@ens-lyon.org>:
David Abrahams wrote:
What is the usecase here?
Iterating over a range [with iterators]
for(iterator_type it = boost::begin(range); it != boost::end(range); ++it)
I don't think it's any uglier than it has to be. That could easily be made into a BOOST_FOREACH_IT macro.
In the case at hand we trying to support the case where range is a temporary where the above implementation may be be inefficient or wrong. Not to say you couldn't implement FOREACH_IT using the same techniques as FOREACH if you really wanted the iterators.

"David Abrahams" <dave@boostpro.com> wrote in message news:877i7uivdq.fsf@mcbain.luannocracy.com...
... However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
I would recommend one of the following, depending on your verbosity comfort level. The vertical bar, | , denotes alternation: (get|as|to)_iterators get_container_bounds Thanks, Michael Goldshteyn

"David Abrahams" <dave@boostpro.com> wrote in message news:877i7uivdq.fsf@mcbain.luannocracy.com...
... However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
I would recommend one of the following, depending on your verbosity comfort level. The vertical bar, | , denotes alternation: (get|as|to)_iterators get_container_bounds Thanks, Michael Goldshteyn

on Mon Oct 27 2008, "Michael G" <mgoldshteyn-AT-comcast.net> wrote:
"David Abrahams" <dave@boostpro.com> wrote in message news:877i7uivdq.fsf@mcbain.luannocracy.com...
... However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
I would recommend one of the following, depending on your verbosity comfort level. The vertical bar, | , denotes alternation:
(get|as|to)_iterators get_container_bounds
Again, quite verbose. But maybe BOOST_FOREACH is the right answer anyway; I don't know. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

on Mon Oct 27 2008, "Michael G" <mgoldshteyn-AT-comcast.net> wrote:
"David Abrahams" <dave@boostpro.com> wrote in message news:877i7uivdq.fsf@mcbain.luannocracy.com...
... However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
I would recommend one of the following, depending on your verbosity comfort level. The vertical bar, | , denotes alternation:
(get|as|to)_iterators get_container_bounds
Again, quite verbose. But maybe BOOST_FOREACH is the right answer anyway; I don't know.
What with FOREACH's potential extra copying in the rvalue case and the occasional desire to avoid a heavy include, I think there is room for this. But OTOH I won't landgrab an operator overload for it. So we want a short verb for it ... It's quite a lot like "tie" but not quite. So some maybes: tie //not caring that it's not really the same and assuming we have enough wriggle room to avoid ambiguity in the U = pair<T,T> case rtie //r is supposed evoke "right tie" i.e. RHS tie untie //in case you think it is actually more like the opposite of tie than tie itself split //keep the distance from tie pry //short, "tie and pry" is quite rhythmical, supposed to be evocative of "pry open" By the way, your scrap paper code had a typo - the return type was intended to be U. But in the envisaged use case of the for loop T has to equal U anyway, so may be your subconscious was toying with the idea of making it a template in only one type :-). Pete

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Abrahams Sent: Monday, 27 October 2008 12:13 PM To: boost Subject: [boost] tie alternative? OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly: vertex_iterator pv, ve; tie(pv, ve) = vertices(g); // unpack the pair returned by vertices for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) My only problem is how to spell xxx.... --- Prioritising (as I do) some measure of self-documentation over concision suggests something like "load_first__return_second" [footnote 1]. Compromising a bit "loadF_returnS", "pair_load_return", "load1_return2", "load_return", "load1_ret2" or even "load_ret". Abandoning my habitual use of "load" for such by-reference assignment, "pair_set_return" et al. (Usual arguments about "&pv" implications left aside.) In particular, generic words like "unpack" have too many varying behaviours in other languages and tools.... Tony [1] I'd use a double underscore, though I know technically it's reserved by the Standard - every related use I've seen involves pre- or postfix "__", and you'd have a namespace too. Having said that, I don't seriously expect anyone to agree in the boost context. -------------------------------------------------------- This is not an offer (or solicitation of an offer) to buy/sell the securities/instruments mentioned or an official confirmation. Morgan Stanley may deal as principal in or own or act as market maker for securities/instruments mentioned or may advise the issuers. This is not research and is not from MS Research but it may refer to a research analyst/research report. Unless indicated, these views are the author's and may differ from those of Morgan Stanley research or others in the Firm. We do not represent this is accurate or complete and we may not update this. Past performance is not indicative of future returns. For additional information, research reports and important disclosures, contact me or see https://secure.ms.com/servlet/cls. You should not use e-mail to request, authorize or effect the purchase or sale of any security or instrument, to send transfer instructions, or to effect any other transactions. We cannot guarantee that any such requests received via e-mail will be processed in a timely manner. This communication is solely for the addressee(s) and may contain confidential information. We do not waive confidentiality by mistransmission. Contact me if you do not wish to receive these communications. In the UK, this communication is directed in the UK to those persons who are professional and eligible counterparties (as defined in the UK Financial Services Authority's rules).

OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) Moreover, in my opinion, the above construct seems a bit awkward to me. Modifying pv and pe at the same time, one as a function parameter,
I have encountered the same problem, but i am not sure why you would want to use anything but BOOST_FOREACH... the other initialized with what the functions returns is a best very confusing. It's very clever, though, but again, why not use BOOST_FOREACH ? Another idea might be to directly use a pair of iterators by creating a special structure for "duplicate pairs"... for( duplicate_pair<vertex_iterator> vip( vertices( g ) ) ; vip.first != vip.second ; ++vip.first ) { //... } I am not sure there's a real gain here though. Oh well. Can't blame me for trying ! :-) Benoît

Benoit skrev:
OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly:
I have encountered the same problem, but i am not sure why you would want to use anything but BOOST_FOREACH...
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) Moreover, in my opinion, the above construct seems a bit awkward to me. Modifying pv and pe at the same time, one as a function parameter, the other initialized with what the functions returns is a best very confusing. It's very clever, though, but again, why not use BOOST_FOREACH ?
Another idea might be to directly use a pair of iterators by creating a special structure for "duplicate pairs"...
for( duplicate_pair<vertex_iterator> vip( vertices( g ) ) ; vip.first != vip.second ; ++vip.first ) { //... }
I am not sure there's a real gain here though. Oh well. Can't blame me for trying ! :-)
FWIW, You can already today do for( boost::iterator_range<vertex_iterator> vip( vertices( g ) ) ; !vip.empty(); vip.advance_begin(1) ) -Thorsten

on Tue Oct 28 2008, Thorsten Ottosen <thorsten.ottosen-AT-dezide.com> wrote:
Benoit skrev:
OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly:
I have encountered the same problem, but i am not sure why you would want to use anything but BOOST_FOREACH...
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) Moreover, in my opinion, the above construct seems a bit awkward to me. Modifying pv and pe at the same time, one as a function parameter, the other initialized with what the functions returns is a best very confusing. It's very clever, though, but again, why not use BOOST_FOREACH ?
Another idea might be to directly use a pair of iterators by creating a special structure for "duplicate pairs"...
for( duplicate_pair<vertex_iterator> vip( vertices( g ) ) ; vip.first != vip.second ; ++vip.first ) { //... }
I am not sure there's a real gain here though. Oh well. Can't blame me for trying ! :-)
FWIW, You can already today do
for( boost::iterator_range<vertex_iterator> vip( vertices( g ) ) ; !vip.empty(); vip.advance_begin(1) )
It's sad, but I'm not as confident in the ability to optimize that form because the iterators are bundled into a single struct. Also I am not fond of the constant 1. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
for( boost::iterator_range<vertex_iterator> vip( vertices( g ) ) ; !vip.empty(); vip.advance_begin(1) )
It's sad, but I'm not as confident in the ability to optimize that form because the iterators are bundled into a single struct. Also I am not fond of the constant 1.
Can't be worse than BOOST_FOREACH, which if I recall correctly is much less efficient than a normal loop on MSVC.

David Abrahams skrev:
on Tue Oct 28 2008, Thorsten Ottosen <thorsten.ottosen-AT-dezide.com> wrote:
Benoit skrev:
Another idea might be to directly use a pair of iterators by creating a special structure for "duplicate pairs"...
for( duplicate_pair<vertex_iterator> vip( vertices( g ) ) ; vip.first != vip.second ; ++vip.first ) { //... }
I am not sure there's a real gain here though. Oh well. Can't blame me for trying ! :-) FWIW, You can already today do
for( boost::iterator_range<vertex_iterator> vip( vertices( g ) ) ; !vip.empty(); vip.advance_begin(1) )
It's sad, but I'm not as confident in the ability to optimize that form because the iterators are bundled into a single struct. Also I am not fond of the constant 1.
I haven't tried on a new compiler (only vc8), but it is quite sad that compilers can't optimize std::advance(i,1) into ++i. -Thorsten

2008/10/27 David Abrahams <dave@boostpro.com>
OK, BOOST_FOREACH aside, iterating over a range returned as a pair of iterators can be painful and ugly:
vertex_iterator pv, ve; tie(pv, ve) = vertices(g); // unpack the pair returned by vertices for (; pv != pe; ++pv) { ... }
However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
You probably know this already, but this functionality is almost covered by the RangeEx proposal in the vault. However, since it's not part of Boost yet, how about anticipating the RangeEx route and adding a, possibly local, templated for_each(...) for a range pair. Just a thought since every alternative seems to have drawbacks. - Rob.

2008/10/27 David Abrahams <dave@boostpro.com>
... The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
Clearly that proof of concept works, but I would have instinctively assumed the arguments to operator%() must be const. Even tho' that's obviously not the case, there's still the question of whether they SHOULD be const. - Rob.

However, we can make it much nicer, e.g.:
for (vertex_iterator pv,ve = xxx(pv,vertices(g)); pv != ve; ++pv) { ... }
My only problem is how to spell xxx. The attached proof-of-concept uses operator%, but I don't feel particularly good about that choice either. Ideas?
Should the operation generalize? Would this also be a use case? T a, b, c = xxx(a, b, f()); // with f() -> tuple<T,T,T> If it is, I don't think that operator%() will give you the same results (could your write c = a % b % f()?). As for a name, I like "truss" as in "truss this result to these objects". Just a thought. Andrew Sutton andrew.n.sutton@gmail.com
participants (13)
-
Andrew Sutton
-
Benoit
-
David Abrahams
-
David Walthall
-
Delroy, Tony (IED)
-
Johan Torp
-
Jonas Persson
-
Mathias Gaunard
-
Michael G
-
Pete Bartlett
-
Peter Bartlett
-
Robert Jones
-
Thorsten Ottosen