DotNext by Roman Sakno

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

 MemoryTemplate<T>

public struct MemoryTemplate<T> where T : IEquatable<T>
Represents generic template for buffer rendering.
using System; using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext.Buffers { [StructLayout(LayoutKind.Auto)] public readonly struct MemoryTemplate<T> where T : IEquatable<T> { private sealed class Placeholder { internal readonly int Offset; [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 0 })] internal Placeholder Next; internal Placeholder(int offset) { Offset = offset; } } [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<T> template; [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 0 })] private readonly Placeholder firstOccurence; private readonly int placeholderLength; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] public ReadOnlyMemory<T> Value { [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] get { return template; } } public MemoryTemplate([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<T> template, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlySpan<T> placeholder) { this.template = template; if (placeholder.IsEmpty || placeholder.Length > template.Length) { placeholderLength = 0; firstOccurence = null; } else { placeholderLength = placeholder.Length; firstOccurence = BuildPlaceholdersChain(template.Span, placeholder); } } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 2, 0 })] private static Placeholder BuildPlaceholdersChain([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlySpan<T> source, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlySpan<T> placeholder) { Placeholder head = null; Placeholder tail = null; int num = 0; while (num < source.Length - placeholder.Length + 1) { if (MemoryExtensions.SequenceEqual<T>(source.Slice(num, placeholder.Length), placeholder)) { CreateNode(ref head, ref tail, num); num += placeholder.Length; } else num++; } return head; } private static void CreateNode([System.Runtime.CompilerServices.Nullable(new byte[] { 2, 0 })] ref Placeholder head, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 0 })] ref Placeholder tail, int offset) { if (head == null || tail == null) head = (tail = new Placeholder(offset)); else { Placeholder placeholder = tail; tail = (placeholder.Next = new Placeholder(offset)); } } [System.Runtime.CompilerServices.NullableContext(1)] public void Render<TWriter>(TWriter output, Action<int, TWriter> rewriter) where TWriter : class, IBufferWriter<T> { Render(output, rewriter, Span.CopyTo<T>); } [System.Runtime.CompilerServices.NullableContext(1)] public void Render<[System.Runtime.CompilerServices.Nullable(2)] TArg>(TArg arg, Action<int, TArg> rewriter, ReadOnlySpanAction<T, TArg> output) { ReadOnlySpan<T> span = this.template.Span; Placeholder placeholder = this.firstOccurence; int offset = 0; int num = 0; int num2 = 0; bool isPlaceholder; while (this.MoveNext(ref offset, ref placeholder, out isPlaceholder)) { if (isPlaceholder) rewriter(num2++, arg); else output(span.Slice(num, offset - num), arg); num = offset; } } private bool MoveNext(ref int offset, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 0 })] ref Placeholder placeholder, out bool isPlaceholder) { if (offset >= template.Length) { isPlaceholder = false; return false; } if (placeholder == null) { isPlaceholder = false; offset = template.Length; } else if (placeholder.Offset == offset) { isPlaceholder = true; offset += placeholderLength; placeholder = placeholder.Next; } else { offset = placeholder.Offset; isPlaceholder = false; } return true; } } }