2
0
Эх сурвалжийг харах

Added Backwards() method to List, Stack.

Mark Sibly 9 жил өмнө
parent
commit
c97fc0562f

+ 96 - 9
modules/std/collections/list.monkey2

@@ -127,7 +127,7 @@ Class List<T> Implements IContainer<T>
 		End
 		
 		Method AssertCurrent()
-			DebugAssert( Valid,"Invalid list iterator" )
+			DebugAssert( Not AtEnd,"Invalid list iterator" )
 		End
 		
 		Public
@@ -147,12 +147,6 @@ Class List<T> Implements IContainer<T>
 			Return _node=_list._head
 		End
 		
-		#rem monkeydoc @hidden
-		#end
-		Property Valid:Bool()
-			Return Not AtEnd
-		End
-		
 		#rem monkeydoc The value contained in the node pointed to by the iterator.
 		#end
 		Property Current:T()
@@ -180,7 +174,7 @@ Class List<T> Implements IContainer<T>
 		
 		#end
 		Method Erase()
-			AssertSeq()
+			AssertCurrent()
 			_node=_node._succ
 			_node._pred.Remove()
 			_list._seq+=1
@@ -200,6 +194,88 @@ Class List<T> Implements IContainer<T>
 		End
 	End
 	
+	#rem monkeydoc The List.BackwardsIterator struct.
+	#end
+	Struct BackwardsIterator
+	
+		Private
+	
+		Field _list:List
+		Field _node:Node
+		Field _seq:Int
+		
+		Method AssertSeq()
+			DebugAssert( _seq=_list._seq,"Concurrent list modification" )
+		End
+		
+		Method AssertCurrent()
+			DebugAssert( Not AtEnd,"Invalid list iterator" )
+		End
+		
+		Public
+		
+		#rem monkeydoc Creates a new iterator.
+		#end
+		Method New( list:List,node:Node )
+			_list=list
+			_node=node
+			_seq=list._seq
+		End
+
+		#rem monkeydoc Checks whether the iterator has reached the end of the list.
+		#end
+		Property AtEnd:Bool()
+			AssertSeq()
+			Return _node=_list._head
+		End
+		
+		#rem monkeydoc The value contained in the node pointed to by the iterator.
+		#end
+		Property Current:T()
+			AssertCurrent()
+			Return _node._value
+			
+		Setter( current:T )
+			AssertCurrent()
+			_node._value=current
+		End
+		
+		#rem monkeydoc Bumps the iterator so it points to the next node in the list.
+		#end
+		Method Bump()
+			AssertCurrent()
+			_node=_node._pred
+		End
+		
+		#rem monkeydoc Safely erases the node referenced by the iterator.
+		
+		After calling this method, the iterator will point to the node after the removed node.
+		
+		Therefore, if you are manually iterating through a list you should not call [[Bump]] after calling this method or you
+		will end up skipping a node.
+		
+		#end
+		Method Erase()
+			AssertCurrent()
+			_node=_node._pred
+			_node._succ.Remove()
+			_list._seq+=1
+			_seq=_list._seq
+		End
+		
+		#rem monkeydoc Safely insert a value before the iterator.
+
+		After calling this method, the iterator will point to the newly added node.
+		
+		#end
+		Method Insert( value:T )
+			AssertSeq()
+			_node=New Node( value,_node._succ )
+			_list._seq+=1
+			_seq=_list._seq
+		End
+	End
+	
 	Private
 	
 '	Field _head:=New Node	'FIXME, causes internal compiler error...
@@ -240,7 +316,7 @@ Class List<T> Implements IContainer<T>
 		AddAll( values )
 	End
 	
-	#rem monkeydoc Gets an iterator for all nodes in the list.
+	#rem monkeydoc Gets an iterator for visiting list values.
 	
 	Returns an iterator suitable for use with [[Eachin]], or for manual iteration.
 	
@@ -250,6 +326,17 @@ Class List<T> Implements IContainer<T>
 	Method All:Iterator()
 		Return New Iterator( Self,_head._succ )
 	End
+
+	#rem monkeydoc Gets an iterator for visiting list values in reverse order.
+	
+	Returns an iterator suitable for use with [[Eachin]], or for manual iteration.
+	
+	@return A backwards list iterator.
+	
+	#end	
+	Method Backwards:BackwardsIterator()
+		Return New BackwardsIterator( Self,_head._pred )
+	End
 	
 	#rem monkeydoc Checks whether the list is empty.
 	

+ 94 - 13
modules/std/collections/stack.monkey2

@@ -11,7 +11,7 @@ Alias StringStack:Stack<String>
 #end
 Class Stack<T> Implements IContainer<T>
 
-	#rem monkeydoc The Stack.Iterator class
+	#rem monkeydoc The Stack.Iterator struct.
 	#end
 	Struct Iterator 'Implements IIterator<T>
 	
@@ -26,19 +26,17 @@ Class Stack<T> Implements IContainer<T>
 		End
 		
 		Method AssertCurrent()
-			DebugAssert( Valid,"Invalid list iterator" )
+			DebugAssert( Not AtEnd,"Invalid list iterator" )
 		End
 		
-		Public
-		
-		#rem monkeydoc Creates a new iterator.
-		#end
 		Method New( stack:Stack,index:Int )
 			_stack=stack
 			_index=index
 			_seq=stack._seq
 		End
 		
+		Public
+		
 		#rem monkeydoc Checks if the iterator has reached the end of the stack.
 		#end
 		Property AtEnd:Bool()
@@ -46,12 +44,6 @@ Class Stack<T> Implements IContainer<T>
 			Return _index=_stack._length
 		End
 		
-		#rem monkeydoc @hidden
-		#end
-		Property Valid:Bool()
-			Return Not AtEnd
-		End
-		
 		#rem monkeydoc The value currently pointed to by the iterator.
 		#end
 		Property Current:T()
@@ -95,6 +87,84 @@ Class Stack<T> Implements IContainer<T>
 		End
 	End
 	
+	#rem monkeydoc The Stack.BackwardsIterator struct.
+	#end
+	Struct BackwardsIterator 'Implements IIterator<T>
+	
+		Private
+
+		Field _stack:Stack
+		Field _index:Int
+		Field _seq:Int
+		
+		Method AssertSeq()
+			DebugAssert( _seq=_stack._seq,"Concurrent list modification" )
+		End
+		
+		Method AssertCurrent()
+			DebugAssert( Not AtEnd,"Invalid list iterator" )
+		End
+		
+		Method New( stack:Stack,index:Int )
+			_stack=stack
+			_index=index
+			_seq=stack._seq
+		End
+		
+		Public
+		
+		#rem monkeydoc Checks if the iterator has reached the end of the stack.
+		#end
+		Property AtEnd:Bool()
+			AssertSeq()
+			Return _index=-1
+		End
+		
+		#rem monkeydoc The value currently pointed to by the iterator.
+		#end
+		Property Current:T()
+			AssertCurrent()
+			Return _stack._data[_index]
+		Setter( current:T )
+			AssertCurrent()
+			_stack._data[_index]=current
+		End
+		
+		#rem monkeydoc Bumps the iterator so it points to the next value in the stack.
+		#end
+		Method Bump()
+			AssertCurrent()
+			_index-=1
+		End
+		
+		#rem monkeydoc Safely erases the value pointed to by the iterator.
+		
+		After calling this method, the iterator will point to the value after the removed value.
+		
+		Therefore, if you are manually iterating through a stack you should not call [[Bump]] after calling this method or you
+		will end up skipping a value.
+		
+		#end
+		Method Erase()
+			AssertCurrent()
+			_index-=1
+			_stack.Erase( _index+1 )
+			_seq=_stack._seq
+		End
+		
+		#rem monkeydoc Safely inserts a value before the value pointed to by the iterator.
+
+		After calling this method, the iterator will point to the newly added value.
+		
+		#end
+		Method Insert( value:T )
+			AssertSeq()
+			_index+=1
+			_stack.Insert( _index,value )
+			_seq=_stack._seq
+		End
+	End
+	
 	Private
 
 	Field _data:T[]
@@ -152,7 +222,7 @@ Class Stack<T> Implements IContainer<T>
 		Return _length=0
 	End
 
-	#rem monkeydoc Gets an iterator to all values in the stack.
+	#rem monkeydoc Gets an iterator for visiting stack values.
 	
 	Returns an iterator suitable for use with [[Eachin]], or for manual iteration.
 	
@@ -162,6 +232,17 @@ Class Stack<T> Implements IContainer<T>
 	Method All:Iterator()
 		Return New Iterator( Self,0 )
 	End
+	
+	#rem monkeydoc Gets an iterator for visiting stack values in reverse order.
+	
+	Returns an iterator suitable for use with [[Eachin]], or for manual iteration.
+
+	@return A backwards stack iterator.
+		
+	#end	
+	Method Backwards:BackwardsIterator()
+		Return New BackwardsIterator( Self,_length-1 )
+	End
 
 	#rem monkeydoc Converts the stack to an array.