#region CPL License /* Nuclex Framework Copyright (C) 2002-2017 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion using System; using System.Collections; using System.Collections.Generic; namespace Nuclex.Support.Collections { partial class MultiDictionary { #region IEnumerable implementation /// Returns a new object enumerator for the Dictionary /// The new object enumerator IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region IDictionary implementation /// Adds an item into the dictionary /// Key under which the item will be added /// Item that will be added void IDictionary.Add(object key, object value) { Add((TKey)key, (TValue)value); } /// Determines whether the specified key exists in the dictionary /// Key that will be checked for /// True if an item with the specified key exists in the dictionary bool IDictionary.Contains(object key) { return this.objectDictionary.Contains(key); } /// Whether the size of the dictionary is fixed bool IDictionary.IsFixedSize { get { return this.objectDictionary.IsFixedSize; } } /// Returns a collection of all keys in the dictionary ICollection IDictionary.Keys { get { return this.objectDictionary.Keys; } } /// Returns a collection of all values stored in the dictionary ICollection IDictionary.Values { get { if(this.valueCollection == null) { this.valueCollection = new ValueCollection(this); } return this.valueCollection; } } /// Removes an item from the dictionary /// Key of the item that will be removed void IDictionary.Remove(object key) { RemoveKey((TKey)key); } /// Accesses an item in the dictionary by its key /// Key of the item that will be accessed /// The item with the specified key object IDictionary.this[object key] { get { return this.objectDictionary[key]; } set { this[(TKey)key] = (ICollection)value; } } #endregion #region IDictionaryEnumerator implementation /// Returns a new entry enumerator for the dictionary /// The new entry enumerator IDictionaryEnumerator IDictionary.GetEnumerator() { return new Enumerator(this); } #endregion // IDictionaryEnumerator implementation #region ICollection> implementation /// Inserts an already prepared element into the dictionary /// Prepared element that will be added to the dictionary void ICollection>.Add( KeyValuePair item ) { Add(item.Key, item.Value); } /// Removes all items from the dictionary /// Item that will be removed from the dictionary bool ICollection>.Remove( KeyValuePair itemToRemove ) { ICollection values; if(!this.typedDictionary.TryGetValue(itemToRemove.Key, out values)) { return false; } if(values.Remove(itemToRemove.Value)) { if(values.Count == 0) { this.typedDictionary.Remove(itemToRemove.Key); } return true; } else { return false; } } #endregion #region ICollection implementation /// Copies the contents of the Dictionary into an array /// Array the Dictionary contents will be copied into /// /// Starting index at which to begin filling the destination array /// void ICollection.CopyTo(Array array, int arrayIndex) { foreach(KeyValuePair> item in this.typedDictionary) { foreach(TValue value in item.Value) { array.SetValue(new KeyValuePair(item.Key, value), arrayIndex); ++arrayIndex; } } } /// Whether the Dictionary is synchronized for multi-threaded usage bool ICollection.IsSynchronized { get { return this.objectDictionary.IsSynchronized; } } /// Synchronization root on which the Dictionary locks object ICollection.SyncRoot { get { return this.objectDictionary.SyncRoot; } } #endregion #region IDictionary> implementation /// Adds a series of values to a dictionary /// Key under which the values will be added /// Values that will be added to the dictionary void IDictionary>.Add(TKey key, ICollection values) { ICollection currentValues; if(!this.typedDictionary.TryGetValue(key, out currentValues)) { currentValues = new ValueList(this); } foreach(TValue value in values) { currentValues.Add(value); } } /// Removes all values with the specified key /// Key whose associated entries will be removed /// True if at least one entry has been removed from the dictionary bool IDictionary>.Remove(TKey key) { return (RemoveKey(key) > 0); } /// Returns a collection of value collections ICollection> IDictionary>.Values { get { return this.typedDictionary.Values; } } #endregion // IDictionary> implementation #region ICollection>> implementation /// Adds a series of values to a dictionary /// Entry containing the values that will be added void ICollection>>.Add( KeyValuePair> item ) { ICollection currentValues; if(!this.typedDictionary.TryGetValue(item.Key, out currentValues)) { currentValues = new ValueList(this); } foreach(TValue value in item.Value) { currentValues.Add(value); } } /// /// Checks whether the dictionary contains the specified key/value pair /// /// Key/value pair for which the dictionary will be checked /// True if the dictionary contains the specified key/value pair bool ICollection>>.Contains( KeyValuePair> item ) { return this.typedDictionary.Contains(item); } /// Copies the contents of the dictionary into an array /// /// void ICollection>>.CopyTo( KeyValuePair>[] array, int arrayIndex ) { this.typedDictionary.CopyTo(array, arrayIndex); } /// Removes the specified key/value pair from the dictionary /// Key/value pair that will be removed /// True if the key/value pair was contained in the dictionary bool ICollection>>.Remove( KeyValuePair> item ) { return this.typedDictionary.Remove(item); } /// Returns an enumerator for the dictionary /// An enumerator for the key/value pairs in the dictionary IEnumerator>> IEnumerable< KeyValuePair> >.GetEnumerator() { return this.typedDictionary.GetEnumerator(); } /// Number of unique keys in the dictionary /// /// /// This Count property returns a different value from the main interface of /// the multi dictionary to stay consistent with the implemented interfaces. /// /// /// If you cast a multi dictionary to a collection of collections, the count /// property of the outer collection should, of course, be the number of inner /// collections it contains (and not the sum of the items contained in all of /// the inner collections). /// /// /// If you use the count property in the main interface of the multi dictionary, /// the value collections are hidden (it behaves as if the key was in the /// dictionary multiple times), so now the sum of all key-value pairs should /// be returned. /// /// int ICollection>>.Count { get { return this.typedDictionary.Count; } } #endregion // ICollection>> implementation } } // namespace Nuclex.Support.Collections