I wrote and use use the following extension/tool methods to concatenate spans:
ReadOnlySpan<T> otherSpan = ...
T[] someArray = ...
var myArray = someSpan.Concat(otherSpan, someArray, etc);
var myArray2 = SpanTool.Concat(someArray, otherSpan, etc);
SpanExtensions.cs
public static class SpanExtensions {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] Concat<T>(this ReadOnlySpan<T> span0, ReadOnlySpan<T> span1)
=> SpanTool.Concat(span0, span1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] Concat<T>(this ReadOnlySpan<T> span0, ReadOnlySpan<T> span1, ReadOnlySpan<T> span2)
=> SpanTool.Concat(span0, span1, span2);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] Concat<T>(this ReadOnlySpan<T> span0, ReadOnlySpan<T> span1, ReadOnlySpan<T> span2, ReadOnlySpan<T> span3)
=> SpanTool.Concat(span0, span1, span2, span3);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] Concat<T>(this ReadOnlySpan<T> span0, ReadOnlySpan<T> span1, ReadOnlySpan<T> span2, ReadOnlySpan<T> span3, ReadOnlySpan<T> span4)
=> SpanTool.Concat(span0, span1, span2, span3, span4);
}
SpanTool.cs
public static class SpanTool {
public static T[] Concat<T>(ReadOnlySpan<T> span0) {
var result = new T[span0.Length];
span0.CopyTo(result);
return result;
}
public static T[] Concat<T>(ReadOnlySpan<T> span0, ReadOnlySpan<T> span1) {
var result = new T[span0.Length + span1.Length];
var resultSpan = result.AsSpan();
span0.CopyTo(result);
var from = span0.Length;
span1.CopyTo(resultSpan.Slice(from));
return result;
}
public static T[] Concat<T>(ReadOnlySpan<T> span0, ReadOnlySpan<T> span1, ReadOnlySpan<T> span2) {
var result = new T[span0.Length + span1.Length + span2.Length];
var resultSpan = result.AsSpan();
span0.CopyTo(result);
var from = span0.Length;
span1.CopyTo(resultSpan.Slice(from));
from += span1.Length;
span2.CopyTo(resultSpan.Slice(from));
return result;
}
public static T[] Concat<T>(ReadOnlySpan<T> span0, ReadOnlySpan<T> span1, ReadOnlySpan<T> span2, ReadOnlySpan<T> span3) {
var result = new T[span0.Length + span1.Length + span2.Length + span3.Length];
var resultSpan = result.AsSpan();
span0.CopyTo(result);
var from = span0.Length;
span1.CopyTo(resultSpan.Slice(from));
from += span1.Length;
span2.CopyTo(resultSpan.Slice(from));
from += span2.Length;
span3.CopyTo(resultSpan.Slice(from));
return result;
}
public static T[] Concat<T>(ReadOnlySpan<T> span0, ReadOnlySpan<T> span1, ReadOnlySpan<T> span2, ReadOnlySpan<T> span3, ReadOnlySpan<T> span4) {
var result = new T[span0.Length + span1.Length + span2.Length + span3.Length + span4.Length];
var resultSpan = result.AsSpan();
span0.CopyTo(result);
var from = span0.Length;
span1.CopyTo(resultSpan.Slice(from));
from += span1.Length;
span2.CopyTo(resultSpan.Slice(from));
from += span2.Length;
span3.CopyTo(resultSpan.Slice(from));
from += span3.Length;
span4.CopyTo(resultSpan.Slice(from));
return result;
}
}
DISCLAIMER I just wrote this now for my project after the answers here were unsatisfactory. If any bugs, will edit later.
string
- immutability is a lie) using the source spans. Concatenation isn't readily built in AFAIK. – Chiltonresult
be eitherReadOnlySpan<char>
orstring
– UnclinchBuffer.Memcpy
through wstrcpy. The important thing is that the string you modify must be newly allocated (with thenew String('\0', length)
constructor for example, or another constructor, or the.Copy()
). See for example here – Azovunsafe
is your friendfixed(char* ptr = theString) { ptr[3] = 'f'; }
– Chilton