diff --git a/src/Box2D.NET/B2FixedArray1.cs b/src/Box2D.NET/B2FixedArray1.cs index d8ba46c..e7de896 100644 --- a/src/Box2D.NET/B2FixedArray1.cs +++ b/src/Box2D.NET/B2FixedArray1.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -21,13 +21,19 @@ public struct B2FixedArray1 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray1024.cs b/src/Box2D.NET/B2FixedArray1024.cs index ff9f8a9..afaeaf0 100644 --- a/src/Box2D.NET/B2FixedArray1024.cs +++ b/src/Box2D.NET/B2FixedArray1024.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -1044,14 +1044,20 @@ public struct B2FixedArray1024 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray11.cs b/src/Box2D.NET/B2FixedArray11.cs index 4d07526..72fa8a3 100644 --- a/src/Box2D.NET/B2FixedArray11.cs +++ b/src/Box2D.NET/B2FixedArray11.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -31,13 +31,19 @@ public struct B2FixedArray11 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray12.cs b/src/Box2D.NET/B2FixedArray12.cs index e2ef267..eae31b1 100644 --- a/src/Box2D.NET/B2FixedArray12.cs +++ b/src/Box2D.NET/B2FixedArray12.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -32,14 +32,20 @@ public struct B2FixedArray12 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray16.cs b/src/Box2D.NET/B2FixedArray16.cs index e38dde3..66b7e6f 100644 --- a/src/Box2D.NET/B2FixedArray16.cs +++ b/src/Box2D.NET/B2FixedArray16.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -36,13 +36,19 @@ public struct B2FixedArray16 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray2.cs b/src/Box2D.NET/B2FixedArray2.cs index c83115d..63a027a 100644 --- a/src/Box2D.NET/B2FixedArray2.cs +++ b/src/Box2D.NET/B2FixedArray2.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -28,14 +28,20 @@ public B2FixedArray2(T v0000, T v0001) public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray24.cs b/src/Box2D.NET/B2FixedArray24.cs index 1108f4d..1862293 100644 --- a/src/Box2D.NET/B2FixedArray24.cs +++ b/src/Box2D.NET/B2FixedArray24.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -44,14 +44,20 @@ public struct B2FixedArray24 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray3.cs b/src/Box2D.NET/B2FixedArray3.cs index 46c4b0c..a6032cc 100644 --- a/src/Box2D.NET/B2FixedArray3.cs +++ b/src/Box2D.NET/B2FixedArray3.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -23,14 +23,20 @@ public struct B2FixedArray3 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray32.cs b/src/Box2D.NET/B2FixedArray32.cs index 97490cb..b62b460 100644 --- a/src/Box2D.NET/B2FixedArray32.cs +++ b/src/Box2D.NET/B2FixedArray32.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -52,14 +52,20 @@ public struct B2FixedArray32 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray4.cs b/src/Box2D.NET/B2FixedArray4.cs index 4e7b0d3..ebf1b90 100644 --- a/src/Box2D.NET/B2FixedArray4.cs +++ b/src/Box2D.NET/B2FixedArray4.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -24,13 +24,19 @@ public struct B2FixedArray4 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray64.cs b/src/Box2D.NET/B2FixedArray64.cs index 11ced7c..e04bf16 100644 --- a/src/Box2D.NET/B2FixedArray64.cs +++ b/src/Box2D.NET/B2FixedArray64.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -84,14 +84,20 @@ public struct B2FixedArray64 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray7.cs b/src/Box2D.NET/B2FixedArray7.cs index e3e99a0..c1a9885 100644 --- a/src/Box2D.NET/B2FixedArray7.cs +++ b/src/Box2D.NET/B2FixedArray7.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -27,14 +27,20 @@ public struct B2FixedArray7 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } + } } \ No newline at end of file diff --git a/src/Box2D.NET/B2FixedArray8.cs b/src/Box2D.NET/B2FixedArray8.cs index 19f65a4..154e58b 100644 --- a/src/Box2D.NET/B2FixedArray8.cs +++ b/src/Box2D.NET/B2FixedArray8.cs @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) // SPDX-License-Identifier: MIT using System; @@ -28,14 +28,20 @@ public struct B2FixedArray8 where T : unmanaged public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref AsSpan()[index]; + get => ref AsSpanUnsafe()[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AsSpan() + internal Span AsSpanUnsafe() { return MemoryMarshal.CreateSpan(ref _v0000, Size); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ReadOnlySpan AsReadOnlySpan() + { + return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in _v0000), Size); + } } -} \ No newline at end of file +} diff --git a/src/Box2D.NET/B2FixedArrayExtensions.cs b/src/Box2D.NET/B2FixedArrayExtensions.cs new file mode 100644 index 0000000..6b53502 --- /dev/null +++ b/src/Box2D.NET/B2FixedArrayExtensions.cs @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com) +// SPDX-License-Identifier: MIT + +using System; +using System.Runtime.CompilerServices; + +namespace Box2D.NET +{ + public static class B2FixedArrayExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray1 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray2 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray3 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray4 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray7 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray8 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray11 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray12 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray16 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray24 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray32 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray64 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Span AsSpan(this ref B2FixedArray1024 array) where T : unmanaged + { + return array.AsSpanUnsafe(); + } + } +} diff --git a/src/Box2D.NET/Box2D.NET.csproj b/src/Box2D.NET/Box2D.NET.csproj index 22dd8a1..77b9c43 100644 --- a/src/Box2D.NET/Box2D.NET.csproj +++ b/src/Box2D.NET/Box2D.NET.csproj @@ -1,4 +1,4 @@ - + netstandard2.1;net8.0;net9.0;net10.0 @@ -26,4 +26,8 @@ $(DefineConstants);B2_SNOOP_TOI_COUNTERS;ENABLED;B2_SNOOP_TABLE_COUNTERS;B2_SNOOP_PAIR_COUNTERS + + + +