Skip to content

Commit 63f52bb

Browse files
committed
Lucene.Net.Support.Arrays::Copy(): Added overloads to cover ReadOnlySpan<T> and Span<T> combinations with arrays so we don't have to change the syntax to differ from Lucene
1 parent 9d7fba3 commit 63f52bb

3 files changed

Lines changed: 340 additions & 3 deletions

File tree

src/Lucene.Net.Tests/Support/TestArrays.cs

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,229 @@ public void Copy_ObjectArray_WithIndices()
833833
Assert.AreEqual(4L, dest[4]);
834834
}
835835

836+
#region Copy (Array-Span overloads)
837+
838+
[Test, LuceneNetSpecific]
839+
public void Copy_Int32Array_Span()
840+
{
841+
int[] source = { 1, 2, 3, 4, 5 };
842+
Span<int> dest = new int[5];
843+
Arrays.Copy(source, dest, source.Length);
844+
Assert.AreEqual(1, dest[0]);
845+
Assert.AreEqual(2, dest[1]);
846+
Assert.AreEqual(3, dest[2]);
847+
Assert.AreEqual(4, dest[3]);
848+
Assert.AreEqual(5, dest[4]);
849+
}
850+
851+
[Test, LuceneNetSpecific]
852+
public void Copy_ObjectArray_Span()
853+
{
854+
object[] source = { 1, 2f, 3d, 4L, new object() };
855+
Span<object> dest = new object[5];
856+
Arrays.Copy(source, dest, source.Length);
857+
Assert.AreEqual(1, dest[0]);
858+
Assert.AreEqual(2f, dest[1]);
859+
Assert.AreEqual(3d, dest[2]);
860+
Assert.AreEqual(4L, dest[3]);
861+
Assert.IsNotNull(dest[4]);
862+
}
863+
864+
[Test, LuceneNetSpecific]
865+
public void Copy_Int32Array_Span_Partial()
866+
{
867+
int[] source = { 1, 2, 3, 4, 5 };
868+
Span<int> dest = new int[3];
869+
Arrays.Copy(source, dest, dest.Length);
870+
Assert.AreEqual(1, dest[0]);
871+
Assert.AreEqual(2, dest[1]);
872+
Assert.AreEqual(3, dest[2]);
873+
}
874+
875+
[Test, LuceneNetSpecific]
876+
public void Copy_ObjectArray_Span_Partial()
877+
{
878+
object[] source = { 1, 2f, 3d, 4L, new object() };
879+
Span<object> dest = new object[3];
880+
Arrays.Copy(source, dest, dest.Length);
881+
Assert.AreEqual(1, dest[0]);
882+
Assert.AreEqual(2f, dest[1]);
883+
Assert.AreEqual(3d, dest[2]);
884+
}
885+
886+
[Test, LuceneNetSpecific]
887+
public void Copy_Int32Array_Span_WithIndices()
888+
{
889+
int[] source = { 1, 2, 3, 4, 5 };
890+
Span<int> dest = new int[5];
891+
Arrays.Copy(source, 1, dest, 2, 3);
892+
Assert.AreEqual(2, dest[2]);
893+
Assert.AreEqual(3, dest[3]);
894+
Assert.AreEqual(4, dest[4]);
895+
}
896+
897+
[Test, LuceneNetSpecific]
898+
public void Copy_ObjectArray_Span_WithIndices()
899+
{
900+
object[] source = { 1, 2f, 3d, 4L, new object() };
901+
Span<object> dest = new object[5];
902+
Arrays.Copy(source, 1, dest, 2, 3);
903+
Assert.AreEqual(2f, dest[2]);
904+
Assert.AreEqual(3d, dest[3]);
905+
Assert.AreEqual(4L, dest[4]);
906+
}
907+
908+
#endregion Copy (Array-Span overloads)
909+
910+
#region Copy (ReadOnlySpan-Array overloads)
911+
912+
[Test, LuceneNetSpecific]
913+
public void Copy_ReadOnlySpan_Int32Array()
914+
{
915+
ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
916+
int[] dest = new int[5];
917+
Arrays.Copy(source, dest, source.Length);
918+
Assert.AreEqual(1, dest[0]);
919+
Assert.AreEqual(2, dest[1]);
920+
Assert.AreEqual(3, dest[2]);
921+
Assert.AreEqual(4, dest[3]);
922+
Assert.AreEqual(5, dest[4]);
923+
}
924+
925+
[Test, LuceneNetSpecific]
926+
public void Copy_ReadOnlySpan_ObjectArray()
927+
{
928+
ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
929+
object[] dest = new object[5];
930+
Arrays.Copy(source, dest, source.Length);
931+
Assert.AreEqual(1, dest[0]);
932+
Assert.AreEqual(2f, dest[1]);
933+
Assert.AreEqual(3d, dest[2]);
934+
Assert.AreEqual(4L, dest[3]);
935+
Assert.IsNotNull(dest[4]);
936+
}
937+
938+
[Test, LuceneNetSpecific]
939+
public void Copy_ReadOnlySpan_Int32Array_Partial()
940+
{
941+
ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
942+
int[] dest = new int[3];
943+
Arrays.Copy(source, dest, dest.Length);
944+
Assert.AreEqual(1, dest[0]);
945+
Assert.AreEqual(2, dest[1]);
946+
Assert.AreEqual(3, dest[2]);
947+
}
948+
949+
[Test, LuceneNetSpecific]
950+
public void Copy_ReadOnlySpan_ObjectArray_Partial()
951+
{
952+
ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
953+
object[] dest = new object[3];
954+
Arrays.Copy(source, dest, dest.Length);
955+
Assert.AreEqual(1, dest[0]);
956+
Assert.AreEqual(2f, dest[1]);
957+
Assert.AreEqual(3d, dest[2]);
958+
}
959+
960+
[Test, LuceneNetSpecific]
961+
public void Copy_ReadOnlySpan_Int32Array_WithIndices()
962+
{
963+
ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
964+
int[] dest = new int[5];
965+
Arrays.Copy(source, 1, dest, 2, 3);
966+
Assert.AreEqual(2, dest[2]);
967+
Assert.AreEqual(3, dest[3]);
968+
Assert.AreEqual(4, dest[4]);
969+
}
970+
971+
[Test, LuceneNetSpecific]
972+
public void Copy_ReadOnlySpan_ObjectArray_WithIndices()
973+
{
974+
ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
975+
object[] dest = new object[5];
976+
Arrays.Copy(source, 1, dest, 2, 3);
977+
Assert.AreEqual(2f, dest[2]);
978+
Assert.AreEqual(3d, dest[3]);
979+
Assert.AreEqual(4L, dest[4]);
980+
}
981+
982+
#endregion Copy (ReadOnlySpan-Array overloads)
983+
984+
#region Copy (ReadOnlySpan-Span overloads)
985+
986+
987+
[Test, LuceneNetSpecific]
988+
public void Copy_Int32_ReadOnlySpan_Span()
989+
{
990+
ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
991+
Span<int> dest = stackalloc int[5];
992+
Arrays.Copy(source, dest, source.Length);
993+
Assert.AreEqual(1, dest[0]);
994+
Assert.AreEqual(2, dest[1]);
995+
Assert.AreEqual(3, dest[2]);
996+
Assert.AreEqual(4, dest[3]);
997+
Assert.AreEqual(5, dest[4]);
998+
}
999+
1000+
[Test, LuceneNetSpecific]
1001+
public void Copy_Object_ReadOnlySpan_Span()
1002+
{
1003+
ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
1004+
Span<object> dest = new object[5];
1005+
Arrays.Copy(source, dest, source.Length);
1006+
Assert.AreEqual(1, dest[0]);
1007+
Assert.AreEqual(2f, dest[1]);
1008+
Assert.AreEqual(3d, dest[2]);
1009+
Assert.AreEqual(4L, dest[3]);
1010+
Assert.IsNotNull(dest[4]);
1011+
}
1012+
1013+
[Test, LuceneNetSpecific]
1014+
public void Copy_Int32_ReadOnlySpan_Span_Partial()
1015+
{
1016+
ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
1017+
Span<int> dest = stackalloc int[3];
1018+
Arrays.Copy(source, dest, dest.Length);
1019+
Assert.AreEqual(1, dest[0]);
1020+
Assert.AreEqual(2, dest[1]);
1021+
Assert.AreEqual(3, dest[2]);
1022+
}
1023+
1024+
[Test, LuceneNetSpecific]
1025+
public void Copy_Object_ReadOnlySpan_Span_Partial()
1026+
{
1027+
ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
1028+
Span<object> dest = new object[3];
1029+
Arrays.Copy(source, dest, dest.Length);
1030+
Assert.AreEqual(1, dest[0]);
1031+
Assert.AreEqual(2f, dest[1]);
1032+
Assert.AreEqual(3d, dest[2]);
1033+
}
1034+
1035+
[Test, LuceneNetSpecific]
1036+
public void Copy_Int32_ReadOnlySpan_Span_WithIndices()
1037+
{
1038+
ReadOnlySpan<int> source = stackalloc int[] { 1, 2, 3, 4, 5 };
1039+
Span<int> dest = stackalloc int[5];
1040+
Arrays.Copy(source, 1, dest, 2, 3);
1041+
Assert.AreEqual(2, dest[2]);
1042+
Assert.AreEqual(3, dest[3]);
1043+
Assert.AreEqual(4, dest[4]);
1044+
}
1045+
1046+
[Test, LuceneNetSpecific]
1047+
public void Copy_Object_ReadOnlySpan_Span_WithIndices()
1048+
{
1049+
ReadOnlySpan<object> source = new object[] { 1, 2f, 3d, 4L, new object() };
1050+
Span<object> dest = new object[5];
1051+
Arrays.Copy(source, 1, dest, 2, 3);
1052+
Assert.AreEqual(2f, dest[2]);
1053+
Assert.AreEqual(3d, dest[3]);
1054+
Assert.AreEqual(4L, dest[4]);
1055+
}
1056+
1057+
#endregion Copy (ReadOnlySpan-Span overloads)
1058+
8361059
[Test, LuceneNetSpecific]
8371060
public void CopyOf_Int32Array()
8381061
{
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.CompilerServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Lucene.Net.Support
9+
{
10+
internal static partial class Arrays
11+
{
12+
// Span overloads of array methods to make usage syntax similar to Lucene.
13+
14+
/// <summary>
15+
/// Copies a range of elements from an Array starting at the first element and pastes them
16+
/// into a Span starting at the first element. The length is specified as a 32-bit integer.
17+
/// </summary>
18+
/// <typeparam name="T">The element type.</typeparam>
19+
/// <param name="sourceArray">The Array that contains the data to copy.</param>
20+
/// <param name="destinationArray">The Span that receives the data.</param>
21+
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
22+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
23+
public static void Copy<T>(T[] sourceArray, Span<T> destinationArray, int length)
24+
{
25+
sourceArray.AsSpan(0, length).CopyTo(destinationArray);
26+
}
27+
28+
/// <summary>
29+
/// Copies a range of elements from a Span starting at the first element and pastes them
30+
/// into an Array starting at the first element. The length is specified as a 32-bit integer.
31+
/// </summary>
32+
/// <typeparam name="T">The element type.</typeparam>
33+
/// <param name="sourceArray">The Span that contains the data to copy.</param>
34+
/// <param name="destinationArray">The Array that receives the data.</param>
35+
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
36+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
37+
public static void Copy<T>(ReadOnlySpan<T> sourceArray, T[] destinationArray, int length)
38+
{
39+
sourceArray.Slice(0, length).CopyTo(destinationArray);
40+
}
41+
42+
/// <summary>
43+
/// Copies a range of elements from a Span starting at the first element and pastes them
44+
/// into another Span starting at the first element. The length is specified as a 32-bit integer.
45+
/// </summary>
46+
/// <typeparam name="T">The element type.</typeparam>
47+
/// <param name="sourceArray">The Span that contains the data to copy.</param>
48+
/// <param name="destinationArray">The Span that receives the data.</param>
49+
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
50+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
51+
public static void Copy<T>(ReadOnlySpan<T> sourceArray, Span<T> destinationArray, int length)
52+
{
53+
sourceArray.Slice(0, length).CopyTo(destinationArray);
54+
}
55+
56+
/// <summary>
57+
/// Copies a range of elements from an Array starting at the specified source index and pastes them
58+
/// to a Span starting at the specified destination index. The length and the indexes are
59+
/// specified as 32-bit integers.
60+
/// </summary>
61+
/// <typeparam name="T">The element type.</typeparam>
62+
/// <param name="sourceArray">The Array that contains the data to copy.</param>
63+
/// <param name="sourceIndex">A 32-bit integer that represents the index in the
64+
/// <paramref name="sourceArray"/> at which copying begins.</param>
65+
/// <param name="destinationArray">The Span that receives the data.</param>
66+
/// <param name="destinationIndex">A 32-bit integer that represents the index in the
67+
/// <paramref name="destinationArray"/> at which storing begins.</param>
68+
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
69+
70+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
71+
public static void Copy<T>(T[] sourceArray, int sourceIndex, Span<T> destinationArray, int destinationIndex, int length)
72+
{
73+
sourceArray.AsSpan(sourceIndex, length).CopyTo(destinationArray.Slice(destinationIndex));
74+
}
75+
76+
/// <summary>
77+
/// Copies a range of elements from a Span starting at the specified source index and pastes them
78+
/// to an Array starting at the specified destination index. The length and the indexes are
79+
/// specified as 32-bit integers.
80+
/// </summary>
81+
/// <typeparam name="T">The element type.</typeparam>
82+
/// <param name="sourceArray">The Span that contains the data to copy.</param>
83+
/// <param name="sourceIndex">A 32-bit integer that represents the index in the
84+
/// <paramref name="sourceArray"/> at which copying begins.</param>
85+
/// <param name="destinationArray">The Array that receives the data.</param>
86+
/// <param name="destinationIndex">A 32-bit integer that represents the index in the
87+
/// <paramref name="destinationArray"/> at which storing begins.</param>
88+
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
89+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
90+
public static void Copy<T>(ReadOnlySpan<T> sourceArray, int sourceIndex, T[] destinationArray, int destinationIndex, int length)
91+
{
92+
sourceArray.Slice(sourceIndex, length).CopyTo(destinationArray.AsSpan(destinationIndex));
93+
}
94+
95+
/// <summary>
96+
/// Copies a range of elements from a Span starting at the specified source index and pastes them
97+
/// to another Span starting at the specified destination index. The length and the indexes are
98+
/// specified as 32-bit integers.
99+
/// </summary>
100+
/// <typeparam name="T">The element type.</typeparam>
101+
/// <param name="sourceArray">The Span that contains the data to copy.</param>
102+
/// <param name="sourceIndex">A 32-bit integer that represents the index in the
103+
/// <paramref name="sourceArray"/> at which copying begins.</param>
104+
/// <param name="destinationArray">The Span that receives the data.</param>
105+
/// <param name="destinationIndex">A 32-bit integer that represents the index in the
106+
/// <paramref name="destinationArray"/> at which storing begins.</param>
107+
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
108+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
109+
public static void Copy<T>(ReadOnlySpan<T> sourceArray, int sourceIndex, Span<T> destinationArray, int destinationIndex, int length)
110+
{
111+
sourceArray.Slice(sourceIndex, length).CopyTo(destinationArray.Slice(destinationIndex));
112+
}
113+
}
114+
}

src/Lucene.Net/Support/Arrays.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace Lucene.Net.Support
2929
* limitations under the License.
3030
*/
3131

32-
internal static class Arrays
32+
internal static partial class Arrays
3333
{
3434
/// <summary>
3535
/// Compares the entire members of one array with the other one.
@@ -167,7 +167,7 @@ public void Fill(T[] array, T value, int startIndex, int count)
167167
/// <b>Usage Note:</b> This implementation uses the most efficient (known) method for copying the
168168
/// array based on the data type and platform.
169169
/// </summary>
170-
/// <typeparam name="T">The array type.</typeparam>
170+
/// <typeparam name="T">The array element type.</typeparam>
171171
/// <param name="sourceArray">The Array that contains the data to copy.</param>
172172
/// <param name="destinationArray">The Array that receives the data.</param>
173173
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
@@ -195,7 +195,7 @@ public static void Copy<T>(T[] sourceArray, T[] destinationArray, int length)
195195
/// <b>Usage Note:</b> This implementation uses the most efficient (known) method for copying the
196196
/// array based on the data type and platform.
197197
/// </summary>
198-
/// <typeparam name="T">The array type.</typeparam>
198+
/// <typeparam name="T">The array element type.</typeparam>
199199
/// <param name="sourceArray">The Array that contains the data to copy.</param>
200200
/// <param name="sourceIndex">A 32-bit integer that represents the index in the
201201
/// <paramref name="sourceArray"/> at which copying begins.</param>

0 commit comments

Comments
 (0)