Skip to content

Commit 957113f

Browse files
committed
CoreFX dotnet#24343 Vector using Span
dotnet/corefx#24343
1 parent f5a4248 commit 957113f

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

src/mscorlib/Resources/Strings.resx

+3
Original file line numberDiff line numberDiff line change
@@ -3718,4 +3718,7 @@
37183718
<data name="Argument_OverlapAlignmentMismatch" xml:space="preserve">
37193719
<value>Overlapping spans have mismatching alignment.</value>
37203720
</data>
3721+
<data name="Arg_InsufficientNumberOfElements" xml:space="preserve">
3722+
<value>At least {0} element(s) are expected in the parameter "{1}".</value>
3723+
</data>
37213724
</root>

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

+26-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,28 @@
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+
var arrAllTypes = allTypes.ToArray();
158+
for (int index = 0; index < arrAllTypes.Length; ++index)
159+
{
160+
if (index == 0)
161+
{
162+
sbuilder.Append("if (").Append(MakeTypeComparisonCondition(arrAllTypes[index]));
163+
}
164+
else
165+
{
166+
sbuilder.AppendLine().Append(" || ").Append(MakeTypeComparisonCondition(arrAllTypes[index]));
167+
}
168+
}
169+
sbuilder.Append(")");
170+
return sbuilder.ToString();
171+
}
172+
#>

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

+34
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 !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
@@ -763,6 +767,36 @@ 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+
[Intrinsic]
775+
public unsafe Vector(Span<T> values)
776+
: this()
777+
{
778+
if ((typeof(T) == typeof(Byte))
779+
|| (typeof(T) == typeof(SByte))
780+
|| (typeof(T) == typeof(UInt16))
781+
|| (typeof(T) == typeof(Int16))
782+
|| (typeof(T) == typeof(UInt32))
783+
|| (typeof(T) == typeof(Int32))
784+
|| (typeof(T) == typeof(UInt64))
785+
|| (typeof(T) == typeof(Int64))
786+
|| (typeof(T) == typeof(Single))
787+
|| (typeof(T) == typeof(Double)))
788+
{
789+
if (values.Length < Count)
790+
{
791+
throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
792+
}
793+
this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
794+
}
795+
else
796+
{
797+
throw new NotSupportedException(SR.Arg_TypeNotSupported);
798+
}
799+
}
766800
#endregion Constructors
767801

768802
#region Public Instance Methods

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

+25
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 !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
@@ -283,6 +287,27 @@ 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+
[Intrinsic]
295+
public unsafe Vector(Span<T> values)
296+
: this()
297+
{
298+
<#=GenerateIfConditionAllTypes(supportedTypes)#>
299+
{
300+
if (values.Length < Count)
301+
{
302+
throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
303+
}
304+
this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
305+
}
306+
else
307+
{
308+
throw new NotSupportedException(SR.Arg_TypeNotSupported);
309+
}
310+
}
286311
#endregion Constructors
287312

288313
#region Public Instance Methods

0 commit comments

Comments
 (0)