Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ All notable changes to **ValueStringBuilder** will be documented in this file. T

## [Unreleased]

### Added

- Added `Replace(Rune, Rune)` overload
- Added `Replace(Rune, Rune, int, int)` overload

## [2.0.0] - 2025-01-12

This is the `v2` release of the **ValueStringBuilder**. There aren't any noticeable breaking changes. Only old framework versions were removed to make further development easier. The API is the same (with new additions) as in `v1`.
Expand Down
4 changes: 2 additions & 2 deletions src/LinkDotNet.StringBuilder/ValueStringBuilder.Insert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ref partial struct ValueStringBuilder
/// <param name="bufferSize">Size of the buffer allocated on the stack.</param>
/// <typeparam name="T">Any <see cref="ISpanFormattable"/>.</typeparam>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Insert<T>(int index, T value, ReadOnlySpan<char> format = default, int bufferSize = 36)
public void Insert<T>(int index, T value, scoped ReadOnlySpan<char> format = default, int bufferSize = 36)
where T : ISpanFormattable => InsertSpanFormattable(index, value, format, bufferSize);

/// <summary>
Expand Down Expand Up @@ -60,7 +60,7 @@ public void Insert(int index, scoped ReadOnlySpan<char> value)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void InsertSpanFormattable<T>(int index, T value, ReadOnlySpan<char> format, int bufferSize)
private void InsertSpanFormattable<T>(int index, T value, scoped ReadOnlySpan<char> format, int bufferSize)
where T : ISpanFormattable
{
if (index < 0)
Expand Down
39 changes: 36 additions & 3 deletions src/LinkDotNet.StringBuilder/ValueStringBuilder.Replace.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using System.Text;

namespace LinkDotNet.StringBuilder;

Expand All @@ -12,6 +13,17 @@ public ref partial struct ValueStringBuilder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Replace(char oldValue, char newValue) => Replace(oldValue, newValue, 0, Length);

/// <summary>
/// Replaces all instances of one rune with another in this builder.
/// </summary>
/// <param name="oldValue">The rune to replace.</param>
/// <param name="newValue">The rune to replace <paramref name="oldValue"/> with.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Replace(Rune oldValue, Rune newValue)
{
Replace(oldValue, newValue, 0, Length);
}

/// <summary>
/// Replaces all instances of one character with another in this builder.
/// </summary>
Expand Down Expand Up @@ -41,6 +53,27 @@ public readonly void Replace(char oldValue, char newValue, int startIndex, int c
}
}

/// <summary>
/// Replaces all instances of one rune with another in this builder.
/// </summary>
/// <param name="oldValue">The rune to replace.</param>
/// <param name="newValue">The rune to replace <paramref name="oldValue"/> with.</param>
/// <param name="startIndex">The index to start in this builder.</param>
/// <param name="count">The number of characters to read in this builder.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Replace(Rune oldValue, Rune newValue, int startIndex, int count)
{
Span<char> oldValueChars = stackalloc char[2];
int oldValueCharsWritten = oldValue.EncodeToUtf16(oldValueChars);
ReadOnlySpan<char> oldValueCharsReadOnly = oldValueChars[..oldValueCharsWritten];

Span<char> newValueChars = stackalloc char[2];
int newValueCharsWritten = newValue.EncodeToUtf16(newValueChars);
ReadOnlySpan<char> newValueCharsReadOnly = newValueChars[..newValueCharsWritten];

Replace(oldValueCharsReadOnly, newValueCharsReadOnly, startIndex, count);
}

/// <summary>
/// Replaces all instances of one string with another in this builder.
/// </summary>
Expand All @@ -51,7 +84,7 @@ public readonly void Replace(char oldValue, char newValue, int startIndex, int c
/// are removed from this builder.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Replace(ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue)
public void Replace(scoped ReadOnlySpan<char> oldValue, scoped ReadOnlySpan<char> newValue)
=> Replace(oldValue, newValue, 0, Length);

/// <summary>
Expand All @@ -65,7 +98,7 @@ public void Replace(ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue)
/// </remarks>
/// /// <typeparam name="T">Any type.</typeparam>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReplaceGeneric<T>(ReadOnlySpan<char> oldValue, T newValue)
public void ReplaceGeneric<T>(scoped ReadOnlySpan<char> oldValue, T newValue)
=> ReplaceGeneric(oldValue, newValue, 0, Length);

/// <summary>
Expand All @@ -81,7 +114,7 @@ public void ReplaceGeneric<T>(ReadOnlySpan<char> oldValue, T newValue)
/// </remarks>
/// /// <typeparam name="T">Any type.</typeparam>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReplaceGeneric<T>(ReadOnlySpan<char> oldValue, T newValue, int startIndex, int count)
public void ReplaceGeneric<T>(scoped ReadOnlySpan<char> oldValue, T newValue, int startIndex, int count)
{
if (newValue is ISpanFormattable spanFormattable)
{
Expand Down