Skip to content

Commit

Permalink
Added SCG.IDictionary<K, V> to DictionaryBase<K, V> (sestoft#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
NightOwl888 committed Dec 31, 2019
1 parent 890929a commit 85c788d
Show file tree
Hide file tree
Showing 26 changed files with 496 additions and 43 deletions.
2 changes: 2 additions & 0 deletions C5.Tests/SupportClasses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ public override SCG.IEnumerator<T> GetEnumerator()
throw exception;
}

public override bool IsReadOnly => true;

public override bool IsEmpty => false;

public override int Count => contents.Length + 1;
Expand Down
260 changes: 260 additions & 0 deletions C5.Tests/Trees/Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,4 +490,264 @@ public void Dispose()
}
}
}

[TestFixture]
public class SCGIDictionary
{
private SCG.IDictionary<string, string> dict;

[SetUp]
public void Init()
{
dict = new TreeDictionary<string, string>(new SC())
{
{ "A", "1" },
{ "C", "2" },
{ "E", "3" }
};
}

[TearDown]
public void Dispose() { dict = null; }

[Test]
public void Add()
{
Assert.AreEqual(3, dict.Count);
dict.Add("S", "4");
Assert.AreEqual(4, dict.Count);
}

[Test]
public void ContainsKey()
{
Assert.IsTrue(dict.ContainsKey("A"));
Assert.IsFalse(dict.ContainsKey("Z"));
}

[Test]
public void Remove()
{
Assert.AreEqual(3, dict.Count);
Assert.IsTrue(dict.Remove("A"));
Assert.AreEqual(2, dict.Count);
Assert.IsFalse(dict.Remove("Z"));
Assert.AreEqual(2, dict.Count);
}

[Test]
public void TryGetValue()
{
Assert.IsTrue(dict.TryGetValue("C", out string value));
Assert.AreEqual("2", value);
Assert.IsFalse(dict.TryGetValue("Z", out value));
Assert.IsNull(value);
}

[Test]
public void GetItem()
{
Assert.AreEqual("3", dict["E"]);
Assert.Throws<NoSuchItemException>(() => { var x = dict["Z"]; });
}

[Test]
public void SetItem()
{
dict["C"] = "9";
Assert.AreEqual("9", dict["C"]);
dict["Z"] = "5";
Assert.AreEqual("5", dict["Z"]);
}

// ICollection<SCG.KeyValuePair<TKey, TValue>>
[Test]
public void Clear()
{
dict.Clear();
Assert.AreEqual(0, dict.Count);
}

[Test]
public void Contains()
{
Assert.IsTrue(dict.Contains(new SCG.KeyValuePair<string, string>("C", "2")));
Assert.IsFalse(dict.Contains(new SCG.KeyValuePair<string, string>("D", "2")));
Assert.IsFalse(dict.Contains(new SCG.KeyValuePair<string, string>("C", "6")));
}

[Test]
public void CopyTo()
{
var pairs = new SCG.KeyValuePair<string, string>[dict.Count];
dict.CopyTo(pairs, 0);
Assert.AreEqual("C", pairs[1].Key);
Assert.AreEqual("2", pairs[1].Value);
Assert.AreEqual("E", pairs[2].Key);
Assert.AreEqual("3", pairs[2].Value);
}

[Test]
public void RemovePair()
{
Assert.AreEqual(3, dict.Count);
Assert.IsTrue(dict.Remove(new SCG.KeyValuePair<string, string>("A", "1")));
Assert.AreEqual(2, dict.Count);
Assert.IsFalse(dict.Remove(new SCG.KeyValuePair<string, string>("Z", "9")));
Assert.AreEqual(2, dict.Count);
}

[Test]
public void Count()
{
Assert.AreEqual(3, dict.Count);
}

[Test]
public void IsReadOnly()
{
Assert.AreEqual(false, dict.IsReadOnly);
}

[Test]
public void GetEnumerable()
{
var enumerable = dict.GetEnumerator();
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual(new SCG.KeyValuePair<string, string>("A", "1"), enumerable.Current);
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual(new SCG.KeyValuePair<string, string>("C", "2"), enumerable.Current);
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual(new SCG.KeyValuePair<string, string>("E", "3"), enumerable.Current);
Assert.IsFalse(enumerable.MoveNext());
}

[Test]
public void Keys_GetEnumerable()
{
var enumerable = dict.Keys.GetEnumerator();
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual("A", enumerable.Current);
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual("C", enumerable.Current);
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual("E", enumerable.Current);
Assert.IsFalse(enumerable.MoveNext());
}

[Test]
public void Keys_Count()
{
Assert.AreEqual(3, dict.Keys.Count);
dict.Remove("C");
Assert.AreEqual(2, dict.Keys.Count);
}

[Test]
public void Keys_IsReadOnly()
{
Assert.AreEqual(true, dict.Keys.IsReadOnly);
}

[Test]
public void Keys_Add()
{
Assert.Throws<ReadOnlyCollectionException>(() => dict.Keys.Add("Foo"));
}

[Test]
public void Keys_Clear()
{
Assert.Throws<ReadOnlyCollectionException>(() => dict.Keys.Clear());
}

[Test]
public void Keys_Contains()
{
Assert.IsTrue(dict.Keys.Contains("A"));
Assert.IsFalse(dict.Keys.Contains("B"));
}

[Test]
public void Keys_CopyTo()
{
var keys = new string[dict.Keys.Count + 2];
dict.Keys.CopyTo(keys, 1);
Assert.AreEqual(null, keys[0]);
Assert.AreEqual("A", keys[1]);
Assert.AreEqual("C", keys[2]);
Assert.AreEqual("E", keys[3]);
Assert.AreEqual(null, keys[4]);
}

[Test]
public void Keys_Remove()
{
Assert.Throws<ReadOnlyCollectionException>(() => dict.Keys.Remove("Foo"));
}

[Test]
public void Values_GetEnumerable()
{
var enumerable = dict.Values.GetEnumerator();
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual("1", enumerable.Current);
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual("2", enumerable.Current);
Assert.IsTrue(enumerable.MoveNext());
Assert.AreEqual("3", enumerable.Current);
Assert.IsFalse(enumerable.MoveNext());
}

[Test]
public void Values_Count()
{
Assert.AreEqual(3, dict.Values.Count);
dict.Remove("C");
Assert.AreEqual(2, dict.Values.Count);
}

[Test]
public void Values_IsReadOnly()
{
Assert.AreEqual(true, dict.Values.IsReadOnly);
}

[Test]
public void Values_Add()
{
Assert.Throws<ReadOnlyCollectionException>(() => dict.Values.Add("Foo"));
}

[Test]
public void Values_Clear()
{
Assert.Throws<ReadOnlyCollectionException>(() => dict.Values.Clear());
}

[Test]
public void Values_Contains()
{
Assert.IsTrue(dict.Values.Contains("1"));
Assert.IsFalse(dict.Values.Contains("9"));
}

[Test]
public void Values_CopyTo()
{
var values = new string[dict.Values.Count + 2];
dict.Values.CopyTo(values, 1);
Assert.AreEqual(null, values[0]);
Assert.AreEqual("1", values[1]);
Assert.AreEqual("2", values[2]);
Assert.AreEqual("3", values[3]);
Assert.AreEqual(null, values[4]);
}

[Test]
public void Values_Remove()
{
Assert.Throws<ReadOnlyCollectionException>(() => dict.Values.Remove("1"));
}
}
}
2 changes: 2 additions & 0 deletions C5.UserGuideExamples/Graph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,8 @@ internal EdgesValue(HashGraph<V, E, W> g)
_graph = g;
}

public override bool IsReadOnly => true;

public override bool IsEmpty => _graph.EdgeCount == 0;

public override int Count => _graph.EdgeCount;
Expand Down
2 changes: 2 additions & 0 deletions C5.UserGuideExamples/MultiCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public BasicCollectionValue(SCG.IEnumerable<T> e, Func<T> chooser, int c)
Count = c;
}

public override bool IsReadOnly => true;

public override int Count { get; }

public override Speed CountSpeed => Speed.Constant;
Expand Down
6 changes: 3 additions & 3 deletions C5/Arrays/ArrayList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ public override bool UnsequencedEquals(ICollection<T> that)
/// </summary>
/// <param name="item">The value to check for.</param>
/// <returns>True if the items is in this collection.</returns>
public virtual bool Contains(T item)
public override bool Contains(T item)
{ ValidityCheck(); return IndexOfInner(item) >= 0; }


Expand Down Expand Up @@ -1611,7 +1611,7 @@ public virtual bool UpdateOrAdd(T item, out T olditem)
/// </summary>
/// <param name="item">The value to remove.</param>
/// <returns>True if the item was found (and removed).</returns>
public virtual bool Remove(T item)
public override bool Remove(T item)
{
UpdateCheck();

Expand Down Expand Up @@ -2142,7 +2142,7 @@ public override bool Check()
/// </summary>
/// <param name="item">The item to add.</param>
/// <returns>True</returns>
public virtual bool Add(T item)
public override bool Add(T item)
{
UpdateCheck();

Expand Down
6 changes: 5 additions & 1 deletion C5/BaseClasses/ArrayBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ protected ArrayBase(int capacity, System.Collections.Generic.IEqualityComparer<T
/// <summary>
/// Remove all items and reset size of internal array container.
/// </summary>
public virtual void Clear()
public override void Clear()
{
UpdateCheck();
array = new T[8];
Expand Down Expand Up @@ -238,6 +238,10 @@ internal Range(ArrayBase<T> thebase, int start, int count, bool forwards)
/// <value>True if this collection is empty.</value>
public override bool IsEmpty { get { thebase.ModifyCheck(stamp); return count == 0; } }

/// <summary>
/// Gets a value indicating whether the <see cref="Range"/> is read-only. Always returns <c>true</c>.
/// </summary>
public override bool IsReadOnly => true;

/// <summary>
///
Expand Down
2 changes: 1 addition & 1 deletion C5/BaseClasses/CollectionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ protected virtual void UpdateCheck()
///
/// </summary>
/// <value>True if this collection is read only</value>
public virtual bool IsReadOnly => isReadOnlyBase;
public override bool IsReadOnly => isReadOnlyBase;

#endregion

Expand Down
43 changes: 43 additions & 0 deletions C5/BaseClasses/CollectionValueBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -653,5 +653,48 @@ public override string ToString()
{
return ToString(null, null);
}

#region SCG.ICollection<T> Members

/// <summary>
/// Gets a value indicating whether the <see cref="System.Collections.Generic.ICollection{T}"/> is read-only.
/// </summary>
public abstract bool IsReadOnly { get; }

/// <summary>
/// Adds an item to the <see cref="System.Collections.Generic.ICollection{T}"/>.
/// <para/>
/// The default implementation throws a <see cref="ReadOnlyCollectionException"/>. Override to provide an implementation.
/// </summary>
/// <param name="item">The object to add to the <see cref="System.Collections.Generic.ICollection{T}"/>.</param>
public virtual bool Add(T item) => throw new ReadOnlyCollectionException();

void System.Collections.Generic.ICollection<T>.Add(T item) => this.Add(item);

/// <summary>
/// Removes all items from the <see cref="System.Collections.Generic.ICollection{T}"/>.
/// <para/>
/// The default implementation throws a <see cref="ReadOnlyCollectionException"/>. Override to provide an implementation.
/// </summary>
public virtual void Clear() => throw new ReadOnlyCollectionException();

/// <summary>
/// Determines whether the <see cref="System.Collections.Generic.ICollection{T}"/> contains a specific value.
/// </summary>
/// <param name="item">The object to locate in the <see cref="System.Collections.Generic.ICollection{T}"/>.</param>
/// <returns><c>true</c> if item is found in the <see cref="System.Collections.Generic.ICollection{T}"/>; otherwise, <c>false</c>.</returns>
public virtual bool Contains(T item) => this.Exists((thisItem) => EqualityComparer<T>.Default.Equals(thisItem, item));

/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="System.Collections.Generic.ICollection{T}"/>.
/// <para/>
/// The default implementation throws a <see cref="ReadOnlyCollectionException"/>. Override to provide an implementation.
/// </summary>
/// <param name="item">The object to remove from the <see cref="System.Collections.Generic.ICollection{T}"/>.</param>
/// <returns><c>true</c> if item was successfully removed from the <see cref="System.Collections.Generic.ICollection{T}"/>; otherwise, <c>false</c>.
/// This method also returns <c>false</c> if item is not found in the original <see cref="System.Collections.Generic.ICollection{T}"/>.</returns>
public virtual bool Remove(T item) => throw new ReadOnlyCollectionException();

#endregion
}
}
Loading

0 comments on commit 85c788d

Please sign in to comment.