Skip to content

Instantly share code, notes, and snippets.

@NoelFB
Created October 5, 2023 04:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NoelFB/e54bbf34d36f1d8ce94f03f9ed46807b to your computer and use it in GitHub Desktop.
Save NoelFB/e54bbf34d36f1d8ce94f03f9ed46807b to your computer and use it in GitHub Desktop.
simple stack-based C# string
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