| | 1 | | namespace Towel; |
| | 2 | |
|
| | 3 | | /// <summary>Represents a <see cref="Span{T}"/> in the process of being initialized.</summary> |
| | 4 | | /// <typeparam name="T">The type of values in the <see cref="Span{T}"/>.</typeparam> |
| | 5 | | public ref struct SpanBuilder<T> |
| | 6 | | { |
| | 7 | | internal Span<T> _span; |
| | 8 | | internal int _i; |
| | 9 | |
|
| | 10 | | /// <summary>Constructs a new <see cref="SpanBuilder{T}"/>.</summary> |
| | 11 | | /// <param name="span">The <see cref="Span{T}"/> to initialize.</param> |
| | 12 | | public SpanBuilder(Span<T> span) |
| 2101164 | 13 | | { |
| 2101164 | 14 | | _span = span; |
| 2101164 | 15 | | _i = 0; |
| 2101164 | 16 | | } |
| | 17 | |
|
| | 18 | | /// <summary>Appends a <typeparamref name="T"/> to this <see cref="SpanBuilder{T}"/>.</summary> |
| | 19 | | /// <param name="value">The <typeparamref name="T"/> to append to this <see cref="SpanBuilder{T}"/>.</param> |
| | 20 | | public void Append(T value) |
| 17007567 | 21 | | { |
| 17007571 | 22 | | if (_i >= _span.Length) throw new InvalidOperationException("The span to append was larger than span being appended |
| 17007563 | 23 | | AppendInternal(value); |
| 17007563 | 24 | | } |
| | 25 | |
|
| | 26 | | /// <summary>Appends a <typeparamref name="T"/> span to this <see cref="SpanBuilder{T}"/>.</summary> |
| | 27 | | /// <param name="span">The <typeparamref name="T"/> span to append to this <see cref="SpanBuilder{T}"/>.</param> |
| | 28 | | public void Append(ReadOnlySpan<T> span) |
| 20698936 | 29 | | { |
| 20698938 | 30 | | if (_i + span.Length > _span.Length) throw new InvalidOperationException("The span to append was larger than span be |
| 20698934 | 31 | | AppendInternal(span); |
| 20698934 | 32 | | } |
| | 33 | |
|
| 17007565 | 34 | | internal void AppendInternal(T value) => _span[_i++] = value; |
| | 35 | | internal void AppendInternal(ReadOnlySpan<T> span) |
| 20698940 | 36 | | { |
| 20698940 | 37 | | span.CopyTo(_span[_i..(_i + span.Length)]); |
| 20698940 | 38 | | _i += span.Length; |
| 20698940 | 39 | | } |
| | 40 | |
|
| | 41 | | /// <summary>Converts a <see cref="SpanBuilder{T}"/> to a <see cref="ReadOnlySpan{T}"/>.</summary> |
| | 42 | | /// <param name="spanBuilder">The <see cref="SpanBuilder{T}"/> to convert to a <see cref="ReadOnlySpan{T}"/>.</param> |
| 4075 | 43 | | public static implicit operator ReadOnlySpan<T>(SpanBuilder<T> spanBuilder) => spanBuilder._span[..spanBuilder._i]; |
| | 44 | |
|
| | 45 | | /// <summary>Converts a <see cref="SpanBuilder{T}"/> to a <see cref="Span{T}"/>.</summary> |
| | 46 | | /// <param name="spanBuilder">The <see cref="SpanBuilder{T}"/> to convert to a <see cref="Span{T}"/>.</param> |
| 2097089 | 47 | | public static implicit operator Span<T>(SpanBuilder<T> spanBuilder) => spanBuilder._span[..spanBuilder._i]; |
| | 48 | |
|
| | 49 | | /// <summary>Converts a <see cref="Span{T}"/> to a <see cref="SpanBuilder{T}"/>.</summary> |
| | 50 | | /// <param name="span">The <see cref="Span{T}"/> to convert to a <see cref="SpanBuilder{T}"/>.</param> |
| 2101164 | 51 | | public static implicit operator SpanBuilder<T>(Span<T> span) => new(span); |
| | 52 | | } |
| | 53 | |
|
| | 54 | | /// <summary>Root type of the static functional methods in Towel.</summary> |
| | 55 | | public static partial class Statics |
| | 56 | | { |
| | 57 | | /// <summary>Appends a <see cref="char"/> followed by <see cref="Environment.NewLine"/> to a <paramref name="spanBuild |
| | 58 | | /// <param name="spanBuilder">The <see cref="SpanBuilder{T}"/> to append to.</param> |
| | 59 | | /// <param name="value">The <see cref="char"/> to append to the <paramref name="spanBuilder"/>.</param> |
| | 60 | | public static void AppendLine(this ref SpanBuilder<char> spanBuilder, char value) |
| | 61 | | { |
| | 62 | | if (spanBuilder._i + 1 + Environment.NewLine.Length > spanBuilder._span.Length) throw new InvalidOperationException( |
| | 63 | | spanBuilder.AppendInternal(value); |
| | 64 | | spanBuilder.AppendInternal(Environment.NewLine); |
| | 65 | | } |
| | 66 | |
|
| | 67 | | /// <summary>Appends a <see cref="char"/> span followed by <see cref="Environment.NewLine"/> to a <paramref name="span |
| | 68 | | /// <param name="spanBuilder">The <see cref="SpanBuilder{T}"/> to append to.</param> |
| | 69 | | /// <param name="span">The <see cref="char"/> span to append to the <paramref name="spanBuilder"/>.</param> |
| | 70 | | public static void AppendLine(this ref SpanBuilder<char> spanBuilder, ReadOnlySpan<char> span) |
| | 71 | | { |
| | 72 | | if (spanBuilder._i + span.Length + Environment.NewLine.Length > spanBuilder._span.Length) throw new InvalidOperation |
| | 73 | | spanBuilder.AppendInternal(span); |
| | 74 | | spanBuilder.AppendInternal(Environment.NewLine); |
| | 75 | | } |
| | 76 | |
|
| | 77 | | /// <summary>Appends a <see cref="Environment.NewLine"/> to a <paramref name="spanBuilder"/>.</summary> |
| | 78 | | /// <param name="spanBuilder">The <see cref="SpanBuilder{T}"/> to append to.</param> |
| | 79 | | public static void AppendLine(this ref SpanBuilder<char> spanBuilder) |
| | 80 | | { |
| | 81 | | spanBuilder.Append(Environment.NewLine); |
| | 82 | | } |
| | 83 | | } |