FrozenSetInternalBase<T, TThisWrapper>
abstract class FrozenSetInternalBase<T, TThisWrapper> : FrozenSet<T> where TThisWrapper : struct, IGenericSpecializedWrapper<T, TThisWrapper>
using System.Buffers;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
namespace System.Collections.Frozen
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
internal abstract class FrozenSetInternalBase<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TThisWrapper> : FrozenSet<T> where TThisWrapper : struct, FrozenSetInternalBase<T, TThisWrapper>.IGenericSpecializedWrapper
{
internal interface IGenericSpecializedWrapper
{
int Count { get; }
IEqualityComparer<T> Comparer { get; }
void Store(FrozenSet<T> this);
int FindItemIndex(T item);
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
Enumerator GetEnumerator();
}
private readonly TThisWrapper _thisSet;
protected FrozenSetInternalBase(IEqualityComparer<T> comparer)
: base(comparer)
{
_thisSet = default(TThisWrapper);
_thisSet.Store(this);
}
private protected override bool IsProperSubsetOfCore(IEnumerable<T> other)
{
ICollection<T> collection = other as ICollection<T>;
TThisWrapper thisSet;
if (collection != null) {
int count = collection.Count;
if (count == 0)
return false;
System.Collections.Generic.IReadOnlySet<T> readOnlySet = other as System.Collections.Generic.IReadOnlySet<T>;
if (readOnlySet != null && ComparersAreCompatible(readOnlySet)) {
thisSet = _thisSet;
if (thisSet.Count < count)
return IsSubsetOfSetWithCompatibleComparer(readOnlySet);
return false;
}
}
KeyValuePairExtensions.Deconstruct<int, int>(CheckUniqueAndUnfoundElements(other, false), out int key, out int value);
int num = key;
int num2 = value;
thisSet = _thisSet;
if (num == thisSet.Count)
return num2 > 0;
return false;
}
private protected override bool IsProperSupersetOfCore(IEnumerable<T> other)
{
ICollection<T> collection = other as ICollection<T>;
TThisWrapper thisSet;
if (collection != null) {
int count = collection.Count;
if (count == 0)
return true;
System.Collections.Generic.IReadOnlySet<T> readOnlySet = other as System.Collections.Generic.IReadOnlySet<T>;
if (readOnlySet != null && ComparersAreCompatible(readOnlySet)) {
thisSet = _thisSet;
if (thisSet.Count > count)
return ContainsAllElements(readOnlySet);
return false;
}
}
KeyValuePairExtensions.Deconstruct<int, int>(CheckUniqueAndUnfoundElements(other, true), out int key, out int value);
int num = key;
int num2 = value;
thisSet = _thisSet;
if (num < thisSet.Count)
return num2 == 0;
return false;
}
private protected override bool IsSubsetOfCore(IEnumerable<T> other)
{
System.Collections.Generic.IReadOnlySet<T> readOnlySet = other as System.Collections.Generic.IReadOnlySet<T>;
TThisWrapper thisSet;
if (readOnlySet != null && ComparersAreCompatible(readOnlySet)) {
thisSet = _thisSet;
if (thisSet.Count <= readOnlySet.Count)
return IsSubsetOfSetWithCompatibleComparer(readOnlySet);
return false;
}
KeyValuePairExtensions.Deconstruct<int, int>(CheckUniqueAndUnfoundElements(other, false), out int key, out int value);
int num = key;
int num2 = value;
thisSet = _thisSet;
if (num == thisSet.Count)
return num2 >= 0;
return false;
}
private protected override bool IsSupersetOfCore(IEnumerable<T> other)
{
ICollection<T> collection = other as ICollection<T>;
if (collection != null) {
int count = collection.Count;
if (count == 0)
return true;
System.Collections.Generic.IReadOnlySet<T> readOnlySet = other as System.Collections.Generic.IReadOnlySet<T>;
if (readOnlySet != null && count > _thisSet.Count && ComparersAreCompatible(readOnlySet))
return false;
}
return ContainsAllElements(other);
}
private protected override bool OverlapsCore(IEnumerable<T> other)
{
foreach (T item in other) {
if (_thisSet.FindItemIndex(item) >= 0)
return true;
}
return false;
}
private protected override bool SetEqualsCore(IEnumerable<T> other)
{
System.Collections.Generic.IReadOnlySet<T> readOnlySet = other as System.Collections.Generic.IReadOnlySet<T>;
TThisWrapper thisSet;
if (readOnlySet != null && ComparersAreCompatible(readOnlySet)) {
thisSet = _thisSet;
if (thisSet.Count == readOnlySet.Count)
return ContainsAllElements(readOnlySet);
return false;
}
KeyValuePairExtensions.Deconstruct<int, int>(CheckUniqueAndUnfoundElements(other, true), out int key, out int value);
int num = key;
int num2 = value;
thisSet = _thisSet;
if (num == thisSet.Count)
return num2 == 0;
return false;
}
private bool ComparersAreCompatible(System.Collections.Generic.IReadOnlySet<T> other)
{
HashSet<T> hashSet = other as HashSet<T>;
TThisWrapper thisSet;
if (hashSet != null) {
thisSet = _thisSet;
return thisSet.Comparer.Equals(hashSet.Comparer);
}
SortedSet<T> sortedSet = other as SortedSet<T>;
if (sortedSet != null) {
thisSet = _thisSet;
return thisSet.Comparer.Equals(sortedSet.Comparer);
}
ImmutableHashSet<T> immutableHashSet = other as ImmutableHashSet<T>;
if (immutableHashSet != null) {
thisSet = _thisSet;
return thisSet.Comparer.Equals(immutableHashSet.KeyComparer);
}
ImmutableSortedSet<T> immutableSortedSet = other as ImmutableSortedSet<T>;
if (immutableSortedSet != null) {
thisSet = _thisSet;
return thisSet.Comparer.Equals(immutableSortedSet.KeyComparer);
}
FrozenSet<T> frozenSet = other as FrozenSet<T>;
if (frozenSet != null) {
thisSet = _thisSet;
return thisSet.Comparer.Equals(frozenSet.Comparer);
}
return false;
}
private unsafe KeyValuePair<int, int> CheckUniqueAndUnfoundElements(IEnumerable<T> other, bool returnIfUnfound)
{
TThisWrapper thisSet = _thisSet;
int num = thisSet.Count / 32 + 1;
int[] array = null;
Span<int> span = (num > 128) ? ((Span<int>)(array = ArrayPool<int>.Shared.Rent(num))) : new Span<int>(stackalloc byte[512], 128);
Span<int> span2 = span;
span2 = span2.Slice(0, num);
span2.Clear();
int num2 = 0;
int num3 = 0;
foreach (T item in other) {
thisSet = _thisSet;
int num4 = thisSet.FindItemIndex(item);
if (num4 >= 0) {
if ((span2[num4 / 32] & (1 << num4)) == 0) {
span2[num4 / 32] |= 1 << num4;
num3++;
}
} else {
num2++;
if (returnIfUnfound)
break;
}
}
if (array != null)
ArrayPool<int>.Shared.Return(array, false);
return new KeyValuePair<int, int>(num3, num2);
}
private bool ContainsAllElements(IEnumerable<T> other)
{
foreach (T item in other) {
if (_thisSet.FindItemIndex(item) < 0)
return false;
}
return true;
}
private bool IsSubsetOfSetWithCompatibleComparer(System.Collections.Generic.IReadOnlySet<T> other)
{
foreach (T item in _thisSet) {
if (!other.Contains(item))
return false;
}
return true;
}
}
}