diff --git a/src/mscorlib/Resources/Strings.resx b/src/mscorlib/Resources/Strings.resx index db6fc9eb23b8..a846605018e0 100644 --- a/src/mscorlib/Resources/Strings.resx +++ b/src/mscorlib/Resources/Strings.resx @@ -3718,4 +3718,7 @@ Overlapping spans have mismatching alignment. + + At least {0} element(s) are expected in the parameter "{1}". + \ No newline at end of file diff --git a/src/mscorlib/shared/System/Numerics/GenerationConfig.ttinclude b/src/mscorlib/shared/System/Numerics/GenerationConfig.ttinclude index cdd9c95213ee..fa9c4aadd449 100644 --- a/src/mscorlib/shared/System/Numerics/GenerationConfig.ttinclude +++ b/src/mscorlib/shared/System/Numerics/GenerationConfig.ttinclude @@ -1,5 +1,6 @@ <#@ import namespace="System.Linq" #> <#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Text" #> <#+ /* This file includes static data used as compilation configuration for the rest of the code generation. It is shared here to ensure that all generated code compiles with the same constants and configurations. */ @@ -144,4 +145,28 @@ string keyword = (type == allTypes.ToArray()[0]) ? "if" : "else if"; return string.Format("{0} (typeof(T) == typeof({1}))", keyword, type.Name); } -#> \ No newline at end of file + + public string MakeTypeComparisonCondition(Type type) + { + return string.Format("(typeof(T) == typeof({0}))", type.Name); + } + + public string GenerateIfConditionAllTypes(IEnumerable allTypes) + { + StringBuilder sbuilder = new StringBuilder(); + var arrAllTypes = allTypes.ToArray(); + for (int index = 0; index < arrAllTypes.Length; ++index) + { + if (index == 0) + { + sbuilder.Append("if (").Append(MakeTypeComparisonCondition(arrAllTypes[index])); + } + else + { + sbuilder.AppendLine().Append(" || ").Append(MakeTypeComparisonCondition(arrAllTypes[index])); + } + } + sbuilder.Append(")"); + return sbuilder.ToString(); + } +#> diff --git a/src/mscorlib/shared/System/Numerics/Vector.cs b/src/mscorlib/shared/System/Numerics/Vector.cs index 5fd286732ee6..9fbafbb16873 100644 --- a/src/mscorlib/shared/System/Numerics/Vector.cs +++ b/src/mscorlib/shared/System/Numerics/Vector.cs @@ -2,9 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if !netstandard +using Internal.Runtime.CompilerServices; +#endif using System.Globalization; using System.Numerics.Hashing; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; namespace System.Numerics @@ -763,6 +767,36 @@ private Vector(ref Register existingRegister) { this.register = existingRegister; } + + /// + /// Constructs a vector from the given span. The span must contain at least Vector'T.Count elements. + /// + [Intrinsic] + public unsafe Vector(Span values) + : this() + { + if ((typeof(T) == typeof(Byte)) + || (typeof(T) == typeof(SByte)) + || (typeof(T) == typeof(UInt16)) + || (typeof(T) == typeof(Int16)) + || (typeof(T) == typeof(UInt32)) + || (typeof(T) == typeof(Int32)) + || (typeof(T) == typeof(UInt64)) + || (typeof(T) == typeof(Int64)) + || (typeof(T) == typeof(Single)) + || (typeof(T) == typeof(Double))) + { + if (values.Length < Count) + { + throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector.Count, nameof(values))); + } + this = Unsafe.ReadUnaligned>(ref Unsafe.As(ref MemoryMarshal.GetReference(values))); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } #endregion Constructors #region Public Instance Methods diff --git a/src/mscorlib/shared/System/Numerics/Vector.tt b/src/mscorlib/shared/System/Numerics/Vector.tt index 275f47350d2d..4a3a5b24ab0f 100644 --- a/src/mscorlib/shared/System/Numerics/Vector.tt +++ b/src/mscorlib/shared/System/Numerics/Vector.tt @@ -7,9 +7,13 @@ <#@ import namespace="System.Runtime.InteropServices" #> <#@ include file="GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #> +#if !netstandard +using Internal.Runtime.CompilerServices; +#endif using System.Globalization; using System.Numerics.Hashing; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; namespace System.Numerics @@ -283,6 +287,27 @@ namespace System.Numerics { this.register = existingRegister; } + + /// + /// Constructs a vector from the given span. The span must contain at least Vector'T.Count elements. + /// + [Intrinsic] + public unsafe Vector(Span values) + : this() + { + <#=GenerateIfConditionAllTypes(supportedTypes)#> + { + if (values.Length < Count) + { + throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector.Count, nameof(values))); + } + this = Unsafe.ReadUnaligned>(ref Unsafe.As(ref MemoryMarshal.GetReference(values))); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } #endregion Constructors #region Public Instance Methods