Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions api_list.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,7 @@
* `StringBuilder Insert(int, ReadOnlySpan<char>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.insert?view=net-11.0#system-text-stringbuilder-insert(system-int32-system-readonlyspan((system-char))))
* `StringBuilder Replace(ReadOnlySpan<char>, ReadOnlySpan<char>, int, int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.replace?view=net-11.0#system-text-stringbuilder-replace(system-char-system-char-system-int32-system-int32))
* `StringBuilder Replace(ReadOnlySpan<char>, ReadOnlySpan<char>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.replace?view=net-11.0#system-text-stringbuilder-replace(system-readonlyspan((system-char))-system-readonlyspan((system-char))))
* `StringBuilder MoveChunks(StringBuilder)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.movechunks?view=net-11.0)


#### Task
Expand Down
1 change: 1 addition & 0 deletions src/Consume/Consume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1526,6 +1526,7 @@ void DefaultInterpolatedStringHandler_Methods()
void StringBuilder_Methods()
{
var builder = new StringBuilder("value");
var moved = StringBuilder.MoveChunks(builder);
#if FeatureMemory
builder.Append("suffix".AsSpan());
var targetSpan = new Span<char>(new char[1]);
Expand Down
63 changes: 63 additions & 0 deletions src/Polyfill/StringBuilderPolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#if !NET12_0_OR_GREATER

namespace Polyfills;

using System;
using System.Reflection;
using System.Text;

static partial class Polyfill
{
extension(StringBuilder)
{
/// <summary>
/// Creates a new <see cref="StringBuilder"/> instance initialized to the same state as
/// <paramref name="source"/>, and resets <paramref name="source"/> to an empty, usable state
/// with no allocated buffers. Ownership of the chunks is transferred in O(1); the underlying
/// character data is not copied. <paramref name="source"/>'s <see cref="StringBuilder.MaxCapacity"/>
/// is preserved.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.movechunks?view=net-11.0
public static StringBuilder MoveChunks(StringBuilder source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}

var charsField = MoveChunksFields.ChunkChars;
var previousField = MoveChunksFields.ChunkPrevious;
var lengthField = MoveChunksFields.ChunkLength;
var offsetField = MoveChunksFields.ChunkOffset;
var maxCapacity = (int) MoveChunksFields.MaxCapacity.GetValue(source)!;

var destination = new StringBuilder(0, maxCapacity);
charsField.SetValue(destination, charsField.GetValue(source));
previousField.SetValue(destination, previousField.GetValue(source));
lengthField.SetValue(destination, lengthField.GetValue(source));
offsetField.SetValue(destination, offsetField.GetValue(source));

charsField.SetValue(source, Array.Empty<char>());
previousField.SetValue(source, null);
lengthField.SetValue(source, 0);
offsetField.SetValue(source, 0);

return destination;
}
}

static class MoveChunksFields
{
internal static readonly FieldInfo ChunkChars = GetField("m_ChunkChars");
internal static readonly FieldInfo ChunkPrevious = GetField("m_ChunkPrevious");
internal static readonly FieldInfo ChunkLength = GetField("m_ChunkLength");
internal static readonly FieldInfo ChunkOffset = GetField("m_ChunkOffset");
internal static readonly FieldInfo MaxCapacity = GetField("m_MaxCapacity");

static FieldInfo GetField(string name) =>
typeof(StringBuilder).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ??
throw new($"Expected to find field '{name}' on StringBuilder");
}
}

#endif
54 changes: 54 additions & 0 deletions src/Split/net10.0/StringBuilderPolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// <auto-generated />
#pragma warning disable
#if !NET12_0_OR_GREATER
namespace Polyfills;
using System;
using System.Reflection;
using System.Text;
static partial class Polyfill
{
extension(StringBuilder)
{
/// <summary>
/// Creates a new <see cref="StringBuilder"/> instance initialized to the same state as
/// <paramref name="source"/>, and resets <paramref name="source"/> to an empty, usable state
/// with no allocated buffers. Ownership of the chunks is transferred in O(1); the underlying
/// character data is not copied. <paramref name="source"/>'s <see cref="StringBuilder.MaxCapacity"/>
/// is preserved.
/// </summary>
public static StringBuilder MoveChunks(StringBuilder source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
var charsField = MoveChunksFields.ChunkChars;
var previousField = MoveChunksFields.ChunkPrevious;
var lengthField = MoveChunksFields.ChunkLength;
var offsetField = MoveChunksFields.ChunkOffset;
var maxCapacity = (int) MoveChunksFields.MaxCapacity.GetValue(source)!;
var destination = new StringBuilder(0, maxCapacity);
charsField.SetValue(destination, charsField.GetValue(source));
previousField.SetValue(destination, previousField.GetValue(source));
lengthField.SetValue(destination, lengthField.GetValue(source));
offsetField.SetValue(destination, offsetField.GetValue(source));
charsField.SetValue(source, Array.Empty<char>());
previousField.SetValue(source, null);
lengthField.SetValue(source, 0);
offsetField.SetValue(source, 0);
return destination;
}
}
static class MoveChunksFields
{
internal static readonly FieldInfo ChunkChars = GetField("m_ChunkChars");
internal static readonly FieldInfo ChunkPrevious = GetField("m_ChunkPrevious");
internal static readonly FieldInfo ChunkLength = GetField("m_ChunkLength");
internal static readonly FieldInfo ChunkOffset = GetField("m_ChunkOffset");
internal static readonly FieldInfo MaxCapacity = GetField("m_MaxCapacity");
static FieldInfo GetField(string name) =>
typeof(StringBuilder).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ??
throw new($"Expected to find field '{name}' on StringBuilder");
}
}
#endif
54 changes: 54 additions & 0 deletions src/Split/net11.0/StringBuilderPolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// <auto-generated />
#pragma warning disable
#if !NET12_0_OR_GREATER
namespace Polyfills;
using System;
using System.Reflection;
using System.Text;
static partial class Polyfill
{
extension(StringBuilder)
{
/// <summary>
/// Creates a new <see cref="StringBuilder"/> instance initialized to the same state as
/// <paramref name="source"/>, and resets <paramref name="source"/> to an empty, usable state
/// with no allocated buffers. Ownership of the chunks is transferred in O(1); the underlying
/// character data is not copied. <paramref name="source"/>'s <see cref="StringBuilder.MaxCapacity"/>
/// is preserved.
/// </summary>
public static StringBuilder MoveChunks(StringBuilder source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
var charsField = MoveChunksFields.ChunkChars;
var previousField = MoveChunksFields.ChunkPrevious;
var lengthField = MoveChunksFields.ChunkLength;
var offsetField = MoveChunksFields.ChunkOffset;
var maxCapacity = (int) MoveChunksFields.MaxCapacity.GetValue(source)!;
var destination = new StringBuilder(0, maxCapacity);
charsField.SetValue(destination, charsField.GetValue(source));
previousField.SetValue(destination, previousField.GetValue(source));
lengthField.SetValue(destination, lengthField.GetValue(source));
offsetField.SetValue(destination, offsetField.GetValue(source));
charsField.SetValue(source, Array.Empty<char>());
previousField.SetValue(source, null);
lengthField.SetValue(source, 0);
offsetField.SetValue(source, 0);
return destination;
}
}
static class MoveChunksFields
{
internal static readonly FieldInfo ChunkChars = GetField("m_ChunkChars");
internal static readonly FieldInfo ChunkPrevious = GetField("m_ChunkPrevious");
internal static readonly FieldInfo ChunkLength = GetField("m_ChunkLength");
internal static readonly FieldInfo ChunkOffset = GetField("m_ChunkOffset");
internal static readonly FieldInfo MaxCapacity = GetField("m_MaxCapacity");
static FieldInfo GetField(string name) =>
typeof(StringBuilder).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ??
throw new($"Expected to find field '{name}' on StringBuilder");
}
}
#endif
54 changes: 54 additions & 0 deletions src/Split/net461/StringBuilderPolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// <auto-generated />
#pragma warning disable
#if !NET12_0_OR_GREATER
namespace Polyfills;
using System;
using System.Reflection;
using System.Text;
static partial class Polyfill
{
extension(StringBuilder)
{
/// <summary>
/// Creates a new <see cref="StringBuilder"/> instance initialized to the same state as
/// <paramref name="source"/>, and resets <paramref name="source"/> to an empty, usable state
/// with no allocated buffers. Ownership of the chunks is transferred in O(1); the underlying
/// character data is not copied. <paramref name="source"/>'s <see cref="StringBuilder.MaxCapacity"/>
/// is preserved.
/// </summary>
public static StringBuilder MoveChunks(StringBuilder source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
var charsField = MoveChunksFields.ChunkChars;
var previousField = MoveChunksFields.ChunkPrevious;
var lengthField = MoveChunksFields.ChunkLength;
var offsetField = MoveChunksFields.ChunkOffset;
var maxCapacity = (int) MoveChunksFields.MaxCapacity.GetValue(source)!;
var destination = new StringBuilder(0, maxCapacity);
charsField.SetValue(destination, charsField.GetValue(source));
previousField.SetValue(destination, previousField.GetValue(source));
lengthField.SetValue(destination, lengthField.GetValue(source));
offsetField.SetValue(destination, offsetField.GetValue(source));
charsField.SetValue(source, Array.Empty<char>());
previousField.SetValue(source, null);
lengthField.SetValue(source, 0);
offsetField.SetValue(source, 0);
return destination;
}
}
static class MoveChunksFields
{
internal static readonly FieldInfo ChunkChars = GetField("m_ChunkChars");
internal static readonly FieldInfo ChunkPrevious = GetField("m_ChunkPrevious");
internal static readonly FieldInfo ChunkLength = GetField("m_ChunkLength");
internal static readonly FieldInfo ChunkOffset = GetField("m_ChunkOffset");
internal static readonly FieldInfo MaxCapacity = GetField("m_MaxCapacity");
static FieldInfo GetField(string name) =>
typeof(StringBuilder).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ??
throw new($"Expected to find field '{name}' on StringBuilder");
}
}
#endif
54 changes: 54 additions & 0 deletions src/Split/net462/StringBuilderPolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// <auto-generated />
#pragma warning disable
#if !NET12_0_OR_GREATER
namespace Polyfills;
using System;
using System.Reflection;
using System.Text;
static partial class Polyfill
{
extension(StringBuilder)
{
/// <summary>
/// Creates a new <see cref="StringBuilder"/> instance initialized to the same state as
/// <paramref name="source"/>, and resets <paramref name="source"/> to an empty, usable state
/// with no allocated buffers. Ownership of the chunks is transferred in O(1); the underlying
/// character data is not copied. <paramref name="source"/>'s <see cref="StringBuilder.MaxCapacity"/>
/// is preserved.
/// </summary>
public static StringBuilder MoveChunks(StringBuilder source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
var charsField = MoveChunksFields.ChunkChars;
var previousField = MoveChunksFields.ChunkPrevious;
var lengthField = MoveChunksFields.ChunkLength;
var offsetField = MoveChunksFields.ChunkOffset;
var maxCapacity = (int) MoveChunksFields.MaxCapacity.GetValue(source)!;
var destination = new StringBuilder(0, maxCapacity);
charsField.SetValue(destination, charsField.GetValue(source));
previousField.SetValue(destination, previousField.GetValue(source));
lengthField.SetValue(destination, lengthField.GetValue(source));
offsetField.SetValue(destination, offsetField.GetValue(source));
charsField.SetValue(source, Array.Empty<char>());
previousField.SetValue(source, null);
lengthField.SetValue(source, 0);
offsetField.SetValue(source, 0);
return destination;
}
}
static class MoveChunksFields
{
internal static readonly FieldInfo ChunkChars = GetField("m_ChunkChars");
internal static readonly FieldInfo ChunkPrevious = GetField("m_ChunkPrevious");
internal static readonly FieldInfo ChunkLength = GetField("m_ChunkLength");
internal static readonly FieldInfo ChunkOffset = GetField("m_ChunkOffset");
internal static readonly FieldInfo MaxCapacity = GetField("m_MaxCapacity");
static FieldInfo GetField(string name) =>
typeof(StringBuilder).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ??
throw new($"Expected to find field '{name}' on StringBuilder");
}
}
#endif
54 changes: 54 additions & 0 deletions src/Split/net47/StringBuilderPolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// <auto-generated />
#pragma warning disable
#if !NET12_0_OR_GREATER
namespace Polyfills;
using System;
using System.Reflection;
using System.Text;
static partial class Polyfill
{
extension(StringBuilder)
{
/// <summary>
/// Creates a new <see cref="StringBuilder"/> instance initialized to the same state as
/// <paramref name="source"/>, and resets <paramref name="source"/> to an empty, usable state
/// with no allocated buffers. Ownership of the chunks is transferred in O(1); the underlying
/// character data is not copied. <paramref name="source"/>'s <see cref="StringBuilder.MaxCapacity"/>
/// is preserved.
/// </summary>
public static StringBuilder MoveChunks(StringBuilder source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
var charsField = MoveChunksFields.ChunkChars;
var previousField = MoveChunksFields.ChunkPrevious;
var lengthField = MoveChunksFields.ChunkLength;
var offsetField = MoveChunksFields.ChunkOffset;
var maxCapacity = (int) MoveChunksFields.MaxCapacity.GetValue(source)!;
var destination = new StringBuilder(0, maxCapacity);
charsField.SetValue(destination, charsField.GetValue(source));
previousField.SetValue(destination, previousField.GetValue(source));
lengthField.SetValue(destination, lengthField.GetValue(source));
offsetField.SetValue(destination, offsetField.GetValue(source));
charsField.SetValue(source, Array.Empty<char>());
previousField.SetValue(source, null);
lengthField.SetValue(source, 0);
offsetField.SetValue(source, 0);
return destination;
}
}
static class MoveChunksFields
{
internal static readonly FieldInfo ChunkChars = GetField("m_ChunkChars");
internal static readonly FieldInfo ChunkPrevious = GetField("m_ChunkPrevious");
internal static readonly FieldInfo ChunkLength = GetField("m_ChunkLength");
internal static readonly FieldInfo ChunkOffset = GetField("m_ChunkOffset");
internal static readonly FieldInfo MaxCapacity = GetField("m_MaxCapacity");
static FieldInfo GetField(string name) =>
typeof(StringBuilder).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ??
throw new($"Expected to find field '{name}' on StringBuilder");
}
}
#endif
Loading
Loading