Skip to content

Commit e53db07

Browse files
committed
Merge branch 'master' into winui
2 parents 04b397a + 7e2d8a8 commit e53db07

File tree

5 files changed

+293
-18
lines changed

5 files changed

+293
-18
lines changed

CommunityToolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -803,15 +803,15 @@ public ref T DangerousGetReferenceAt(int i, int j)
803803
/// </summary>
804804
/// <param name="row">The target row to map within the current instance.</param>
805805
/// <param name="column">The target column to map within the current instance.</param>
806-
/// <param name="width">The width to map within the current instance.</param>
807806
/// <param name="height">The height to map within the current instance.</param>
807+
/// <param name="width">The width to map within the current instance.</param>
808808
/// <exception cref="ArgumentException">
809809
/// Thrown when either <paramref name="height"/>, <paramref name="width"/> or <paramref name="height"/>
810810
/// are negative or not within the bounds that are valid for the current instance.
811811
/// </exception>
812812
/// <returns>A new <see cref="ReadOnlySpan2D{T}"/> instance representing a slice of the current one.</returns>
813813
[Pure]
814-
public ReadOnlySpan2D<T> Slice(int row, int column, int width, int height)
814+
public ReadOnlySpan2D<T> Slice(int row, int column, int height, int width)
815815
{
816816
if ((uint)row >= Height)
817817
{
@@ -823,14 +823,14 @@ public ReadOnlySpan2D<T> Slice(int row, int column, int width, int height)
823823
ThrowHelper.ThrowArgumentOutOfRangeExceptionForColumn();
824824
}
825825

826-
if ((uint)width > (this.width - column))
826+
if ((uint)height > (Height - row))
827827
{
828-
ThrowHelper.ThrowArgumentOutOfRangeExceptionForWidth();
828+
ThrowHelper.ThrowArgumentOutOfRangeExceptionForHeight();
829829
}
830830

831-
if ((uint)height > (Height - row))
831+
if ((uint)width > (this.width - column))
832832
{
833-
ThrowHelper.ThrowArgumentOutOfRangeExceptionForHeight();
833+
ThrowHelper.ThrowArgumentOutOfRangeExceptionForWidth();
834834
}
835835

836836
nint shift = ((nint)(uint)this.stride * (nint)(uint)row) + (nint)(uint)column;
@@ -906,7 +906,10 @@ public bool TryGetSpan(out ReadOnlySpan<T> span)
906906
// Without Span<T> runtime support, we can only get a Span<T> from a T[] instance
907907
if (this.instance.GetType() == typeof(T[]))
908908
{
909-
span = Unsafe.As<T[]>(this.instance).AsSpan((int)this.offset, (int)Length);
909+
T[] array = Unsafe.As<T[]>(this.instance)!;
910+
int index = array.AsSpan().IndexOf(ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, this.offset));
911+
912+
span = array.AsSpan(index, (int)Length);
910913

911914
return true;
912915
}

CommunityToolkit.HighPerformance/Memory/Span2D{T}.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,10 @@ public bool TryGetSpan(out Span<T> span)
10621062
// Without Span<T> runtime support, we can only get a Span<T> from a T[] instance
10631063
if (this.Instance.GetType() == typeof(T[]))
10641064
{
1065-
span = Unsafe.As<T[]>(this.Instance).AsSpan((int)this.Offset, (int)Length);
1065+
T[] array = Unsafe.As<T[]>(this.Instance)!;
1066+
int index = array.AsSpan().IndexOf(ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, this.Offset));
1067+
1068+
span = array.AsSpan(index, (int)Length);
10661069

10671070
return true;
10681071
}

CommunityToolkit.WinUI.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public bool TryInsertExpressionKeyFrame(KeyFrameAnimation animation, TimeSpan du
172172
[MethodImpl(MethodImplOptions.AggressiveInlining)]
173173
public float GetNormalizedProgress(TimeSpan duration)
174174
{
175-
return (float)Math.Clamp(this.progress.TotalMilliseconds * 100 / duration.TotalMilliseconds, 0, 1);
175+
return (float)Math.Clamp(this.progress.TotalMilliseconds / duration.TotalMilliseconds, 0, 1);
176176
}
177177

178178
/// <inheritdoc/>

UnitTests/UnitTests.HighPerformance.Shared/Memory/Test_ReadOnlySpan2D{T}.cs

Lines changed: 134 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,89 @@ ref Unsafe.AsRef<int>(null),
400400
Assert.IsTrue(Unsafe.AreSame(ref r0, ref array[0, 0]));
401401
}
402402

403+
#if NETCOREAPP3_1_OR_GREATER
404+
[TestCategory("Span2DT")]
405+
[TestMethod]
406+
public unsafe void Test_ReadOnlySpan2DT_Index_Indexer_1()
407+
{
408+
int[,] array = new int[4, 4];
409+
410+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
411+
412+
ref int arrayRef = ref array[1, 3];
413+
ref readonly int span2dRef = ref span2d[1, ^1];
414+
415+
Assert.IsTrue(Unsafe.AreSame(ref arrayRef, ref Unsafe.AsRef(in span2dRef)));
416+
}
417+
418+
[TestCategory("Span2DT")]
419+
[TestMethod]
420+
public unsafe void Test_ReadOnlySpan2DT_Index_Indexer_2()
421+
{
422+
int[,] array = new int[4, 4];
423+
424+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
425+
426+
ref int arrayRef = ref array[2, 1];
427+
ref readonly int span2dRef = ref span2d[^2, ^3];
428+
429+
Assert.IsTrue(Unsafe.AreSame(ref arrayRef, ref Unsafe.AsRef(in span2dRef)));
430+
}
431+
432+
[TestCategory("Span2DT")]
433+
[TestMethod]
434+
[ExpectedException(typeof(IndexOutOfRangeException))]
435+
public unsafe void Test_ReadOnlySpan2DT_Index_Indexer_Fail()
436+
{
437+
int[,] array = new int[4, 4];
438+
439+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
440+
441+
ref readonly int span2dRef = ref span2d[^6, 2];
442+
}
443+
444+
[TestCategory("Span2DT")]
445+
[TestMethod]
446+
public unsafe void Test_ReadOnlySpan2DT_Range_Indexer_1()
447+
{
448+
int[,] array = new int[4, 4];
449+
450+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
451+
ReadOnlySpan2D<int> slice = span2d[1.., 1..];
452+
453+
Assert.AreEqual(slice.Length, 9);
454+
Assert.IsTrue(Unsafe.AreSame(ref array[1, 1], ref Unsafe.AsRef(in slice[0, 0])));
455+
Assert.IsTrue(Unsafe.AreSame(ref array[3, 3], ref Unsafe.AsRef(in slice[2, 2])));
456+
}
457+
458+
[TestCategory("Span2DT")]
459+
[TestMethod]
460+
public unsafe void Test_ReadOnlySpan2DT_Range_Indexer_2()
461+
{
462+
int[,] array = new int[4, 4];
463+
464+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
465+
ReadOnlySpan2D<int> slice = span2d[0..^2, 1..^1];
466+
467+
Assert.AreEqual(slice.Length, 4);
468+
Assert.IsTrue(Unsafe.AreSame(ref array[0, 1], ref Unsafe.AsRef(in slice[0, 0])));
469+
Assert.IsTrue(Unsafe.AreSame(ref array[1, 2], ref Unsafe.AsRef(in slice[1, 1])));
470+
}
471+
472+
[TestCategory("Span2DT")]
473+
[TestMethod]
474+
[ExpectedException(typeof(ArgumentOutOfRangeException))]
475+
public unsafe void Test_ReadOnlySpan2DT_Range_Indexer_Fail()
476+
{
477+
int[,] array = new int[4, 4];
478+
479+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
480+
_ = span2d[0..6, 2..^1];
481+
482+
Assert.Fail();
483+
}
484+
#endif
485+
403486
[TestCategory("ReadOnlySpan2DT")]
404487
[TestMethod]
405488
public void Test_ReadOnlySpan2DT_Slice_1()
@@ -412,7 +495,7 @@ public void Test_ReadOnlySpan2DT_Slice_1()
412495

413496
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array);
414497

415-
ReadOnlySpan2D<int> slice1 = span2d.Slice(1, 1, 2, 1);
498+
ReadOnlySpan2D<int> slice1 = span2d.Slice(1, 1, 1, 2);
416499

417500
Assert.AreEqual(slice1.Length, 2);
418501
Assert.AreEqual(slice1.Height, 1);
@@ -431,11 +514,11 @@ public void Test_ReadOnlySpan2DT_Slice_1()
431514

432515
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(-1, 1, 1, 1));
433516
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, -1, 1, 1));
434-
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 1, -1, 1));
435517
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 1, 1, -1));
518+
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 1, -1, 1));
436519
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(10, 1, 1, 1));
437-
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 12, 12, 1));
438-
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 1, 1, 55));
520+
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 12, 1, 12));
521+
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new ReadOnlySpan2D<int>(array).Slice(1, 1, 55, 1));
439522
}
440523

441524
[TestCategory("ReadOnlySpan2DT")]
@@ -458,7 +541,7 @@ public void Test_ReadOnlySpan2DT_Slice_2()
458541
Assert.AreEqual(slice1[0, 0], 1);
459542
Assert.AreEqual(slice1[1, 1], 5);
460543

461-
ReadOnlySpan2D<int> slice2 = slice1.Slice(1, 0, 2, 1);
544+
ReadOnlySpan2D<int> slice2 = slice1.Slice(1, 0, 1, 2);
462545

463546
Assert.AreEqual(slice2.Length, 2);
464547
Assert.AreEqual(slice2.Height, 1);
@@ -503,7 +586,51 @@ ref Unsafe.AsRef(span[2]),
503586

504587
[TestCategory("ReadOnlySpan2DT")]
505588
[TestMethod]
506-
public void Test_ReadOnlySpan2DT_TryGetReadOnlySpan_1()
589+
public void Test_ReadOnlySpan2DT_TryGetSpan_From1DArray_1()
590+
{
591+
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
592+
593+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array, 3, 3);
594+
595+
bool success = span2d.TryGetSpan(out ReadOnlySpan<int> span);
596+
597+
Assert.IsTrue(success);
598+
Assert.AreEqual(span.Length, span2d.Length);
599+
Assert.IsTrue(Unsafe.AreSame(ref array[0], ref Unsafe.AsRef(in span[0])));
600+
}
601+
602+
[TestCategory("ReadOnlySpan2DT")]
603+
[TestMethod]
604+
public void Test_ReadOnlySpan2DT_TryGetSpan_From1DArray_2()
605+
{
606+
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
607+
608+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array, 3, 3).Slice(1, 0, 2, 3);
609+
610+
bool success = span2d.TryGetSpan(out ReadOnlySpan<int> span);
611+
612+
Assert.IsTrue(success);
613+
Assert.AreEqual(span.Length, span2d.Length);
614+
Assert.IsTrue(Unsafe.AreSame(ref array[3], ref Unsafe.AsRef(in span[0])));
615+
}
616+
617+
[TestCategory("ReadOnlySpan2DT")]
618+
[TestMethod]
619+
public void Test_ReadOnlySpan2DT_TryGetSpan_From1DArray_3()
620+
{
621+
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
622+
623+
ReadOnlySpan2D<int> span2d = new ReadOnlySpan2D<int>(array, 3, 3).Slice(0, 1, 3, 2);
624+
625+
bool success = span2d.TryGetSpan(out ReadOnlySpan<int> span);
626+
627+
Assert.IsFalse(success);
628+
Assert.AreEqual(span.Length, 0);
629+
}
630+
631+
[TestCategory("ReadOnlySpan2DT")]
632+
[TestMethod]
633+
public void Test_ReadOnlySpan2DT_TryGetReadOnlySpan_From2DArray_1()
507634
{
508635
int[,] array =
509636
{
@@ -527,7 +654,7 @@ public void Test_ReadOnlySpan2DT_TryGetReadOnlySpan_1()
527654

528655
[TestCategory("ReadOnlySpan2DT")]
529656
[TestMethod]
530-
public void Test_ReadOnlySpan2DT_TryGetReadOnlySpan_2()
657+
public void Test_ReadOnlySpan2DT_TryGetReadOnlySpan_From2DArray_2()
531658
{
532659
int[,] array =
533660
{

0 commit comments

Comments
 (0)