767 lines
18 KiB
C#
767 lines
18 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using Microsoft.CodeAnalysis.Collections.Internal;
|
|
|
|
namespace Microsoft.CodeAnalysis.Collections;
|
|
|
|
internal static class ImmutableSegmentedHashSet
|
|
{
|
|
public static ImmutableSegmentedHashSet<T> Create<T>()
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty;
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> Create<T>(T item)
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.Add(item);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> Create<T>(params T[] items)
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.Union(items);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> Create<T>(IEqualityComparer<T>? equalityComparer)
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.WithComparer(equalityComparer);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> Create<T>(IEqualityComparer<T>? equalityComparer, T item)
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.WithComparer(equalityComparer).Add(item);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> Create<T>(IEqualityComparer<T>? equalityComparer, params T[] items)
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.WithComparer(equalityComparer).Union(items);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T>.Builder CreateBuilder<T>()
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.ToBuilder();
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T>.Builder CreateBuilder<T>(IEqualityComparer<T>? equalityComparer)
|
|
{
|
|
return ImmutableSegmentedHashSet<T>.Empty.WithComparer(equalityComparer).ToBuilder();
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> CreateRange<T>(IEnumerable<T> items)
|
|
{
|
|
if (items is ImmutableSegmentedHashSet<T> immutableSegmentedHashSet)
|
|
{
|
|
return immutableSegmentedHashSet.WithComparer(null);
|
|
}
|
|
return ImmutableSegmentedHashSet<T>.Empty.Union(items);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<T> CreateRange<T>(IEqualityComparer<T>? equalityComparer, IEnumerable<T> items)
|
|
{
|
|
if (items is ImmutableSegmentedHashSet<T> immutableSegmentedHashSet)
|
|
{
|
|
return immutableSegmentedHashSet.WithComparer(equalityComparer);
|
|
}
|
|
return ImmutableSegmentedHashSet<T>.Empty.WithComparer(equalityComparer).Union(items);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<TSource> ToImmutableSegmentedHashSet<TSource>(this IEnumerable<TSource> source)
|
|
{
|
|
if (source is ImmutableSegmentedHashSet<TSource> immutableSegmentedHashSet)
|
|
{
|
|
return immutableSegmentedHashSet.WithComparer(null);
|
|
}
|
|
return ImmutableSegmentedHashSet<TSource>.Empty.Union(source);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<TSource> ToImmutableSegmentedHashSet<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource>? equalityComparer)
|
|
{
|
|
if (source is ImmutableSegmentedHashSet<TSource> immutableSegmentedHashSet)
|
|
{
|
|
return immutableSegmentedHashSet.WithComparer(equalityComparer);
|
|
}
|
|
return ImmutableSegmentedHashSet<TSource>.Empty.WithComparer(equalityComparer).Union(source);
|
|
}
|
|
|
|
public static ImmutableSegmentedHashSet<TSource> ToImmutableSegmentedHashSet<TSource>(this ImmutableSegmentedHashSet<TSource>.Builder builder)
|
|
{
|
|
if (builder == null)
|
|
{
|
|
throw new ArgumentNullException("builder");
|
|
}
|
|
return builder.ToImmutable();
|
|
}
|
|
}
|
|
internal readonly struct ImmutableSegmentedHashSet<T> : IImmutableSet<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, ISet<T>, ICollection<T>, ICollection, IEquatable<ImmutableSegmentedHashSet<T>>
|
|
{
|
|
public sealed class Builder : ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>
|
|
{
|
|
private ImmutableSegmentedHashSet<T> _set;
|
|
|
|
private SegmentedHashSet<T>? _mutableSet;
|
|
|
|
public IEqualityComparer<T> KeyComparer
|
|
{
|
|
get
|
|
{
|
|
return ReadOnlySet.Comparer;
|
|
}
|
|
set
|
|
{
|
|
if (!object.Equals(KeyComparer, value ?? EqualityComparer<T>.Default))
|
|
{
|
|
_mutableSet = new SegmentedHashSet<T>(ReadOnlySet, value ?? EqualityComparer<T>.Default);
|
|
_set = default(ImmutableSegmentedHashSet<T>);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int Count => ReadOnlySet.Count;
|
|
|
|
private SegmentedHashSet<T> ReadOnlySet => _mutableSet ?? _set._set;
|
|
|
|
bool ICollection<T>.IsReadOnly => false;
|
|
|
|
internal Builder(ImmutableSegmentedHashSet<T> set)
|
|
{
|
|
_set = set;
|
|
_mutableSet = null;
|
|
}
|
|
|
|
private SegmentedHashSet<T> GetOrCreateMutableSet()
|
|
{
|
|
if (_mutableSet == null)
|
|
{
|
|
ImmutableSegmentedHashSet<T> immutableSegmentedHashSet = RoslynImmutableInterlocked.InterlockedExchange(ref _set, default(ImmutableSegmentedHashSet<T>));
|
|
if (immutableSegmentedHashSet.IsDefault)
|
|
{
|
|
throw new InvalidOperationException($"Unexpected concurrent access to {GetType()}");
|
|
}
|
|
_mutableSet = new SegmentedHashSet<T>(immutableSegmentedHashSet._set, immutableSegmentedHashSet.KeyComparer);
|
|
}
|
|
return _mutableSet;
|
|
}
|
|
|
|
public bool Add(T item)
|
|
{
|
|
if (_mutableSet == null && Contains(item))
|
|
{
|
|
return false;
|
|
}
|
|
return GetOrCreateMutableSet().Add(item);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
if (ReadOnlySet.Count != 0)
|
|
{
|
|
if (_mutableSet == null)
|
|
{
|
|
_mutableSet = new SegmentedHashSet<T>(KeyComparer);
|
|
_set = default(ImmutableSegmentedHashSet<T>);
|
|
}
|
|
else
|
|
{
|
|
_mutableSet.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool Contains(T item)
|
|
{
|
|
return ReadOnlySet.Contains(item);
|
|
}
|
|
|
|
public void ExceptWith(IEnumerable<T> other)
|
|
{
|
|
if (other == null)
|
|
{
|
|
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.other);
|
|
}
|
|
if (_mutableSet != null)
|
|
{
|
|
_mutableSet.ExceptWith(other);
|
|
return;
|
|
}
|
|
if (other == this)
|
|
{
|
|
Clear();
|
|
return;
|
|
}
|
|
if (other is ImmutableSegmentedHashSet<T> immutableSegmentedHashSet)
|
|
{
|
|
if (immutableSegmentedHashSet == _set)
|
|
{
|
|
Clear();
|
|
}
|
|
else if (!immutableSegmentedHashSet.IsEmpty)
|
|
{
|
|
GetOrCreateMutableSet().ExceptWith(immutableSegmentedHashSet._set);
|
|
}
|
|
return;
|
|
}
|
|
SegmentedHashSet<T> segmentedHashSet = null;
|
|
foreach (T item in other)
|
|
{
|
|
if (segmentedHashSet == null)
|
|
{
|
|
if (!ReadOnlySet.Contains(item))
|
|
{
|
|
continue;
|
|
}
|
|
segmentedHashSet = GetOrCreateMutableSet();
|
|
}
|
|
segmentedHashSet.Remove(item);
|
|
}
|
|
}
|
|
|
|
public Enumerator GetEnumerator()
|
|
{
|
|
return new Enumerator(GetOrCreateMutableSet());
|
|
}
|
|
|
|
public void IntersectWith(IEnumerable<T> other)
|
|
{
|
|
GetOrCreateMutableSet().IntersectWith(other);
|
|
}
|
|
|
|
public bool IsProperSubsetOf(IEnumerable<T> other)
|
|
{
|
|
return ReadOnlySet.IsProperSubsetOf(other);
|
|
}
|
|
|
|
public bool IsProperSupersetOf(IEnumerable<T> other)
|
|
{
|
|
return ReadOnlySet.IsProperSupersetOf(other);
|
|
}
|
|
|
|
public bool IsSubsetOf(IEnumerable<T> other)
|
|
{
|
|
return ReadOnlySet.IsSubsetOf(other);
|
|
}
|
|
|
|
public bool IsSupersetOf(IEnumerable<T> other)
|
|
{
|
|
return ReadOnlySet.IsSupersetOf(other);
|
|
}
|
|
|
|
public bool Overlaps(IEnumerable<T> other)
|
|
{
|
|
return ReadOnlySet.Overlaps(other);
|
|
}
|
|
|
|
public bool Remove(T item)
|
|
{
|
|
if (_mutableSet == null && !Contains(item))
|
|
{
|
|
return false;
|
|
}
|
|
return GetOrCreateMutableSet().Remove(item);
|
|
}
|
|
|
|
public bool SetEquals(IEnumerable<T> other)
|
|
{
|
|
return ReadOnlySet.SetEquals(other);
|
|
}
|
|
|
|
public void SymmetricExceptWith(IEnumerable<T> other)
|
|
{
|
|
GetOrCreateMutableSet().SymmetricExceptWith(other);
|
|
}
|
|
|
|
public bool TryGetValue(T equalValue, out T actualValue)
|
|
{
|
|
if (ReadOnlySet.TryGetValue(equalValue, out var actualValue2))
|
|
{
|
|
actualValue = actualValue2;
|
|
return true;
|
|
}
|
|
actualValue = equalValue;
|
|
return false;
|
|
}
|
|
|
|
public void UnionWith(IEnumerable<T> other)
|
|
{
|
|
if (other == null)
|
|
{
|
|
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.other);
|
|
}
|
|
if (_mutableSet != null)
|
|
{
|
|
_mutableSet.UnionWith(other);
|
|
}
|
|
else
|
|
{
|
|
if (other is ImmutableSegmentedHashSet<T> { IsEmpty: not false })
|
|
{
|
|
return;
|
|
}
|
|
SegmentedHashSet<T> segmentedHashSet = null;
|
|
foreach (T item in other)
|
|
{
|
|
if (segmentedHashSet == null)
|
|
{
|
|
if (ReadOnlySet.Contains(item))
|
|
{
|
|
continue;
|
|
}
|
|
segmentedHashSet = GetOrCreateMutableSet();
|
|
}
|
|
segmentedHashSet.Add(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> ToImmutable()
|
|
{
|
|
_set = new ImmutableSegmentedHashSet<T>(ReadOnlySet);
|
|
_mutableSet = null;
|
|
return _set;
|
|
}
|
|
|
|
void ICollection<T>.Add(T item)
|
|
{
|
|
((ICollection<T>)GetOrCreateMutableSet()).Add(item);
|
|
}
|
|
|
|
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
|
|
{
|
|
((ICollection<T>)ReadOnlySet).CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
}
|
|
|
|
public struct Enumerator : IEnumerator<T>, IEnumerator, IDisposable
|
|
{
|
|
private readonly SegmentedHashSet<T> _set;
|
|
|
|
private SegmentedHashSet<T>.Enumerator _enumerator;
|
|
|
|
public readonly T Current => _enumerator.Current;
|
|
|
|
readonly object? IEnumerator.Current => ((IEnumerator)_enumerator).Current;
|
|
|
|
internal Enumerator(SegmentedHashSet<T> set)
|
|
{
|
|
_set = set;
|
|
_enumerator = set.GetEnumerator();
|
|
}
|
|
|
|
public readonly void Dispose()
|
|
{
|
|
_enumerator.Dispose();
|
|
}
|
|
|
|
public bool MoveNext()
|
|
{
|
|
return _enumerator.MoveNext();
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_enumerator = _set.GetEnumerator();
|
|
}
|
|
}
|
|
|
|
internal static class PrivateInterlocked
|
|
{
|
|
internal static ImmutableSegmentedHashSet<T> VolatileRead(in ImmutableSegmentedHashSet<T> location)
|
|
{
|
|
SegmentedHashSet<T> segmentedHashSet = Volatile.Read(in Unsafe.AsRef(in location._set));
|
|
if (segmentedHashSet == null)
|
|
{
|
|
return default(ImmutableSegmentedHashSet<T>);
|
|
}
|
|
return new ImmutableSegmentedHashSet<T>(segmentedHashSet);
|
|
}
|
|
|
|
internal static ImmutableSegmentedHashSet<T> InterlockedExchange(ref ImmutableSegmentedHashSet<T> location, ImmutableSegmentedHashSet<T> value)
|
|
{
|
|
SegmentedHashSet<T> segmentedHashSet = Interlocked.Exchange(ref Unsafe.AsRef(in location._set), value._set);
|
|
if (segmentedHashSet == null)
|
|
{
|
|
return default(ImmutableSegmentedHashSet<T>);
|
|
}
|
|
return new ImmutableSegmentedHashSet<T>(segmentedHashSet);
|
|
}
|
|
|
|
internal static ImmutableSegmentedHashSet<T> InterlockedCompareExchange(ref ImmutableSegmentedHashSet<T> location, ImmutableSegmentedHashSet<T> value, ImmutableSegmentedHashSet<T> comparand)
|
|
{
|
|
SegmentedHashSet<T> segmentedHashSet = Interlocked.CompareExchange(ref Unsafe.AsRef(in location._set), value._set, comparand._set);
|
|
if (segmentedHashSet == null)
|
|
{
|
|
return default(ImmutableSegmentedHashSet<T>);
|
|
}
|
|
return new ImmutableSegmentedHashSet<T>(segmentedHashSet);
|
|
}
|
|
}
|
|
|
|
public static readonly ImmutableSegmentedHashSet<T> Empty = new ImmutableSegmentedHashSet<T>(new SegmentedHashSet<T>());
|
|
|
|
private readonly SegmentedHashSet<T> _set;
|
|
|
|
public IEqualityComparer<T> KeyComparer => _set.Comparer;
|
|
|
|
public int Count => _set.Count;
|
|
|
|
public bool IsDefault => _set == null;
|
|
|
|
public bool IsEmpty => _set.Count == 0;
|
|
|
|
bool ICollection<T>.IsReadOnly => true;
|
|
|
|
bool ICollection.IsSynchronized => true;
|
|
|
|
object ICollection.SyncRoot => _set;
|
|
|
|
private ImmutableSegmentedHashSet(SegmentedHashSet<T> set)
|
|
{
|
|
_set = set;
|
|
}
|
|
|
|
public static bool operator ==(ImmutableSegmentedHashSet<T> left, ImmutableSegmentedHashSet<T> right)
|
|
{
|
|
return left.Equals(right);
|
|
}
|
|
|
|
public static bool operator !=(ImmutableSegmentedHashSet<T> left, ImmutableSegmentedHashSet<T> right)
|
|
{
|
|
return !left.Equals(right);
|
|
}
|
|
|
|
public static bool operator ==(ImmutableSegmentedHashSet<T>? left, ImmutableSegmentedHashSet<T>? right)
|
|
{
|
|
return left.GetValueOrDefault().Equals(right.GetValueOrDefault());
|
|
}
|
|
|
|
public static bool operator !=(ImmutableSegmentedHashSet<T>? left, ImmutableSegmentedHashSet<T>? right)
|
|
{
|
|
return !left.GetValueOrDefault().Equals(right.GetValueOrDefault());
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> Add(T value)
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (result.IsEmpty)
|
|
{
|
|
return new ImmutableSegmentedHashSet<T>(new SegmentedHashSet<T>(result.KeyComparer) { value });
|
|
}
|
|
if (result.Contains(value))
|
|
{
|
|
return result;
|
|
}
|
|
Builder builder = result.ToBuilder();
|
|
builder.Add(value);
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> Clear()
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (result.IsEmpty)
|
|
{
|
|
return result;
|
|
}
|
|
return Empty.WithComparer(result.KeyComparer);
|
|
}
|
|
|
|
public bool Contains(T value)
|
|
{
|
|
return _set.Contains(value);
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> Except(IEnumerable<T> other)
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (other is ImmutableSegmentedHashSet<T> { IsEmpty: not false })
|
|
{
|
|
return result;
|
|
}
|
|
if (result.IsEmpty)
|
|
{
|
|
foreach (T item in other)
|
|
{
|
|
_ = item;
|
|
}
|
|
return result;
|
|
}
|
|
Builder builder = result.ToBuilder();
|
|
builder.ExceptWith(other);
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
public Enumerator GetEnumerator()
|
|
{
|
|
return new Enumerator(_set);
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> Intersect(IEnumerable<T> other)
|
|
{
|
|
ImmutableSegmentedHashSet<T> immutableSegmentedHashSet = this;
|
|
if (immutableSegmentedHashSet.IsEmpty || other is ImmutableSegmentedHashSet<T> { IsEmpty: not false })
|
|
{
|
|
return immutableSegmentedHashSet.Clear();
|
|
}
|
|
Builder builder = immutableSegmentedHashSet.ToBuilder();
|
|
builder.IntersectWith(other);
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
public bool IsProperSubsetOf(IEnumerable<T> other)
|
|
{
|
|
return _set.IsProperSubsetOf(other);
|
|
}
|
|
|
|
public bool IsProperSupersetOf(IEnumerable<T> other)
|
|
{
|
|
return _set.IsProperSupersetOf(other);
|
|
}
|
|
|
|
public bool IsSubsetOf(IEnumerable<T> other)
|
|
{
|
|
return _set.IsSubsetOf(other);
|
|
}
|
|
|
|
public bool IsSupersetOf(IEnumerable<T> other)
|
|
{
|
|
return _set.IsSupersetOf(other);
|
|
}
|
|
|
|
public bool Overlaps(IEnumerable<T> other)
|
|
{
|
|
return _set.Overlaps(other);
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> Remove(T value)
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (!result.Contains(value))
|
|
{
|
|
return result;
|
|
}
|
|
Builder builder = result.ToBuilder();
|
|
builder.Remove(value);
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
public bool SetEquals(IEnumerable<T> other)
|
|
{
|
|
return _set.SetEquals(other);
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> SymmetricExcept(IEnumerable<T> other)
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (other is ImmutableSegmentedHashSet<T> immutableSegmentedHashSet)
|
|
{
|
|
if (immutableSegmentedHashSet.IsEmpty)
|
|
{
|
|
return result;
|
|
}
|
|
if (result.IsEmpty)
|
|
{
|
|
return immutableSegmentedHashSet.WithComparer(result.KeyComparer);
|
|
}
|
|
}
|
|
if (result.IsEmpty)
|
|
{
|
|
return ImmutableSegmentedHashSet.CreateRange(result.KeyComparer, other);
|
|
}
|
|
Builder builder = result.ToBuilder();
|
|
builder.SymmetricExceptWith(other);
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
public bool TryGetValue(T equalValue, out T actualValue)
|
|
{
|
|
if (_set.TryGetValue(equalValue, out var actualValue2))
|
|
{
|
|
actualValue = actualValue2;
|
|
return true;
|
|
}
|
|
actualValue = equalValue;
|
|
return false;
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> Union(IEnumerable<T> other)
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (other is ImmutableSegmentedHashSet<T> immutableSegmentedHashSet)
|
|
{
|
|
if (immutableSegmentedHashSet.IsEmpty)
|
|
{
|
|
return result;
|
|
}
|
|
if (result.IsEmpty)
|
|
{
|
|
return immutableSegmentedHashSet.WithComparer(result.KeyComparer);
|
|
}
|
|
}
|
|
Builder builder = result.ToBuilder();
|
|
builder.UnionWith(other);
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
public Builder ToBuilder()
|
|
{
|
|
return new Builder(this);
|
|
}
|
|
|
|
public ImmutableSegmentedHashSet<T> WithComparer(IEqualityComparer<T>? equalityComparer)
|
|
{
|
|
ImmutableSegmentedHashSet<T> result = this;
|
|
if (equalityComparer == null)
|
|
{
|
|
equalityComparer = EqualityComparer<T>.Default;
|
|
}
|
|
if (object.Equals(result.KeyComparer, equalityComparer))
|
|
{
|
|
return result;
|
|
}
|
|
return new ImmutableSegmentedHashSet<T>(new SegmentedHashSet<T>(result._set, equalityComparer));
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return _set?.GetHashCode() ?? 0;
|
|
}
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
if (obj is ImmutableSegmentedHashSet<T> other)
|
|
{
|
|
return Equals(other);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(ImmutableSegmentedHashSet<T> other)
|
|
{
|
|
return _set == other._set;
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.Clear()
|
|
{
|
|
return Clear();
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.Add(T value)
|
|
{
|
|
return Add(value);
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.Remove(T value)
|
|
{
|
|
return Remove(value);
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.Intersect(IEnumerable<T> other)
|
|
{
|
|
return Intersect(other);
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.Except(IEnumerable<T> other)
|
|
{
|
|
return Except(other);
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.SymmetricExcept(IEnumerable<T> other)
|
|
{
|
|
return SymmetricExcept(other);
|
|
}
|
|
|
|
IImmutableSet<T> IImmutableSet<T>.Union(IEnumerable<T> other)
|
|
{
|
|
return Union(other);
|
|
}
|
|
|
|
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
|
|
{
|
|
_set.CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
void ICollection.CopyTo(Array array, int index)
|
|
{
|
|
if (array == null)
|
|
{
|
|
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
|
|
}
|
|
if (index < 0)
|
|
{
|
|
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
|
|
}
|
|
if (array.Length < index + Count)
|
|
{
|
|
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
|
|
}
|
|
using Enumerator enumerator = GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
T current = enumerator.Current;
|
|
array.SetValue(current, index++);
|
|
}
|
|
}
|
|
|
|
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
bool ISet<T>.Add(T item)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
void ISet<T>.UnionWith(IEnumerable<T> other)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
void ISet<T>.IntersectWith(IEnumerable<T> other)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
void ISet<T>.ExceptWith(IEnumerable<T> other)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
void ISet<T>.SymmetricExceptWith(IEnumerable<T> other)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
void ICollection<T>.Add(T item)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
void ICollection<T>.Clear()
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
bool ICollection<T>.Remove(T item)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
}
|