DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="1.2.0" />

 OneDimensionalArray

public static class OneDimensionalArray
Provides specialized methods to work with one-dimensional array.
using DotNext.Runtime.InteropServices; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext { public static class OneDimensionalArray { private struct RemovalCounter<T> : IConsumer<T> { internal long Count; void IConsumer<T>.Invoke(T item) { Count++; } } public static bool IsNullOrEmpty<T>(this T[] array) { if (array != null) return array.LongLength == 0; return true; } public static void ForEach<T>(this T[] array, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueRefAction<T, long> action) { for (long num = 0; num < array.LongLength; num++) { action.Invoke(ref array[num], num); } } public static void ForEach<T>(this T[] array, RefAction<T, long> action) { ValueRefAction<T, long> action2 = new ValueRefAction<T, long>(action, true); array.ForEach(ref action2); } public static T[] Insert<T>(this T[] array, T element, long index) { if (index < 0 || index > array.LongLength) throw new ArgumentOutOfRangeException("index"); if (array.LongLength == 0) return new T[1] { element }; T[] array2 = new T[array.LongLength + 1]; Array.Copy(array, 0, array2, 0, Math.Min(index + 1, array.LongLength)); Array.Copy(array, index, array2, index + 1, array.LongLength - index); array2[index] = element; return array2; } public static T[] RemoveAt<T>(this T[] array, long index) { if (index < 0 || index >= array.LongLength) throw new ArgumentOutOfRangeException("index"); if (array.LongLength == 1) return Array.Empty<T>(); T[] array2 = new T[array.LongLength - 1]; Array.Copy(array, 0, array2, 0, index); Array.Copy(array, index + 1, array2, index, array.LongLength - index - 1); return array2; } private static T[] RemoveAll<T, C>(T[] array, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, bool> match, ref C callback) where C : struct, IConsumer<T> { if (array.LongLength == 0) return array; long num = 0; T[] array2 = new T[array.LongLength]; T[] array3 = array; foreach (T val in array3) { if (match.Invoke(val)) ((IConsumer<T>)callback).Invoke(val); else { T[] array4 = array2; long num2 = num; num = num2 + 1; array4[num2] = val; } } if (array.LongLength - num == 0) return array; if (num == 0) return Array.Empty<T>(); array = new T[num]; Array.Copy(array2, 0, array, 0, num); return array; } public static T[] RemoveAll<T>(this T[] array, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, bool> match, out long count) { RemovalCounter<T> callback = default(RemovalCounter<T>); T[] result = RemoveAll(array, ref match, ref callback); count = callback.Count; return result; } public static T[] RemoveAll<T>(this T[] array, Predicate<T> match, out long count) { ValueFunc<T, bool> match2 = match.AsValueFunc(true); return array.RemoveAll(ref match2, out count); } public static T[] RemoveAll<T>(this T[] array, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<T, bool> match, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueAction<T> callback) { return OneDimensionalArray.RemoveAll<T, ValueAction<T>>(array, ref match, ref Unsafe.AsRef(ref callback)); } public static T[] RemoveAll<T>(this T[] array, Predicate<T> match, Action<T> callback) { ValueFunc<T, bool> match2 = match.AsValueFunc(true); ValueAction<T> callback2 = new ValueAction<T>(callback, true); return array.RemoveAll(ref match2, ref callback2); } internal static T[] New<T>(long length) { if (length != 0) return new T[length]; return Array.Empty<T>(); } public static T[] RemoveFirst<T>(this T[] input, long count) { if (count == 0) return input; if (count >= input.LongLength) return Array.Empty<T>(); T[] array = new T[input.LongLength - count]; Array.Copy(input, count, array, 0, array.LongLength); return array; } public static T[] Slice<T>(this T[] input, long startIndex, long length) { if (startIndex >= input.LongLength || length == 0) return Array.Empty<T>(); if (startIndex == 0 && length == input.Length) return input; length = Math.Min(input.LongLength - startIndex, length); T[] array = new T[length]; Array.Copy(input, startIndex, array, 0, length); return array; } public static T[] RemoveLast<T>(this T[] input, long count) { if (count == 0) return input; if (count >= input.LongLength) return Array.Empty<T>(); T[] array = new T[input.LongLength - count]; Array.Copy(input, array, array.LongLength); return array; } public unsafe static bool BitwiseEquals<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] first, T[] second) where T : struct { if (first == null || second == null) return first == second; if (first.LongLength != second.LongLength) return false; if (first.LongLength != 0) { fixed (T* value = first) { fixed (T* value2 = second) { return Memory.EqualsAligned(new IntPtr(value), new IntPtr(value2), first.LongLength * sizeof(T)); } } } return true; } public unsafe static int BitwiseHashCode<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] array, bool salted = true) where T : struct { if (!array.IsNullOrEmpty()) { fixed (T* value = array) { return Memory.GetHashCode32Aligned(new IntPtr(value), array.LongLength * sizeof(T), salted); } } return 0; } public unsafe static int BitwiseHashCode<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] array, int hash, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<int, int, int> hashFunction, bool salted = true) where T : struct { if (!array.IsNullOrEmpty()) { fixed (T* value = array) { return Memory.GetHashCode32Aligned(new IntPtr(value), array.LongLength * sizeof(T), hash, ref hashFunction, salted); } } return hash; } public static int BitwiseHashCode<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] array, int hash, Func<int, int, int> hashFunction, bool salted = true) where T : struct { ValueFunc<int, int, int> hashFunction2 = new ValueFunc<int, int, int>(hashFunction, true); return array.BitwiseHashCode(hash, ref hashFunction2, salted); } public unsafe static long BitwiseHashCode64<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] array, long hash, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<long, long, long> hashFunction, bool salted = true) where T : struct { if (!array.IsNullOrEmpty()) { fixed (T* value = array) { return Memory.GetHashCode64Aligned(new IntPtr(value), array.LongLength * sizeof(T), hash, ref hashFunction, salted); } } return hash; } public static long BitwiseHashCode64<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] array, long hash, Func<long, long, long> hashFunction, bool salted = true) where T : struct { ValueFunc<long, long, long> hashFunction2 = new ValueFunc<long, long, long>(hashFunction, true); return array.BitwiseHashCode64(hash, ref hashFunction2, salted); } public unsafe static long BitwiseHashCode64<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] array, bool salted = true) where T : struct { if (!array.IsNullOrEmpty()) { fixed (T* value = array) { return Memory.GetHashCode64Aligned(new IntPtr(value), array.LongLength * sizeof(T), salted); } } return 0; } public static bool SequenceEqual(this object[] first, object[] second) { if (first == second) return true; if (first == null) return second == null; if (second == null || first.LongLength != second.LongLength) return false; for (long num = 0; num < first.LongLength; num++) { if (!object.Equals(first[num], second[num])) return false; } return true; } public unsafe static int BitwiseCompare<[System.Runtime.CompilerServices.IsUnmanaged] T>(this T[] first, T[] second) where T : struct { if (first == null) { if (second != null) return -1; return 0; } if (second == null) return 1; if (first.LongLength == second.LongLength) { fixed (T* value = first) { fixed (T* value2 = second) { return Memory.CompareUnaligned(new IntPtr(value), new IntPtr(value2), first.LongLength * sizeof(T)); } } } return first.LongLength.CompareTo(second.LongLength); } } }