Last active
September 29, 2025 07:30
-
-
Save aetos382/e0230de51081390ce997e2f6ab57f3be to your computer and use it in GitHub Desktop.
This file contains hidden or 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; | |
| 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