serde-generate/runtime/csharp/Serde/ValueArray.cs (55 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Serde
{
/// <summary>
/// Immutable wrapper class around T[]. Implements value semantics for
/// <see cref="object.Equals(object)"/> and <see cref="object.GetHashCode"/>.
/// </summary>
public class ValueArray<T> : IEquatable<ValueArray<T>>, IReadOnlyList<T>, IStructuralEquatable
where T: IEquatable<T>
{
private readonly T[] array;
private int? hashCode;
public int Count => array.Length;
public T this[int index] => array[index];
public ValueArray(T[] data) {
array = data ?? throw new ArgumentNullException(nameof(data));
hashCode = null;
}
public T[] ToArray() => array.ToArray();
public static implicit operator ReadOnlySpan<T>(ValueArray<T> bytes) => bytes.array;
public ReadOnlySpan<T> AsReadOnlySpan() => array;
public override bool Equals(object obj) => obj is ValueArray<T> bytes && Equals(bytes);
public bool Equals(ValueArray<T> other) {
if (other == null) return false;
if (ReferenceEquals(this, other)) return true;
if (Count != other.Count) return false;
for (int i = 0; i < Count; i++)
if (!array[i].Equals(other[i])) return false;
return true;
}
public static bool operator ==(ValueArray<T> left, ValueArray<T> right) => Equals(left, right);
public static bool operator !=(ValueArray<T> left, ValueArray<T> right) => !Equals(left, right);
public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>)array).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => array.GetEnumerator();
public override int GetHashCode()
{
unchecked
{
if (hashCode.HasValue) return hashCode.Value;
int code = 1849862467;
foreach (T elem in array)
code = code * 31 + elem.GetHashCode();
hashCode = code;
return code;
}
}
public bool Equals(object other, IEqualityComparer comparer)
{
return ((IStructuralEquatable)array).Equals(other, comparer);
}
public int GetHashCode(IEqualityComparer comparer)
{
return ((IStructuralEquatable)array).GetHashCode(comparer);
}
}
}