5 // Jb Evain <jbevain@novell.com>
7 // Copyright (C) 2010 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
31 using System
.Collections
.Generic
;
33 using System
.Runtime
.Serialization
;
34 using System
.Runtime
.InteropServices
;
35 using System
.Security
;
36 using System
.Security
.Permissions
;
37 using System
.Diagnostics
;
39 // SortedSet is basically implemented as a reduction of SortedDictionary<K, V>
43 namespace System
.Collections
.Generic
{
46 [DebuggerDisplay ("Count={Count}")]
47 [DebuggerTypeProxy (typeof (CollectionDebuggerView
))]
48 public class SortedSet
<T
> : ISet
<T
>, ICollection
, ISerializable
, IDeserializationCallback
50 class Node
: RBTree
.Node
{
59 public override void SwapValue (RBTree
.Node other
)
68 class NodeHelper
: RBTree
.INodeHelper
<T
> {
70 static NodeHelper Default
= new NodeHelper (Comparer
<T
>.Default
);
72 public IComparer
<T
> comparer
;
74 public int Compare (T item
, RBTree
.Node node
)
76 return comparer
.Compare (item
, ((Node
) node
).item
);
79 public RBTree
.Node
CreateNode (T item
)
81 return new Node (item
);
84 NodeHelper (IComparer
<T
> comparer
)
86 this.comparer
= comparer
;
89 public static NodeHelper
GetHelper (IComparer
<T
> comparer
)
91 if (comparer
== null || comparer
== Comparer
<T
>.Default
)
94 return new NodeHelper (comparer
);
100 SerializationInfo si
;
103 : this (Comparer
<T
>.Default
)
107 public SortedSet (IEnumerable
<T
> collection
)
108 : this (collection
, Comparer
<T
>.Default
)
112 public SortedSet (IEnumerable
<T
> collection
, IComparer
<T
> comparer
)
115 if (collection
== null)
116 throw new ArgumentNullException ("collection");
118 foreach (var item
in collection
)
122 public SortedSet (IComparer
<T
> comparer
)
124 this.helper
= NodeHelper
.GetHelper (comparer
);
125 this.tree
= new RBTree (this.helper
);
128 protected SortedSet (SerializationInfo info
, StreamingContext context
)
133 public IComparer
<T
> Comparer
{
134 get { return helper.comparer; }
138 get { return tree.Count; }
142 get { return GetMax (); }
146 get { return GetMin (); }
149 internal virtual T
GetMax ()
154 return GetItem (tree
.Count
- 1);
157 internal virtual T
GetMin ()
165 T
GetItem (int index
)
167 return ((Node
) tree
[index
]).item
;
170 public bool Add (T item
)
172 return TryAdd (item
);
175 internal virtual bool TryAdd (T item
)
177 var node
= new Node (item
);
178 return tree
.Intern (item
, node
) == node
;
181 public virtual void Clear ()
186 public virtual bool Contains (T item
)
188 return tree
.Lookup (item
) != null;
191 public void CopyTo (T
[] array
)
193 CopyTo (array
, 0, Count
);
196 public void CopyTo (T
[] array
, int index
)
198 CopyTo (array
, index
, Count
);
201 public void CopyTo (T
[] array
, int index
, int count
)
204 throw new ArgumentNullException ("array");
206 throw new ArgumentOutOfRangeException ("index");
207 if (index
> array
.Length
)
208 throw new ArgumentException ("index larger than largest valid index of array");
209 if (array
.Length
- index
< count
)
210 throw new ArgumentException ("destination array cannot hold the requested elements");
212 foreach (Node node
in tree
) {
216 array
[index
++] = node
.item
;
220 public bool Remove (T item
)
222 return TryRemove (item
);
225 internal virtual bool TryRemove (T item
)
227 return tree
.Remove (item
) != null;
230 public int RemoveWhere (Predicate
<T
> match
)
232 var array
= ToArray ();
235 foreach (var item
in array
) {
246 public IEnumerable
<T
> Reverse ()
248 for (int i
= tree
.Count
- 1; i
>= 0; i
--)
249 yield return GetItem (i
);
254 var array
= new T
[this.Count
];
259 public Enumerator
GetEnumerator ()
261 return new Enumerator (this);
264 IEnumerator
<T
> IEnumerable
<T
>.GetEnumerator ()
266 return new Enumerator (this);
269 IEnumerator IEnumerable
.GetEnumerator ()
271 return new Enumerator (this);
274 public static IEqualityComparer
<SortedSet
<T
>> CreateSetComparer ()
276 return CreateSetComparer (EqualityComparer
<T
>.Default
);
280 public static IEqualityComparer
<SortedSet
<T
>> CreateSetComparer (IEqualityComparer
<T
> memberEqualityComparer
)
282 throw new NotImplementedException ();
286 protected virtual void GetObjectData (SerializationInfo info
, StreamingContext context
)
288 throw new NotImplementedException ();
291 void ISerializable
.GetObjectData (SerializationInfo info
, StreamingContext context
)
293 GetObjectData (info
, context
);
297 protected virtual void OnDeserialization (object sender
)
302 throw new NotImplementedException ();
305 void IDeserializationCallback
.OnDeserialization (object sender
)
307 OnDeserialization (sender
);
311 public void ExceptWith (IEnumerable
<T
> other
)
313 throw new NotImplementedException ();
316 public virtual SortedSet
<T
> GetViewBetween (T lowerValue
, T upperValue
)
318 if (Comparer
.Compare (lowerValue
, upperValue
) > 0)
319 throw new ArgumentException ("The lowerValue is bigger than upperValue");
321 return new SortedSubSet (this, lowerValue
, upperValue
);
325 public virtual void IntersectWith (IEnumerable
<T
> other
)
327 throw new NotImplementedException ();
331 public bool IsProperSubsetOf (IEnumerable
<T
> other
)
333 throw new NotImplementedException ();
337 public bool IsProperSupersetOf (IEnumerable
<T
> other
)
339 throw new NotImplementedException ();
343 public bool IsSubsetOf (IEnumerable
<T
> other
)
345 throw new NotImplementedException ();
349 public bool IsSupersetOf (IEnumerable
<T
> other
)
351 throw new NotImplementedException ();
355 public bool Overlaps (IEnumerable
<T
> other
)
357 throw new NotImplementedException ();
361 public bool SetEquals (IEnumerable
<T
> other
)
363 throw new NotImplementedException ();
367 public void SymmetricExceptWith (IEnumerable
<T
> other
)
369 throw new NotImplementedException ();
373 public void UnionWith (IEnumerable
<T
> other
)
375 throw new NotImplementedException ();
378 void ICollection
<T
>.Add (T item
)
383 void ICollection
<T
>.CopyTo (T
[] array
, int index
)
385 CopyTo (array
, index
, Count
);
388 bool ICollection
<T
>.IsReadOnly
{
389 get { return false; }
392 void ICollection
.CopyTo (Array array
, int index
)
397 throw new ArgumentNullException ("array");
398 if (index
< 0 || array
.Length
<= index
)
399 throw new ArgumentOutOfRangeException ("index");
400 if (array
.Length
- index
< Count
)
401 throw new ArgumentException ();
403 foreach (Node node
in tree
)
404 array
.SetValue (node
.item
, index
++);
407 bool ICollection
.IsSynchronized
{
408 get { return false; }
411 // TODO:Is this correct? If this is wrong,please fix.
412 object ICollection
.SyncRoot
{
417 public struct Enumerator
: IEnumerator
<T
>, IDisposable
{
419 RBTree
.NodeEnumerator host
;
423 internal Enumerator (SortedSet
<T
> set)
425 host
= set.tree
.GetEnumerator ();
426 current
= default (T
);
430 get { return current; }
433 object IEnumerator
.Current
{
435 host
.check_current ();
436 return ((Node
) host
.Current
).item
;
440 public bool MoveNext ()
442 if (!host
.MoveNext ())
445 current
= ((Node
) host
.Current
).item
;
449 public void Dispose ()
454 void IEnumerator
.Reset ()
461 sealed class SortedSubSet
: SortedSet
<T
>, IEnumerable
<T
>, IEnumerable
{
467 public SortedSubSet (SortedSet
<T
> set, T lower
, T upper
)
468 : base (set.Comparer
)
475 internal override T
GetMin ()
477 for (int i
= 0; i
< set.tree
.Count
; i
++) {
478 var item
= set.GetItem (i
);
486 internal override T
GetMax ()
488 for (int i
= set.tree
.Count
- 1; i
>= 0; i
--) {
489 var item
= set.GetItem (i
);
497 internal override bool TryAdd (T item
)
500 throw new ArgumentOutOfRangeException ("item");
502 return set.TryAdd (item
);
505 internal override bool TryRemove (T item
)
510 return set.TryRemove (item
);
513 public override bool Contains (T item
)
518 return set.Contains (item
);
521 public override void Clear ()
523 set.RemoveWhere (InRange
);
526 bool InRange (T item
)
528 return Comparer
.Compare (item
, lower
) >= 0
529 && Comparer
.Compare (item
, upper
) <= 0;
532 public override SortedSet
<T
> GetViewBetween (T lowerValue
, T upperValue
)
534 if (Comparer
.Compare (lowerValue
, upperValue
) > 0)
535 throw new ArgumentException ("The lowerValue is bigger than upperValue");
536 if (!InRange (lowerValue
))
537 throw new ArgumentOutOfRangeException ("lowerValue");
538 if (!InRange (upperValue
))
539 throw new ArgumentOutOfRangeException ("upperValue");
541 return new SortedSubSet (set, lowerValue
, upperValue
);
544 public IEnumerator
<T
> GetEnumerator ()
546 var yielding
= false;
548 foreach (Node node
in set.tree
) {
549 var item
= node
.item
;
551 if (InRange (item
)) {
559 IEnumerator
<T
> IEnumerable
<T
>.GetEnumerator ()
561 return GetEnumerator ();
564 IEnumerator IEnumerable
.GetEnumerator ()
566 return GetEnumerator ();