From a3cd9db0737e22259301c7a3f17bfb1655f847a8 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Thu, 23 Jan 2025 19:12:12 +0000
Subject: [PATCH 1/3] Add insert replace methods for runes
---
.../ValueStringBuilder.Insert.cs | 24 +++++++++++++
.../ValueStringBuilder.Replace.cs | 35 ++++++++-----------
2 files changed, 38 insertions(+), 21 deletions(-)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
index a6cc015..f6fe34e 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
+using System.Text;
namespace LinkDotNet.StringBuilder;
@@ -12,6 +13,29 @@ public ref partial struct ValueStringBuilder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Insert(int index, bool value) => Insert(index, value.ToString());
+ ///
+ /// Insert the string representation of the character to the builder at the given index.
+ ///
+ /// Index where should be inserted.
+ /// Character to insert into this builder.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Insert(int index, char value) => Insert(index, [value]);
+
+ ///
+ /// Insert the string representation of the rune to the builder at the given index.
+ ///
+ /// Index where should be inserted.
+ /// Rune to insert into this builder.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Insert(int index, Rune value)
+ {
+ Span valueChars = stackalloc char[2];
+ int valueCharsWritten = value.EncodeToUtf16(valueChars);
+ ReadOnlySpan valueCharsReadOnly = valueChars[..valueCharsWritten];
+
+ Insert(index, valueCharsReadOnly);
+ }
+
///
/// Insert the string representation of the char to the builder at the given index.
///
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
index 0994f28..a160b6f 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
@@ -13,17 +13,6 @@ public ref partial struct ValueStringBuilder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Replace(char oldValue, char newValue) => Replace(oldValue, newValue, 0, Length);
- ///
- /// Replaces all instances of one rune with another in this builder.
- ///
- /// The rune to replace.
- /// The rune to replace with.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Replace(Rune oldValue, Rune newValue)
- {
- Replace(oldValue, newValue, 0, Length);
- }
-
///
/// Replaces all instances of one character with another in this builder.
///
@@ -34,15 +23,8 @@ public void Replace(Rune oldValue, Rune newValue)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Replace(char oldValue, char newValue, int startIndex, int count)
{
- if (startIndex < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), "Start index can't be smaller than 0.");
- }
-
- if (count > bufferPosition)
- {
- throw new ArgumentOutOfRangeException(nameof(count), $"Count: {count} is bigger than the current size {bufferPosition}.");
- }
+ ArgumentOutOfRangeException.ThrowIfLessThan(startIndex, 0);
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex + count, Length);
for (var i = startIndex; i < startIndex + count; i++)
{
@@ -53,6 +35,14 @@ public readonly void Replace(char oldValue, char newValue, int startIndex, int c
}
}
+ ///
+ /// Replaces all instances of one rune with another in this builder.
+ ///
+ /// The rune to replace.
+ /// The rune to replace with.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Replace(Rune oldValue, Rune newValue) => Replace(oldValue, newValue, 0, Length);
+
///
/// Replaces all instances of one rune with another in this builder.
///
@@ -99,6 +89,9 @@ public void Replace(scoped ReadOnlySpan oldValue, scoped ReadOnlySpan oldValue, scoped ReadOnlySpan newValue, int startIndex, int count)
{
+ ArgumentOutOfRangeException.ThrowIfLessThan(startIndex, 0);
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex + count, Length);
+
var length = startIndex + count;
var slice = buffer[startIndex..length];
@@ -188,7 +181,7 @@ public void ReplaceGeneric(ReadOnlySpan oldValue, T newValue, int start
}
else
{
- Replace(oldValue, (ReadOnlySpan)newValue?.ToString(), startIndex, count);
+ Replace(oldValue, (newValue?.ToString() ?? string.Empty).AsSpan(), startIndex, count);
}
}
}
\ No newline at end of file
From b58a14accb50a75fa0c50f2bebeb0d8137d81f0a Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Thu, 23 Jan 2025 23:41:18 +0000
Subject: [PATCH 2/3] Update CHANGELOG.md
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3017007..a8d17cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,10 @@ All notable changes to **ValueStringBuilder** will be documented in this file. T
- Added `TrimPrefix(ReadOnlySpan, StringComparison)` (by yours truly (@Joy-less) in #226)
- Added `TrimSuffix(ReadOnlySpan, StringComparison)` (also by yours truly (@Joy-less) in #226)
+- Added `Insert(int, char)` overload (by yours truly (@Joy-less) in #225)
+- Added `Insert(int, Rune)` overload (again by yours truly (@Joy-less) in #225)
+- Added `Replace(Rune, Rune)` overload (see yours truly (@Joy-less) in #225)
+- Improved `Replace(scoped ReadOnlySpan, scoped ReadOnlySpan, int, int)` fallback (achieved by yours truly (@Joy-less) in #225)
## [2.1.0] - 2025-01-14
From 33bf847e788f9b801921c75c3a681a62ac194ae0 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Fri, 24 Jan 2025 17:44:58 +0000
Subject: [PATCH 3/3] Make requested changes
---
.../ValueStringBuilder.Append.cs | 6 +++---
.../ValueStringBuilder.Insert.cs | 6 +++---
.../ValueStringBuilder.Replace.cs | 10 +++++-----
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
index d126ea8..716eef6 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
@@ -126,10 +126,10 @@ public void Append(char value)
public void Append(Rune value)
{
Span valueChars = stackalloc char[2];
- int valueCharsWritten = value.EncodeToUtf16(valueChars);
- ReadOnlySpan valueCharsReadOnly = valueChars[..valueCharsWritten];
+ var valueCharsWritten = value.EncodeToUtf16(valueChars);
+ ReadOnlySpan valueCharsSlice = valueChars[..valueCharsWritten];
- Append(valueCharsReadOnly);
+ Append(valueCharsSlice);
}
///
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
index f6fe34e..d3f9a30 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
@@ -30,10 +30,10 @@ public ref partial struct ValueStringBuilder
public void Insert(int index, Rune value)
{
Span valueChars = stackalloc char[2];
- int valueCharsWritten = value.EncodeToUtf16(valueChars);
- ReadOnlySpan valueCharsReadOnly = valueChars[..valueCharsWritten];
+ var valueCharsWritten = value.EncodeToUtf16(valueChars);
+ ReadOnlySpan valueCharsSlice = valueChars[..valueCharsWritten];
- Insert(index, valueCharsReadOnly);
+ Insert(index, valueCharsSlice);
}
///
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
index a160b6f..d3284a0 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
@@ -54,14 +54,14 @@ public readonly void Replace(char oldValue, char newValue, int startIndex, int c
public void Replace(Rune oldValue, Rune newValue, int startIndex, int count)
{
Span oldValueChars = stackalloc char[2];
- int oldValueCharsWritten = oldValue.EncodeToUtf16(oldValueChars);
- ReadOnlySpan oldValueCharsReadOnly = oldValueChars[..oldValueCharsWritten];
+ var oldValueCharsWritten = oldValue.EncodeToUtf16(oldValueChars);
+ ReadOnlySpan oldValueCharsSlice = oldValueChars[..oldValueCharsWritten];
Span newValueChars = stackalloc char[2];
- int newValueCharsWritten = newValue.EncodeToUtf16(newValueChars);
- ReadOnlySpan newValueCharsReadOnly = newValueChars[..newValueCharsWritten];
+ var newValueCharsWritten = newValue.EncodeToUtf16(newValueChars);
+ ReadOnlySpan newValueCharsSlice = newValueChars[..newValueCharsWritten];
- Replace(oldValueCharsReadOnly, newValueCharsReadOnly, startIndex, count);
+ Replace(oldValueCharsSlice, newValueCharsSlice, startIndex, count);
}
///