Created
October 5, 2023 04:43
-
-
Save NoelFB/e54bbf34d36f1d8ce94f03f9ed46807b to your computer and use it in GitHub Desktop.
simple stack-based C# string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
/// <summary> | |
/// Stack-based String | |
/// </summary> | |
[InterpolatedStringHandler] | |
[SkipLocalsInit] | |
public unsafe struct StackString | |
{ | |
public const int Capacity = 128; | |
public fixed char Buffer[Capacity]; | |
public int Length { get; private set; } | |
public StackString() { Buffer[0] = '\0'; Length = 0; } | |
public StackString(int literalLength, int formattedCount) : this() { } | |
public StackString(in string str) : this() { Append(str); } | |
public StackString(in ReadOnlySpan<char> str) : this() { Append(str); } | |
public static implicit operator StackString(in string str) => new(str); | |
public static implicit operator StackString(in ReadOnlySpan<char> str) => new(str); | |
public ReadOnlySpan<char> Span => MemoryMarshal.CreateReadOnlySpan(ref Buffer[0], Length); | |
private Span<char> Avail | |
{ | |
get | |
{ | |
if (Length < Capacity - 1) | |
return MemoryMarshal.CreateSpan(ref Buffer[0], Capacity)[Length..^1]; | |
return Span<char>.Empty; | |
} | |
} | |
public void Append(ReadOnlySpan<char> s) | |
{ | |
if (Avail.Length > 0) | |
{ | |
if (s.Length > Avail.Length) | |
s = s[0..Avail.Length]; | |
s.CopyTo(Avail); | |
Length += s.Length; | |
Buffer[Length] = '\0'; | |
} | |
} | |
public void AppendLiteral(string s) => Append(s); | |
public void AppendFormatted(int value) => AppendFormatted(value, null); | |
public void AppendFormatted(int value, string? format) | |
{ | |
value.TryFormat(Avail, out int len, format ?? default); | |
Length += len; | |
Buffer[Length] = '\0'; | |
} | |
public void AppendFormatted(long value) => AppendFormatted(value, null); | |
public void AppendFormatted(long value, string? format) | |
{ | |
value.TryFormat(Avail, out int len, format ?? default); | |
Length += len; | |
Buffer[Length] = '\0'; | |
} | |
public void AppendFormatted(float value) => AppendFormatted(value, null); | |
public void AppendFormatted(float value, string? format) | |
{ | |
value.TryFormat(Avail, out int len, format ?? default); | |
Length += len; | |
Buffer[Length] = '\0'; | |
} | |
public void AppendFormatted(double value) => AppendFormatted(value, null); | |
public void AppendFormatted(double value, string? format) | |
{ | |
value.TryFormat(Avail, out int len, format ?? default); | |
Length += len; | |
Buffer[Length] = '\0'; | |
} | |
public void AppendFormatted<T>(T t) => AppendFormatted(t, null); | |
public void AppendFormatted<T>(T t, string? format) | |
{ | |
if (t is string vStr) | |
{ | |
Append(vStr); | |
} | |
else | |
{ | |
throw new NotImplementedException(); | |
} | |
Buffer[Length] = '\0'; | |
} | |
public override string ToString() | |
{ | |
return Span.ToString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment