Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
SortedList.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under MIT License. See LICENSE.md for details.
3 //
4 // System.Collections.Generic.SortedList.cs
5 //
6 // Author:
7 // Sergey Chaban (serge@wildwestsoftware.com)
8 // Duncan Mak (duncan@ximian.com)
9 // Herve Poussineau (hpoussineau@fr.st
10 // Zoltan Varga (vargaz@gmail.com)
11 //
12 
13 //
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 //
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 //
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35 using System;
36 using System.Collections;
37 using System.Collections.Generic;
38 using System.Diagnostics;
39 
40 namespace SiliconStudio.Core.Collections
41 {
42  /// <summary>
43  /// Represents a collection of associated keys and values
44  /// that are sorted by the keys and are accessible by key
45  /// and by index.
46  /// </summary>
47  [DebuggerDisplay("Count = {Count}")]
48  public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
49  {
50  private readonly static int INITIAL_SIZE = 16;
51 
52  private enum EnumeratorMode : int { KEY_MODE = 0, VALUE_MODE, ENTRY_MODE }
53 
54  private int inUse;
55  private int modificationCount;
56  private KeyValuePair<TKey, TValue>[] table;
57  private IComparer<TKey> comparer;
58  private int defaultCapacity;
59 
60  //
61  // Constructors
62  //
63  public SortedList()
64  : this(INITIAL_SIZE, null)
65  {
66  }
67 
68  public SortedList(int capacity)
69  : this(capacity, null)
70  {
71  }
72 
73  public SortedList(int capacity, IComparer<TKey> comparer)
74  {
75  if (capacity < 0)
76  throw new ArgumentOutOfRangeException("initialCapacity");
77 
78  if (capacity == 0)
79  defaultCapacity = 0;
80  else
81  defaultCapacity = INITIAL_SIZE;
82  Init(comparer, capacity, true);
83  }
84 
85  public SortedList(IComparer<TKey> comparer)
86  : this(INITIAL_SIZE, comparer)
87  {
88  }
89 
91  : this(dictionary, null)
92  {
93  }
94 
96  {
97  if (dictionary == null)
98  throw new ArgumentNullException("dictionary");
99 
100  Init(comparer, dictionary.Count, true);
101 
102  foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
103  Add(kvp.Key, kvp.Value);
104  }
105 
106  //
107  // Properties
108  //
109 
110  // ICollection
111 
112  public int Count
113  {
114  get
115  {
116  return inUse;
117  }
118  }
119 
120  bool ICollection.IsSynchronized
121  {
122  get
123  {
124  return false;
125  }
126  }
127 
128  Object ICollection.SyncRoot
129  {
130  get
131  {
132  return this;
133  }
134  }
135 
136  // IDictionary
137 
138  bool IDictionary.IsFixedSize
139  {
140  get
141  {
142  return false;
143  }
144  }
145 
146  bool IDictionary.IsReadOnly
147  {
148  get
149  {
150  return false;
151  }
152  }
153 
154  public TValue this[TKey key]
155  {
156  get
157  {
158  if (key == null)
159  throw new ArgumentNullException("key");
160 
161  int i = Find(key);
162 
163  if (i >= 0)
164  return table[i].Value;
165  else
166  throw new KeyNotFoundException();
167  }
168  set
169  {
170  if (key == null)
171  throw new ArgumentNullException("key");
172 
173  PutImpl(key, value, true);
174  }
175  }
176 
177  object IDictionary.this[object key]
178  {
179  get
180  {
181  if (!(key is TKey))
182  return null;
183  else
184  return this[(TKey)key];
185  }
186 
187  set
188  {
189  this[ToKey(key)] = ToValue(value);
190  }
191  }
192 
193  public int Capacity
194  {
195  get
196  {
197  return table.Length;
198  }
199 
200  set
201  {
202  int current = this.table.Length;
203 
204  if (inUse > value)
205  {
206  throw new ArgumentOutOfRangeException("capacity too small");
207  }
208  else if (value == 0)
209  {
210  // return to default size
211  KeyValuePair<TKey, TValue>[] newTable = new KeyValuePair<TKey, TValue>[defaultCapacity];
212  Array.Copy(table, newTable, inUse);
213  this.table = newTable;
214  }
215 #if NET_1_0
216  else if (current > defaultCapacity && value < current) {
217  KeyValuePair<TKey, TValue> [] newTable = new KeyValuePair<TKey, TValue> [defaultCapacity];
218  Array.Copy (table, newTable, inUse);
219  this.table = newTable;
220  }
221 #endif
222  else if (value > inUse)
223  {
224  KeyValuePair<TKey, TValue>[] newTable = new KeyValuePair<TKey, TValue>[value];
225  Array.Copy(table, newTable, inUse);
226  this.table = newTable;
227  }
228  else if (value > current)
229  {
230  KeyValuePair<TKey, TValue>[] newTable = new KeyValuePair<TKey, TValue>[value];
231  Array.Copy(table, newTable, current);
232  this.table = newTable;
233  }
234  }
235  }
236 
237  public IList<TKey> Keys
238  {
239  get
240  {
241  return new ListKeys(this);
242  }
243  }
244 
245  public IList<TValue> Values
246  {
247  get
248  {
249  return new ListValues(this);
250  }
251  }
252 
253  ICollection IDictionary.Keys
254  {
255  get
256  {
257  return new ListKeys(this);
258  }
259  }
260 
261  ICollection IDictionary.Values
262  {
263  get
264  {
265  return new ListValues(this);
266  }
267  }
268 
270  {
271  get
272  {
273  return Keys;
274  }
275  }
276 
278  {
279  get
280  {
281  return Values;
282  }
283  }
284 
285  public IComparer<TKey> Comparer
286  {
287  get
288  {
289  return comparer;
290  }
291  }
292 
294  {
295  get
296  {
297  return false;
298  }
299  }
300 
301  //
302  // Public instance methods.
303  //
304 
305  public void Add(TKey key, TValue value)
306  {
307  if (key == null)
308  throw new ArgumentNullException("key");
309 
310  PutImpl(key, value, false);
311  }
312 
313  public bool ContainsKey(TKey key)
314  {
315  if (key == null)
316  throw new ArgumentNullException("key");
317 
318  return (Find(key) >= 0);
319  }
320 
321  public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
322  {
323  for (int i = 0; i < inUse; i++)
324  {
325  KeyValuePair<TKey, TValue> current = this.table[i];
326 
327  yield return new KeyValuePair<TKey, TValue>(current.Key, current.Value);
328  }
329  }
330 
331  public bool Remove(TKey key)
332  {
333  if (key == null)
334  throw new ArgumentNullException("key");
335 
336  int i = IndexOfKey(key);
337  if (i >= 0)
338  {
339  RemoveAt(i);
340  return true;
341  }
342  else
343  return false;
344  }
345 
346  // ICollection<KeyValuePair<TKey, TValue>>
347 
349  {
350  defaultCapacity = INITIAL_SIZE;
351  this.table = new KeyValuePair<TKey, TValue>[defaultCapacity];
352  inUse = 0;
353  modificationCount++;
354  }
355 
356  public void Clear()
357  {
358  defaultCapacity = INITIAL_SIZE;
359  this.table = new KeyValuePair<TKey, TValue>[defaultCapacity];
360  inUse = 0;
361  modificationCount++;
362  }
363 
364  void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
365  {
366  if (Count == 0)
367  return;
368 
369  if (null == array)
370  throw new ArgumentNullException();
371 
372  if (arrayIndex < 0)
373  throw new ArgumentOutOfRangeException();
374 
375  if (arrayIndex >= array.Length)
376  throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length");
377  if (Count > (array.Length - arrayIndex))
378  throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array");
379 
380  int i = arrayIndex;
381  foreach (KeyValuePair<TKey, TValue> pair in this)
382  array[i++] = pair;
383  }
384 
385  void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
386  {
387  Add(keyValuePair.Key, keyValuePair.Value);
388  }
389 
390  bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair)
391  {
392  int i = Find(keyValuePair.Key);
393 
394  if (i >= 0)
395  return Comparer<KeyValuePair<TKey, TValue>>.Default.Compare(table[i], keyValuePair) == 0;
396  else
397  return false;
398  }
399 
400  bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair)
401  {
402  int i = Find(keyValuePair.Key);
403 
404  if (i >= 0 && (Comparer<KeyValuePair<TKey, TValue>>.Default.Compare(table[i], keyValuePair) == 0))
405  {
406  RemoveAt(i);
407  return true;
408  }
409  else
410  return false;
411  }
412 
413  // IEnumerable<KeyValuePair<TKey, TValue>>
414 
415  IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
416  {
417  for (int i = 0; i < inUse; i++)
418  {
419  KeyValuePair<TKey, TValue> current = this.table[i];
420 
421  yield return new KeyValuePair<TKey, TValue>(current.Key, current.Value);
422  }
423  }
424 
425  // IEnumerable
426 
427  IEnumerator IEnumerable.GetEnumerator()
428  {
429  return GetEnumerator();
430  }
431 
432  // IDictionary
433 
434  void IDictionary.Add(object key, object value)
435  {
436  PutImpl(ToKey(key), ToValue(value), false);
437  }
438 
439  bool IDictionary.Contains(object key)
440  {
441  if (null == key)
442  throw new ArgumentNullException();
443  if (!(key is TKey))
444  return false;
445 
446  return (Find((TKey)key) >= 0);
447  }
448 
449  IDictionaryEnumerator IDictionary.GetEnumerator()
450  {
451  return new Enumerator(this, EnumeratorMode.ENTRY_MODE);
452  }
453 
454  void IDictionary.Remove(object key)
455  {
456  if (null == key)
457  throw new ArgumentNullException("key");
458  if (!(key is TKey))
459  return;
460  int i = IndexOfKey((TKey)key);
461  if (i >= 0) RemoveAt(i);
462  }
463 
464  // ICollection
465 
466  void ICollection.CopyTo(Array array, int arrayIndex)
467  {
468  if (Count == 0)
469  return;
470 
471  if (null == array)
472  throw new ArgumentNullException();
473 
474  if (arrayIndex < 0)
475  throw new ArgumentOutOfRangeException();
476 
477  if (array.Rank > 1)
478  throw new ArgumentException("array is multi-dimensional");
479  if (arrayIndex >= array.Length)
480  throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length");
481  if (Count > (array.Length - arrayIndex))
482  throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array");
483 
484  IEnumerator<KeyValuePair<TKey, TValue>> it = GetEnumerator();
485  int i = arrayIndex;
486 
487  while (it.MoveNext())
488  {
489  array.SetValue(it.Current, i++);
490  }
491  }
492 
493  //
494  // SortedList<TKey, TValue>
495  //
496 
497  public void RemoveAt(int index)
498  {
499  KeyValuePair<TKey, TValue>[] table = this.table;
500  int cnt = Count;
501  if (index >= 0 && index < cnt)
502  {
503  if (index != cnt - 1)
504  {
505  Array.Copy(table, index + 1, table, index, cnt - 1 - index);
506  }
507  else
508  {
509  table[index] = default(KeyValuePair<TKey, TValue>);
510  }
511  --inUse;
512  ++modificationCount;
513  }
514  else
515  {
516  throw new ArgumentOutOfRangeException("index out of range");
517  }
518  }
519 
520  public int IndexOfKey(TKey key)
521  {
522  if (key == null)
523  throw new ArgumentNullException("key");
524 
525  int indx = 0;
526  try
527  {
528  indx = Find(key);
529  }
530  catch (Exception)
531  {
532  throw new InvalidOperationException();
533  }
534 
535  return (indx | (indx >> 31));
536  }
537 
538  public int IndexOfValue(TValue value)
539  {
540  if (inUse == 0)
541  return -1;
542 
543  for (int i = 0; i < inUse; i++)
544  {
545  KeyValuePair<TKey, TValue> current = this.table[i];
546 
547  if (Equals(value, current.Value))
548  return i;
549  }
550 
551  return -1;
552  }
553 
554  public bool ContainsValue(TValue value)
555  {
556  return IndexOfValue(value) >= 0;
557  }
558 
559  public void TrimExcess()
560  {
561  if (inUse < table.Length * 0.9)
562  Capacity = inUse;
563  }
564 
565  public bool TryGetValue(TKey key, out TValue value)
566  {
567  if (key == null)
568  throw new ArgumentNullException("key");
569 
570  int i = Find(key);
571 
572  if (i >= 0)
573  {
574  value = table[i].Value;
575  return true;
576  }
577  else
578  {
579  value = default(TValue);
580  return false;
581  }
582  }
583 
584  //
585  // Private methods
586  //
587 
588  private void EnsureCapacity(int n, int free)
589  {
590  KeyValuePair<TKey, TValue>[] table = this.table;
591  KeyValuePair<TKey, TValue>[] newTable = null;
592  int cap = Capacity;
593  bool gap = (free >= 0 && free < Count);
594 
595  if (n > cap)
596  {
597  newTable = new KeyValuePair<TKey, TValue>[n << 1];
598  }
599 
600  if (newTable != null)
601  {
602  if (gap)
603  {
604  int copyLen = free;
605  if (copyLen > 0)
606  {
607  Array.Copy(table, 0, newTable, 0, copyLen);
608  }
609  copyLen = Count - free;
610  if (copyLen > 0)
611  {
612  Array.Copy(table, free, newTable, free + 1, copyLen);
613  }
614  }
615  else
616  {
617  // Just a resizing, copy the entire table.
618  Array.Copy(table, newTable, Count);
619  }
620  this.table = newTable;
621  }
622  else if (gap)
623  {
624  Array.Copy(table, free, table, free + 1, Count - free);
625  }
626  }
627 
628  private void PutImpl(TKey key, TValue value, bool overwrite)
629  {
630  if (key == null)
631  throw new ArgumentNullException("null key");
632 
633  KeyValuePair<TKey, TValue>[] table = this.table;
634 
635  int freeIndx = -1;
636 
637  try
638  {
639  freeIndx = Find(key);
640  }
641  catch (Exception)
642  {
643  throw new InvalidOperationException();
644  }
645 
646  if (freeIndx >= 0)
647  {
648  if (!overwrite)
649  throw new ArgumentException("element already exists");
650 
651  table[freeIndx] = new KeyValuePair<TKey, TValue>(key, value);
652  ++modificationCount;
653  return;
654  }
655 
656  freeIndx = ~freeIndx;
657 
658  if (freeIndx > Capacity + 1)
659  throw new Exception("SortedList::internal error (" + key + ", " + value + ") at [" + freeIndx + "]");
660 
661 
662  EnsureCapacity(Count + 1, freeIndx);
663 
664  table = this.table;
665  table[freeIndx] = new KeyValuePair<TKey, TValue>(key, value);
666 
667  ++inUse;
668  ++modificationCount;
669 
670  }
671 
672  private void Init(IComparer<TKey> comparer, int capacity, bool forceSize)
673  {
674  if (comparer == null)
675  comparer = Comparer<TKey>.Default;
676  this.comparer = comparer;
677  if (!forceSize && (capacity < defaultCapacity))
678  capacity = defaultCapacity;
679  this.table = new KeyValuePair<TKey, TValue>[capacity];
680  this.inUse = 0;
681  this.modificationCount = 0;
682  }
683 
684  private void CopyToArray(Array arr, int i,
685  EnumeratorMode mode)
686  {
687  if (arr == null)
688  throw new ArgumentNullException("arr");
689 
690  if (i < 0 || i + this.Count > arr.Length)
691  throw new ArgumentOutOfRangeException("i");
692 
693  IEnumerator it = new Enumerator(this, mode);
694 
695  while (it.MoveNext())
696  {
697  arr.SetValue(it.Current, i++);
698  }
699  }
700 
701  private int Find(TKey key)
702  {
703  KeyValuePair<TKey, TValue>[] table = this.table;
704  int len = Count;
705 
706  if (len == 0) return ~0;
707 
708  int left = 0;
709  int right = len - 1;
710 
711  while (left <= right)
712  {
713  int guess = (left + right) >> 1;
714 
715  int cmp = comparer.Compare(table[guess].Key, key);
716  if (cmp == 0) return guess;
717 
718  if (cmp < 0) left = guess + 1;
719  else right = guess - 1;
720  }
721 
722  return ~left;
723  }
724 
725  private TKey ToKey(object key)
726  {
727  if (key == null)
728  throw new ArgumentNullException("key");
729  if (!(key is TKey))
730  throw new ArgumentException("The value \"" + key + "\" isn't of type \"" + typeof(TKey) + "\" and can't be used in this generic collection.", "key");
731  return (TKey)key;
732  }
733 
734  private TValue ToValue(object value)
735  {
736  if (!(value is TValue))
737  throw new ArgumentException("The value \"" + value + "\" isn't of type \"" + typeof(TValue) + "\" and can't be used in this generic collection.", "value");
738  return (TValue)value;
739  }
740 
741  internal TKey KeyAt(int index)
742  {
743  if (index >= 0 && index < Count)
744  return table[index].Key;
745  else
746  throw new ArgumentOutOfRangeException("Index out of range");
747  }
748 
749  internal TValue ValueAt(int index)
750  {
751  if (index >= 0 && index < Count)
752  return table[index].Value;
753  else
754  throw new ArgumentOutOfRangeException("Index out of range");
755  }
756 
757  //
758  // Inner classes
759  //
760 
761 
762  private sealed class Enumerator : IDictionaryEnumerator, IEnumerator
763  {
764 
765  private SortedList<TKey, TValue> host;
766  private int stamp;
767  private int pos;
768  private int size;
769  private EnumeratorMode mode;
770 
771  private object currentKey;
772  private object currentValue;
773 
774  bool invalid = false;
775 
776  private readonly static string xstr = "SortedList.Enumerator: snapshot out of sync.";
777 
778  public Enumerator(SortedList<TKey, TValue> host, EnumeratorMode mode)
779  {
780  this.host = host;
781  stamp = host.modificationCount;
782  size = host.Count;
783  this.mode = mode;
784  Reset();
785  }
786 
787  public Enumerator(SortedList<TKey, TValue> host)
788  : this(host, EnumeratorMode.ENTRY_MODE)
789  {
790  }
791 
792  public void Reset()
793  {
794  if (host.modificationCount != stamp || invalid)
795  throw new InvalidOperationException(xstr);
796 
797  pos = -1;
798  currentKey = null;
799  currentValue = null;
800  }
801 
802  public bool MoveNext()
803  {
804  if (host.modificationCount != stamp || invalid)
805  throw new InvalidOperationException(xstr);
806 
807  KeyValuePair<TKey, TValue>[] table = host.table;
808 
809  if (++pos < size)
810  {
811  KeyValuePair<TKey, TValue> entry = table[pos];
812 
813  currentKey = entry.Key;
814  currentValue = entry.Value;
815  return true;
816  }
817 
818  currentKey = null;
819  currentValue = null;
820  return false;
821  }
822 
823  public DictionaryEntry Entry
824  {
825  get
826  {
827  if (invalid || pos >= size || pos == -1)
828  throw new InvalidOperationException(xstr);
829 
830  return new DictionaryEntry(currentKey,
831  currentValue);
832  }
833  }
834 
835  public Object Key
836  {
837  get
838  {
839  if (invalid || pos >= size || pos == -1)
840  throw new InvalidOperationException(xstr);
841  return currentKey;
842  }
843  }
844 
845  public Object Value
846  {
847  get
848  {
849  if (invalid || pos >= size || pos == -1)
850  throw new InvalidOperationException(xstr);
851  return currentValue;
852  }
853  }
854 
855  public Object Current
856  {
857  get
858  {
859  if (invalid || pos >= size || pos == -1)
860  throw new InvalidOperationException(xstr);
861 
862  switch (mode)
863  {
864  case EnumeratorMode.KEY_MODE:
865  return currentKey;
866  case EnumeratorMode.VALUE_MODE:
867  return currentValue;
868  case EnumeratorMode.ENTRY_MODE:
869  return this.Entry;
870 
871  default:
872  throw new NotSupportedException(mode + " is not a supported mode.");
873  }
874  }
875  }
876 
877  // ICloneable
878 
879  public object Clone()
880  {
881  Enumerator e = new Enumerator(host, mode);
882  e.stamp = stamp;
883  e.pos = pos;
884  e.size = size;
885  e.currentKey = currentKey;
886  e.currentValue = currentValue;
887  e.invalid = invalid;
888  return e;
889  }
890  }
891 
892  struct KeyEnumerator : IEnumerator<TKey>, IDisposable
893  {
894  const int NOT_STARTED = -2;
895 
896  // this MUST be -1, because we depend on it in move next.
897  // we just decr the size, so, 0 - 1 == FINISHED
898  const int FINISHED = -1;
899 
900  SortedList<TKey, TValue> l;
901  int idx;
902  int ver;
903 
904  internal KeyEnumerator(SortedList<TKey, TValue> l)
905  {
906  this.l = l;
907  idx = NOT_STARTED;
908  ver = l.modificationCount;
909  }
910 
911  public void Dispose()
912  {
913  idx = NOT_STARTED;
914  }
915 
916  public bool MoveNext()
917  {
918  if (ver != l.modificationCount)
919  throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
920 
921  if (idx == NOT_STARTED)
922  idx = l.Count;
923 
924  return idx != FINISHED && --idx != FINISHED;
925  }
926 
927  public TKey Current
928  {
929  get
930  {
931  if (idx < 0)
932  throw new InvalidOperationException();
933 
934  return l.KeyAt(l.Count - 1 - idx);
935  }
936  }
937 
938  void IEnumerator.Reset()
939  {
940  if (ver != l.modificationCount)
941  throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
942 
943  idx = NOT_STARTED;
944  }
945 
946  object IEnumerator.Current
947  {
948  get { return Current; }
949  }
950  }
951 
952  struct ValueEnumerator : IEnumerator<TValue>, IDisposable
953  {
954  const int NOT_STARTED = -2;
955 
956  // this MUST be -1, because we depend on it in move next.
957  // we just decr the size, so, 0 - 1 == FINISHED
958  const int FINISHED = -1;
959 
960  SortedList<TKey, TValue> l;
961  int idx;
962  int ver;
963 
964  internal ValueEnumerator(SortedList<TKey, TValue> l)
965  {
966  this.l = l;
967  idx = NOT_STARTED;
968  ver = l.modificationCount;
969  }
970 
971  public void Dispose()
972  {
973  idx = NOT_STARTED;
974  }
975 
976  public bool MoveNext()
977  {
978  if (ver != l.modificationCount)
979  throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
980 
981  if (idx == NOT_STARTED)
982  idx = l.Count;
983 
984  return idx != FINISHED && --idx != FINISHED;
985  }
986 
987  public TValue Current
988  {
989  get
990  {
991  if (idx < 0)
992  throw new InvalidOperationException();
993 
994  return l.ValueAt(l.Count - 1 - idx);
995  }
996  }
997 
998  void IEnumerator.Reset()
999  {
1000  if (ver != l.modificationCount)
1001  throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
1002 
1003  idx = NOT_STARTED;
1004  }
1005 
1006  object IEnumerator.Current
1007  {
1008  get { return Current; }
1009  }
1010  }
1011 
1012  private class ListKeys : IList<TKey>, ICollection, IEnumerable
1013  {
1014 
1015  private SortedList<TKey, TValue> host;
1016 
1017  public ListKeys(SortedList<TKey, TValue> host)
1018  {
1019  if (host == null)
1020  throw new ArgumentNullException();
1021 
1022  this.host = host;
1023  }
1024 
1025  // ICollection<TKey>
1026 
1027  public virtual void Add(TKey item)
1028  {
1029  throw new NotSupportedException();
1030  }
1031 
1032  public virtual bool Remove(TKey key)
1033  {
1034  throw new NotSupportedException();
1035  }
1036 
1037  public virtual void Clear()
1038  {
1039  throw new NotSupportedException();
1040  }
1041 
1042  public virtual void CopyTo(TKey[] array, int arrayIndex)
1043  {
1044  if (host.Count == 0)
1045  return;
1046  if (array == null)
1047  throw new ArgumentNullException("array");
1048  if (arrayIndex < 0)
1049  throw new ArgumentOutOfRangeException();
1050  if (arrayIndex >= array.Length)
1051  throw new ArgumentOutOfRangeException("arrayIndex is greater than or equal to array.Length");
1052  if (Count > (array.Length - arrayIndex))
1053  throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array");
1054 
1055  int j = arrayIndex;
1056  for (int i = 0; i < Count; ++i)
1057  array[j++] = host.KeyAt(i);
1058  }
1059 
1060  public virtual bool Contains(TKey item)
1061  {
1062  return host.IndexOfKey(item) > -1;
1063  }
1064 
1065  //
1066  // IList<TKey>
1067  //
1068  public virtual int IndexOf(TKey item)
1069  {
1070  return host.IndexOfKey(item);
1071  }
1072 
1073  public virtual void Insert(int index, TKey item)
1074  {
1075  throw new NotSupportedException();
1076  }
1077 
1078  public virtual void RemoveAt(int index)
1079  {
1080  throw new NotSupportedException();
1081  }
1082 
1083  public virtual TKey this[int index]
1084  {
1085  get
1086  {
1087  return host.KeyAt(index);
1088  }
1089  set
1090  {
1091  throw new NotSupportedException("attempt to modify a key");
1092  }
1093  }
1094 
1095  //
1096  // IEnumerable<TKey>
1097  //
1098 
1099  public virtual IEnumerator<TKey> GetEnumerator()
1100  {
1101  /* We couldn't use yield as it does not support Reset () */
1102  return new KeyEnumerator(host);
1103  }
1104 
1105  //
1106  // ICollection
1107  //
1108 
1109  public virtual int Count
1110  {
1111  get
1112  {
1113  return host.Count;
1114  }
1115  }
1116 
1117  public virtual bool IsSynchronized
1118  {
1119  get
1120  {
1121  return ((ICollection)host).IsSynchronized;
1122  }
1123  }
1124 
1125  public virtual bool IsReadOnly
1126  {
1127  get
1128  {
1129  return true;
1130  }
1131  }
1132 
1133  public virtual Object SyncRoot
1134  {
1135  get
1136  {
1137  return ((ICollection)host).SyncRoot;
1138  }
1139  }
1140 
1141  public virtual void CopyTo(Array array, int arrayIndex)
1142  {
1143  host.CopyToArray(array, arrayIndex, EnumeratorMode.KEY_MODE);
1144  }
1145 
1146  //
1147  // IEnumerable
1148  //
1149 
1150  IEnumerator IEnumerable.GetEnumerator()
1151  {
1152  for (int i = 0; i < host.Count; ++i)
1153  yield return host.KeyAt(i);
1154  }
1155  }
1156 
1157  private class ListValues : IList<TValue>, ICollection, IEnumerable
1158  {
1159 
1160  private SortedList<TKey, TValue> host;
1161 
1162  public ListValues(SortedList<TKey, TValue> host)
1163  {
1164  if (host == null)
1165  throw new ArgumentNullException();
1166 
1167  this.host = host;
1168  }
1169 
1170  // ICollection<TValue>
1171 
1172  public virtual void Add(TValue item)
1173  {
1174  throw new NotSupportedException();
1175  }
1176 
1177  public virtual bool Remove(TValue value)
1178  {
1179  throw new NotSupportedException();
1180  }
1181 
1182  public virtual void Clear()
1183  {
1184  throw new NotSupportedException();
1185  }
1186 
1187  public virtual void CopyTo(TValue[] array, int arrayIndex)
1188  {
1189  if (host.Count == 0)
1190  return;
1191  if (array == null)
1192  throw new ArgumentNullException("array");
1193  if (arrayIndex < 0)
1194  throw new ArgumentOutOfRangeException();
1195  if (arrayIndex >= array.Length)
1196  throw new ArgumentOutOfRangeException("arrayIndex is greater than or equal to array.Length");
1197  if (Count > (array.Length - arrayIndex))
1198  throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array");
1199 
1200  int j = arrayIndex;
1201  for (int i = 0; i < Count; ++i)
1202  array[j++] = host.ValueAt(i);
1203  }
1204 
1205  public virtual bool Contains(TValue item)
1206  {
1207  return host.IndexOfValue(item) > -1;
1208  }
1209 
1210  //
1211  // IList<TValue>
1212  //
1213  public virtual int IndexOf(TValue item)
1214  {
1215  return host.IndexOfValue(item);
1216  }
1217 
1218  public virtual void Insert(int index, TValue item)
1219  {
1220  throw new NotSupportedException();
1221  }
1222 
1223  public virtual void RemoveAt(int index)
1224  {
1225  throw new NotSupportedException();
1226  }
1227 
1228  public virtual TValue this[int index]
1229  {
1230  get
1231  {
1232  return host.ValueAt(index);
1233  }
1234  set
1235  {
1236  throw new NotSupportedException("attempt to modify a key");
1237  }
1238  }
1239 
1240  //
1241  // IEnumerable<TValue>
1242  //
1243 
1244  public virtual IEnumerator<TValue> GetEnumerator()
1245  {
1246  /* We couldn't use yield as it does not support Reset () */
1247  return new ValueEnumerator(host);
1248  }
1249 
1250  //
1251  // ICollection
1252  //
1253 
1254  public virtual int Count
1255  {
1256  get
1257  {
1258  return host.Count;
1259  }
1260  }
1261 
1262  public virtual bool IsSynchronized
1263  {
1264  get
1265  {
1266  return ((ICollection)host).IsSynchronized;
1267  }
1268  }
1269 
1270  public virtual bool IsReadOnly
1271  {
1272  get
1273  {
1274  return true;
1275  }
1276  }
1277 
1278  public virtual Object SyncRoot
1279  {
1280  get
1281  {
1282  return ((ICollection)host).SyncRoot;
1283  }
1284  }
1285 
1286  public virtual void CopyTo(Array array, int arrayIndex)
1287  {
1288  host.CopyToArray(array, arrayIndex, EnumeratorMode.VALUE_MODE);
1289  }
1290 
1291  //
1292  // IEnumerable
1293  //
1294 
1295  IEnumerator IEnumerable.GetEnumerator()
1296  {
1297  for (int i = 0; i < host.Count; ++i)
1298  yield return host.ValueAt(i);
1299  }
1300  }
1301 
1302  } // SortedList
1303 
1304 } // System.Collections.Generic
Keys
Enumeration for keys.
Definition: Keys.cs:8
IEnumerator< KeyValuePair< TKey, TValue > > GetEnumerator()
Definition: SortedList.cs:321
SiliconStudio.Paradox.Input.Keys Keys
One bounding volume completely contains another.
The clone mixin to clone the current mixins where the clone is emitted.
SortedList(int capacity, IComparer< TKey > comparer)
Definition: SortedList.cs:73
The remove mixin to remove a mixin from current mixins.
SortedList(IDictionary< TKey, TValue > dictionary, IComparer< TKey > comparer)
Definition: SortedList.cs:95
The device failed due to a badly formed command. This is a run-time issue; The application should des...
_In_ size_t _In_ size_t size
Definition: DirectXTexP.h:175
SortedList(IDictionary< TKey, TValue > dictionary)
Definition: SortedList.cs:90