Extract `ConcatArray` helper

This commit is contained in:
YoshiRulz 2022-11-26 18:36:58 +10:00
parent 1df6ce4e38
commit b8182f9149
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
3 changed files with 42 additions and 9 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
@ -122,6 +123,33 @@ namespace BizHawk.Common.CollectionExtensions
foreach (var item in collection) list.Add(item);
}
/// <returns>
/// portion of <paramref name="dest"/> that was written to,
/// unless either span is empty, in which case the other reference is returned<br/>
/// if <paramref name="dest"/> is too small, returns <see cref="Span{T}.Empty"/>
/// </returns>
public static ReadOnlySpan<T> ConcatArray<T>(this ReadOnlySpan<T> a, ReadOnlySpan<T> b, Span<T> dest)
{
if (b.Length is 0) return a;
if (a.Length is 0) return b;
var combinedLen = a.Length + b.Length;
if (combinedLen < dest.Length) return Span<T>.Empty;
a.CopyTo(dest);
b.CopyTo(dest.Slice(start: a.Length));
return dest.Slice(start: 0, length: combinedLen);
}
/// <returns>freshly-allocated array, unless either array is empty, in which case the other reference is returned</returns>
public static T[] ConcatArray<T>(this T[] a, T[] b)
{
if (b.Length is 0) return a;
if (a.Length is 0) return b;
var combined = new T[a.Length + b.Length];
var returned = ((ReadOnlySpan<T>) a).ConcatArray(b, combined);
Debug.Assert(returned == combined);
return combined;
}
public static bool CountIsAtLeast<T>(this IEnumerable<T> collection, int n)
=> collection is ICollection countable
? countable.Count >= n

View File

@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
using System.Security.Cryptography;
using BizHawk.Common.BufferExtensions;
using BizHawk.Common.CollectionExtensions;
namespace BizHawk.Common
{
@ -70,15 +71,7 @@ namespace BizHawk.Common
public static byte[] ComputeConcat(byte[] dataA, byte[] dataB)
{
if (LibBizHash.BizSupportsShaInstructions())
{
var concat = new byte[dataA.Length + dataB.Length];
Array.Copy(sourceArray: dataA, destinationArray: concat, length: dataA.Length);
Array.Copy(
sourceArray: dataB, sourceIndex: 0,
destinationArray: concat, destinationIndex: dataA.Length, length: dataB.Length);
return UnmanagedImpl(concat);
}
if (LibBizHash.BizSupportsShaInstructions()) return UnmanagedImpl(dataA.ConcatArray(dataB));
using var impl = IncrementalHash.CreateHash(HashAlgorithmName.SHA1);
impl.AppendData(dataA);
impl.AppendData(dataB);

View File

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Common.CollectionExtensions;
@ -63,6 +64,17 @@ namespace BizHawk.Tests.Common.CollectionExtensions
Assert.AreEqual(4, b.Count, nameof(CE.AddRange) + " failed on (ICollection<int> not List<int>)");
}
[TestMethod]
public void TestConcatArray()
{
var a123 = new[] { 1, 2, 3 };
var a456 = new[] { 4, 5, 6 };
Assert.IsTrue(a123.ConcatArray(a456).SequenceEqual(new[] { 1, 2, 3, 4, 5, 6 }));
Assert.AreSame(a123, a123.ConcatArray(Array.Empty<int>()));
Assert.AreSame(a456, Array.Empty<int>().ConcatArray(a456));
Assert.AreEqual(0, Array.Empty<int>().ConcatArray(Array.Empty<int>()).Length);
}
[TestMethod]
public void TestRemoveAll()
{