Merge branch 'develop' into main

This commit is contained in:
Oliver Booth 2023-04-12 12:47:53 +01:00
commit 9b4ef5abb6
No known key found for this signature in database
GPG Key ID: 20BEB9DC87961025
25 changed files with 1574 additions and 679 deletions

View File

@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- X10D: Added `TextWriter.WriteLineNoAlloc(uint[, ReadOnlySpan<char>[, IFormatProvider]])`. - X10D: Added `TextWriter.WriteLineNoAlloc(uint[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`. - X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`. - X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D.Unity: Added `RaycastHit.GetComponent` and `RaycastHit.TryGetComponent`.
### Changed ### Changed

View File

@ -9,6 +9,10 @@ This project uses C# 11.0 language features where feasible, and adheres to Style
There is an `.editorconfig` included in this repository. For quick and painless pull requests, ensure that the analyzer does not There is an `.editorconfig` included in this repository. For quick and painless pull requests, ensure that the analyzer does not
throw warnings. throw warnings.
Please ensure that you follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
specification, as the GitHub release for this project is automatically generated from the commit history, and formatted using the
convetional commits specification.
### Code style ### Code style
Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list: Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list:

View File

@ -0,0 +1,131 @@
using System.Globalization;
using System.Text;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class TextWriterTests
{
[Test]
public void WriteNoAlloc_ShouldThrowArgumentNullException_GivenDouble_AndNullWriter()
{
TextWriter writer = null!;
Assert.Throws<ArgumentNullException>(() => writer.WriteNoAlloc(420.0));
Assert.Throws<ArgumentNullException>(() => writer.WriteNoAlloc(420.0, "N0"));
Assert.Throws<ArgumentNullException>(() => writer.WriteNoAlloc(420.0, "N0", null));
}
[Test]
public void WriteNoAlloc_ShouldThrowObjectDisposedException_GivenDouble_AndDisposedStream()
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream, Encoding.UTF8);
writer.Dispose();
stream.Dispose();
Assert.Throws<ObjectDisposedException>(() => writer.WriteNoAlloc(420.0));
Assert.Throws<ObjectDisposedException>(() => writer.WriteNoAlloc(420.0, "N0"));
Assert.Throws<ObjectDisposedException>(() => writer.WriteNoAlloc(420.0, "N0", null));
}
[Test]
public void WriteLineNoAlloc_ShouldThrowArgumentNullException_GivenDouble_AndNullWriter()
{
TextWriter writer = null!;
Assert.Throws<ArgumentNullException>(() => writer.WriteLineNoAlloc(420.0));
Assert.Throws<ArgumentNullException>(() => writer.WriteLineNoAlloc(420.0, "N0"));
Assert.Throws<ArgumentNullException>(() => writer.WriteLineNoAlloc(420.0, "N0", null));
}
[Test]
public void WriteLineNoAlloc_ShouldThrowObjectDisposedException_GivenDouble_AndDisposedStream()
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream, Encoding.UTF8);
writer.Dispose();
stream.Dispose();
Assert.Throws<ObjectDisposedException>(() => writer.WriteLineNoAlloc(420.0));
Assert.Throws<ObjectDisposedException>(() => writer.WriteLineNoAlloc(420.0, "N0"));
Assert.Throws<ObjectDisposedException>(() => writer.WriteLineNoAlloc(420.0, "N0", null));
}
[Test]
public void WriteNoAlloc_ShouldWriteTextValue_GivenDouble()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteNoAlloc(420.0);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
const string expected = "420";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteNoAlloc_ShouldWriteTextValue_GivenDouble_AndFormatString()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteNoAlloc(420.0, "N0");
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
const string expected = "420";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteNoAlloc_ShouldWriteTextValue_GivenDouble_AndFormatString_AndCultureInfo()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteNoAlloc(420.0, "N0", CultureInfo.CurrentCulture);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
const string expected = "420";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteLineNoAlloc_ShouldWriteTextValue_GivenDouble()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteLineNoAlloc(420.0);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
var expected = $"420{Environment.NewLine}";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteLineNoAlloc_ShouldWriteTextValue_GivenDouble_AndFormatString()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteLineNoAlloc(420.0, "N0");
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
var expected = $"420{Environment.NewLine}";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteLineNoAlloc_ShouldWriteTextValue_GivenDouble_AndFormatString_AndCultureInfo()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteLineNoAlloc(420.0, "N0", CultureInfo.CurrentCulture);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
var expected = $"420{Environment.NewLine}";
Assert.That(actual, Is.EqualTo(expected));
}
}

View File

@ -0,0 +1,131 @@
using System.Globalization;
using System.Text;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class TextWriterTests
{
[Test]
public void WriteNoAlloc_ShouldThrowArgumentNullException_GivenSingle_AndNullWriter()
{
TextWriter writer = null!;
Assert.Throws<ArgumentNullException>(() => writer.WriteNoAlloc(420.0f));
Assert.Throws<ArgumentNullException>(() => writer.WriteNoAlloc(420.0f, "N0"));
Assert.Throws<ArgumentNullException>(() => writer.WriteNoAlloc(420.0f, "N0", null));
}
[Test]
public void WriteNoAlloc_ShouldThrowObjectDisposedException_GivenSingle_AndDisposedStream()
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream, Encoding.UTF8);
writer.Dispose();
stream.Dispose();
Assert.Throws<ObjectDisposedException>(() => writer.WriteNoAlloc(420.0f));
Assert.Throws<ObjectDisposedException>(() => writer.WriteNoAlloc(420.0f, "N0"));
Assert.Throws<ObjectDisposedException>(() => writer.WriteNoAlloc(420.0f, "N0", null));
}
[Test]
public void WriteLineNoAlloc_ShouldThrowArgumentNullException_GivenSingle_AndNullWriter()
{
TextWriter writer = null!;
Assert.Throws<ArgumentNullException>(() => writer.WriteLineNoAlloc(420.0f));
Assert.Throws<ArgumentNullException>(() => writer.WriteLineNoAlloc(420.0f, "N0"));
Assert.Throws<ArgumentNullException>(() => writer.WriteLineNoAlloc(420.0f, "N0", null));
}
[Test]
public void WriteLineNoAlloc_ShouldThrowObjectDisposedException_GivenSingle_AndDisposedStream()
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream, Encoding.UTF8);
writer.Dispose();
stream.Dispose();
Assert.Throws<ObjectDisposedException>(() => writer.WriteLineNoAlloc(420.0f));
Assert.Throws<ObjectDisposedException>(() => writer.WriteLineNoAlloc(420.0f, "N0"));
Assert.Throws<ObjectDisposedException>(() => writer.WriteLineNoAlloc(420.0f, "N0", null));
}
[Test]
public void WriteNoAlloc_ShouldWriteTextValue_GivenSingle()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteNoAlloc(420.0f);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
const string expected = "420";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteNoAlloc_ShouldWriteTextValue_GivenSingle_AndFormatString()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteNoAlloc(420.0f, "N0");
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
const string expected = "420";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteNoAlloc_ShouldWriteTextValue_GivenSingle_AndFormatString_AndCultureInfo()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteNoAlloc(420.0f, "N0", CultureInfo.CurrentCulture);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
const string expected = "420";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteLineNoAlloc_ShouldWriteTextValue_GivenSingle()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteLineNoAlloc(420.0f);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
var expected = $"420{Environment.NewLine}";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteLineNoAlloc_ShouldWriteTextValue_GivenSingle_AndFormatString()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteLineNoAlloc(420.0f, "N0");
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
var expected = $"420{Environment.NewLine}";
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void WriteLineNoAlloc_ShouldWriteTextValue_GivenSingle_AndFormatString_AndCultureInfo()
{
Assert.That(_stream.Length, Is.Zero);
_writer.WriteLineNoAlloc(420.0f, "N0", CultureInfo.CurrentCulture);
_writer.Flush();
string actual = Encoding.UTF8.GetString(_stream.ToArray());
var expected = $"420{Environment.NewLine}";
Assert.That(actual, Is.EqualTo(expected));
}
}

View File

@ -14,8 +14,14 @@ public static class ComponentExtensions
/// <param name="component">The component whose child components to retrieve.</param> /// <param name="component">The component whose child components to retrieve.</param>
/// <typeparam name="T">The type of the components to retrieve.</typeparam> /// <typeparam name="T">The type of the components to retrieve.</typeparam>
/// <returns>An array <typeparamref name="T" /> representing the child components.</returns> /// <returns>An array <typeparamref name="T" /> representing the child components.</returns>
/// <exception cref="ArgumentNullException"><paramref name="component" /> is <see langword="null" />.</exception>
public static T[] GetComponentsInChildrenOnly<T>(this Component component) public static T[] GetComponentsInChildrenOnly<T>(this Component component)
{ {
if (component == null)
{
throw new ArgumentNullException(nameof(component));
}
return component.gameObject.GetComponentsInChildrenOnly<T>(); return component.gameObject.GetComponentsInChildrenOnly<T>();
} }
} }

View File

@ -14,8 +14,14 @@ public static class PolygonExtensions
/// </summary> /// </summary>
/// <param name="polygon">The polygon whose points to update.</param> /// <param name="polygon">The polygon whose points to update.</param>
/// <param name="point">The point to add.</param> /// <param name="point">The point to add.</param>
/// <exception cref="ArgumentNullException"><paramref name="polygon" /> is <see langword="null" />.</exception>
public static void AddVertex(this Polygon polygon, Vector2Int point) public static void AddVertex(this Polygon polygon, Vector2Int point)
{ {
if (polygon is null)
{
throw new ArgumentNullException(nameof(polygon));
}
polygon.AddVertex(point.ToSystemPoint()); polygon.AddVertex(point.ToSystemPoint());
} }
@ -24,8 +30,23 @@ public static class PolygonExtensions
/// </summary> /// </summary>
/// <param name="polygon">The polygon whose vertices to update.</param> /// <param name="polygon">The polygon whose vertices to update.</param>
/// <param name="vertices">The vertices to add.</param> /// <param name="vertices">The vertices to add.</param>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="polygon" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="vertices" /> is <see langword="null" />.</para>
/// </exception>
public static void AddVertices(this Polygon polygon, IEnumerable<Vector2Int> vertices) public static void AddVertices(this Polygon polygon, IEnumerable<Vector2Int> vertices)
{ {
if (polygon is null)
{
throw new ArgumentNullException(nameof(polygon));
}
if (vertices is null)
{
throw new ArgumentNullException(nameof(vertices));
}
foreach (Vector2Int vertex in vertices) foreach (Vector2Int vertex in vertices)
{ {
polygon.AddVertex(vertex); polygon.AddVertex(vertex);

View File

@ -14,8 +14,14 @@ public static class PolygonFExtensions
/// </summary> /// </summary>
/// <param name="polygon">The polygon whose vertices to update.</param> /// <param name="polygon">The polygon whose vertices to update.</param>
/// <param name="vertex">The vertex to add.</param> /// <param name="vertex">The vertex to add.</param>
/// <exception cref="ArgumentNullException"><paramref name="polygon" /> is <see langword="null" />.</exception>
public static void AddVertex(this PolygonF polygon, Vector2Int vertex) public static void AddVertex(this PolygonF polygon, Vector2Int vertex)
{ {
if (polygon is null)
{
throw new ArgumentNullException(nameof(polygon));
}
polygon.AddVertex(vertex.ToSystemPoint()); polygon.AddVertex(vertex.ToSystemPoint());
} }
@ -24,8 +30,14 @@ public static class PolygonFExtensions
/// </summary> /// </summary>
/// <param name="polygon">The polygon whose vertices to update.</param> /// <param name="polygon">The polygon whose vertices to update.</param>
/// <param name="vertex">The vertex to add.</param> /// <param name="vertex">The vertex to add.</param>
/// <exception cref="ArgumentNullException"><paramref name="polygon" /> is <see langword="null" />.</exception>
public static void AddVertex(this PolygonF polygon, Vector2 vertex) public static void AddVertex(this PolygonF polygon, Vector2 vertex)
{ {
if (polygon is null)
{
throw new ArgumentNullException(nameof(polygon));
}
polygon.AddVertex(vertex.ToSystemPointF()); polygon.AddVertex(vertex.ToSystemPointF());
} }
@ -34,8 +46,23 @@ public static class PolygonFExtensions
/// </summary> /// </summary>
/// <param name="polygon">The polygon whose vertices to update.</param> /// <param name="polygon">The polygon whose vertices to update.</param>
/// <param name="vertices">The vertices to add.</param> /// <param name="vertices">The vertices to add.</param>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="polygon" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="vertices" /> is <see langword="null" />.</para>
/// </exception>
public static void AddVertices(this PolygonF polygon, IEnumerable<Vector2Int> vertices) public static void AddVertices(this PolygonF polygon, IEnumerable<Vector2Int> vertices)
{ {
if (polygon is null)
{
throw new ArgumentNullException(nameof(polygon));
}
if (vertices is null)
{
throw new ArgumentNullException(nameof(vertices));
}
foreach (Vector2Int vertex in vertices) foreach (Vector2Int vertex in vertices)
{ {
polygon.AddVertex(vertex); polygon.AddVertex(vertex);
@ -47,8 +74,23 @@ public static class PolygonFExtensions
/// </summary> /// </summary>
/// <param name="polygon">The polygon whose vertices to update.</param> /// <param name="polygon">The polygon whose vertices to update.</param>
/// <param name="vertices">The vertices to add.</param> /// <param name="vertices">The vertices to add.</param>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="polygon" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="vertices" /> is <see langword="null" />.</para>
/// </exception>
public static void AddVertices(this PolygonF polygon, IEnumerable<Vector2> vertices) public static void AddVertices(this PolygonF polygon, IEnumerable<Vector2> vertices)
{ {
if (polygon is null)
{
throw new ArgumentNullException(nameof(polygon));
}
if (vertices is null)
{
throw new ArgumentNullException(nameof(vertices));
}
foreach (Vector2 vertex in vertices) foreach (Vector2 vertex in vertices)
{ {
polygon.AddVertex(vertex); polygon.AddVertex(vertex);

View File

@ -14,8 +14,14 @@ public static class PolyhedronExtensions
/// </summary> /// </summary>
/// <param name="polyhedron">The polyhedron whose vertices to update.</param> /// <param name="polyhedron">The polyhedron whose vertices to update.</param>
/// <param name="vertex">The vertex to add.</param> /// <param name="vertex">The vertex to add.</param>
/// <exception cref="ArgumentNullException"><paramref name="polyhedron" /> is <see langword="null" />.</exception>
public static void AddVertex(this Polyhedron polyhedron, Vector3Int vertex) public static void AddVertex(this Polyhedron polyhedron, Vector3Int vertex)
{ {
if (polyhedron is null)
{
throw new ArgumentNullException(nameof(polyhedron));
}
polyhedron.AddVertex(vertex.ToSystemVector()); polyhedron.AddVertex(vertex.ToSystemVector());
} }
@ -24,8 +30,14 @@ public static class PolyhedronExtensions
/// </summary> /// </summary>
/// <param name="polyhedron">The polyhedron whose vertices to update.</param> /// <param name="polyhedron">The polyhedron whose vertices to update.</param>
/// <param name="vertex">The vertex to add.</param> /// <param name="vertex">The vertex to add.</param>
/// <exception cref="ArgumentNullException"><paramref name="polyhedron" /> is <see langword="null" />.</exception>
public static void AddVertex(this Polyhedron polyhedron, Vector3 vertex) public static void AddVertex(this Polyhedron polyhedron, Vector3 vertex)
{ {
if (polyhedron is null)
{
throw new ArgumentNullException(nameof(polyhedron));
}
polyhedron.AddVertex(vertex.ToSystemVector()); polyhedron.AddVertex(vertex.ToSystemVector());
} }
@ -34,8 +46,23 @@ public static class PolyhedronExtensions
/// </summary> /// </summary>
/// <param name="polyhedron">The polyhedron whose vertices to update.</param> /// <param name="polyhedron">The polyhedron whose vertices to update.</param>
/// <param name="vertices">The vertices to add.</param> /// <param name="vertices">The vertices to add.</param>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="polyhedron" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="vertices" /> is <see langword="null" />.</para>
/// </exception>
public static void AddVertices(this Polyhedron polyhedron, IEnumerable<Vector3Int> vertices) public static void AddVertices(this Polyhedron polyhedron, IEnumerable<Vector3Int> vertices)
{ {
if (polyhedron is null)
{
throw new ArgumentNullException(nameof(polyhedron));
}
if (vertices is null)
{
throw new ArgumentNullException(nameof(vertices));
}
foreach (Vector3Int vertex in vertices) foreach (Vector3Int vertex in vertices)
{ {
polyhedron.AddVertex(vertex); polyhedron.AddVertex(vertex);
@ -47,8 +74,23 @@ public static class PolyhedronExtensions
/// </summary> /// </summary>
/// <param name="polyhedron">The polyhedron whose vertices to update.</param> /// <param name="polyhedron">The polyhedron whose vertices to update.</param>
/// <param name="vertices">The vertices to add.</param> /// <param name="vertices">The vertices to add.</param>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="polyhedron" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="vertices" /> is <see langword="null" />.</para>
/// </exception>
public static void AddVertices(this Polyhedron polyhedron, IEnumerable<Vector3> vertices) public static void AddVertices(this Polyhedron polyhedron, IEnumerable<Vector3> vertices)
{ {
if (polyhedron is null)
{
throw new ArgumentNullException(nameof(polyhedron));
}
if (vertices is null)
{
throw new ArgumentNullException(nameof(vertices));
}
foreach (Vector3 vertex in vertices) foreach (Vector3 vertex in vertices)
{ {
polyhedron.AddVertex(vertex); polyhedron.AddVertex(vertex);

View File

@ -2,6 +2,8 @@
using X10D.Core; using X10D.Core;
using Random = System.Random; using Random = System.Random;
#pragma warning disable CA5394
namespace X10D.Unity.Drawing; namespace X10D.Unity.Drawing;
/// <summary> /// <summary>

View File

@ -13,8 +13,14 @@ public static class GameObjectExtensions
/// <param name="gameObject">The game object whose child components to retrieve.</param> /// <param name="gameObject">The game object whose child components to retrieve.</param>
/// <typeparam name="T">The type of the components to retrieve.</typeparam> /// <typeparam name="T">The type of the components to retrieve.</typeparam>
/// <returns>An array <typeparamref name="T" /> representing the child components.</returns> /// <returns>An array <typeparamref name="T" /> representing the child components.</returns>
/// <exception cref="ArgumentNullException"><paramref name="gameObject" /> is <see langword="null" />.</exception>
public static T[] GetComponentsInChildrenOnly<T>(this GameObject gameObject) public static T[] GetComponentsInChildrenOnly<T>(this GameObject gameObject)
{ {
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
Transform rootTransform = gameObject.transform; Transform rootTransform = gameObject.transform;
var components = new List<T>(gameObject.GetComponentsInChildren<T>()); var components = new List<T>(gameObject.GetComponentsInChildren<T>());

View File

@ -2,6 +2,8 @@
using X10D.Core; using X10D.Core;
using Random = System.Random; using Random = System.Random;
#pragma warning disable CA5394
namespace X10D.Unity.Numerics; namespace X10D.Unity.Numerics;
/// <summary> /// <summary>

View File

@ -0,0 +1,109 @@
using System.Diagnostics.CodeAnalysis;
using UnityEngine;
namespace X10D.Unity;
/// <summary>
/// Extension methods for <see cref="RaycastHit" />.
/// </summary>
public static class RaycastHitExtensions
{
/// <summary>
/// Gets the component of the specified type from the object that was hit by the raycast.
/// </summary>
/// <param name="hit">The raycast hit.</param>
/// <typeparam name="T">The type of the component to retrieve.</typeparam>
/// <returns>
/// The component of the specified type from the object that was hit by the raycast, or <see langword="null" /> if no
/// component of the specified type was found.
/// </returns>
public static T? GetComponent<T>(this RaycastHit hit)
{
if (hit.transform == null)
{
return default;
}
return hit.transform.GetComponent<T>();
}
/// <summary>
/// Gets the component of the specified type from the object that was hit by the raycast.
/// </summary>
/// <param name="hit">The raycast hit.</param>
/// <param name="componentType">The type of the component to retrieve.</param>
/// <returns>
/// The component of the specified type from the object that was hit by the raycast, or <see langword="null" /> if no
/// component of the specified type was found.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="componentType" /> is <see langword="null" />.</exception>
public static Component? GetComponent(this RaycastHit hit, Type componentType)
{
if (componentType is null)
{
throw new ArgumentNullException(nameof(componentType));
}
if (hit.transform == null)
{
return default;
}
return hit.transform.GetComponent(componentType);
}
/// <summary>
/// Attempts to get the component of the specified type from the object that was hit by the raycast, and returns a value
/// that indicates whether the operation succeeded.
/// </summary>
/// <param name="hit">The raycast hit.</param>
/// <param name="component">
/// When this method returns, contains the component of the specified type from the object that was hit by the raycast, or
/// <see langword="null" /> if no component of the specified type was found.
/// </param>
/// <typeparam name="T">The type of the component to retrieve.</typeparam>
/// <returns>
/// <see langword="true" /> if the component of the specified type was found; otherwise, <see langword="false" />.
/// </returns>
public static bool TryGetComponent<T>(this RaycastHit hit, [NotNullWhen(true)] out T? component)
{
if (hit.transform == null)
{
component = default;
return false;
}
return hit.transform.TryGetComponent(out component);
}
/// <summary>
/// Attempts to get the component of the specified type from the object that was hit by the raycast, and returns a value
/// that indicates whether the operation succeeded.
/// </summary>
/// <param name="hit">The raycast hit.</param>
/// <param name="componentType">The type of the component to retrieve.</param>
/// <param name="component">
/// When this method returns, contains the component of the specified type from the object that was hit by the raycast, or
/// <see langword="null" /> if no component of the specified type was found.
/// </param>
/// <returns>
/// <see langword="true" /> if the component of the specified type was found; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="componentType" /> is <see langword="null" />.</exception>
public static bool TryGetComponent(this RaycastHit hit, Type componentType, [NotNullWhen(true)] out Component? component)
{
if (componentType is null)
{
throw new ArgumentNullException(nameof(componentType));
}
if (hit.transform == null)
{
component = default;
return false;
}
return hit.transform.TryGetComponent(componentType, out component);
}
}

View File

@ -0,0 +1,83 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of an 8-byte floating-point value to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte floating-point value to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, double value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte floating-point value to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, double value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteLineNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte floating-point value to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, double value, ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
}

View File

@ -0,0 +1,83 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, int value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteLineNoAlloc(writer, (long)value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
}

View File

@ -0,0 +1,85 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, long value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, long value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer,
long value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
}

View File

@ -0,0 +1,83 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of a 4-byte floating-point value to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte floating-point value to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, float value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte floating-point value to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, float value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteLineNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte floating-point value to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, float value, ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
}

View File

@ -0,0 +1,88 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, uint value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, uint value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteLineNoAlloc(writer, (long)value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer,
uint value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
}

View File

@ -0,0 +1,88 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of an 8-byte unsigned integer to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, ulong value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte unsigned integer to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, ulong value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte unsigned integer to the text stream, followed by a line terminator,
/// without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer,
ulong value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
}

View File

@ -0,0 +1,91 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of an 8-byte floating-point value to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte floating-point value to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, double value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte floating-point value to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, double value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte floating-point value to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, double value, ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
Span<char> buffer = stackalloc char[100];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
}

View File

@ -0,0 +1,92 @@
using System.Globalization;
using X10D.Math;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, int value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format, IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(value < 0 ? digitCount + 1 : digitCount, 100)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
}

View File

@ -0,0 +1,95 @@
using System.Globalization;
using X10D.Math;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, long value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, long value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer,
long value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(value < 0 ? digitCount + 1 : digitCount, 100)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
}

View File

@ -0,0 +1,91 @@
using System.Globalization;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of a 4-byte floating-point value to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte floating-point value to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, float value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte floating-point value to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, float value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte floating-point value to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte floating-point value to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, float value, ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
Span<char> buffer = stackalloc char[100];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
}

View File

@ -0,0 +1,98 @@
using System.Globalization;
using X10D.Math;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, uint value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, uint value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer,
uint value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(digitCount, 100)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
}

View File

@ -0,0 +1,98 @@
using System.Globalization;
using X10D.Math;
namespace X10D.IO;
public static partial class TextWriterExtensions
{
/// <summary>
/// Writes the text representation of an 8-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, ulong value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, ulong value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of an 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer,
ulong value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(digitCount, 100)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
}

View File

@ -1,685 +1,8 @@
using System.Globalization; namespace X10D.IO;
using X10D.Math;
namespace X10D.IO;
/// <summary> /// <summary>
/// IO-related extension methods for <see cref="TextWriter" />. /// IO-related extension methods for <see cref="TextWriter" />.
/// </summary> /// </summary>
public static class TextWriterExtensions public static partial class TextWriterExtensions
{ {
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, int value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format, IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(value < 0 ? digitCount + 1 : digitCount, 1000)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, uint value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, uint value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer,
uint value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(digitCount, 1000)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, long value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer, long value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteNoAlloc(this TextWriter writer,
long value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(value < 0 ? digitCount + 1 : digitCount, 1000)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
/// <summary>
/// Writes the text representation of a 8-byte unsigned integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, ulong value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer, ulong value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
WriteNoAlloc(writer, value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, without allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteNoAlloc(this TextWriter writer,
ulong value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
int digitCount = value.CountDigits();
Span<char> buffer = stackalloc char[System.Math.Max(digitCount, 1000)];
if (value.TryFormat(buffer, out int charsWritten, format, formatProvider))
{
Span<char> truncated = buffer[..charsWritten];
for (var index = 0; index < truncated.Length; index++)
{
writer.Write(truncated[index]);
}
}
else
{
writer.Write(value.ToString(format.ToString(), formatProvider));
}
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, int value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, int value, ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, uint value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, uint value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 4-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 4-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer,
uint value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, long value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer, long value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte signed integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
public static void WriteLineNoAlloc(this TextWriter writer,
long value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
/// <summary>
/// Writes the text representation of a 8-byte unsigned integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, ulong value)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, "N0".AsSpan(), CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer, ulong value, ReadOnlySpan<char> format)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteLineNoAlloc(value, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// Writes the text representation of a 8-byte signed integer to the text stream, followed by a line terminator, without
/// allocating a string.
/// </summary>
/// <param name="writer">The <see cref="TextWriter" /> to write to.</param>
/// <param name="value">The 8-byte unsigned integer to write.</param>
/// <param name="format">A standard or custom numeric format string.</param>
/// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
/// <remarks>This method may still allocate if the integer is too large to fit in a stack-allocated buffer.</remarks>
/// <exception cref="ArgumentNullException"><paramref name="writer" /> is <see langword="null" />.</exception>
/// <exception cref="ObjectDisposedException">The <see cref="TextWriter" /> is closed.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception>
[CLSCompliant(false)]
public static void WriteLineNoAlloc(this TextWriter writer,
ulong value,
ReadOnlySpan<char> format,
IFormatProvider? formatProvider)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(writer);
#else
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
#endif
writer.WriteNoAlloc(value, format, formatProvider);
writer.WriteLine();
}
} }