Browse Source

Added TSet.

woollybah 6 years ago
parent
commit
c160cf62f9

+ 1 - 0
collections.mod/collections.bmx

@@ -18,3 +18,4 @@ Import "list.bmx"
 Import "queue.bmx"
 Import "queue.bmx"
 Import "stack.bmx"
 Import "stack.bmx"
 Import "linkedlist.bmx"
 Import "linkedlist.bmx"
+Import "set.bmx"

+ 34 - 0
collections.mod/doc/tset_add.bmx

@@ -0,0 +1,34 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local cities:TSet<String> = New TSet<String>
+
+AddCity(cities, "Shanghai")
+AddCity(cities, "Beijing")
+AddCity(cities, "Guangzhou")
+AddCity(cities, "Shenzhen")
+AddCity(cities, "Tianjin")
+AddCity(cities, "Wuhan")
+
+Print "~nCount : " + cities.Count()
+Print
+
+For Local city:String = EachIn cities
+	Print city
+Next
+
+Print
+' try to add duplicate
+AddCity(cities, "Shanghai")
+
+Print "~nCount : " + cities.Count()
+
+Function AddCity(cities:TSet<String>, city:String)
+	If cities.Add(city) Then
+		Print "Added " + city
+	Else
+		Print city + " already exists."
+	End If
+End Function

+ 43 - 0
collections.mod/doc/tset_intersection.bmx

@@ -0,0 +1,43 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local data1:Int[] = [3, 4, 5, 6, 8, 9]
+Local data2:Int[] = [1, 2, 3, 4]
+Local data3:Int[] = [10, 11]
+
+Local a:TSet<Int> = New TSet<Int>(data1)
+Local b:TSet<Int> = New TSet<Int>(data2)
+Local c:TSet<Int> = New TSet<Int>(data3)
+
+Print "Set A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nSet B"
+For Local num:Int = EachIn b
+	Print num
+Next
+
+Print "~nSet C"
+For Local num:Int = EachIn c
+	Print num
+Next
+
+Print "~nA.Union(B)"
+a.Union(b)
+
+Print "~nSet A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nA.Union(C)"
+a.Union(c)
+
+Print "~nSet A"
+For Local num:Int = EachIn a
+	Print num
+Next

+ 31 - 0
collections.mod/doc/tset_issubsetof.bmx

@@ -0,0 +1,31 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local data1:Int[] = [3, 4, 5, 6, 8, 9]
+Local data2:Int[] = [1, 2, 3, 4]
+Local data3:Int[] = [6, 8]
+
+Local a:TSet<Int> = New TSet<Int>(data1)
+Local b:TSet<Int> = New TSet<Int>(data2)
+Local c:TSet<Int> = New TSet<Int>(data3)
+
+Print "Set A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nSet B"
+For Local num:Int = EachIn b
+	Print num
+Next
+
+Print "~nSet C"
+For Local num:Int = EachIn c
+	Print num
+Next
+
+Print "~nB.IsSubsetOf(A) : " + b.IsSubsetOf(a)
+Print "C.IsSubsetOf(A) : " + c.IsSubsetOf(a)
+Print "C.IsSubsetOf(B) : " + c.IsSubsetOf(b)

+ 31 - 0
collections.mod/doc/tset_issupersetof.bmx

@@ -0,0 +1,31 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local data1:Int[] = [3, 4, 5, 6, 8, 9]
+Local data2:Int[] = [1, 2, 3, 4]
+Local data3:Int[] = [6, 8]
+
+Local a:TSet<Int> = New TSet<Int>(data1)
+Local b:TSet<Int> = New TSet<Int>(data2)
+Local c:TSet<Int> = New TSet<Int>(data3)
+
+Print "Set A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nSet B"
+For Local num:Int = EachIn b
+	Print num
+Next
+
+Print "~nSet C"
+For Local num:Int = EachIn c
+	Print num
+Next
+
+
+Print "~nA.IsSupersetOf(B) : " + a.IsSupersetOf(b)
+Print "A.IsSupersetOf(C) : " + a.IsSupersetOf(c)

+ 28 - 0
collections.mod/doc/tset_symmetricdifference.bmx

@@ -0,0 +1,28 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local data1:Int[] = [3, 4, 5, 6, 7, 8]
+Local data2:Int[] = [1, 2, 3, 4, 5]
+
+Local a:TSet<Int> = New TSet<Int>(data1)
+Local b:TSet<Int> = New TSet<Int>(data2)
+
+Print "Set A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nSet B"
+For Local num:Int = EachIn b
+	Print num
+Next
+
+Print "~nA.SymmetricDifference(B)"
+a.SymmetricDifference(b)
+
+Print "~nSet A"
+For Local num:Int = EachIn a
+	Print num
+Next

+ 43 - 0
collections.mod/doc/tset_union.bmx

@@ -0,0 +1,43 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local data1:Int[] = [3, 4, 5, 6, 8, 9]
+Local data2:Int[] = [1, 2, 3, 4]
+Local data3:Int[] = [10, 11]
+
+Local a:TSet<Int> = New TSet<Int>(data1)
+Local b:TSet<Int> = New TSet<Int>(data2)
+Local c:TSet<Int> = New TSet<Int>(data3)
+
+Print "Set A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nSet B"
+For Local num:Int = EachIn b
+	Print num
+Next
+
+Print "~nSet C"
+For Local num:Int = EachIn c
+	Print num
+Next
+
+Print "~nA.Union(B)"
+a.Union(b)
+
+Print "~nSet A"
+For Local num:Int = EachIn a
+	Print num
+Next
+
+Print "~nA.Union(C)"
+a.Union(c)
+
+Print "~nSet A"
+For Local num:Int = EachIn a
+	Print num
+Next

+ 64 - 0
collections.mod/doc/tset_viewbetween.bmx

@@ -0,0 +1,64 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+
+Local data:Int[] = [3, 4, 5, 6, 8, 9]
+
+Local numbers:TSet<Int> = New TSet<Int>(data)
+Print "numbers.Count : " + numbers.Count()
+
+For Local num:Int = EachIn numbers
+	Print num
+Next
+
+Print "~nSubset(5, 8)"
+Local subset:TSet<Int> = numbers.ViewBetween(5, 8)
+Print "Count : " + subset.Count()
+
+For Local num:Int = EachIn subset
+	Print num
+Next
+
+Print "~nsubset.Add(7)"
+subset.Add(7)
+
+Print "~nSubset(5, 8)"
+Print "Count : " + subset.Count()
+
+For Local num:Int = EachIn subset
+	Print num
+Next
+
+Print "~nnumbers.Count : " + numbers.Count()
+
+Print "~nSub-Subset(6, 7)"
+Local subsubSet:TSet<Int> = subset.ViewBetween(6, 7)
+Print "Count : " + subsubSet.Count()
+
+For Local num:Int = EachIn subsubSet
+	Print num
+Next
+
+Print "~nsubsubSet.Remove(6)"
+subsubSet.Remove(6)
+
+Print "numbers.Count : " + numbers.Count()
+
+For Local num:Int = EachIn numbers
+	Print num
+Next
+
+Print "~nSubset(5, 8)"
+Print "Count : " + subset.Count()
+
+For Local num:Int = EachIn subset
+	Print num
+Next
+
+Print "~nSub-Subset(6, 7)"
+Print "Count : " + subsubSet.Count()
+
+For Local num:Int = EachIn subsubSet
+	Print num
+Next

+ 22 - 2
collections.mod/map.bmx

@@ -92,7 +92,7 @@ Type TTreeMap<K, V> Implements IMap<K,V>
 		End If
 		End If
 	
 	
 		Local node:TMapNode<K,V>=root
 		Local node:TMapNode<K,V>=root
-		Local parent:TMapNode<K,V>'=nil
+		Local parent:TMapNode<K,V>
 		Local cmp:Int
 		Local cmp:Int
 		
 		
 		While node<>Null
 		While node<>Null
@@ -137,13 +137,28 @@ Type TTreeMap<K, V> Implements IMap<K,V>
 
 
 	Rem
 	Rem
 	bbdoc: Determines whether the #TTreeMap contains the specified key.
 	bbdoc: Determines whether the #TTreeMap contains the specified key.
+	returns: #True if the #TTreeMap contains an element with the specified key; otherwise, #False.
 	End Rem
 	End Rem
 	Method ContainsKey:Int(key:K)
 	Method ContainsKey:Int(key:K)
 		Return FindNode( key )<>Null
 		Return FindNode( key )<>Null
 	End Method
 	End Method
+	
+	Rem
+	bbdoc: Determines whether the #TTreeMap contains a specific value.
+	returns: #True if the #TTreeMap contains an element with the specified value; otherwise, #False.
+	End Rem
+	Method ContainsValue:Int(value:V)
+		For Local node:TMapNode<K,V> = EachIn Self
+			If value = node.value Then
+				Return True
+			End If
+		Next
+		Return False
+	End Method
 
 
 	Rem
 	Rem
 	bbdoc: Removes the value with the specified key from the #TTreeMap.
 	bbdoc: Removes the value with the specified key from the #TTreeMap.
+	returns: #True if the element is successfully found and removed; otherwise, #False. This method returns #False if key is not found in the #TTreeMap.
 	End Rem
 	End Rem
 	Method Remove:Int(key:K)
 	Method Remove:Int(key:K)
 		Local node:TMapNode<K,V> = FindNode(key)
 		Local node:TMapNode<K,V> = FindNode(key)
@@ -157,6 +172,9 @@ Type TTreeMap<K, V> Implements IMap<K,V>
 
 
 	Rem
 	Rem
 	bbdoc: Gets the value associated with the specified key.
 	bbdoc: Gets the value associated with the specified key.
+	returns: #True if the #TTreeMap contains an element with the specified key; otherwise, #False.
+	about: When this method returns, @value contains the value associated with the specified key, if the key is found;
+	otherwise, @value will remain unchanged.
 	End Rem
 	End Rem
 	Method TryGetValue:Int(key:K, value:V Var)
 	Method TryGetValue:Int(key:K, value:V Var)
 		Local node:TMapNode<K,V> = FindNode(key)
 		Local node:TMapNode<K,V> = FindNode(key)
@@ -169,6 +187,7 @@ Type TTreeMap<K, V> Implements IMap<K,V>
 
 
 	Rem
 	Rem
 	bbdoc: Gets the element with the specified key.
 	bbdoc: Gets the element with the specified key.
+	returns: The value if @key exists in the #TTreeMap; otherwise returns the default/#Null value for the value type.
 	End Rem
 	End Rem
 	Method Operator [] :V(key:K)
 	Method Operator [] :V(key:K)
 		Local node:TMapNode<K,V> = FindNode(key)
 		Local node:TMapNode<K,V> = FindNode(key)
@@ -176,7 +195,8 @@ Type TTreeMap<K, V> Implements IMap<K,V>
 		If node Then
 		If node Then
 			Return node.value
 			Return node.value
 		Else
 		Else
-			Return Null
+			Local value:V
+			Return value
 		End If
 		End If
 	End Method
 	End Method
 
 

+ 1060 - 0
collections.mod/set.bmx

@@ -0,0 +1,1060 @@
+SuperStrict
+
+Import "list.bmx"
+
+Interface ISet<T> Extends ICollection<T>
+
+	Method Add:Int(element:T)
+	Method Clear()
+	Method Contains:Int(element:T)
+
+End Interface
+
+Rem
+bbdoc: Represents a collection of elements that is maintained in sorted order. Duplicate elements are not allowed.
+End Rem
+Type TSet<T> Implements ISet<T>
+
+	Private
+	Field root:TSetNode<T>
+	Field size:Int
+	
+	Field version:Int
+	
+	Field comparator:IComparator<T>
+	Public
+
+	Rem
+	bbdoc: Creates a new #TSet instance using the default comparator.
+	End Rem
+	Method New()
+	End Method
+	
+	Rem
+	bbdoc: Creates a new #TSet instance using the specified comparator.
+	End Rem
+	Method New(comparator:IComparator<T>)
+		Self.comparator = comparator
+	End Method
+
+	Rem
+	bbdoc: Creates a new #TSet initialised by @array.
+	End Rem
+	Method New(array:T[], comparator:IComparator<T> = Null)
+		Self.comparator = comparator
+		
+		If array Then
+			For Local element:T = EachIn array
+				Add(element)
+			Next
+		End If
+	End Method
+
+	Rem
+	bbdoc: Creates a new #TSet initialised by @iterable.
+	End Rem
+	Method New(iterable:IIterable<T>, comparator:IComparator<T> = Null)
+		Self.comparator = comparator
+		
+		If iterable Then
+			For Local element:T = EachIn iterable
+				Add(element)
+			Next
+		End If
+	End Method
+
+	Rem
+	bbdoc: Returns an iterator that iterates through the #TSet.
+	End Rem
+	Method GetIterator:IIterator<T>()
+		Return New TSetIterator<T>(FirstNode())
+	End Method
+	
+	Rem
+	bbdoc: Removes all elements from the set.
+	End Rem
+	Method Clear()
+		root = Null
+		size = 0
+		version :+ 1
+	End Method
+
+	Rem
+	bbdoc: Gets the number of elements contained in the #TSet.
+	End Rem
+	Method Count:Int()
+		Return size
+	End Method
+
+	Method CopyTo(array:T[], index:Int = 0)
+	End Method
+	
+	Rem
+	bbdoc: Adds an element to the #TSet and returns a value that indicates if it was successfully added.
+	End Rem
+	Method Add:Int(element:T)
+		Local node:TSetNode<T>=root
+		Local parent:TSetNode<T>
+		Local cmp:Int
+		
+		While node<>Null
+			parent=node
+			
+			cmp = DoCompare(element, node.element)
+			
+			If cmp < 0 Then
+				node=node.leftNode
+			Else If cmp > 0 Then
+				node=node.rightNode
+			Else
+				Return False
+			End If
+		Wend
+		
+		node=New TSetNode<T>
+		node.element=element
+		node.colour=0
+		node.parent=parent
+
+		size :+ 1
+		version :+ 1
+
+		If parent=Null
+			root=node
+			Return True
+		EndIf
+		If cmp > 0 Then
+			parent.rightNode=node
+		Else
+			parent.leftNode=node
+		EndIf
+		
+		RepairAdd node		
+		
+		Return True
+	End Method
+
+	Rem
+	bbdoc: Removes any element in the current #TSet that is also in @other.
+	End Rem
+	Method Complement(other:IIterable<T>)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+
+		If Not size Then
+			Return
+		End If
+		
+		If other = Self Then
+			Clear()
+			Return
+		End If
+		
+		Local set:TSet<T> = TSet<T>(other)
+		If set Then
+			If Not (DoCompare(set.LastNode().element, FirstNode().element) < 0 Or DoCompare(set.FirstNode().element, LastNode().element) > 0) Then
+				Local minimum:T = FirstNode().element
+				Local maximum:T = LastNode().element
+				For Local element:T = EachIn other
+					If DoCompare(element, minimum) < 0 Then
+						Continue
+					End If
+					
+					If DoCompare(element, maximum) > 0 Then
+						Exit
+					End If
+					
+					Remove(element)
+				Next
+			End If
+		Else
+			Local minimum:T = FirstNode().element
+			Local maximum:T = LastNode().element
+			For Local element:T = EachIn other
+				If Not (DoCompare(element, minimum) < 0 Or DoCompare(element, maximum) > 0) And Contains(element) Then
+					Remove(element)
+				End If
+			Next
+		End If
+	End Method
+
+	Rem
+	bbdoc: Determines whether the #TSet contains the specified key.
+	returns: #True if the #TSet contains an element with the specified key; otherwise, #False.
+	End Rem
+	Method Contains:Int(element:T)
+		Return FindNode( element )<>Null
+	End Method
+	
+	Rem
+	bbdoc: Returns a view of a subset in the #TSet.
+	returns: A subset view that contains only the values in the specified range.
+	about: This method returns a view of the range of elements that fall between #lowerValue and #upperValue.
+	This method does not copy elements from the #TSet, but provides a window into the underlying #TSet itself.
+	You can make changes in both the view and in the underlying #TSet.
+	End Rem
+	Method ViewBetween:TSet<T>(lowerValue:T, upperValue:T)
+		If DoCompare(lowerValue, upperValue) > 0 Then
+			Throw New TArgumentException("lowerValue is greater than upperValue")
+		End If
+		
+		Return New TSubSet<T>(Self, lowerValue, upperValue)
+	End Method
+
+	Rem
+	bbdoc: Modifies the current #TSet so that it contains only elements that are also in a specified #IIterable.
+	End Rem
+	Method Intersection(other:IIterable<T>)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+
+		If Not size Then
+			Return
+		End If
+		
+		If TSubSet<T>(Self) Then
+			Sync()
+		End If
+		
+		Local tmp:TArrayList<T> = New TArrayList<T>(size)
+		For Local element:T = EachIn other
+			If Contains(element) Then
+				tmp.Add(element)
+				Remove(element)
+			End If
+		Next
+		Clear()
+
+		For Local element:T = EachIn tmp
+			If Not Contains(element) Then
+				Add(element)
+			End If
+		Next
+	End Method
+	
+	Rem
+	bbdoc: Determines whether the #TSet object is a proper subset of the specified #IIterable.
+	returns: #True if the #TSet is a proper subset of @other; otherwise, #False.
+	about: An empty set is a proper subset of any other collection. Therefore, this method returns #True if the collection represented
+	by the current #TSet is empty unless @other is also an empty set.
+
+	This method always returns #False if #Count is greater than or equal to the number of elements in @other.
+	End Rem
+	Method IsProperSubsetOf:Int(other:IIterable<T>)
+		Return DoIsSubsetOf(other, True)
+	End Method
+	
+	Rem
+	bbdoc: Determines whether the #TSet is a proper superset of the specified #IIterable.
+	returns: #True if the #TSet is a proper superset of @other; otherwise, #False.
+	about: An empty set is a proper superset of any other collection. Therefore, this method returns #True if the
+	collection represented by @other is empty unless the current #TSet is also empty.
+
+	This method always returns #False if #Count is less than or equal to the number of elements in @other.
+	End Rem
+	Method IsProperSupersetOf:Int(other:IIterable<T>)
+		Return DoIsSupersetOf(other, True)
+	End Method
+	
+	Rem
+	bbdoc: Determines whether the #TSet is a subset of the specified #IIterable.
+	returns: #True if the current #TSet is a subset of @other; otherwise, #False.
+	about: An empty set is a subset of any other collection, including an empty set; therefore, this method returns
+	#True if the collection represented by the current #TSet is empty, even if the @other parameter is an empty set.
+
+	This method always returns #False if #Count is greater than the number of elements in @other.
+	End Rem
+	Method IsSubsetOf:Int(other:IIterable<T>)
+		Return DoIsSubsetOf(other, False)
+	End Method
+	
+	Rem
+	bbdoc: Determines whether the #TSet is a superset of the specified #IIterable.
+	returns: #True if the #TSet is a superset of @other; otherwise, #False.
+	about: All collections, including the empty set, are supersets of the empty set. Therefore, this method returns #True if
+	the collection represented by @other is empty, even if the current #TSet is empty.
+
+	This method always returns #False if #Count is less than the number of elements in @other.
+	End Rem
+	Method IsSupersetOf:Int(other:IIterable<T>)
+		Return DoIsSupersetOf(other, False)
+	End Method
+	
+	Rem
+	bbdoc: Determines whether the current #TSet and a specified #IIterable share common elements.
+	returns: #True if the #TSet and @other share at least one common element; otherwise, #False.
+	End Rem
+	Method Overlaps:Int(other:IIterable<T>)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+		
+		If Not size Then
+			Return False
+		End If
+		
+		For Local element:T = EachIn other
+			If Contains(element) Then
+				Return True
+			End If
+		Next
+		
+		Return False
+	End Method
+
+	Rem
+	bbdoc: Removes a specified element from the #TSet.
+	returns: #True if the element is successfully found and removed; otherwise, #False. This method returns #False if the element is not found in the #TSet.
+	End Rem
+	Method Remove:Int(element:T)
+		Local node:TSetNode<T> = FindNode(element)
+		If node=Null Then
+			Return False
+		End If
+		RemoveNode node
+		size :- 1
+		version :+ 1
+		Return True
+	End Method
+
+	Rem
+	bbdoc: Modifies the current #TSet so that it contains only elements that are present either in the current set or in the specified #IIterable, but not both.
+	End Rem
+	Method SymmetricDifference(other:IIterable<T>)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+
+		If Not size Then
+			Union(other)
+			Return
+		End If
+		
+		If other = Self Then
+			Clear()
+			Return
+		End If
+		
+		Local set:TSet<T> = TSet<T>(other)
+		
+		If Not set Then
+			set = New TSet<T>(other, comparator)
+		End If
+		
+		For Local element:T = EachIn set
+			If Contains(element) Then
+				Remove(element)
+			Else
+				Add(element)
+			End If
+		Next
+	End Method
+
+	Rem
+	bbdoc: Searches the set for a given value and returns the equal value it finds, if any.
+	End Rem
+	Method TryGetValue:Int(value:T, actualValue:T Var)
+		Local node:TSetNode<T> = FindNode(value)
+		If node <> Null Then
+			actualValue = node.element
+			Return True
+		End If
+		Return False
+	End Method
+	
+	Rem
+	bbdoc: Modifies the current #TSet so that it contains all elements that are present in either the current #TSet or the specified #IIterable.
+	End Rem
+	Method Union(other:IIterable<T>)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+		
+		Local set:TSet<T> = TSet<T>(other)
+
+		If TSubSet<T>(Self) Then
+			Sync()
+		End If
+		
+		If set And Not TSubSet<T>(Self) And Not size Then
+			Local tmp:TSet<T> = New TSet<T>(other, comparator)
+			root = tmp.root
+			size = tmp.size
+			version :+ 1
+			Return
+		End If
+				
+		For Local element:T = EachIn other
+			If Not Contains(element) Then
+				Add(element)
+			End If
+		Next
+	End Method
+
+Private
+	Method RotateLeft( node:TSetNode<T> )
+		Local child:TSetNode<T>=node.rightNode
+		node.rightNode=child.leftNode
+		If child.leftNode<>Null
+			child.leftNode.parent=node
+		EndIf
+		child.parent=node.parent
+		If node.parent<>Null
+			If node=node.parent.leftNode
+				node.parent.leftNode=child
+			Else
+				node.parent.rightNode=child
+			EndIf
+		Else
+			root=child
+		EndIf
+		child.leftNode=node
+		node.parent=child
+	End Method
+	
+	Method RotateRight( node:TSetNode<T> )
+		Local child:TSetNode<T>=node.leftNode
+		node.leftNode=child.rightNode
+		If child.rightNode<>Null
+			child.rightNode.parent=node
+		EndIf
+		child.parent=node.parent
+		If node.parent<>Null
+			If node=node.parent.rightNode
+				node.parent.rightNode=child
+			Else
+				node.parent.leftNode=child
+			EndIf
+		Else
+			root=child
+		EndIf
+		child.rightNode=node
+		node.parent=child
+	End Method
+	
+	Method RepairAdd( node:TSetNode<T> )
+		While node.parent And node.parent.colour=0 And node.parent.parent<>Null
+			If node.parent = node.parent.parent.leftNode Then
+				Local uncle:TSetNode<T>=node.parent.parent.rightNode
+				If uncle And uncle.colour = 0 Then
+					node.parent.colour = 1
+					uncle.colour = 1
+					uncle.parent.colour = 0
+					node = uncle.parent
+				Else
+					If node = node.parent.rightNode Then
+						node = node.parent
+						RotateLeft node
+					EndIf
+					node.parent.colour=1
+					node.parent.parent.colour=0
+					RotateRight node.parent.parent
+				EndIf
+			Else
+				Local uncle:TSetNode<T>=node.parent.parent.leftNode
+				If uncle And uncle.colour=0
+					node.parent.colour=1
+					uncle.colour=1
+					uncle.parent.colour=0
+					node=uncle.parent
+				Else
+					If node = node.parent.leftNode Then
+						node=node.parent
+						RotateRight node
+					EndIf
+					node.parent.colour=1
+					node.parent.parent.colour=0
+					RotateLeft node.parent.parent
+				EndIf
+			EndIf
+		Wend
+		root.colour=1
+	End Method
+
+	Method FindNode:TSetNode<T>( element:T )
+		Local node:TSetNode<T>=root
+		While node<>Null
+			Local cmp:Int = DoCompare(element, node.element)
+
+			If cmp > 0 Then
+				node=node.rightNode
+			Else If cmp < 0 Then
+				node=node.leftNode
+			Else
+				Return node
+			EndIf
+		Wend
+		Return node
+	End Method
+
+	Method FirstNode:TSetNode<T>()
+		Local node:TSetNode<T> = root
+		While node.leftNode <> Null
+			node = node.leftNode
+		Wend
+		Return node
+	End Method
+
+	Method LastNode:TSetNode<T>()
+		Local node:TSetNode<T> = root
+		While node.rightNode <> Null
+			node = node.rightNode
+		Wend
+		Return node
+	End Method
+
+	Method RemoveNode( node:TSetNode<T> )
+		Local splice:TSetNode<T>
+		Local child:TSetNode<T>
+		
+		If node.leftNode = Null Then
+			splice = node
+			child = node.rightNode
+		Else If node.rightNode = Null Then
+			splice = node
+			child = node.leftNode
+		Else
+			splice = node.leftNode
+			While splice.rightNode <> Null
+				splice = splice.rightNode
+			Wend
+			child = splice.leftNode
+			node.element = splice.element
+		EndIf
+		
+		Local parent:TSetNode<T> = splice.parent
+		If child <> Null Then
+			child.parent = parent
+		EndIf
+		If parent = Null Then
+			root = child
+			Return
+		EndIf
+		If splice = parent.leftNode Then
+			parent.leftNode = child
+		Else
+			parent.rightNode = child
+		EndIf
+		
+		If splice.colour=1 Then
+			RepairRemove child, parent
+		End If
+	End Method
+
+	Method RepairRemove(node:TSetNode<T>, parent:TSetNode<T> )
+	
+		While node And node <> root And node.colour=1
+			If node=parent.leftNode
+			
+				Local sib:TSetNode<T> = parent.rightNode
+
+				If sib.colour=0
+					sib.colour=1
+					parent.colour=0
+					RotateLeft parent
+					sib=parent.rightNode
+				EndIf
+				
+				If sib.leftNode.colour=1 And sib.rightNode.colour=1
+					sib.colour=0
+					node=parent
+					parent=parent.parent
+				Else
+					If sib.rightNode.colour=1
+						sib.leftNode.colour=1
+						sib.colour=0
+						RotateRight sib
+						sib=parent.rightNode
+					EndIf
+					sib.colour=parent.colour
+					parent.colour=1
+					sib.rightNode.colour=1
+					RotateLeft parent
+					node=root
+				EndIf
+			Else	
+				Local sib:TSetNode<T> = parent.leftNode
+				
+				If sib.colour=0
+					sib.colour=1
+					parent.colour=0
+					RotateRight parent
+					sib=parent.leftNode
+				EndIf
+				
+				If sib.rightNode.colour=1 And sib.leftNode.colour=1
+					sib.colour=0
+					node=parent
+					parent=parent.parent
+				Else
+					If sib.leftNode.colour=1
+						sib.rightNode.colour=1
+						sib.colour=0
+						RotateLeft sib
+						sib=parent.leftNode
+					EndIf
+					sib.colour=parent.colour
+					parent.colour=1
+					sib.leftNode.colour=1
+					RotateRight parent
+					node=root
+				EndIf
+			EndIf
+		Wend
+		If node Then
+			node.colour=1
+		End If
+	End Method
+
+	Method FindRange:TSetNode<T>(elementFrom:T, elementTo:T)
+		Local currentNode:TSetNode<T> = root
+		While currentNode
+			Local cmp:Int = DoCompare(elementFrom, currentNode.element)
+			
+			If cmp > 0 Then
+				currentNode = currentNode.NextNode()
+			Else
+				cmp = DoCompare(elementTo, currentNode.element)
+				
+				If cmp < 0 Then
+					currentNode = currentNode.PreviousNode()
+				Else
+					Return currentNode
+				End If
+			End If
+		Wend
+		
+		Return Null
+	End Method
+	
+	Method CountUniqueAndMissingElements:SElementCount(other:IIterable<T>, exitIfMissing:Int)
+		
+		Local elementCount:SElementCount
+		
+		If Not size Then
+			Local hasElements:Int
+			For Local element:T = EachIn other
+				hasElements = True
+				Exit
+			Next
+			elementCount.missingCount = hasElements
+			Return elementCount
+		End If
+		
+		Local bitTest:TBitTest =  New TBitTest(size)
+		Local missingCount:Int
+		Local foundCount:Int
+		
+		For Local element:T = EachIn other
+			Local index:Int = IndexOf(element)
+			If index >= 0 Then
+				If Not bitTest.IsMarked(index) Then
+					bitTest.Mark(index)
+					foundCount :+ 1
+				End If
+			Else
+				missingCount :+ 1
+				If exitIfMissing Then
+					Exit
+				End If
+			End If
+		Next
+		
+		elementCount.uniqueCount = foundCount
+		elementCount.missingCount = missingCount
+		
+		Return elementCount
+	End Method
+	
+	Method IndexOf:Int(element:T)
+		Local currentNode:TSetNode<T> = root
+		Local count:Int
+		While currentNode
+			Local cmp:Int = DoCompare(element, currentNode.element)
+			
+			If Not cmp Then
+				Return count
+			Else If cmp < 0 Then
+				currentNode = currentNode.PreviousNode()
+				count = 2 * count + 1
+			Else
+				currentNode = currentNode.NextNode()
+				count = 2 * count + 2
+			End If
+		Wend
+		
+		Return -1
+	End Method
+
+	Method DoIsSubsetOf:Int(other:IIterable<T>, isProper:Int)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+
+		If isProper Then
+			If ICollection<T>(other) Then
+				If Not size Then
+					Return ICollection<T>(other).Count() > 0
+				End If
+			End If
+		Else If Not size Then
+			Return True
+		End If
+		
+		Local otherSet:TSet<T> = TSet<T>(other)
+		If otherSet Then
+			If size > otherSet.size Then
+				Return False
+			End If
+
+			Local prunedOther:TSet<T> = otherSet.ViewBetween(FirstNode().element, LastNode().element)
+			For Local element:T = EachIn Self
+				If Not prunedOther.Contains(element) Then
+					Return False
+				End If
+			Next
+			
+			Return True
+		Else
+			Local elementCount:SElementCount = CountUniqueAndMissingElements(other, False)
+			Return elementCount.uniqueCount = size And elementCount.missingCount >= 0
+		End If
+	End Method
+
+	Method DoIsSupersetOf:Int(other:IIterable<T>, proper:Int)
+		If Not other Then
+			Throw New TArgumentNullException("other")
+		End If
+
+		If proper Then
+			If Not size Then
+				Return False
+			End If
+		Else
+			If ICollection<T>(other) And Not ICollection<T>(other).Count() Then
+				Return True
+			End If
+		End If
+		
+		Local set:TSet<T> = TSet<T>(other)
+		If set Then
+			If size < set.size Then
+				Return False
+			End If
+			
+			Local pruned:TSet<T> = ViewBetween(set.FirstNode().element, set.LastNode().element)
+			For Local element:T = EachIn set
+				If Not pruned.Contains(element) Then
+					Return False
+				End If
+			Next
+			Return True
+		Else
+			For Local element:T = EachIn other
+				If Not Contains(element) Then
+					Return False
+				End If
+			Next
+			Return True
+		End If
+	End Method
+
+	Method DoCompare:Int(elem1:T, elem2:T)
+		If comparator Then
+			Return comparator.Compare(elem1, elem2)
+		Else
+			Return DefaultComparator_Compare(elem1, elem2)
+		End If
+	End Method
+	
+	Method Sync()
+	End Method
+Public
+
+	Method ToString:String()
+	End Method
+End Type
+
+Type TSetNode<T>
+Private
+	Field parent:TSetNode
+	Field leftNode:TSetNode
+	Field rightNode:TSetNode
+	Field colour:Int
+Public
+	Field element:T
+	
+	Method NextNode:TSetNode<T>()
+		Local node:TSetNode<T> = Self
+		If node.rightNode<>Null
+			node=rightNode
+			While node.leftNode <> Null
+				node=node.leftNode
+			Wend
+			Return node
+		EndIf
+		Local parent:TSetNode<T>=parent
+		While parent And node=parent.rightNode
+			node=parent
+			parent=parent.parent
+		Wend
+		Return parent
+	End Method
+
+	Method PreviousNode:TSetNode<T>()
+		Local node:TSetNode<T> = Self
+		If node.leftNode<>Null
+			node=node.leftNode
+			While node.rightNode <> Null
+				node = node.rightNode
+			Wend
+			Return node
+		EndIf
+		Local parent:TSetNode<T> = node.parent
+		While node = parent.leftNode
+			node = parent
+			parent = node.parent
+		Wend
+		Return parent
+	End Method
+
+End Type
+
+Type TSetIterator<T> Implements IIterator<T> 
+	Private
+	Field initial:TSetNode<T>
+	
+	Method New(initial:TSetNode<T>)
+		Self.initial = initial
+	End Method
+	
+	Field node:TSetNode<T>
+
+	Public
+
+	Method Current:T()
+		Return node.element
+	End Method
+	
+	Method MoveNext:Int()
+		If initial Then
+			node = initial
+			initial = Null
+			Return True
+		End If
+		
+		If node Then
+			node = node.NextNode()
+			Return node <> Null
+		End If
+		
+		Return False
+	End Method
+
+End Type
+
+Type TSubSet<T> Extends TSet<T>
+Private
+	Field base:TSet<T>
+	Field minimum:T
+	Field maximum:T
+
+	Method New(base:TSet<T>, minimum:T, maximum:T)
+		New(base.comparator)
+		Self.base = base
+		Self.minimum = minimum
+		Self.maximum = maximum
+		root = base.FindRange(minimum, maximum)
+		version = -1
+		size = 0
+		Sync()
+	End Method
+
+	Method FindNode:TSetNode<T>( element:T )
+		If Not IsWithinRange(element) Then
+			Return Null
+		End If
+		
+		Sync()
+		
+		Return Super.FindNode(element)
+	End Method
+
+	Method FirstNode:TSetNode<T>()
+		Sync()
+		Return root
+	End Method
+
+	Method IsWithinRange:Int(element:T)
+		Local cmp:Int = DoCompare(minimum, element)
+		
+		If cmp > 0 Then
+			Return False
+		End If
+		
+		cmp = DoCompare(maximum, element)
+		
+		If cmp < 0 Then
+			Return False
+		End If
+		
+		Return True
+	End Method
+	
+	Method Sync()
+		If version <> base.version Then
+
+			root = base.FindRange(minimum, maximum)
+			version = base.version
+			size = 0
+			
+			For Local element:T = EachIn Self
+				size :+ 1
+			Next
+		End If
+	End Method
+	
+Public
+	Method Add:Int(element:T)
+		If Not IsWithinRange(element) Then
+			Throw New TArgumentOutOfRangeException
+		End If
+	
+		Local result:Int = base.Add(element)
+		
+		Sync()
+		
+		Return result
+	End Method
+
+	Method Count:Int()
+		Sync()
+		Return Super.Count()
+	End Method
+
+	Method GetIterator:IIterator<T>()
+		Return New TSubSetIterator<T>(FirstNode(), Self)
+	End Method
+	
+	Method ViewBetween:TSet<T>(lowerValue:T, upperValue:T)
+		Local cmp:Int = DoCompare(minimum, lowerValue)
+		
+		If cmp > 0 Then
+			Throw New TArgumentOutOfRangeException
+		End If
+
+		cmp = DoCompare(maximum, upperValue)
+
+		If cmp < 0 Then
+			Throw New TArgumentOutOfRangeException
+		End If
+
+		Return base.ViewBetween(lowerValue, upperValue)
+	End Method
+
+	Method Contains:Int(element:T)
+		Sync()
+		
+		Return  Super.Contains(element)
+	End Method
+	
+	Method Clear()
+		If Not size Then
+			Return
+		End If
+		
+		Local list:TArrayList<T> = New TArrayList<T>
+		For Local element:T = EachIn Self
+			list.Add(element)
+		Next
+		
+		While list.Count()
+			base.Remove(list[list.Count() - 1])
+			list.RemoveAt(list.Count() - 1)
+		Wend
+		
+		root = Null
+		size = 0
+		version = base.version
+	End Method
+	
+	Method Remove:Int(element:T)
+		If Not IsWithinRange(element) Then
+			Return False
+		End If
+		
+		Local result:Int = base.Remove(element)
+		Sync()
+		
+		Return result
+	End Method
+
+End Type
+
+Type TSubSetIterator<T> Extends TSetIterator<T> 
+	Private
+	Field subset:TSubSet<T>
+	
+	Method New(initial:TSetNode<T>, subset:TSubSet<T>)
+		Self.initial = initial
+		Self.subset = subset
+	End Method
+	
+	Public
+	
+	Method MoveNext:Int()
+		If initial Then
+			node = initial
+			initial = Null
+			Return True
+		End If
+		
+		If node Then
+			node = node.NextNode()
+			If node And subset.IsWithinRange(node.element) Then
+				Return True
+			End If
+		End If
+		
+		Return False
+	End Method
+
+End Type
+
+Struct SElementCount
+	Field uniqueCount:Int
+	Field missingCount:Int
+End Struct
+
+Type TBitTest
+
+	Field bits:Int[]
+	Field count:Int
+
+	Method New(count:Int)
+		Self.count = count
+		Local size:Int
+		If count Then
+			size = (count - 1) / 33
+		End If
+		bits = New Int[size]
+	End Method
+
+	Method Mark(bit:Int)
+		Local index:Int = bit / 32
+		If index < bits.length And index >= 0 Then
+			bits[index] :| (1 Shl (bit Mod 32))
+		End If
+	End Method
+	
+	Method IsMarked:Int(bit:Int)
+		Local index:Int = bit / 32
+		If index < bits.length And index >= 0 Then
+			Return bits[index] & (1 Shl (bit Mod 32))
+		End If
+		Return False
+	End Method
+	
+End Type