You've already forked linux-packaging-mono
Imported Upstream version 5.8.0.22
Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
parent
5f4a27cc8a
commit
7d05485754
@@ -10,7 +10,7 @@
|
||||
<SupportedFramework>net45;netcore45;netcoreapp1.0;wp8;wpa81;$(AllXamarinFrameworks)</SupportedFramework>
|
||||
</ProjectReference>
|
||||
<InboxOnTargetFramework Include="netcoreapp2.0" />
|
||||
<InboxOnTargetFramework Include="uap10.1" />
|
||||
<InboxOnTargetFramework Include="$(UAPvNextTFM)" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
@@ -37,6 +37,8 @@
|
||||
<Compile Include="System\Collections\Immutable\IImmutableQueue.cs" />
|
||||
<Compile Include="System\Collections\Immutable\IImmutableSet.cs" />
|
||||
<Compile Include="System\Collections\Immutable\IImmutableStack.cs" />
|
||||
<Compile Include="System\Collections\Immutable\ImmutableHashSet_1.HashBucketByValueEqualityComparer.cs" />
|
||||
<Compile Include="System\Collections\Immutable\ImmutableHashSet_1.HashBucketByRefEqualityComparer.cs" />
|
||||
<Compile Include="System\Collections\Immutable\IStrongEnumerable_2.cs" />
|
||||
<Compile Include="System\Collections\Immutable\IStrongEnumerator_1.cs" />
|
||||
<Compile Include="System\Collections\Immutable\IOrderedCollection.cs" />
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace System.Collections.Immutable
|
||||
/// <summary>
|
||||
/// Contains all the key/values in the collection that hash to the same value.
|
||||
/// </summary>
|
||||
internal struct HashBucket : IEnumerable<KeyValuePair<TKey, TValue>>, IEquatable<HashBucket>
|
||||
internal struct HashBucket : IEnumerable<KeyValuePair<TKey, TValue>>
|
||||
{
|
||||
/// <summary>
|
||||
/// One of the values in this bucket.
|
||||
@@ -110,12 +110,21 @@ namespace System.Collections.Immutable
|
||||
/// <summary>
|
||||
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
|
||||
/// </summary>
|
||||
bool IEquatable<HashBucket>.Equals(HashBucket other)
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// This should never be called, as hash buckets don't know how to equate themselves.
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// This should never be called, as hash buckets don't know how to hash themselves.
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified key.
|
||||
/// </summary>
|
||||
|
||||
@@ -16,6 +16,21 @@ namespace System.Collections.Immutable
|
||||
/// </summary>
|
||||
internal static partial class ImmutableExtensions
|
||||
{
|
||||
internal static bool IsValueType<T>()
|
||||
{
|
||||
if (default(T) != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Type t = typeof(T);
|
||||
if (t.IsConstructedGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if EqualsStructurally
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@ namespace System.Collections.Immutable
|
||||
/// </summary>
|
||||
private IEqualityComparer<T> _equalityComparer;
|
||||
|
||||
/// <summary>
|
||||
/// The equality comparer to use when balancing the tree of hash buckets.
|
||||
/// </summary>
|
||||
private IEqualityComparer<HashBucket> _hashBucketEqualityComparer;
|
||||
|
||||
/// <summary>
|
||||
/// The number of elements in this collection.
|
||||
/// </summary>
|
||||
@@ -69,6 +74,7 @@ namespace System.Collections.Immutable
|
||||
_root = set._root;
|
||||
_count = set._count;
|
||||
_equalityComparer = set._equalityComparer;
|
||||
_hashBucketEqualityComparer = set._hashBucketEqualityComparer;
|
||||
_immutable = set;
|
||||
}
|
||||
|
||||
@@ -113,7 +119,7 @@ namespace System.Collections.Immutable
|
||||
|
||||
if (value != _equalityComparer)
|
||||
{
|
||||
var result = Union(this, new MutationInput(SortedInt32KeyNode<HashBucket>.EmptyNode, value, 0));
|
||||
var result = Union(this, new MutationInput(SortedInt32KeyNode<HashBucket>.EmptyNode, value, _hashBucketEqualityComparer, 0));
|
||||
|
||||
_immutable = null;
|
||||
_equalityComparer = value;
|
||||
@@ -136,7 +142,7 @@ namespace System.Collections.Immutable
|
||||
/// </summary>
|
||||
private MutationInput Origin
|
||||
{
|
||||
get { return new MutationInput(this.Root, _equalityComparer, _count); }
|
||||
get { return new MutationInput(this.Root, _equalityComparer, _hashBucketEqualityComparer, _count); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -259,7 +265,7 @@ namespace System.Collections.Immutable
|
||||
/// <param name="other">The collection of items to remove from the set.</param>
|
||||
public void ExceptWith(IEnumerable<T> other)
|
||||
{
|
||||
var result = ImmutableHashSet<T>.Except(other, _equalityComparer, _root);
|
||||
var result = ImmutableHashSet<T>.Except(other, _equalityComparer, _hashBucketEqualityComparer, _root);
|
||||
this.Apply(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Collections.Immutable
|
||||
{
|
||||
@@ -76,6 +77,49 @@ namespace System.Collections.Immutable
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
|
||||
/// </summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// This should never be called, as hash buckets don't know how to equate themselves.
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception to catch any errors in comparing <see cref="HashBucket"/> instances.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// This should never be called, as hash buckets don't know how to hash themselves.
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this <see cref="HashBucket"/> is exactly like another one,
|
||||
/// comparing by reference. For use when type parameter T is an object.
|
||||
/// </summary>
|
||||
/// <param name="other">The other bucket.</param>
|
||||
/// <returns><c>true</c> if the two <see cref="HashBucket"/> structs have precisely the same values.</returns>
|
||||
internal bool EqualsByRef(HashBucket other)
|
||||
{
|
||||
return object.ReferenceEquals(_firstValue, other._firstValue)
|
||||
&& object.ReferenceEquals(_additionalElements, other._additionalElements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this <see cref="HashBucket"/> is exactly like another one,
|
||||
/// comparing by value. For use when type parameter T is a struct.
|
||||
/// </summary>
|
||||
/// <param name="other">The other bucket.</param>
|
||||
/// <param name="valueComparer">The comparer to use for the first value in the bucket.</param>
|
||||
/// <returns><c>true</c> if the two <see cref="HashBucket"/> structs have precisely the same values.</returns>
|
||||
internal bool EqualsByValue(HashBucket other, IEqualityComparer<T> valueComparer)
|
||||
{
|
||||
return valueComparer.Equals(_firstValue, other._firstValue)
|
||||
&& object.ReferenceEquals(_additionalElements, other._additionalElements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified value.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System.Collections.Immutable
|
||||
{
|
||||
/// <content>
|
||||
/// Contains the inner <see cref="ImmutableHashSet{T}.HashBucketByRefEqualityComparer"/> class.
|
||||
/// </content>
|
||||
public sealed partial class ImmutableHashSet<T> : IImmutableSet<T>, IHashKeyCollection<T>, IReadOnlyCollection<T>, ICollection<T>, ISet<T>, ICollection, IStrongEnumerable<T, ImmutableHashSet<T>.Enumerator>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares equality between two <see cref="HashBucket"/> instances
|
||||
/// by reference.
|
||||
/// </summary>
|
||||
private class HashBucketByRefEqualityComparer : IEqualityComparer<HashBucket>
|
||||
{
|
||||
/// <summary>
|
||||
/// The singleton instance.
|
||||
/// </summary>
|
||||
private static readonly IEqualityComparer<HashBucket> s_defaultInstance = new HashBucketByRefEqualityComparer();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton instance to use.
|
||||
/// </summary>
|
||||
internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="HashBucketByRefEqualityComparer"/> class from being created.
|
||||
/// </summary>
|
||||
private HashBucketByRefEqualityComparer()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(HashBucket x, HashBucket y) => x.EqualsByRef(y);
|
||||
|
||||
/// <inheritdoc />
|
||||
public int GetHashCode(HashBucket obj) => throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System.Collections.Immutable
|
||||
{
|
||||
/// <content>
|
||||
/// Contains the inner <see cref="ImmutableHashSet{T}.HashBucketByValueEqualityComparer"/> class.
|
||||
/// </content>
|
||||
public sealed partial class ImmutableHashSet<T> : IImmutableSet<T>, IHashKeyCollection<T>, IReadOnlyCollection<T>, ICollection<T>, ISet<T>, ICollection, IStrongEnumerable<T, ImmutableHashSet<T>.Enumerator>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares equality between two <see cref="HashBucket"/> instances
|
||||
/// by value.
|
||||
/// </summary>
|
||||
private class HashBucketByValueEqualityComparer : IEqualityComparer<HashBucket>
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance to use when the value comparer is <see cref="EqualityComparer{T}.Default"/>.
|
||||
/// </summary>
|
||||
private static readonly IEqualityComparer<HashBucket> s_defaultInstance = new HashBucketByValueEqualityComparer(EqualityComparer<T>.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance to use when the value comparer is
|
||||
/// <see cref="EqualityComparer{T}.Default"/>.
|
||||
/// </summary>
|
||||
internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;
|
||||
|
||||
/// <summary>
|
||||
/// The value comparer to use when comparing two T instances.
|
||||
/// </summary>
|
||||
private readonly IEqualityComparer<T> _valueComparer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HashBucketByValueEqualityComparer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="valueComparer">The value comparer for T.</param>
|
||||
internal HashBucketByValueEqualityComparer(IEqualityComparer<T> valueComparer)
|
||||
{
|
||||
Requires.NotNull(valueComparer, nameof(valueComparer));
|
||||
_valueComparer = valueComparer;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(HashBucket x, HashBucket y) => x.EqualsByValue(y, _valueComparer);
|
||||
|
||||
/// <inheritdoc />
|
||||
public int GetHashCode(HashBucket obj) => throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,11 @@ namespace System.Collections.Immutable
|
||||
/// </summary>
|
||||
private readonly int _count;
|
||||
|
||||
/// <summary>
|
||||
/// The equality comparer to use when checking for <see cref="HashBucket"/> equality.
|
||||
/// </summary>
|
||||
private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImmutableHashSet{T}.MutationInput"/> struct.
|
||||
/// </summary>
|
||||
@@ -42,6 +47,7 @@ namespace System.Collections.Immutable
|
||||
_root = set._root;
|
||||
_equalityComparer = set._equalityComparer;
|
||||
_count = set._count;
|
||||
_hashBucketEqualityComparer = set._hashBucketEqualityComparer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,15 +55,19 @@ namespace System.Collections.Immutable
|
||||
/// </summary>
|
||||
/// <param name="root">The root.</param>
|
||||
/// <param name="equalityComparer">The equality comparer.</param>
|
||||
/// <param name="hashBucketEqualityComparer">The equality comparer to use when checking for <see cref="HashBucket"/> equality.</param>
|
||||
/// <param name="count">The count.</param>
|
||||
internal MutationInput(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, int count)
|
||||
internal MutationInput(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, IEqualityComparer<HashBucket> hashBucketEqualityComparer, int count)
|
||||
{
|
||||
Requires.NotNull(root, nameof(root));
|
||||
Requires.NotNull(equalityComparer, nameof(equalityComparer));
|
||||
Requires.Range(count >= 0, nameof(count));
|
||||
Requires.NotNull(hashBucketEqualityComparer, nameof(hashBucketEqualityComparer));
|
||||
|
||||
_root = root;
|
||||
_equalityComparer = equalityComparer;
|
||||
_count = count;
|
||||
_hashBucketEqualityComparer = hashBucketEqualityComparer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,6 +93,11 @@ namespace System.Collections.Immutable
|
||||
{
|
||||
get { return _count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the equality comparer to use when checking for <see cref="HashBucket"/> equality.
|
||||
/// </summary>
|
||||
internal IEqualityComparer<HashBucket> HashBucketEqualityComparer => _hashBucketEqualityComparer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ namespace System.Collections.Immutable
|
||||
/// </summary>
|
||||
private readonly SortedInt32KeyNode<HashBucket> _root;
|
||||
|
||||
/// <summary>
|
||||
/// The equality comparer to use when balancing the tree of hash buckets.
|
||||
/// </summary>
|
||||
private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImmutableHashSet{T}"/> class.
|
||||
/// </summary>
|
||||
@@ -68,6 +73,7 @@ namespace System.Collections.Immutable
|
||||
_root = root;
|
||||
_count = count;
|
||||
_equalityComparer = equalityComparer;
|
||||
_hashBucketEqualityComparer = GetHashBucketEqualityComparer(equalityComparer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -213,7 +219,7 @@ namespace System.Collections.Immutable
|
||||
/// <param name="actualValue">The value from the set that the search found, or the original value if the search yielded no match.</param>
|
||||
/// <returns>A value indicating whether the search was successful.</returns>
|
||||
/// <remarks>
|
||||
/// This can be useful when you want to reuse a previously stored reference instead of
|
||||
/// This can be useful when you want to reuse a previously stored reference instead of
|
||||
/// a newly constructed one (so that more sharing of references can occur) or to look up
|
||||
/// a value that has more complete data than the value you currently have, although their
|
||||
/// comparer functions indicate they are equal.
|
||||
@@ -264,7 +270,7 @@ namespace System.Collections.Immutable
|
||||
{
|
||||
Requires.NotNull(other, nameof(other));
|
||||
|
||||
var result = Except(other, _equalityComparer, _root);
|
||||
var result = Except(other, _equalityComparer, _hashBucketEqualityComparer, _root);
|
||||
return result.Finalize(this);
|
||||
}
|
||||
|
||||
@@ -648,7 +654,7 @@ namespace System.Collections.Immutable
|
||||
return new MutationResult(origin.Root, 0);
|
||||
}
|
||||
|
||||
var newRoot = UpdateRoot(origin.Root, hashCode, newBucket);
|
||||
var newRoot = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket);
|
||||
Debug.Assert(result == OperationResult.SizeChanged);
|
||||
return new MutationResult(newRoot, 1 /*result == OperationResult.SizeChanged ? 1 : 0*/);
|
||||
}
|
||||
@@ -670,7 +676,7 @@ namespace System.Collections.Immutable
|
||||
return new MutationResult(origin.Root, 0);
|
||||
}
|
||||
|
||||
newRoot = UpdateRoot(origin.Root, hashCode, newBucket);
|
||||
newRoot = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket);
|
||||
}
|
||||
|
||||
return new MutationResult(newRoot, result == OperationResult.SizeChanged ? -1 : 0);
|
||||
@@ -708,7 +714,7 @@ namespace System.Collections.Immutable
|
||||
var newBucket = bucket.Add(item, origin.EqualityComparer, out result);
|
||||
if (result == OperationResult.SizeChanged)
|
||||
{
|
||||
newRoot = UpdateRoot(newRoot, hashCode, newBucket);
|
||||
newRoot = UpdateRoot(newRoot, hashCode, origin.HashBucketEqualityComparer, newBucket);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -769,7 +775,7 @@ namespace System.Collections.Immutable
|
||||
/// <summary>
|
||||
/// Performs the set operation on a given data structure.
|
||||
/// </summary>
|
||||
private static SortedInt32KeyNode<HashBucket> UpdateRoot(SortedInt32KeyNode<HashBucket> root, int hashCode, HashBucket newBucket)
|
||||
private static SortedInt32KeyNode<HashBucket> UpdateRoot(SortedInt32KeyNode<HashBucket> root, int hashCode, IEqualityComparer<HashBucket> hashBucketEqualityComparer, HashBucket newBucket)
|
||||
{
|
||||
bool mutated;
|
||||
if (newBucket.IsEmpty)
|
||||
@@ -778,8 +784,7 @@ namespace System.Collections.Immutable
|
||||
}
|
||||
else
|
||||
{
|
||||
bool replacedExistingValue;
|
||||
return root.SetItem(hashCode, newBucket, EqualityComparer<HashBucket>.Default, out replacedExistingValue, out mutated);
|
||||
return root.SetItem(hashCode, newBucket, hashBucketEqualityComparer, out bool replacedExistingValue, out mutated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,7 +801,7 @@ namespace System.Collections.Immutable
|
||||
{
|
||||
if (Contains(item, origin))
|
||||
{
|
||||
var result = Add(item, new MutationInput(newSet, origin.EqualityComparer, count));
|
||||
var result = Add(item, new MutationInput(newSet, origin.EqualityComparer, origin.HashBucketEqualityComparer, count));
|
||||
newSet = result.Root;
|
||||
count += result.Count;
|
||||
}
|
||||
@@ -808,7 +813,7 @@ namespace System.Collections.Immutable
|
||||
/// <summary>
|
||||
/// Performs the set operation on a given data structure.
|
||||
/// </summary>
|
||||
private static MutationResult Except(IEnumerable<T> other, IEqualityComparer<T> equalityComparer, SortedInt32KeyNode<HashBucket> root)
|
||||
private static MutationResult Except(IEnumerable<T> other, IEqualityComparer<T> equalityComparer, IEqualityComparer<HashBucket> hashBucketEqualityComparer, SortedInt32KeyNode<HashBucket> root)
|
||||
{
|
||||
Requires.NotNull(other, nameof(other));
|
||||
Requires.NotNull(equalityComparer, nameof(equalityComparer));
|
||||
@@ -827,7 +832,7 @@ namespace System.Collections.Immutable
|
||||
if (result == OperationResult.SizeChanged)
|
||||
{
|
||||
count--;
|
||||
newRoot = UpdateRoot(newRoot, hashCode, newBucket);
|
||||
newRoot = UpdateRoot(newRoot, hashCode, hashBucketEqualityComparer, newBucket);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -851,7 +856,7 @@ namespace System.Collections.Immutable
|
||||
{
|
||||
if (!otherAsSet.Contains(item))
|
||||
{
|
||||
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, count));
|
||||
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, origin.HashBucketEqualityComparer, count));
|
||||
result = mutationResult.Root;
|
||||
count += mutationResult.Count;
|
||||
}
|
||||
@@ -861,7 +866,7 @@ namespace System.Collections.Immutable
|
||||
{
|
||||
if (!Contains(item, origin))
|
||||
{
|
||||
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, count));
|
||||
var mutationResult = Add(item, new MutationInput(result, origin.EqualityComparer, origin.HashBucketEqualityComparer, count));
|
||||
result = mutationResult.Root;
|
||||
count += mutationResult.Count;
|
||||
}
|
||||
@@ -993,6 +998,27 @@ namespace System.Collections.Immutable
|
||||
return new ImmutableHashSet<T>(root, equalityComparer, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IEqualityComparer{HashBucket}"/> to use.
|
||||
/// </summary>
|
||||
/// <param name="valueComparer">The value comparer for T.</param>
|
||||
/// <returns>The equality comparer to use.</returns>
|
||||
private static IEqualityComparer<HashBucket> GetHashBucketEqualityComparer(IEqualityComparer<T> valueComparer)
|
||||
{
|
||||
if (!ImmutableExtensions.IsValueType<T>())
|
||||
{
|
||||
return HashBucketByRefEqualityComparer.DefaultInstance;
|
||||
}
|
||||
else if (valueComparer == EqualityComparer<T>.Default)
|
||||
{
|
||||
return HashBucketByValueEqualityComparer.DefaultInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new HashBucketByValueEqualityComparer(valueComparer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the specified data structure with an immutable collection wrapper.
|
||||
/// </summary>
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace System.Collections.Immutable.Tests
|
||||
// Now check where collisions have conflicting values.
|
||||
builder = ImmutableDictionary.Create<string, string>()
|
||||
.Add("a", "1").Add("A", "2").Add("b", "3").ToBuilder();
|
||||
Assert.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// Force all values to be considered equal.
|
||||
builder.ValueComparer = EverythingEqual<string>.Default;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace System.Collections.Immutable.Tests
|
||||
{
|
||||
var builder = this.GetBuilder<string, int>();
|
||||
builder.Add("five", 5);
|
||||
Assert.Throws<ArgumentException>(null, () => builder.Add("five", 6));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => builder.Add("five", 6));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace System.Collections.Immutable.Tests
|
||||
// Now check where collisions have conflicting values.
|
||||
map = ImmutableDictionary.Create<string, string>()
|
||||
.Add("a", "1").Add("A", "2").Add("b", "3");
|
||||
Assert.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
|
||||
|
||||
// Force all values to be considered equal.
|
||||
map = map.WithComparers(StringComparer.OrdinalIgnoreCase, EverythingEqual<string>.Default);
|
||||
@@ -279,7 +279,7 @@ namespace System.Collections.Immutable.Tests
|
||||
{
|
||||
var map = ImmutableDictionary.Create<string, string>()
|
||||
.Add("firstKey", "1").Add("secondKey", "2");
|
||||
var exception = Assert.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
|
||||
var exception = AssertExtensions.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
|
||||
|
||||
if (!PlatformDetection.IsNetNative) //.Net Native toolchain removes exception messages.
|
||||
{
|
||||
|
||||
@@ -466,8 +466,8 @@ namespace System.Collections.Immutable.Tests
|
||||
|
||||
var map1 = map.Add(key, value1);
|
||||
var map2 = map.Add(key, value2);
|
||||
Assert.Throws<ArgumentException>(null, () => map1.Add(key, value2));
|
||||
Assert.Throws<ArgumentException>(null, () => map2.Add(key, value1));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => map1.Add(key, value2));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => map2.Add(key, value1));
|
||||
}
|
||||
|
||||
protected void ContainsKeyTestHelper<TKey, TValue>(IImmutableDictionary<TKey, TValue> map, TKey key, TValue value)
|
||||
|
||||
@@ -64,13 +64,19 @@ namespace System.Collections.Immutable.Tests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[ActiveIssue("https://github.com/dotnet/corefx/issues/19044 - HashBucket.Equals() always returning true", TargetFrameworkMonikers.UapAot)]
|
||||
public void EnumeratorWithHashCollisionsTest()
|
||||
{
|
||||
var emptySet = this.EmptyTyped<int>().WithComparer(new BadHasher<int>());
|
||||
this.EnumeratorTestHelper(emptySet, null, 3, 1, 5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnumeratorWithHashCollisionsTest_RefType()
|
||||
{
|
||||
var emptySet = this.EmptyTyped<string>().WithComparer(new BadHasher<string>());
|
||||
this.EnumeratorTestHelper(emptySet, null, "c", "a", "e");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnumeratorRecyclingMisuse()
|
||||
{
|
||||
@@ -148,7 +154,6 @@ namespace System.Collections.Immutable.Tests
|
||||
/// that *is* in the set.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
[ActiveIssue("https://github.com/dotnet/corefx/issues/19044 - HashBucket.Equals() always returning true", TargetFrameworkMonikers.UapAot)]
|
||||
public void RemoveValuesFromCollidedHashCode()
|
||||
{
|
||||
var set = ImmutableHashSet.Create<int>(new BadHasher<int>(), 5, 6);
|
||||
@@ -158,6 +163,21 @@ namespace System.Collections.Immutable.Tests
|
||||
Assert.Equal(new[] { 6 }, setAfterRemovingFive);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the non-removal of an item that does not belong to the set,
|
||||
/// but which happens to have a colliding hash code with another value
|
||||
/// that *is* in the set.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void RemoveValuesFromCollidedHashCode_RefType()
|
||||
{
|
||||
var set = ImmutableHashSet.Create<string>(new BadHasher<string>(), "a", "b");
|
||||
Assert.Same(set, set.Remove("c"));
|
||||
var setAfterRemovingA = set.Remove("a");
|
||||
Assert.Equal(1, setAfterRemovingA.Count);
|
||||
Assert.Equal(new[] { "b" }, setAfterRemovingA);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetValueTest()
|
||||
{
|
||||
@@ -176,7 +196,7 @@ namespace System.Collections.Immutable.Tests
|
||||
public void SymmetricExceptWithComparerTests()
|
||||
{
|
||||
var set = ImmutableHashSet.Create<string>("a").WithComparer(StringComparer.OrdinalIgnoreCase);
|
||||
var otherCollection = new[] {"A"};
|
||||
var otherCollection = new[] { "A" };
|
||||
|
||||
var expectedSet = new HashSet<string>(set, set.KeyComparer);
|
||||
expectedSet.SymmetricExceptWith(otherCollection);
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace System.Collections.Immutable.Tests
|
||||
// Now check where collisions have conflicting values.
|
||||
builder = ImmutableSortedDictionary.Create<string, string>()
|
||||
.Add("a", "1").Add("A", "2").Add("b", "3").ToBuilder();
|
||||
Assert.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => builder.KeyComparer = StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// Force all values to be considered equal.
|
||||
builder.ValueComparer = EverythingEqual<string>.Default;
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace System.Collections.Immutable.Tests
|
||||
};
|
||||
|
||||
var map = Empty<string, string>(StringComparer.Ordinal, StringComparer.Ordinal);
|
||||
Assert.Throws<ArgumentException>(null, () => map.AddRange(uniqueEntries));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => map.AddRange(uniqueEntries));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -294,7 +294,7 @@ namespace System.Collections.Immutable.Tests
|
||||
// Now check where collisions have conflicting values.
|
||||
map = ImmutableSortedDictionary.Create<string, string>()
|
||||
.Add("a", "1").Add("A", "2").Add("b", "3");
|
||||
Assert.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => map.WithComparers(StringComparer.OrdinalIgnoreCase));
|
||||
|
||||
// Force all values to be considered equal.
|
||||
map = map.WithComparers(StringComparer.OrdinalIgnoreCase, EverythingEqual<string>.Default);
|
||||
@@ -310,7 +310,7 @@ namespace System.Collections.Immutable.Tests
|
||||
{
|
||||
var map = ImmutableSortedDictionary.Create<string, string>()
|
||||
.Add("firstKey", "1").Add("secondKey", "2");
|
||||
var exception = Assert.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
|
||||
var exception = AssertExtensions.Throws<ArgumentException>(null, () => map.Add("firstKey", "3"));
|
||||
if (!PlatformDetection.IsNetNative) //.Net Native toolchain removes exception messages.
|
||||
{
|
||||
Assert.Contains("firstKey", exception.Message);
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace System.Collections.Immutable.Tests
|
||||
{
|
||||
Requires.Argument(true);
|
||||
Requires.Argument(true, "parameterName", "message");
|
||||
Assert.Throws<ArgumentException>(null, () => Requires.Argument(false));
|
||||
AssertExtensions.Throws<ArgumentException>(null, () => Requires.Argument(false));
|
||||
AssertExtensions.Throws<ArgumentException>("parameterName", () => Requires.Argument(false, "parameterName", "message"));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Library>
|
||||
<!-- Needed because of objects in [Theory] data which causes xunit to reflect on its ToString() -->
|
||||
<Type Name="System.Collections.Generic.ComparisonComparer<T>" Dynamic="Required Public" />
|
||||
<Type Name="System.Collections.Generic.ComparisonComparer`1" Dynamic="Required Public" />
|
||||
<Type Name="System.Collections.Generic.GenericComparer`1" Dynamic="Required Public" />
|
||||
<Type Name="System.Collections.Generic.GenericEqualityComparer`1" Dynamic="Required Public" />
|
||||
<Type Name="System.Collections.Generic.ObjectComparer`1" Dynamic="Required Public" />
|
||||
</Library>
|
||||
</Directives>
|
||||
|
||||
|
||||
@@ -48,9 +48,6 @@
|
||||
<Compile Include="RequiresTests.cs" />
|
||||
<Compile Include="SimpleElementImmutablesTestBase.cs" />
|
||||
<Compile Include="TestExtensionsMethods.cs" />
|
||||
<Compile Include="$(CommonTestPath)\System\AssertExtensions.cs">
|
||||
<Link>Common\System\AssertExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonTestPath)\System\Diagnostics\DebuggerAttributes.cs">
|
||||
<Link>Common\System\Diagnostics\DebuggerAttributes.cs</Link>
|
||||
</Compile>
|
||||
|
||||
Reference in New Issue
Block a user