MultiPassInputIterator concept

I have a question about the requirements of the MultiPassInputIterator concept as used in the Boost Graph Library. Does the ++first_iter == ++second_iter requirement hold across calls to out_edges(vertex, g)? Or put another way, does out_edges always have to return an iterator with same ordering of returned edges? The difference is between: graph_traits<graph>::out_edge_iterator i = out_edges(vertex, g); graph_traits<graph>::out_edge_iterator j = i; ++i == ++j; // clearly required, but sufficient? and graph_traits<graph>::out_edge_iterator i = out_edges(vertex, g); graph_traits<graph>::out_edge_iterator j = out_edges(vertex, g); ++i == ++j; // also required? Strangely enough, I have an application where the second case is (currently) not guaranteed (its a custom graph class where the out_edge_iterator is constructed on-the-fly). THK -- Timothy H. Keitt http://www.keittlab.org/

on Tue Nov 11 2008, "Tim Keitt"
I have a question about the requirements of the MultiPassInputIterator concept as used in the Boost Graph Library. Does the ++first_iter == ++second_iter requirement hold across calls to out_edges(vertex, g)? Or put another way, does out_edges always have to return an iterator with same ordering of returned edges?
The difference is between:
graph_traits<graph>::out_edge_iterator i = out_edges(vertex, g); graph_traits<graph>::out_edge_iterator j = i; ++i == ++j; // clearly required, but sufficient?
and
graph_traits<graph>::out_edge_iterator i = out_edges(vertex, g); graph_traits<graph>::out_edge_iterator j = out_edges(vertex, g); ++i == ++j; // also required?
Strangely enough, I have an application where the second case is (currently) not guaranteed (its a custom graph class where the out_edge_iterator is constructed on-the-fly).
I don't think any code is relying on the 2nd case, but it's hard to be sure. You could check for it by adding a generation counter in the iterator and assert if two iterators from different generations are compared. After all, they are effectively iterating different sequences. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams
I don't think any code is relying on the 2nd case, but it's hard to be sure. You could check for it by adding a generation counter in the iterator and assert if two iterators from different generations are compared. After all, they are effectively iterating different sequences.
I found a case where the second condition is required. Its in push_relabel_max_flow: while (1) { out_edge_iterator ai, ai_end; for (ai = current[u], ai_end = out_edges(u, g).second; ai != ai_end; ++ai) { edge_descriptor a = *ai; current is an vector of edge iterators. Notice the call to out_edges. This should be relatively easy to fix by storing the end iterators as well as the current iterator. THK
participants (3)
-
David Abrahams
-
Tim Keitt
-
Tim Keitt