using System; using System.Text; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder { /// /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. /// /// /// /// public void AppendJoin(char separator, params T[] values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values.AsSpan()); } public void AppendJoin(char separator, List values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, (IReadOnlyList)values); } public void AppendJoin(char separator, ReadOnlySpan values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } /// /// Concatenates and appends the members of a collection, using the specified char separator between each member. /// /// /// /// public void AppendJoin(char separator, IEnumerable values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } public void AppendJoin(char separator, ICollection values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values.AsEnumerable()); } public void AppendJoin(char separator, IList values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } public void AppendJoin(char separator, IReadOnlyList values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } public void AppendJoin(char separator, IReadOnlyCollection values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values.AsEnumerable()); } /// /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. /// /// /// /// public void AppendJoin(string separator, params T[] values) { AppendJoinInternal(separator.AsSpan(), values.AsSpan()); } public void AppendJoin(string separator, List values) { AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); } public void AppendJoin(string separator, ReadOnlySpan values) { AppendJoinInternal(separator.AsSpan(), values); } /// /// Concatenates and appends the members of a collection, using the specified separator between each member. /// /// /// /// public void AppendJoin(string separator, IEnumerable values) { AppendJoinInternal(separator.AsSpan(), values); } public void AppendJoin(string separator, ICollection values) { AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); } public void AppendJoin(string separator, IList values) { AppendJoinInternal(separator.AsSpan(), values); } public void AppendJoin(string separator, IReadOnlyList values) { AppendJoinInternal(separator.AsSpan(), values); } public void AppendJoin(string separator, IReadOnlyCollection values) { AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); } internal void AppendJoinInternal(ReadOnlySpan separator, IList values) { var readOnlyList = values as IReadOnlyList; // Boxing will occur, but JIT will be de-virtualized. readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); AppendJoinInternal(separator, readOnlyList); } internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) { var count = values.Count; for (int i = 0; i < count; i++) { if (i != 0) { Append(separator); } var item = values[i]; if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); if (!string.IsNullOrEmpty(s)) { Append(s); } } else { Append(item); } } } internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { for (int i = 0; i < values.Length; i++) { if (i != 0) { Append(separator); } var item = values[i]; if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); if (!string.IsNullOrEmpty(s)) { Append(s); } } else { Append(item); } } } internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) { var isFirst = true; foreach (var item in values) { if (!isFirst) { Append(separator); } else { isFirst = false; } if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); if (!string.IsNullOrEmpty(s)) { Append(s); } } else { Append(item); } } } } public partial struct Utf8ValueStringBuilder { /// /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. /// /// /// /// public void AppendJoin(char separator, params T[] values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values.AsSpan()); } public void AppendJoin(char separator, List values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, (IReadOnlyList)values); } public void AppendJoin(char separator, ReadOnlySpan values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } /// /// Concatenates and appends the members of a collection, using the specified char separator between each member. /// /// /// /// public void AppendJoin(char separator, IEnumerable values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } public void AppendJoin(char separator, ICollection values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values.AsEnumerable()); } public void AppendJoin(char separator, IList values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } public void AppendJoin(char separator, IReadOnlyList values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values); } public void AppendJoin(char separator, IReadOnlyCollection values) { ReadOnlySpan s = stackalloc char[1] { separator }; AppendJoinInternal(s, values.AsEnumerable()); } /// /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. /// /// /// /// public void AppendJoin(string separator, params T[] values) { AppendJoinInternal(separator.AsSpan(), values.AsSpan()); } public void AppendJoin(string separator, List values) { AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); } public void AppendJoin(string separator, ReadOnlySpan values) { AppendJoinInternal(separator.AsSpan(), values); } /// /// Concatenates and appends the members of a collection, using the specified separator between each member. /// /// /// /// public void AppendJoin(string separator, IEnumerable values) { AppendJoinInternal(separator.AsSpan(), values); } public void AppendJoin(string separator, ICollection values) { AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); } public void AppendJoin(string separator, IList values) { AppendJoinInternal(separator.AsSpan(), values); } public void AppendJoin(string separator, IReadOnlyList values) { AppendJoinInternal(separator.AsSpan(), values); } public void AppendJoin(string separator, IReadOnlyCollection values) { AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); } internal void AppendJoinInternal(ReadOnlySpan separator, IList values) { var readOnlyList = values as IReadOnlyList; // Boxing will occur, but JIT will be de-virtualized. readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); AppendJoinInternal(separator, readOnlyList); } internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) { var count = values.Count; for (int i = 0; i < count; i++) { if (i != 0) { Append(separator); } var item = values[i]; if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); if (!string.IsNullOrEmpty(s)) { Append(s); } } else { Append(item); } } } internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { for (int i = 0; i < values.Length; i++) { if (i != 0) { Append(separator); } var item = values[i]; if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); if (!string.IsNullOrEmpty(s)) { Append(s); } } else { Append(item); } } } internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) { var isFirst = true; foreach (var item in values) { if (!isFirst) { Append(separator); } else { isFirst = false; } if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); if (!string.IsNullOrEmpty(s)) { Append(s); } } else { Append(item); } } } } }