Refactor and enhance math, memory, and utilities
Refactored `sincos` usage in `quaternion` to use tuple-based returns for improved readability. Introduced a `random` struct with methods for generating random values of various types and dimensions, including ranges and directions. Added a `DynamicArray` class for dynamic resizing and manipulation of collections. Enhanced `SlotMap` with new methods for safe access and updates. Updated `uint` vector types with `NumericConvertable` attributes for better type interoperability. Removed the `MathUtilities` class and refactored `adj` and `adjInverse` methods for encapsulation. Improved memory management with `StackAllocator` and `UnsafeArray` enhancements. Added geometry utilities like `AABB`, `OBB`, `Plane`, and `SphereBounds` for 3D operations. Updated project configuration for versioning and NuGet packaging. Performed general code cleanup, improved validation, and aligned with modern C# practices.
This commit is contained in:
129
Misaki.HighPerformance.LowLevel/Collections/FixedString.tt
Normal file
129
Misaki.HighPerformance.LowLevel/Collections/FixedString.tt
Normal file
@@ -0,0 +1,129 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Misaki.HighPerformance.LowLevel.Collections;
|
||||
|
||||
<# for (int i = 32; i <= 4096; i *= 2) { #>
|
||||
/// <summary>
|
||||
/// Represents a stack allocated fixed-size UTF-8 encoded string of length <#= i #> bytes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This struct is designed to hold data on the stack. Every copy of this struct causes a copy of the underlying data.
|
||||
/// If you need a heap allocated fixed-size UTF-8 encoded string of length <#= i #> bytes, consider using <see cref="Misaki.HighPerformance.Unsafe.Buffer.FixedString<#= i #>"/>.
|
||||
/// </remarks>
|
||||
[StructLayout(LayoutKind.Sequential, Size = <#= i #>)]
|
||||
public unsafe struct FixedString<#= i #>
|
||||
{
|
||||
private ushort _length;
|
||||
private fixed byte _buffer[<#= i - 2 #>];
|
||||
|
||||
public readonly ushort Length => _length;
|
||||
public string Value
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (byte* bufferPtr = _buffer)
|
||||
{
|
||||
return Encoding.UTF8.GetString(bufferPtr, _length);
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
_length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
var maxBytes = Encoding.UTF8.GetByteCount(value);
|
||||
if (maxBytes > <#= i - 2 #>)
|
||||
{
|
||||
throw new ArgumentException("Input string is too long to fit in FixedString<#= i #>.");
|
||||
}
|
||||
|
||||
fixed (byte* bufferPtr = _buffer)
|
||||
{
|
||||
_length = (ushort)Encoding.UTF8.GetBytes(value, new Span<byte>(bufferPtr, <#= i - 2 #>));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FixedString<#= i #>(ReadOnlySpan<char> input)
|
||||
{
|
||||
var maxBytes = Encoding.UTF8.GetByteCount(input);
|
||||
if (maxBytes > <#= i - 2 #>)
|
||||
{
|
||||
throw new ArgumentException("Input string is too long to fit in FixedString<#= i #>.");
|
||||
}
|
||||
|
||||
fixed (char* inputPtr = input)
|
||||
fixed (byte* bufferPtr = _buffer)
|
||||
{
|
||||
var actualByteCount = Encoding.UTF8.GetBytes(inputPtr, input.Length, bufferPtr, <#= i - 2 #>);
|
||||
_length = (ushort)actualByteCount;
|
||||
}
|
||||
}
|
||||
|
||||
public FixedString<#= i #>(string input)
|
||||
: this(input.AsSpan())
|
||||
{
|
||||
}
|
||||
|
||||
public FixedString<#= i #>(char* input, ushort length)
|
||||
: this(new Span<char>(input, length))
|
||||
{
|
||||
}
|
||||
|
||||
public FixedString<#= i #>(ReadOnlySpan<byte> input)
|
||||
{
|
||||
if (input.Length > <#= i - 2 #>)
|
||||
{
|
||||
throw new ArgumentException("Input byte array is too long to fit in FixedString<#= i #>.");
|
||||
}
|
||||
|
||||
_length = (ushort)input.Length;
|
||||
|
||||
fixed (byte* inputPtr = input)
|
||||
fixed (byte* bufferPtr = _buffer)
|
||||
{
|
||||
Unsafe.CopyBlockUnaligned(bufferPtr, inputPtr, _length);
|
||||
}
|
||||
}
|
||||
|
||||
public FixedString<#= i #>(byte* input, ushort length)
|
||||
: this(new ReadOnlySpan<byte>(input, length))
|
||||
{
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span<byte> AsSpan()
|
||||
{
|
||||
fixed (byte* ptr = _buffer)
|
||||
{
|
||||
return new(ptr, _length);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public byte* GetUnsafePointer()
|
||||
{
|
||||
fixed (byte* ptr = _buffer)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
|
||||
<# } #>
|
||||
Reference in New Issue
Block a user