From 55681c35e49cd537c5047849ee7ef123a62261a1 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Jan 2025 01:49:15 +0000
Subject: [PATCH 1/6] Add Append(Rune)
---
.../ValueStringBuilder.Append.cs | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
index 0bbc6bb..9f97141 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Text;
namespace LinkDotNet.StringBuilder;
@@ -117,6 +118,19 @@ public void Append(char value)
bufferPosition++;
}
+ ///
+ /// Appends a single rune to the string builder.
+ ///
+ /// Rune to add.
+ public void Append(Rune value)
+ {
+ Span valueChars = stackalloc char[2];
+ int valueCharsWritten = value.EncodeToUtf16(valueChars);
+ ReadOnlySpan valueCharsReadOnly = valueChars[..valueCharsWritten];
+
+ Append(valueCharsReadOnly);
+ }
+
///
/// Adds the default new line separator.
///
From ec686ed78052d0b95883481931364edb7bef18d8 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Jan 2025 01:49:47 +0000
Subject: [PATCH 2/6] Add AppendJoin(Rune, IEnumerable)
---
.../ValueStringBuilder.AppendJoin.cs | 60 +++++++++++++++----
1 file changed, 50 insertions(+), 10 deletions(-)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.AppendJoin.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.AppendJoin.cs
index a6241c5..b7bdb76 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.AppendJoin.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.AppendJoin.cs
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
+using System.Text;
namespace LinkDotNet.StringBuilder;
@@ -8,7 +9,7 @@ public ref partial struct ValueStringBuilder
/// Concatenates and appends all values with the given separator between each entry at the end of the string.
///
/// String used as separator between the entries.
- /// Array of strings, which will be concatenated.
+ /// Enumerable of strings to be concatenated.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AppendJoin(ReadOnlySpan separator, IEnumerable values)
=> AppendJoinInternalString(separator, values);
@@ -17,17 +18,26 @@ public void AppendJoin(ReadOnlySpan separator, IEnumerable values
/// Concatenates and appends all values with the given separator between each entry at the end of the string.
///
/// Character used as separator between the entries.
- /// Array of strings, which will be concatenated.
+ /// Enumerable of strings to be concatenated.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AppendJoin(char separator, IEnumerable values)
=> AppendJoinInternalChar(separator, values);
+ ///
+ /// Concatenates and appends all values with the given separator between each entry at the end of the string.
+ ///
+ /// Rune used as separator between the entries.
+ /// Enumerable of strings to be concatenated.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void AppendJoin(Rune separator, IEnumerable values)
+ => AppendJoinInternalRune(separator, values);
+
///
/// Concatenates and appends all values with the given separator between each entry at the end of the string.
///
/// String used as separator between the entries.
- /// Array of strings, which will be concatenated.
- /// Type of the given array.
+ /// Enumerable to be concatenated.
+ /// Type of the given enumerable.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AppendJoin(ReadOnlySpan separator, IEnumerable values)
=> AppendJoinInternalString(separator, values);
@@ -36,12 +46,22 @@ public void AppendJoin(ReadOnlySpan separator, IEnumerable values)
/// Concatenates and appends all values with the given separator between each entry at the end of the string.
///
/// Character used as separator between the entries.
- /// Array of strings, which will be concatenated.
- /// Type of the given array.
+ /// Enumerable to be concatenated.
+ /// Type of the given enumerable.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AppendJoin(char separator, IEnumerable values)
=> AppendJoinInternalChar(separator, values);
+ ///
+ /// Concatenates and appends all values with the given separator between each entry at the end of the string.
+ ///
+ /// Rune used as separator between the entries.
+ /// Enumerable to be concatenated.
+ /// Type of the given enumerable.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void AppendJoin(Rune separator, IEnumerable values)
+ => AppendJoinInternalRune(separator, values);
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void AppendJoinInternalString(ReadOnlySpan separator, IEnumerable values)
{
@@ -55,10 +75,7 @@ private void AppendJoinInternalString(ReadOnlySpan separator, IEnumerab
}
var current = enumerator.Current;
- if (current is not null)
- {
- AppendInternal(current);
- }
+ AppendInternal(current);
while (enumerator.MoveNext())
{
@@ -91,6 +108,29 @@ private void AppendJoinInternalChar(char separator, IEnumerable values)
}
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void AppendJoinInternalRune(Rune separator, IEnumerable values)
+ {
+ ArgumentNullException.ThrowIfNull(values);
+
+ using var enumerator = values.GetEnumerator();
+
+ if (!enumerator.MoveNext())
+ {
+ return;
+ }
+
+ var current = enumerator.Current;
+ AppendInternal(current);
+
+ while (enumerator.MoveNext())
+ {
+ Append(separator);
+ current = enumerator.Current;
+ AppendInternal(current);
+ }
+ }
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void AppendInternal(T value)
{
From 3a14027c2246e93e3d24c718fb509da546bed394 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Jan 2025 01:51:56 +0000
Subject: [PATCH 3/6] Avoid string allocation in AppendLine(ReadOnlySpan)
---
src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
index 9f97141..b21c1c3 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
@@ -143,11 +143,12 @@ public void AppendLine()
///
/// Does the same as but adds a newline at the end.
///
- /// String, which will be added to this builder.
+ /// String to be added to this builder.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AppendLine(scoped ReadOnlySpan str)
{
- Append(string.Concat(str, Environment.NewLine));
+ Append(str);
+ Append(Environment.NewLine);
}
///
From 136808cd481bd425e01598534cac806ec46afb7c Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Jan 2025 01:58:11 +0000
Subject: [PATCH 4/6] Add missing AggressiveInlining attribute
---
src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
index b21c1c3..c3259e0 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs
@@ -122,6 +122,7 @@ public void Append(char value)
/// Appends a single rune to the string builder.
///
/// Rune to add.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Append(Rune value)
{
Span valueChars = stackalloc char[2];
From a0a918e4f98c0f4a1b7066d840621359590c8552 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Jan 2025 15:06:48 +0000
Subject: [PATCH 5/6] Update CHANGELOG.md
---
CHANGELOG.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 61f24ea..bc39f22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,14 @@ This is the `v2` release of the **ValueStringBuilder**. There aren't any noticea
### Changed
- Added `OverloadResolutionPriority` for `Span` overload for the ctor to keep the current behavior. Reported by [@nsentinel])(https://github.com/nsentinel) in [#210](https://github.com/linkdotnet/StringBuilder/issues/210).
+## [1.23.0] - 2025-01-11
+
+- Added `Append(Rune)` overload
+- Added `AppendJoin(Rune, IEnumerable)` overload
+- Added `AppendJoin(Rune, IEnumerable)` overload
+- Optimised `AppendLine(scoped ReadOnlySpan)` by avoiding allocating a new string
+- Removed erroneous null check in `AppendJoin(ReadOnlySpan, IEnumerable)`
+
## [1.22.0] - 2024-12-18
### Added
From 83662086913864ae2cd465466962fb8b7c5e21b9 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Jan 2025 16:01:24 +0000
Subject: [PATCH 6/6] Restructure CHANGELOG.md changes
---
CHANGELOG.md | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc39f22..03005d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,17 +8,19 @@ All notable changes to **ValueStringBuilder** will be documented in this file. T
This is the `v2` release of the **ValueStringBuilder**. There aren't any noticeable changes. Only old framework versions were removed to make further development easier.
+### Added
+
+- Added `Append(Rune)` overload
+- Added `AppendJoin(Rune, IEnumerable)` overload
+- Added `AppendJoin(Rune, IEnumerable)` overload
+
### Removed
+
- Support for `net6.0` and `net7.0` was removed.
### Changed
-- Added `OverloadResolutionPriority` for `Span` overload for the ctor to keep the current behavior. Reported by [@nsentinel])(https://github.com/nsentinel) in [#210](https://github.com/linkdotnet/StringBuilder/issues/210).
-
-## [1.23.0] - 2025-01-11
-- Added `Append(Rune)` overload
-- Added `AppendJoin(Rune, IEnumerable)` overload
-- Added `AppendJoin(Rune, IEnumerable)` overload
+- Added `OverloadResolutionPriority` for `Span` overload for the ctor to keep the current behavior. Reported by [@nsentinel])(https://github.com/nsentinel) in [#210](https://github.com/linkdotnet/StringBuilder/issues/210).
- Optimised `AppendLine(scoped ReadOnlySpan)` by avoiding allocating a new string
- Removed erroneous null check in `AppendJoin(ReadOnlySpan, IEnumerable)`