#pragma warning disable CS9074 #nullable enable using System; using System.Runtime.InteropServices; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using ZLinq.Internal; using ZLinq.Linq; namespace ZLinq { public static class NativeArrayExtensions { public static ValueEnumerable, T> AsValueEnumerable(this NativeArray source) where T : struct { return new(new(source.AsReadOnly())); } public static ValueEnumerable, T> AsValueEnumerable(this NativeArray.ReadOnly source) where T : struct { return new(new(source)); } public static ValueEnumerable, T> AsValueEnumerable(this NativeSlice source) where T : struct { return new(new(source)); } } } namespace ZLinq.Linq { [StructLayout(LayoutKind.Auto)] public struct FromNativeArray : IValueEnumerator where T : struct { public FromNativeArray(NativeArray.ReadOnly source) { this.source = source; this.index = 0; } NativeArray.ReadOnly source; int index; public void Dispose() { } public bool TryCopyTo(Span destination, Index offset) { #if UNITY_2022_1_OR_NEWER if (EnumeratorHelper.TryGetSlice(source, offset, destination.Length, out var slice)) { slice.CopyTo(destination); return true; } #else unsafe { if (EnumeratorHelper.TryGetSlice(new ReadOnlySpan(source.GetUnsafeReadOnlyPtr(), source.Length), offset, destination.Length, out var slice)) { slice.CopyTo(destination); return true; } } #endif return false; } public bool TryGetNext(out T current) { if ((uint)index < (uint)source.Length) { current = source[index++]; return true; } current = default!; return false; } public bool TryGetNonEnumeratedCount(out int count) { count = source.Length; return true; } public bool TryGetSpan(out ReadOnlySpan span) { #if UNITY_2022_1_OR_NEWER span = source; return true; #else unsafe { span = new ReadOnlySpan(source.GetUnsafeReadOnlyPtr(), source.Length); } return true; #endif } } [StructLayout(LayoutKind.Auto)] public struct FromNativeSlice : IValueEnumerator where T : struct { NativeSlice source; int index; public FromNativeSlice(NativeSlice source) { this.source = source; this.index = 0; } public void Dispose() { } public unsafe bool TryCopyTo(Span destination, Index offset) { if (EnumeratorHelper.TryGetSlice(new ReadOnlySpan(source.GetUnsafePtr(), source.Length), offset, destination.Length, out var slice)) { slice.CopyTo(destination); return true; } return false; } public bool TryGetNext(out T current) { if ((uint)index < (uint)source.Length) { current = source[index++]; return true; } current = default!; return false; } public bool TryGetNonEnumeratedCount(out int count) { count = source.Length; return true; } public unsafe bool TryGetSpan(out ReadOnlySpan span) { span = new ReadOnlySpan(source.GetUnsafePtr(), source.Length); return true; } } } #pragma warning restore CS9074