// 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
{
///
/// Immutable wrapper class around T[]. Implements value semantics for
/// and .
///
public class ValueArray : IEquatable>, IReadOnlyList, IStructuralEquatable
where T: IEquatable
{
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(ValueArray bytes) => bytes.array;
public ReadOnlySpan AsReadOnlySpan() => array;
public override bool Equals(object obj) => obj is ValueArray bytes && Equals(bytes);
public bool Equals(ValueArray 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 left, ValueArray right) => Equals(left, right);
public static bool operator !=(ValueArray left, ValueArray right) => !Equals(left, right);
public IEnumerator GetEnumerator() => ((IEnumerable)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);
}
}
}