Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
MultiValueSortedDictionary.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 CPL License. See LICENSE.md for details.
3 //
4 // Copyright (c) 2011 Irfan Ahmad
5 // Source: http://koderhack.blogspot.com/2011/04/priority-queue-and-multi-value-sorted.html
6 // License: "I haven't applied any particular licensing on the source. You can use it as you want. Its also shared on Code Project with CPL licensing."
7 
8  using System;
9 using System.Collections;
10 using System.Collections.Generic;
11 using System.Diagnostics;
12 
13 namespace SiliconStudio.Core.Collections
14 {
15  /// <summary>
16  /// Represents a priority queue, where keys are sorted and each key might have mlutiple values.
17  /// </summary>
18  /// <remarks>
19  /// Storage is based on a <see cref="SortedDictionary{TKey, List{TValue}}"/>.
20  /// </remarks>
21  /// <typeparam name="TKey">The type of the key.</typeparam>
22  /// <typeparam name="TValue">The type of the value.</typeparam>
23  public class MultiValueSortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable
24  {
25  private SortedDictionary<TKey, List<TValue>> _SortedDictionary;
26  private int _Count;
27  private bool _IsModified;
28 
29  /// <summary>
30  /// Initializes a new instance of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
31  /// class that is empty and uses the default System.Collections.Generic.IComparer&lt;TKey&gt;
32  /// implementation to compare keys.
33  /// </summary>
35  {
36  _SortedDictionary = new SortedDictionary<TKey, List<TValue>>();
37  }
38 
39  /// <summary>
40  /// Initializes a new instance of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
41  /// class that is empty and uses the specified System.Collections.Generic.IComparer&lt;TKey&gt;
42  /// implementation to compare keys.
43  /// </summary>
44  /// <param name="comparer">
45  /// The System.Collections.Generic.IComparer&lt;TKey&gt; implementation to use when comparing
46  /// keys, or null to use the default System.Collections.Generic.Comparer&lt;TKey&gt; for
47  /// the type of the key.
48  /// </param>
50  {
51  _SortedDictionary = new SortedDictionary<TKey, List<TValue>>(comparer);
52  }
53 
54  /// <summary>
55  /// Initializes a new instance of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
56  /// class that contains elements copied from the specified System.Collections.Generic.IDictionary&lt;TKey,TValue&gt;
57  /// and uses the default System.Collections.Generic.IComparer&lt;T&gt; implementation
58  /// for the key type.
59  /// </summary>
60  /// <param name="dictionary">
61  /// The System.Collections.Generic.IDictionary&lt;TKey,TValue&gt; whose elements are
62  /// copied to the new KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
63  /// </param>
64  /// <exception cref="System.ArgumentNullException">dictionary is null</exception>
66  : this()
67  {
68  if (dictionary == null) throw new ArgumentNullException("dictionary");
69 
70  foreach (KeyValuePair<TKey, TValue> pair in dictionary)
71  this.Add(pair.Key, pair.Value);
72  _IsModified = false;
73  }
74 
75  /// <summary>
76  /// Initializes a new instance of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
77  /// class that contains elements copied from the specified System.Collections.Generic.IDictionary&lt;TKey,TValue&gt;
78  /// and uses the specified System.Collections.Generic.IComparer&lt;TKey&gt; implementation
79  /// to compare keys.
80  /// </summary>
81  /// <param name="dictionary">
82  /// The System.Collections.Generic.IDictionary&lt;TKey,TValue&gt; whose elements are
83  /// copied to the new KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
84  /// </param>
85  /// <param name="comparer">
86  /// The System.Collections.Generic.IComparer&lt;T&gt; implementation to use when comparing
87  /// keys, or null to use the default System.Collections.Generic.Comparer&lt;TKey&gt; for
88  /// the type of the key.
89  /// </param>
90  /// <exception cref="System.ArgumentNullException">dictionary is null</exception>
92  : this(comparer)
93  {
94  if (dictionary == null) throw new ArgumentNullException("dictionary");
95 
96  foreach (KeyValuePair<TKey, TValue> pair in dictionary)
97  this.Add(pair.Key, pair.Value);
98  _IsModified = false;
99  }
100 
101  /// <summary>
102  /// Gets the System.Collections.Generic.IComparer&lt;TKey&gt; used to order the elements
103  /// of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
104  /// </summary>
105  /// <returns>
106  /// The System.Collections.Generic.IComparer&lt;TKey&gt; used to order the elements of
107  /// the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
108  /// </returns>
109  public IComparer<TKey> Comparer { get { return _SortedDictionary.Comparer; } }
110 
111  /// <summary>
112  /// Gets the number of key/value pairs contained in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
113  /// </summary>
114  /// <returns>
115  /// The number of key/value pairs contained in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
116  /// </returns>
117  public int Count { get { return _Count; } }
118 
119  /// <summary>
120  /// Gets a collection containing the keys in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
121  /// </summary>
122  /// <returns>
123  /// A KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.KeyCollection
124  /// containing the keys in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
125  /// </returns>
126  public SortedDictionary<TKey, List<TValue>>.KeyCollection Keys { get { return _SortedDictionary.Keys; } }
127 
128  /// <summary>
129  /// Gets a collection containing the values in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
130  /// </summary>
131  /// <returns>
132  /// A KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
133  /// containing the keys in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
134  /// </returns>
135  public ValueCollection Values { get { return new ValueCollection(this); } }
136 
137  /// <summary>
138  /// Gets or sets the value associated with the specified key.
139  /// <summary>
140  /// <param name="key">
141  /// The key of the value to get or set.
142  /// </param>
143  /// <returns>
144  /// The value associated with the specified key. If the specified key is not
145  /// found, a get operation throws a System.Collections.Generic.KeyNotFoundException,
146  /// and a set operation creates a new element with the specified key.
147  /// </returns>
148  /// <exception cref="System.ArgumentNullException">key is null.</exception>
149  /// <exception cref="System.Collections.Generic.KeyNotFoundException">
150  /// The property is retrieved and key does not exist in the collection.
151  /// </exception>
152  public TValue this[TKey key]
153  {
154  get
155  {
156  if (key == null) throw new ArgumentNullException("key");
157 
158  List<TValue> values;
159  if (!_SortedDictionary.TryGetValue(key, out values))
160  return (TValue)TryToGetOnNotFound(key);
161  TValue value = default(TValue);
162  if (values != null)
163  value = values[0];
164  return value;
165  }
166  set
167  {
168  if (key == null) throw new ArgumentNullException("key");
169 
170  Add(key, value);
171  }
172  }
173 
174  /// <summary>
175  /// Adds an element with the specified key and value into the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
176  /// </summary>
177  /// <param name="key">
178  /// The key of the element to add.
179  /// </param>
180  /// <param name="value">
181  /// The value of the element to add. The value can be null for reference types.
182  /// </param>
183  /// <exception cref="System.ArgumentNullException">key is null.</exception>
184  public void Add(TKey key, TValue value)
185  {
186  if (key == null) throw new ArgumentNullException("key");
187 
188  List<TValue> values;
189 
190  if (!_SortedDictionary.TryGetValue(key, out values))
191  {
192  values = new List<TValue>();
193  _SortedDictionary[key] = values;
194  }
195 
196  values.Add(value);
197  ++_Count;
198  _IsModified = true;
199  }
200 
201  /// <summary>
202  /// Removes all elements from the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
203  /// <summary>
204  public void Clear()
205  {
206  _SortedDictionary.Clear();
207  _Count = 0;
208  _IsModified = true;
209  }
210 
211  /// <summary>
212  /// Determines whether the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
213  /// contains an element with the specified key.
214  /// </summary>
215  /// <param name="key">
216  /// The key to locate in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
217  /// </param>
218  /// <returns>
219  /// true if the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt; contains
220  /// an element with the specified key; otherwise, false.
221  /// </returns>
222  /// <exception cref="System.ArgumentNullException">key is null.</exception>
223  public bool ContainsKey(TKey key)
224  {
225  return _SortedDictionary.ContainsKey(key);
226  }
227 
228  /// <summary>
229  /// Determines whether the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
230  /// contains an element with the specified value.
231  /// </summary>
232  /// <param name="value">
233  /// The value to locate in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
234  /// The value can be null for reference types.
235  /// </param>
236  /// <returns>
237  /// true if the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt; contains
238  /// an element with the specified value; otherwise, false.
239  /// <returns>
240  public bool ContainsValue(TValue value)
241  {
242  bool contains = false;
243  foreach (TValue val in Values)
244  {
245  if (val.Equals(value))
246  {
247  contains = true;
248  break;
249  }
250  }
251  return contains;
252  }
253 
254  /// <summary>
255  /// Copies the elements of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
256  /// to the specified array of System.Collections.Generic.KeyValuePair<TKey,TValue>
257  /// structures, starting at the specified index.
258  /// <summary>
259  /// <param name="dictionary">
260  /// The one-dimensional array of System.Collections.Generic.KeyValuePair<TKey,TValue>
261  /// structures that is the destination of the elements copied from the current
262  /// KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt; The array must have
263  /// zero-based indexing.
264  /// </param>
265  /// <param name="index">
266  /// The zero-based index in array at which copying begins.
267  /// </param>
268  /// <exception cref="System.ArgumentNullException">array is null.</exception>
269  /// <exception cref="System.ArgumentOutOfRangeException">
270  /// index is equal to or greater than the length of array. -or- index is less
271  /// than 0.
272  /// </exception>
273  /// <exception cref="System.ArgumentException">
274  /// The number of elements in the source KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;
275  /// is greater than the available space from index to the end of the destination
276  /// array.
277  /// </exception>
278  public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
279  {
280  if (array == null)
281  throw new ArgumentNullException("array");
282  else if (index < 0)
283  throw new ArgumentOutOfRangeException("index");
284  else if (index >= array.Length || _Count > array.Length - index)
285  throw new ArgumentException("index");
286 
287  int copyIndex = index;
288  foreach (KeyValuePair<TKey, TValue> pair in this)
289  array[copyIndex++] = new KeyValuePair<TKey, TValue>(pair.Key, pair.Value);
290  }
291 
292  /// <summary>
293  /// Returns an enumerator that iterates through the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
294  /// </summary>
295  /// <returns>
296  /// A KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.Enumerator for
297  /// the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
298  /// </returns>
299  public Enumerator GetEnumerator()
300  {
301  _IsModified = false;
302  return new Enumerator(this);
303  }
304 
305  /// <summary>
306  /// Removes the element with the specified key from the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
307  /// </summary>
308  /// <param name="dictionary">
309  /// The key of the element to remove.
310  /// </param>
311  /// <returns>
312  /// true if the element is successfully removed; otherwise, false. This method
313  /// also returns false if key is not found in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
314  /// </returns>
315  /// <exception cref="System.ArgumentNullException">key is null.</exception>
316  public bool Remove(KeyValuePair<TKey, TValue> item)
317  {
318  if (item.Key == null ||
319  item.Key == null)
320  throw new ArgumentException();
321 
322  bool removed = false;
323  List<TValue> values;
324  if (_SortedDictionary.TryGetValue(item.Key, out values) &&
325  values.Remove(item.Value))
326  {
327  --_Count;
328  if (values.Count == 0)
329  _SortedDictionary.Remove(item.Key);
330  removed = true;
331  _IsModified = true;
332  }
333  return removed;
334  }
335 
336  /// <summary>
337  /// Removes the elements with the specified key from the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
338  /// </summary>
339  /// <param name="dictionary">
340  /// The key of the element to remove.
341  /// </param>
342  /// <returns>
343  /// true if the element is successfully removed; otherwise, false. This method
344  /// also returns false if key is not found in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
345  /// </returns>
346  /// <exception cref="System.ArgumentNullException">key is null.</exception>
347  public bool Remove(TKey key)
348  {
349  if (key == null) throw new ArgumentNullException();
350 
351  bool removed = false;
352  List<TValue> values;
353  if (_SortedDictionary.TryGetValue(key, out values) &&
354  _SortedDictionary.Remove(key))
355  {
356  _Count -= values.Count;
357  _IsModified = removed = true;
358  }
359  return removed;
360  }
361 
362  /// <summary>
363  /// Gets the value associated with the specified key.
364  /// </summary>
365  /// <param name="key">
366  /// The key of the value to get.
367  /// </param>
368  /// <param name="value">
369  /// When this method returns, the value associated with the specified key, if
370  /// the key is found; otherwise, the default value for the type of the value
371  /// parameter.
372  /// </param>
373  /// <returns>
374  /// true if the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt; contains
375  /// an element with the specified key; otherwise, false.
376  /// </returns>
377  /// <exception cref="System.ArgumentNullException">
378  /// key is null.
379  /// </exception>
380  public bool TryGetValue(TKey key, out TValue value)
381  {
382  if (key == null) throw new ArgumentNullException();
383 
384  value = default(TValue);
385  bool found = false;
386  List<TValue> values;
387  if (_SortedDictionary.TryGetValue(key, out values))
388  {
389  value = values[0];
390  found = true;
391  }
392  return found;
393  }
394 
395  /// <summary>
396  /// Gets the value associated with the specified key.
397  /// </summary>
398  /// <param name="key">
399  /// The key of the value to get.
400  /// </param>
401  /// <param name="dictionary">
402  /// When this method returns, the values associated with the specified key, if
403  /// the key is found; otherwise null.
404  /// </param>
405  /// <returns>
406  /// true if the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt; contains
407  /// an element with the specified key; otherwise, false.
408  /// </returns>
409  /// <exception cref="System.ArgumentNullException">
410  /// key is null.
411  /// </exception>
412  public bool TryGetValue(TKey key, out IEnumerable<TValue> values)
413  {
414  if (key == null) throw new ArgumentNullException();
415 
416  values = null;
417  bool found = false;
418  List<TValue> valuesList;
419  if (_SortedDictionary.TryGetValue(key, out valuesList))
420  {
421  values = valuesList;
422  found = true;
423  }
424  return found;
425  }
426 
427  #region IDictionary members
428 
430  {
431  get { return Keys; }
432  }
433 
435  {
436  get { return Values; }
437  }
438 
439  bool IDictionary.IsFixedSize { get { return false; } }
440  bool IDictionary.IsReadOnly { get { return false; } }
441  ICollection IDictionary.Keys { get { return _SortedDictionary.Keys; } }
442  ICollection IDictionary.Values { get { return new ValueCollection(this); } }
443  object IDictionary.this[object key]
444  {
445  get
446  {
447  if (key == null) throw new ArgumentNullException("key");
448 
449  List<TValue> values;
450  var keyT = (TKey) Convert.ChangeType(key, typeof(TKey));
451  if (!_SortedDictionary.TryGetValue(keyT, out values))
452  return TryToGetOnNotFound(keyT);
453  return values[0];
454  }
455  set
456  {
457  if (key == null) throw new ArgumentNullException("key");
458 
459  Add((TKey)Convert.ChangeType(key, typeof(TKey)), (TValue)Convert.ChangeType(value, typeof(TValue)));
460  }
461  }
462  void IDictionary.Add(object key, object value)
463  {
464  if (key == null) throw new ArgumentNullException("key");
465 
466  Add((TKey)Convert.ChangeType(key, typeof(TKey)), (TValue)Convert.ChangeType(value, typeof(TValue)));
467  }
468 
469  bool IDictionary.Contains(object key)
470  {
471  if (key == null) throw new ArgumentNullException("key");
472 
473  return ContainsKey((TKey)Convert.ChangeType(key, typeof(TKey)));
474  }
475 
476  IDictionaryEnumerator IDictionary.GetEnumerator()
477  {
478  _IsModified = false;
479  return new Enumerator(this);
480  }
481 
482  void IDictionary.Remove(object key)
483  {
484  if (key == null) throw new ArgumentNullException("key");
485 
486  this.Remove((TKey)Convert.ChangeType(key, typeof(TKey)));
487  }
488 
489  #endregion
490 
491  #region ICollection members
492 
493  bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly { get { return false; } }
494  bool ICollection.IsSynchronized { get { return false; } }
495  object ICollection.SyncRoot { get { return this; } }
496  void ICollection.CopyTo(Array array, int index)
497  {
498  if (array == null)
499  throw new ArgumentNullException("array");
500  else if (index < 0)
501  throw new ArgumentOutOfRangeException("index");
502  else if (index >= array.Length || _Count > array.Length - index)
503  throw new ArgumentException("index");
504 
505  int copyIndex = index;
506  foreach (KeyValuePair<TKey, TValue> pair in this)
507  array.SetValue(pair, copyIndex++);
508  }
509 
510  bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
511  {
512  bool done = false;
513  List<TValue> values;
514  if (_SortedDictionary.TryGetValue(item.Key, out values) &&
515  values.Contains(item.Value))
516  {
517  if (values.Remove(item.Value))
518  {
519  --_Count;
520  _IsModified = done = true;
521  if (values.Count == 0)
522  _SortedDictionary.Remove(item.Key);
523  }
524  }
525  return done;
526  }
527 
528  bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
529  {
530  List<TValue> values;
531  return _SortedDictionary.TryGetValue(item.Key, out values) &&
532  values.Contains(item.Value);
533  }
534 
535  void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
536  {
537  Add(item.Key, item.Value);
538  }
539 
540  #endregion
541 
542  #region IEnumerable members
543 
544  IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
545  {
546  return GetEnumerator();
547  }
548 
549  IEnumerator IEnumerable.GetEnumerator()
550  {
551  return GetEnumerator();
552  }
553 
554  #endregion
555 
556  /// <summary>
557  /// Represents the collection of values in a KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
558  /// This class cannot be inherited
559  /// </summary>
560  [DebuggerDisplay("Count = {Count}")]
561  //[DebuggerTypeProxy(typeof(System_DictionaryValueCollectionDebugView<,>))]
562  public sealed class ValueCollection : ICollection<TValue>, IEnumerable<TValue>, ICollection, IEnumerable
563  {
564  private MultiValueSortedDictionary<TKey, TValue> _Dictionary;
565 
566  /// <summary>
567  /// Initializes a new instance of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
568  /// class that reflects the values in the specified KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
569  /// </summary>
570  /// <param name="dictionary">
571  /// The KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt; whose values
572  /// are reflected in the new KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
573  /// </param>
574  /// <exception cref="System.ArgumentNullException">
575  /// dictionary is null.
576  /// </exception>
578  {
579  if (dictionary == null) throw new ArgumentNullException();
580 
581  _Dictionary = dictionary;
582  //foreach (KeyValuePair<TKey, List<TValue>> pair in dictionary._SortedDictionary)
583  // _values.AddRange(pair.Value);
584  }
585 
586  /// <summary>
587  /// Gets the number of elements contained in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
588  /// </summary>
589  /// <returns>
590  /// The number of elements contained in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
591  /// </returns>
592  public int Count { get { return _Dictionary.Count; } }
593 
594  /// <summary>
595  /// Copies the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
596  /// elements to an existing one-dimensional array, starting at the specified
597  /// array index.
598  /// </summary>
599  /// <param name="array">
600  /// The one-dimensional array that is the destination of the elements copied
601  /// from the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
602  /// The array must have zero-based indexing.
603  /// </param>
604  /// <param name="index">
605  /// The zero-based index in array at which copying begins.
606  /// </param>
607  /// <exception cref="System.ArgumentNullException">
608  /// array is null.
609  /// </exception>
610  /// <exception cref="System.ArgumentOutOfRangeException">
611  /// index is less than 0.
612  /// </exception>
613  /// <exception cref="System.ArgumentException">
614  /// index is equal to or greater than the length of array. -or- The number of
615  /// elements in the source KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
616  /// is greater than the available space from index to the end of the destination
617  /// array.
618  /// </exception>
619  public void CopyTo(TValue[] array, int index)
620  {
621  if (array == null)
622  throw new ArgumentNullException("array");
623  else if (index < 0)
624  throw new ArgumentOutOfRangeException("index");
625  else if (index >= array.Length || Count > array.Length - index)
626  throw new ArgumentException("index");
627 
628  int copyIndex = index;
629  foreach (TValue value in this)
630  array[copyIndex++] = value;
631  }
632 
633  /// <summary>
634  /// Returns an enumerator that iterates through the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
635  /// </summary>
636  /// <returns>
637  /// A KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.Enumerator
638  /// structure for the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
639  /// </returns>
640  public Enumerator GetEnumerator()
641  {
642  _Dictionary._IsModified = false;
643  return new Enumerator(_Dictionary);
644  }
645 
646  #region ICollection member
647 
648  /// <summary>
649  /// Gets a value indicating whether the KoderHack.MultiValueSortedDictionary.ValueCollection is read-only.
650  /// </summary>
651  /// <returns>
652  /// true if the KoderHack.MultiValueSortedDictionary.ValueCollection is read-only; otherwise false.
653  /// </returns>
654  bool ICollection<TValue>.IsReadOnly { get { return true; } }
655 
656  void ICollection<TValue>.Add(TValue item)
657  {
658  throw new InvalidOperationException();
659  }
660 
661  void ICollection<TValue>.Clear()
662  {
663  throw new InvalidOperationException();
664  }
665 
666  bool ICollection<TValue>.Remove(TValue item)
667  {
668  throw new InvalidOperationException();
669  }
670 
671  void ICollection.CopyTo(Array array, int index)
672  {
673  if (array == null)
674  throw new ArgumentNullException("array");
675  else if (index < 0)
676  throw new ArgumentOutOfRangeException("index");
677  else if (index >= array.Length || Count > array.Length - index)
678  throw new ArgumentException("index");
679 
680  int copyIndex = index;
681  foreach (TValue value in this)
682  array.SetValue(value, copyIndex++);
683  }
684 
685  bool ICollection<TValue>.Contains(TValue item)
686  {
687  return _Dictionary.ContainsValue(item);
688  }
689 
690  /// <summary>
691  /// Gets a value indicating whether access to the System.Collections.ICollection
692  /// is synchronized (thread safe).
693  /// </summary>
694  /// <returns>
695  /// true if access to the System.Collections.ICollection is synchronized (thread
696  /// safe); otherwise, false.
697  /// </returns>
698  bool ICollection.IsSynchronized { get { return false; } }
699 
700  /// <summary>
701  /// Gets an object that can be used to synchronize access to the System.Collections.ICollection.
702  /// </summary>
703  /// <returns>
704  /// An object that can be used to synchronize access to the System.Collections.ICollection.
705  /// </returns>
706  object ICollection.SyncRoot { get { return this; } }
707 
708  #endregion
709 
710  #region IEnumerator members
711 
712  IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
713  {
714  return GetEnumerator();
715  }
716 
717  IEnumerator IEnumerable.GetEnumerator()
718  {
719  return GetEnumerator();
720  }
721 
722  #endregion
723 
724  /// <summary>
725  /// Enumerates the elements of a KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
726  /// </summary>
727  public struct Enumerator : IEnumerator<TValue>, IDisposable, IEnumerator
728  {
729  private MultiValueSortedDictionary<TKey, TValue> _Dictionary;
730  private MultiValueSortedDictionary<TKey, TValue>.Enumerator _Enumerator;
731 
732  internal Enumerator(MultiValueSortedDictionary<TKey, TValue> dictionary)
733  {
734  _Dictionary = dictionary;
735  _Enumerator = new MultiValueSortedDictionary<TKey, TValue>.Enumerator(_Dictionary);
736  }
737 
738  /// <summary>
739  /// Gets the element at the current position of the enumerator.
740  /// </summary>
741  /// <returns>
742  /// The element in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
743  /// at the current position of the enumerator.
744  /// </returns>
745  public TValue Current { get { return _Enumerator.Current.Value; } }
746 
747  /// <summary>
748  /// Releases all resources used by the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.Enumerator.
749  /// </summary>
750  public void Dispose()
751  {
752  }
753 
754  /// <summary>
755  /// Advances the enumerator to the next element of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection.
756  /// </summary>
757  /// <returns>
758  /// true if the enumerator was successfully advanced to the next element; false
759  /// if the enumerator has passed the end of the collection.
760  /// </returns>
761  /// <exception cref="System.InvalidOperationException">
762  /// The collection was modified after the enumerator was created.
763  /// </exception>
764  public bool MoveNext()
765  {
766  return _Enumerator.MoveNext();
767  }
768 
769  /// <summary>
770  /// Gets the element at the current position of the enumerator.
771  /// </summary>
772  /// <returns>
773  /// The element in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
774  /// at the current position of the enumerator.
775  /// </returns>
776  object IEnumerator.Current
777  {
778  get { return Current; }
779  }
780 
781  /// <summary>
782  /// Sets the enumerator to its initial position, which is before the first element
783  /// in the collection.
784  /// </summary>
785  /// <exception cref="System.InvalidOperationException">
786  /// The collection was modified after the enumerator was created.
787  /// </exception>
788  void IEnumerator.Reset()
789  {
790  (_Enumerator as IEnumerator).Reset();
791  }
792  }
793  }
794 
795  protected virtual object TryToGetOnNotFound(TKey name)
796  {
797  throw new KeyNotFoundException();
798  }
799 
800  /// <summary>
801  /// Enumerates the elements of a KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
802  /// </summary>
803  public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, IDictionaryEnumerator, IEnumerator
804  {
805  private readonly KeyValuePair<TKey, TValue> DefaultCurrent;
806  private MultiValueSortedDictionary<TKey, TValue> _Dictionary;
807  private IEnumerator<KeyValuePair<TKey, List<TValue>>> _Enumerator1;
808  private IEnumerator<TValue> _Enumerator2;
809  private KeyValuePair<TKey, TValue> _Current;
810 
811  //private bool _Disposed;
812  private bool _Valid;
813 
815  {
816  if (dictionary == null)
817  throw new ArgumentNullException("dictionary");
818 
819  _Dictionary = dictionary;
820  _Enumerator1 = dictionary._SortedDictionary.GetEnumerator();
821  _Enumerator2 = null;
822  DefaultCurrent = new KeyValuePair<TKey, TValue>(default(TKey), default(TValue));
823  _Current = DefaultCurrent;
824  //_Disposed = false;
825  _Valid = true;
826  }
827 
828  /// <summary>
829  /// Gets the element at the current position of the enumerator.
830  /// </summary>
831  /// <returns>
832  /// The element in the System.Collections.Generic.SortedDictionary<TKey,TValue>
833  /// at the current position of the enumerator.
834  /// </returns>
835  public KeyValuePair<TKey, TValue> Current
836  {
837  get
838  {
839  return _Current;
840  }
841  }
842 
843  /// <summary>
844  /// Gets both the key and the value of the current dictionary entry.
845  /// </summary>
846  /// <returns>
847  /// A System.Collections.DictionaryEntry containing both the key and the value
848  /// of the current dictionary entry.
849  /// </returns>
850  /// <exception cref="System.InvalidOperationException">
851  /// The System.Collections.IDictionaryEnumerator is positioned before the first
852  /// entry of the dictionary or after the last entry.
853  /// </exception>
854  DictionaryEntry IDictionaryEnumerator.Entry
855  {
856  get
857  {
858  return new DictionaryEntry(Current.Key, Current.Value);
859  }
860  }
861 
862  /// <summary>
863  /// Gets the key of the current dictionary entry.
864  /// </summary>
865  /// <returns>
866  /// The key of the current element of the enumeration.
867  /// </returns>
868  /// <exception cref="System.InvalidOperationException">
869  /// The System.Collections.IDictionaryEnumerator is positioned before the first
870  /// entry of the dictionary or after the last entry.
871  /// </exception>
872  object IDictionaryEnumerator.Key
873  {
874  get
875  {
876  return Current.Key;
877  }
878  }
879 
880  /// <summary>
881  /// Gets the value of the current dictionary entry.
882  /// </summary>
883  /// <returns>
884  /// The value of the current element of the enumeration.
885  /// </returns>
886  /// <exception cref="System.InvalidOperationException">
887  /// The System.Collections.IDictionaryEnumerator is positioned before the first
888  /// entry of the dictionary or after the last entry.
889  /// </exception>
890  object IDictionaryEnumerator.Value
891  {
892  get
893  {
894  return Current.Value;
895  }
896  }
897 
898  /// <summary>
899  /// Releases all resources used by the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.Enumerator.
900  /// </summary>
901  public void Dispose()
902  {
903  //_Enumerator1.Dispose();
904  //_Enumerator2.Dispose();
905  //_Dictionary._IsModified = false;
906  //_Dictionary = null;
907  //_Disposed = true;
908  }
909 
910  /// <summary>
911  /// Advances the enumerator to the next element of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.
912  /// </summary>
913  /// <returns>
914  /// true if the enumerator was successfully advanced to the next element; false
915  /// if the enumerator has passed the end of the collection.
916  /// </returns>
917  /// <exception cref="System.InvalidOperationException">
918  /// The collection was modified after the enumerator was created.
919  /// </exception>
920  public bool MoveNext()
921  {
922  //if (_Disposed)
923  // throw new InvalidOperationException("The enumerator has already been disposed.");
924 
925  if (_Dictionary._IsModified)
926  throw new InvalidOperationException("The collection was modified after the enumerator was created.");
927 
928  if (!_Valid) return false;
929  TKey key = default(TKey);
930  TValue value = default(TValue);
931  if (_Enumerator2 == null)
932  {
933  if (_Enumerator1.MoveNext())
934  {
935  if (_Enumerator1.Current.Value != null)
936  _Enumerator2 = _Enumerator1.Current.Value.GetEnumerator();
937  }
938  else
939  _Valid = false;
940  }
941 
942  if (!_Valid) return false;
943 
944  key = _Enumerator1.Current.Key;
945  if (_Enumerator2 != null)
946  {
947  if (_Enumerator2.MoveNext())
948  value = _Enumerator2.Current;
949  else
950  {
951  _Enumerator2 = null;
952  return MoveNext();
953  }
954  }
955  _Current = new KeyValuePair<TKey, TValue>(key, value);
956  return true;
957  }
958 
959  /// <summary>
960  /// Gets the element at the current position of the enumerator.
961  /// </summary>
962  /// <returns>
963  /// The element in the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.ValueCollection
964  /// at the current position of the enumerator.
965  /// </returns>
966  object IEnumerator.Current
967  {
968  get { return Current; }
969  }
970 
971  /// <summary>
972  /// Sets the enumerator to its initial position, which is before the first element
973  /// in the collection.
974  /// </summary>
975  /// <exception cref="System.InvalidOperationException">
976  /// The collection was modified after the enumerator was created.
977  /// </exception>
978  void IEnumerator.Reset()
979  {
980  //if (_Disposed)
981  // throw new InvalidOperationException("The enumerator has already been disposed.");
982  if (_Dictionary._IsModified)
983  throw new InvalidOperationException("The collection was modified after the enumerator was created.");
984 
985  _Enumerator1.Reset();
986  _Enumerator2 = null;
987  _Valid = true;
988  }
989  }
990  }
991 }
MultiValueSortedDictionary(IDictionary< TKey, TValue > dictionary, IComparer< TKey > comparer)
Initializes a new instance of the KoderHack.MultiValueSortedDictionary class that contai...
MultiValueSortedDictionary(IDictionary< TKey, TValue > dictionary)
Initializes a new instance of the KoderHack.MultiValueSortedDictionary class that contai...
void Dispose()
Releases all resources used by the KoderHack.MultiValueSortedDictionary.ValueCollection.Enumerator.
bool TryGetValue(TKey key, out TValue value)
Gets the value associated with the specified key.
void Clear()
Removes all elements from the KoderHack.MultiValueSortedDictionary.
MultiValueSortedDictionary()
Initializes a new instance of the KoderHack.MultiValueSortedDictionary class that is emp...
Keys
Enumeration for keys.
Definition: Keys.cs:8
Enumerator GetEnumerator()
Returns an enumerator that iterates through the KoderHack.MultiValueSortedDictionary.
bool Remove(TKey key)
Removes the elements with the specified key from the KoderHack.MultiValueSortedDictionary.
void CopyTo(TValue[] array, int index)
Copies the KoderHack.MultiValueSortedDictionary.ValueCollection elements to an existing ...
SiliconStudio.Paradox.Input.Keys Keys
bool MoveNext()
Advances the enumerator to the next element of the KoderHack.MultiValueSortedDictionary.
void CopyTo(KeyValuePair< TKey, TValue >[] array, int index)
Copies the elements of the KoderHack.MultiValueSortedDictionary to the specified array o...
bool ContainsKey(TKey key)
Determines whether the KoderHack.MultiValueSortedDictionary contains an element with the...
bool TryGetValue(TKey key, out IEnumerable< TValue > values)
Gets the value associated with the specified key.
void Add(TKey key, TValue value)
Adds an element with the specified key and value into the KoderHack.MultiValueSortedDictionary.
bool MoveNext()
Advances the enumerator to the next element of the KoderHack.MultiValueSortedDictionary.ValueCollection.
Enumerator GetEnumerator()
Returns an enumerator that iterates through the KoderHack.MultiValueSortedDictionary.ValueCollection.
bool ContainsValue(TValue value)
Determines whether the KoderHack.MultiValueSortedDictionary contains an element with the...
HRESULT Convert(_In_ const Image &srcImage, _In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold, _Out_ ScratchImage &image)
MultiValueSortedDictionary(IComparer< TKey > comparer)
Initializes a new instance of the KoderHack.MultiValueSortedDictionary class that is emp...
void Dispose()
Releases all resources used by the KoderHack.MultiValueSortedDictionary.Enumerator.
ValueCollection(MultiValueSortedDictionary< TKey, TValue > dictionary)
Initializes a new instance of the KoderHack.MultiValueSortedDictionary.ValueCollection class that reflects the values in the specified KoderHack.MultiValueSortedDictionary.
Represents a priority queue, where keys are sorted and each key might have mlutiple values...
bool Remove(KeyValuePair< TKey, TValue > item)
Removes the element with the specified key from the KoderHack.MultiValueSortedDictionary.