/* * GNU AFFERO GENERAL PUBLIC LICENSE * Version 3, 19 November 2007 * Copyright (C) 2007 Free Software Foundation, Inc. * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ using System; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace UVtools.Core.Extensions; public static class SpanExtensions { public static unsafe void Fill(this Span span, Func provider, int cores = -1) where T : struct { if (cores <= 0) cores = Environment.ProcessorCount; int batch = span.Length / cores, mod = span.Length % cores, size = Unsafe.SizeOf(); ref T r0 = ref span.GetPinnableReference(); fixed (byte* p0 = &Unsafe.As(ref r0)) { byte* p = p0; Parallel.For(0, cores, i => { byte* pi = p + i * batch * size; for (int j = 0; j < batch; j++, pi += size) Unsafe.Write(pi, provider()); }); // Remaining values if (mod < 1) return; for (int i = span.Length - mod; i < span.Length; i++) Unsafe.Write(p + i * size, provider()); } } }