<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://stlab.adobe.com/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;feed=atom&amp;action=history</id>
		<title>Edge Interface For Forest Iterators - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;feed=atom&amp;action=history"/>
		<link rel="alternate" type="text/html" href="http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;action=history"/>
		<updated>2013-05-25T16:23:30Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.19.0</generator>

	<entry>
		<id>http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;diff=1883&amp;oldid=prev</id>
		<title>SeanParent at 22:21, 13 March 2007</title>
		<link rel="alternate" type="text/html" href="http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;diff=1883&amp;oldid=prev"/>
				<updated>2007-03-13T22:21:44Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:21, 13 March 2007&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 8:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 8:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt;, a vertex descriptor (in the forest implementation this is the pointer to the node).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt;, a vertex descriptor (in the forest implementation this is the pointer to the node).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, an &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; index - this specifies how we are pointing at the node &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(this was the &amp;quot;leading bool&amp;quot; and is now the &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; and the topic of this document)&lt;/del&gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, an &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; index - this specifies how we are pointing at the node.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, a property (this is fixed to a single property of the &amp;lt;code&amp;gt;value_type&amp;lt;/code&amp;gt; of the iterator).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, a property (this is fixed to a single property of the &amp;lt;code&amp;gt;value_type&amp;lt;/code&amp;gt; of the iterator).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt;, a function to move from an &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; to a corresponding &amp;lt;code&amp;gt;out_edge&amp;lt;/code&amp;gt; (for a fullorder iterator on a forest this is the identity function).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* &amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt;, a function to move from an &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; to a corresponding &amp;lt;code&amp;gt;out_edge&amp;lt;/code&amp;gt; (for a fullorder iterator on a forest this is the identity function).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 33:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 33:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;==Child iterators==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;==Child iterators==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;I think the &lt;/del&gt;same description holds for &amp;lt;code&amp;gt;child_iterator&amp;lt;/code&amp;gt; except &amp;lt;code&amp;gt;f()&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;trailing_of(*v)&amp;lt;/code&amp;gt; and it no longer depends on which &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; you arrive on.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;The &lt;/ins&gt;same description holds for &amp;lt;code&amp;gt;child_iterator&amp;lt;/code&amp;gt; except &amp;lt;code&amp;gt;f()&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;trailing_of(*v)&amp;lt;/code&amp;gt; and it no longer depends on which &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; you arrive on.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;==The reverse iterator problem with edge()==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;==The reverse iterator problem with edge()==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The standard notion of a reverse iterator transforms a range &amp;lt;code&amp;gt;[first, last)&amp;lt;/code&amp;gt; to the range &amp;lt;code&amp;gt;(first, last]&amp;lt;/code&amp;gt; without introducing any extra &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;position &lt;/del&gt;by having the base iterator point one after the element. Reverse iterators for a strict sequence work fine with a forest, but a reverse iterator which supports &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; is trickier.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The standard notion of a reverse iterator transforms a range &amp;lt;code&amp;gt;[first, last)&amp;lt;/code&amp;gt; to the range &amp;lt;code&amp;gt;(first, last]&amp;lt;/code&amp;gt; without introducing any extra &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;positions &lt;/ins&gt;by having the base iterator point one after the element. Reverse iterators for a strict sequence work fine with a forest, but a reverse iterator which supports &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; is trickier.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The next (or prior) edge is dependent on where you came from and it is a function of a vertex. So to read the edge when &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;your &lt;/del&gt;iterator is after the current mark you need to &amp;lt;code&amp;gt;decrement&amp;lt;/code&amp;gt; - but this means you are reading a vertex which is _before_ your offset range - this is because the edge is defined even on an end iterator (the vertex exists even if the property doesn't).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The next (or prior) edge is dependent on where you came from and it is a function of a vertex. So to read the edge when &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;the &lt;/ins&gt;iterator is after the current mark you need to &amp;lt;code&amp;gt;decrement&amp;lt;/code&amp;gt; - but this means you are reading a vertex which is _before_ your offset range - this is because the edge is defined even on an end iterator (the vertex exists even if the property doesn't).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Right away then we violate &lt;/del&gt;our range just to read an &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; - to set an edge you defer the actual assignment of the edge until you reach the node - then set the edge to determine where to go next - so incrementing a reverse iterator looks like:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;This violates &lt;/ins&gt;our range just to read an &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; - to set an edge you defer the actual assignment of the edge until you reach the node - then set the edge to determine where to go next - so incrementing a reverse iterator looks like:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* Decrement the base iterator&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;* Decrement the base iterator&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 58:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 58:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This all works on a forest, despite the range violations, because a forest is implemented as a loop structure and the prior vertex of any node is guaranteed to exist (that is, we have a &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt; as well as an &amp;lt;code&amp;gt;end()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--begin()&amp;lt;/code&amp;gt; will yield &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt;).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This all works on a forest, despite the range violations, because a forest is implemented as a loop structure and the prior vertex of any node is guaranteed to exist (that is, we have a &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt; as well as an &amp;lt;code&amp;gt;end()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--begin()&amp;lt;/code&amp;gt; will yield &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt;).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;A simpler form of a reverse iterator &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;could simply rely &lt;/del&gt;on the fact that the forest ranges are symmetrical. In that case &amp;lt;code&amp;gt;rend()&amp;lt;/code&amp;gt; could return &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt; and we would scrap the whole off by one. This does not change the requirements of our reverse iterator at all, but for anyone familiar with STL reverse iterators it does change the behavior of &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;A simpler form of a reverse iterator &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;relies &lt;/ins&gt;on the fact that the forest ranges are symmetrical. In that case &amp;lt;code&amp;gt;rend()&amp;lt;/code&amp;gt; could return &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt; and we would scrap the whole off by one. This does not change the requirements of our reverse iterator at all, but for anyone familiar with STL reverse iterators it does change the behavior of &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;===Final Resolution===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;===Final Resolution===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The simpler form mentioned above was implemented and I've decided the simplifications are well worth it. The off-by-one issue of &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt; is resolved by simply having &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt; return &amp;lt;code&amp;gt;next(base_m)&amp;lt;/code&amp;gt;. The requirement imposed by the reverse iterator is actually the same requirement imposed by &amp;lt;code&amp;gt;set_next()&amp;lt;/code&amp;gt;. For any valid range &amp;lt;code&amp;gt;[first, last)&amp;lt;/code&amp;gt; there must exist a valid range &amp;lt;code&amp;gt;(prior&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(first)&lt;/del&gt;, last)&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The simpler form mentioned above was implemented and I've decided the simplifications are well worth it. The off-by-one issue of &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt; is resolved by simply having &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt; return &amp;lt;code&amp;gt;next(base_m)&amp;lt;/code&amp;gt;. The requirement imposed by the reverse iterator is actually the same requirement imposed by &amp;lt;code&amp;gt;set_next()&amp;lt;/code&amp;gt;. For any valid range &amp;lt;code&amp;gt;[first, last)&amp;lt;/code&amp;gt; there must exist a valid range &amp;lt;code&amp;gt;(prior, last)&amp;lt;/code&amp;gt; &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;such that next(prior) == first&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>SeanParent</name></author>	</entry>

	<entry>
		<id>http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;diff=1445&amp;oldid=prev</id>
		<title>FosterBrereton: initial population</title>
		<link rel="alternate" type="text/html" href="http://stlab.adobe.com/wiki/index.php?title=Edge_Interface_For_Forest_Iterators&amp;diff=1445&amp;oldid=prev"/>
				<updated>2006-06-21T22:47:18Z</updated>
		
		<summary type="html">&lt;p&gt;initial population&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Introduction==&lt;br /&gt;
&lt;br /&gt;
We can define the concept of the forest iterator in terms of a general graph using the terminology from Boost graph - this is useful because at some point we may wish to generalize these constructs to apply to other graph structures.&lt;br /&gt;
&lt;br /&gt;
A forest is (loosely) a [http://www.boost.org/libs/graph/doc/BidirectionalGraph.html Bidirectional Graph].&lt;br /&gt;
&lt;br /&gt;
A forest iterator consists of the following:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt;, a vertex descriptor (in the forest implementation this is the pointer to the node).&lt;br /&gt;
* &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt;, an &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; index - this specifies how we are pointing at the node (this was the &amp;quot;leading bool&amp;quot; and is now the &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; and the topic of this document).&lt;br /&gt;
* &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, a property (this is fixed to a single property of the &amp;lt;code&amp;gt;value_type&amp;lt;/code&amp;gt; of the iterator).&lt;br /&gt;
* &amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt;, a function to move from an &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; to a corresponding &amp;lt;code&amp;gt;out_edge&amp;lt;/code&amp;gt; (for a fullorder iterator on a forest this is the identity function).&lt;br /&gt;
&lt;br /&gt;
An edge is a directed link (with a &amp;lt;code&amp;gt;from()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;to()&amp;lt;/code&amp;gt; function) - and because it is bidirectional you can find the corresponding input link. &lt;br /&gt;
&lt;br /&gt;
The increment operation can be defined as follows in pseudo code (once I'm more fluent in Boost Graph this could be described more concretely):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
current_edge = out_edge(*v, e);&lt;br /&gt;
v = to(curent_edge);&lt;br /&gt;
e = f(find_in_edge(*v, current_edge));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this way we can think of a forest iterator as being a traversal defined over a Bidirectional Graph. The &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; interface on the iterator allows you to manipulate what &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; is being used to reach the vertex, and correspondingly what &amp;lt;code&amp;gt;out_edge&amp;lt;/code&amp;gt; will be followed next. The type of the result is the index for the edge sequence. In the case of forest this is an array, so &amp;lt;code&amp;gt;std::size_t&amp;lt;/code&amp;gt; is the correct type, even though it will only be a value of 0 or 1.&lt;br /&gt;
&lt;br /&gt;
The signature for &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
std::size_t edge() const; // read access to the edge&lt;br /&gt;
std::size_t&amp;amp; edge(); // write access to the edge&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Child iterators==&lt;br /&gt;
&lt;br /&gt;
I think the same description holds for &amp;lt;code&amp;gt;child_iterator&amp;lt;/code&amp;gt; except &amp;lt;code&amp;gt;f()&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;trailing_of(*v)&amp;lt;/code&amp;gt; and it no longer depends on which &amp;lt;code&amp;gt;in_edge&amp;lt;/code&amp;gt; you arrive on.&lt;br /&gt;
&lt;br /&gt;
==The reverse iterator problem with edge()==&lt;br /&gt;
&lt;br /&gt;
The standard notion of a reverse iterator transforms a range &amp;lt;code&amp;gt;[first, last)&amp;lt;/code&amp;gt; to the range &amp;lt;code&amp;gt;(first, last]&amp;lt;/code&amp;gt; without introducing any extra position by having the base iterator point one after the element. Reverse iterators for a strict sequence work fine with a forest, but a reverse iterator which supports &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; is trickier.&lt;br /&gt;
&lt;br /&gt;
The next (or prior) edge is dependent on where you came from and it is a function of a vertex. So to read the edge when your iterator is after the current mark you need to &amp;lt;code&amp;gt;decrement&amp;lt;/code&amp;gt; - but this means you are reading a vertex which is _before_ your offset range - this is because the edge is defined even on an end iterator (the vertex exists even if the property doesn't).&lt;br /&gt;
&lt;br /&gt;
Right away then we violate our range just to read an &amp;lt;code&amp;gt;edge()&amp;lt;/code&amp;gt; - to set an edge you defer the actual assignment of the edge until you reach the node - then set the edge to determine where to go next - so incrementing a reverse iterator looks like:&lt;br /&gt;
&lt;br /&gt;
* Decrement the base iterator&lt;br /&gt;
* Set the edge to our next edge&lt;br /&gt;
* remember what the next edge should be&lt;br /&gt;
&lt;br /&gt;
We run into a big problem if we set the edge and then decrement the reverse iterator - setting the edge may have pivoted on the previous node and we should land on a node which isn't reachable in one step from the current base!&lt;br /&gt;
&lt;br /&gt;
The algorithm for decrementing the reverse iterator is&lt;br /&gt;
&lt;br /&gt;
* Decrement the base iterator&lt;br /&gt;
* Set the edge to our next edge&lt;br /&gt;
* increment the base iterator ''twice''&lt;br /&gt;
* remember what the next edge should be&lt;br /&gt;
&lt;br /&gt;
This all works on a forest, despite the range violations, because a forest is implemented as a loop structure and the prior vertex of any node is guaranteed to exist (that is, we have a &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt; as well as an &amp;lt;code&amp;gt;end()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--begin()&amp;lt;/code&amp;gt; will yield &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
A simpler form of a reverse iterator could simply rely on the fact that the forest ranges are symmetrical. In that case &amp;lt;code&amp;gt;rend()&amp;lt;/code&amp;gt; could return &amp;lt;code&amp;gt;root()&amp;lt;/code&amp;gt; and we would scrap the whole off by one. This does not change the requirements of our reverse iterator at all, but for anyone familiar with STL reverse iterators it does change the behavior of &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Final Resolution===&lt;br /&gt;
&lt;br /&gt;
The simpler form mentioned above was implemented and I've decided the simplifications are well worth it. The off-by-one issue of &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt; is resolved by simply having &amp;lt;code&amp;gt;base()&amp;lt;/code&amp;gt; return &amp;lt;code&amp;gt;next(base_m)&amp;lt;/code&amp;gt;. The requirement imposed by the reverse iterator is actually the same requirement imposed by &amp;lt;code&amp;gt;set_next()&amp;lt;/code&amp;gt;. For any valid range &amp;lt;code&amp;gt;[first, last)&amp;lt;/code&amp;gt; there must exist a valid range &amp;lt;code&amp;gt;(prior(first), last)&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>FosterBrereton</name></author>	</entry>

	</feed>