Skip to content

Instantly share code, notes, and snippets.

@aetos382
Last active September 29, 2025 07:30
Show Gist options
  • Select an option

  • Save aetos382/e0230de51081390ce997e2f6ab57f3be to your computer and use it in GitHub Desktop.

Select an option

Save aetos382/e0230de51081390ce997e2f6ab57f3be to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
var span = "abcdefg".AsSpan();
var original = span;
Print(original);
Print(span + 1);
Print(span += 1);
Print(++span);
Print(span++);
Print(span);
Print("foo" * 3);
Print("bar".AsSpan() * 3);
static void Print(ReadOnlySpan<char> text, [CallerArgumentExpression(nameof(text))] string expression = "")
{
Console.WriteLine($"{expression,-20}: {text}");
}
file static class Extensions
{
extension<T>(Span<T>)
{
public static Span<T> operator +(Span<T> span, int advance)
{
ArgumentOutOfRangeException.ThrowIfNegative(advance);
ArgumentOutOfRangeException.ThrowIfGreaterThan(advance, span.Length);
if (advance == 0)
{
return span;
}
return span[advance..];
}
public static Span<T> operator ++(Span<T> span)
{
return span + 1;
}
}
extension<T>(ref Span<T> span)
{
public void operator +=(int advance)
{
ArgumentOutOfRangeException.ThrowIfNegative(advance);
ArgumentOutOfRangeException.ThrowIfGreaterThan(advance, span.Length);
if (advance == 0)
{
return;
}
span = span[advance..];
}
public void operator ++()
{
span += 1;
}
}
extension<T>(ReadOnlySpan<T>)
{
public static ReadOnlySpan<T> operator +(ReadOnlySpan<T> span, int advance)
{
ArgumentOutOfRangeException.ThrowIfNegative(advance);
ArgumentOutOfRangeException.ThrowIfGreaterThan(advance, span.Length);
if (advance == 0)
{
return span;
}
return span[advance..];
}
public static ReadOnlySpan<T> operator ++(ReadOnlySpan<T> span)
{
return span + 1;
}
}
extension<T>(ref ReadOnlySpan<T> span)
{
public void operator +=(int advance)
{
ArgumentOutOfRangeException.ThrowIfNegative(advance);
ArgumentOutOfRangeException.ThrowIfGreaterThan(advance, span.Length);
if (advance == 0)
{
return;
}
span = span[advance..];
}
public void operator ++()
{
span += 1;
}
}
extension(string)
{
[return: NotNullIfNotNull(nameof(str))]
public static string? operator *(string? str, int repeat)
{
ArgumentOutOfRangeException.ThrowIfNegative(repeat);
if (string.IsNullOrEmpty(str))
{
return str;
}
if (repeat is 0)
{
return string.Empty;
}
if (repeat is 1)
{
return str;
}
return RepeatCore(str, repeat);
}
}
extension(ReadOnlySpan<char>)
{
public static string operator *(ReadOnlySpan<char> span, int repeat)
{
ArgumentOutOfRangeException.ThrowIfNegative(repeat);
if (span.IsEmpty || repeat is 0)
{
return string.Empty;
}
return RepeatCore(span, repeat);
}
}
private static string RepeatCore(ReadOnlySpan<char> span, int repeat)
{
var buffer = new DefaultInterpolatedStringHandler(span.Length * repeat, 0);
for (var i = 0; i < repeat; ++i)
{
buffer.AppendFormatted(span);
}
return buffer.ToStringAndClear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment