Skip to content

Commit 1912fe1

Browse files
committed
CoreFX dotnet#24343 Vector using Span
dotnet/corefx#24343
1 parent c973431 commit 1912fe1

File tree

4 files changed

+90
-4
lines changed

4 files changed

+90
-4
lines changed

src/mscorlib/Resources/Strings.resx

+4-1
Original file line numberDiff line numberDiff line change
@@ -3715,4 +3715,7 @@
37153715
<data name="Argument_OverlapAlignmentMismatch" xml:space="preserve">
37163716
<value>Overlapping spans have mismatching alignment.</value>
37173717
</data>
3718-
</root>
3718+
<data name="Arg_InsufficientNumberOfElements" xml:space="preserve">
3719+
<value>At least {0} element(s) are expected in the parameter "{1}".</value>
3720+
</data>
3721+
</root>

src/mscorlib/shared/System/Numerics/GenerationConfig.ttinclude

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<#@ import namespace="System.Linq" #>
22
<#@ import namespace="System.Collections.Generic" #>
3+
<#@ import namespace="System.Text" #>
34
<#+
45
/* This file includes static data used as compilation configuration for the rest of the code generation.
56
It is shared here to ensure that all generated code compiles with the same constants and configurations. */
@@ -144,4 +145,29 @@
144145
string keyword = (type == allTypes.ToArray()[0]) ? "if" : "else if";
145146
return string.Format("{0} (typeof(T) == typeof({1}))", keyword, type.Name);
146147
}
147-
#>
148+
149+
public string MakeTypeComparisonCondition(Type type)
150+
{
151+
return string.Format("(typeof(T) == typeof({0}))", type.Name);
152+
}
153+
154+
public string GenerateIfConditionAllTypes(IEnumerable<Type> allTypes)
155+
{
156+
StringBuilder sbuilder = new StringBuilder();
157+
bool firstTime = true;
158+
foreach (var type in allTypes)
159+
{
160+
if (firstTime)
161+
{
162+
sbuilder.Append("if (").Append(MakeTypeComparisonCondition(type));
163+
firstTime = false;
164+
}
165+
else
166+
{
167+
sbuilder.AppendLine().Append(" || ").Append(MakeTypeComparisonCondition(type));
168+
}
169+
}
170+
sbuilder.Append(")");
171+
return sbuilder.ToString();
172+
}
173+
#>

src/mscorlib/shared/System/Numerics/Vector.cs

+34-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
#if (!netfx && !netstandard)
6+
using Internal.Runtime.CompilerServices;
7+
#endif
58
using System.Globalization;
69
using System.Numerics.Hashing;
710
using System.Runtime.CompilerServices;
11+
using System.Runtime.InteropServices;
812
using System.Text;
913

1014
namespace System.Numerics
@@ -386,7 +390,7 @@ public unsafe Vector(T[] values, int index)
386390
}
387391
if (index < 0 || (values.Length - index) < Count)
388392
{
389-
throw new IndexOutOfRangeException();
393+
throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
390394
}
391395

392396
if (Vector.IsHardwareAccelerated)
@@ -763,6 +767,35 @@ private Vector(ref Register existingRegister)
763767
{
764768
this.register = existingRegister;
765769
}
770+
771+
/// <summary>
772+
/// Constructs a vector from the given span. The span must contain at least Vector'T.Count elements.
773+
/// </summary>
774+
public Vector(Span<T> values)
775+
: this()
776+
{
777+
if ((typeof(T) == typeof(Byte))
778+
|| (typeof(T) == typeof(SByte))
779+
|| (typeof(T) == typeof(UInt16))
780+
|| (typeof(T) == typeof(Int16))
781+
|| (typeof(T) == typeof(UInt32))
782+
|| (typeof(T) == typeof(Int32))
783+
|| (typeof(T) == typeof(UInt64))
784+
|| (typeof(T) == typeof(Int64))
785+
|| (typeof(T) == typeof(Single))
786+
|| (typeof(T) == typeof(Double)))
787+
{
788+
if (values.Length < Count)
789+
{
790+
throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
791+
}
792+
this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
793+
}
794+
else
795+
{
796+
throw new NotSupportedException(SR.Arg_TypeNotSupported);
797+
}
798+
}
766799
#endregion Constructors
767800

768801
#region Public Instance Methods

src/mscorlib/shared/System/Numerics/Vector.tt

+25-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
<#@ import namespace="System.Runtime.InteropServices" #>
88
<#@ include file="GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #>
99

10+
#if (!netfx && !netstandard)
11+
using Internal.Runtime.CompilerServices;
12+
#endif
1013
using System.Globalization;
1114
using System.Numerics.Hashing;
1215
using System.Runtime.CompilerServices;
16+
using System.Runtime.InteropServices;
1317
using System.Text;
1418

1519
namespace System.Numerics
@@ -198,7 +202,7 @@ namespace System.Numerics
198202
}
199203
if (index < 0 || (values.Length - index) < Count)
200204
{
201-
throw new IndexOutOfRangeException();
205+
throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
202206
}
203207

204208
if (Vector.IsHardwareAccelerated)
@@ -283,6 +287,26 @@ namespace System.Numerics
283287
{
284288
this.register = existingRegister;
285289
}
290+
291+
/// <summary>
292+
/// Constructs a vector from the given span. The span must contain at least Vector'T.Count elements.
293+
/// </summary>
294+
public Vector(Span<T> values)
295+
: this()
296+
{
297+
<#=GenerateIfConditionAllTypes(supportedTypes)#>
298+
{
299+
if (values.Length < Count)
300+
{
301+
throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
302+
}
303+
this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
304+
}
305+
else
306+
{
307+
throw new NotSupportedException(SR.Arg_TypeNotSupported);
308+
}
309+
}
286310
#endregion Constructors
287311

288312
#region Public Instance Methods

0 commit comments

Comments
 (0)