From 30af957fc616ec9b6d01a93671d2caca956e66ca Mon Sep 17 00:00:00 2001 From: JustFixMe Date: Thu, 15 Aug 2024 20:14:38 +0400 Subject: [PATCH] + added ImmutableSequence --- Core/Collections/ImmutableSequence.cs | 92 +++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Core/Collections/ImmutableSequence.cs diff --git a/Core/Collections/ImmutableSequence.cs b/Core/Collections/ImmutableSequence.cs new file mode 100644 index 0000000..8a89403 --- /dev/null +++ b/Core/Collections/ImmutableSequence.cs @@ -0,0 +1,92 @@ +using System.Collections; +using System.Collections.Immutable; +using System.Numerics; + +namespace Just.Core.Collections; + +public class ImmutableSequence : + IEnumerable, + IReadOnlyList, + IEquatable>, + IEqualityOperators, ImmutableSequence, bool> +{ + private static readonly int InitialHash = typeof(ImmutableSequence).GetHashCode(); + private static readonly Func CompareItem = EqualityComparer.Default.Equals; + private readonly ImmutableList _values; + + public ImmutableSequence(ImmutableList values) => _values = values; + public ImmutableSequence() : this(ImmutableArray.Empty) + { + } + public ImmutableSequence(IEnumerable values) + { + _values = [..values]; + } + public ImmutableSequence(ReadOnlySpan values) : this(ImmutableList.Create(values)) + { + } + + public bool IsEmpty => _values.IsEmpty; + public int Count => _values.Count; + public T this[int index] => _values[index]; + public T this[Index index] => _values[index]; + public ImmutableSequence this[Range range] + { + get + { + var (offset, count) = range.GetOffsetAndLength(_values.Count); + return ConstructNew(_values.GetRange(offset, count)); + } + } + + protected virtual ImmutableSequence ConstructNew(ImmutableList values) => new(values); + + public ImmutableSequence Add(T value) => ConstructNew([.._values, value]); + public ImmutableSequence AddFront(T value) => ConstructNew([value, .._values]); + + public ImmutableList.Enumerator GetEnumerator() => _values.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_values).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_values).GetEnumerator(); + + public override string ToString() => string.Join(Environment.NewLine, _values); + + public virtual bool Equals([NotNullWhen(true)] ImmutableSequence? other) + { + if (ReferenceEquals(this, other)) + { + return true; + } + + if (_values.Count != other?._values.Count) + { + return false; + } + + for (int i = 0; i < _values.Count; i++) + { + if (!CompareItem(_values[i], other._values[i])) + { + return false; + } + } + + return true; + } + + public override bool Equals([NotNullWhen(true)] object? obj) => Equals(obj as ImmutableSequence); + public override int GetHashCode() + { + HashCode hash = new(); + hash.Add(InitialHash); + + foreach (var value in _values) + { + hash.Add(value); + } + + return hash.ToHashCode(); + } + + public static bool operator ==(ImmutableSequence? left, ImmutableSequence? right) => left is null ? right is null : left.Equals(right); + public static bool operator !=(ImmutableSequence? left, ImmutableSequence? right) => !(left == right); +}