[Intrinsic]
get
{
- return s_count;
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ return Unsafe.SizeOf<Vector<T>>() / Unsafe.SizeOf<T>();
}
}
- private static readonly int s_count = InitializeCount();
/// <summary>
/// Returns a vector containing all zeroes.
private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());
#endregion Static Members
- #region Static Initialization
- private struct VectorSizeHelper
- {
- internal Vector<T> _placeholder;
- internal byte _byte;
- }
-
- // Calculates the size of this struct in bytes, by computing the offset of a field in a structure
- private static unsafe int InitializeCount()
- {
- VectorSizeHelper vsh;
- byte* vectorBase = &vsh._placeholder.register.byte_0;
- byte* byteBase = &vsh._byte;
- int vectorSizeInBytes = (int)(byteBase - vectorBase);
-
- int typeSizeInBytes = -1;
- if (typeof(T) == typeof(byte))
- {
- typeSizeInBytes = sizeof(byte);
- }
- else if (typeof(T) == typeof(sbyte))
- {
- typeSizeInBytes = sizeof(sbyte);
- }
- else if (typeof(T) == typeof(ushort))
- {
- typeSizeInBytes = sizeof(ushort);
- }
- else if (typeof(T) == typeof(short))
- {
- typeSizeInBytes = sizeof(short);
- }
- else if (typeof(T) == typeof(uint))
- {
- typeSizeInBytes = sizeof(uint);
- }
- else if (typeof(T) == typeof(int))
- {
- typeSizeInBytes = sizeof(int);
- }
- else if (typeof(T) == typeof(ulong))
- {
- typeSizeInBytes = sizeof(ulong);
- }
- else if (typeof(T) == typeof(long))
- {
- typeSizeInBytes = sizeof(long);
- }
- else if (typeof(T) == typeof(float))
- {
- typeSizeInBytes = sizeof(float);
- }
- else if (typeof(T) == typeof(double))
- {
- typeSizeInBytes = sizeof(double);
- }
- else
- {
- throw new NotSupportedException(SR.Arg_TypeNotSupported);
- }
-
- return vectorSizeInBytes / typeSizeInBytes;
- }
- #endregion Static Initialization
-
#region Constructors
/// <summary>
/// Constructs a vector whose components are all <code>value</code>
#if netcoreapp
/// <summary>
- /// Constructs a vector from the given span. The span must contain at least Vector'T.Count elements.
+ /// Constructs a vector from the given <see cref="ReadOnlySpan{Byte}"/>. The span must contain at least <see cref="Vector{Byte}.Count"/> elements.
/// </summary>
- public Vector(Span<T> values)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector(ReadOnlySpan<byte> values)
: this()
{
- if ((typeof(T) == typeof(byte))
- || (typeof(T) == typeof(sbyte))
- || (typeof(T) == typeof(ushort))
- || (typeof(T) == typeof(short))
- || (typeof(T) == typeof(uint))
- || (typeof(T) == typeof(int))
- || (typeof(T) == typeof(ulong))
- || (typeof(T) == typeof(long))
- || (typeof(T) == typeof(float))
- || (typeof(T) == typeof(double)))
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ if (values.Length < Vector<byte>.Count)
{
- if (values.Length < Count)
- {
- throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
- }
- this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
+ Vector.ThrowInsufficientNumberOfElementsException(Vector<byte>.Count);
}
- else
+ this = Unsafe.ReadUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(values));
+ }
+
+ /// <summary>
+ /// Constructs a vector from the given <see cref="ReadOnlySpan{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector(ReadOnlySpan<T> values)
+ : this()
+ {
+ if (values.Length < Count)
{
- throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
}
+ this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
+ }
+
+ /// <summary>
+ /// Constructs a vector from the given <see cref="Span{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector(Span<T> values)
+ : this()
+ {
+ if (values.Length < Count)
+ {
+ Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
+ }
+ this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
}
#endif
#endregion Constructors
#region Public Instance Methods
/// <summary>
+ /// Copies the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination span</exception>
+ public void CopyTo(Span<byte> destination)
+ {
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ if ((uint)destination.Length < (uint)Vector<byte>.Count)
+ {
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+ Unsafe.WriteUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(destination), this);
+ }
+
+ /// <summary>
+ /// Copies the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination span</exception>
+ public void CopyTo(Span<T> destination)
+ {
+ if ((uint)destination.Length < (uint)Count)
+ {
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+
+ Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), this);
+ }
+
+ /// <summary>
/// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
/// </summary>
/// <param name="destination">The destination array which the values are copied into</param>
sb.Append('>');
return sb.ToString();
}
+
+ /// <summary>
+ /// Attempts to copy the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <returns>True if the source vector was successfully copied to <paramref name="destination"/>. False if
+ /// <paramref name="destination"/> is not large enough to hold the source vector.</returns>
+ public bool TryCopyTo(Span<byte> destination)
+ {
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ if ((uint)destination.Length < (uint)Vector<byte>.Count)
+ {
+ return false;
+ }
+
+ Unsafe.WriteUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(destination), this);
+ return true;
+ }
+
+ /// <summary>
+ /// Attempts to copy the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <returns>True if the source vector was successfully copied to <paramref name="destination"/>. False if
+ /// <paramref name="destination"/> is not large enough to hold the source vector.</returns>
+ public bool TryCopyTo(Span<T> destination)
+ {
+ if ((uint)destination.Length < (uint)Count)
+ {
+ return false;
+ }
+
+ Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), this);
+ return true;
+ }
#endregion Public Instance Methods
#region Arithmetic Operators
}
#endregion Same-Size Conversion
+
+ #region Throw Helpers
+ internal static void ThrowInsufficientNumberOfElementsException(int requiredElementCount)
+ {
+ throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, requiredElementCount, "values"));
+ }
+ #endregion
}
}
[Intrinsic]
get
{
- return s_count;
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ return Unsafe.SizeOf<Vector<T>>() / Unsafe.SizeOf<T>();
}
}
- private static readonly int s_count = InitializeCount();
/// <summary>
/// Returns a vector containing all zeroes.
private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());
#endregion Static Members
- #region Static Initialization
- private struct VectorSizeHelper
- {
- internal Vector<T> _placeholder;
- internal byte _byte;
- }
-
- // Calculates the size of this struct in bytes, by computing the offset of a field in a structure
- private static unsafe int InitializeCount()
- {
- VectorSizeHelper vsh;
- byte* vectorBase = &vsh._placeholder.register.byte_0;
- byte* byteBase = &vsh._byte;
- int vectorSizeInBytes = (int)(byteBase - vectorBase);
-
- int typeSizeInBytes = -1;
-<#
- foreach (Type type in supportedTypes)
- {
-#>
- <#=GenerateIfStatementHeader(type)#>
- {
- typeSizeInBytes = sizeof(<#=typeAliases[type]#>);
- }
-<#
- }
-#>
- else
- {
- throw new NotSupportedException(SR.Arg_TypeNotSupported);
- }
-
- return vectorSizeInBytes / typeSizeInBytes;
- }
- #endregion Static Initialization
-
#region Constructors
/// <summary>
/// Constructs a vector whose components are all <code>value</code>
#if netcoreapp
/// <summary>
- /// Constructs a vector from the given span. The span must contain at least Vector'T.Count elements.
+ /// Constructs a vector from the given <see cref="ReadOnlySpan{Byte}"/>. The span must contain at least <see cref="Vector{Byte}.Count"/> elements.
/// </summary>
- public Vector(Span<T> values)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector(ReadOnlySpan<byte> values)
: this()
{
- <#=GenerateIfConditionAllTypes(supportedTypes)#>
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ if (values.Length < Vector<byte>.Count)
{
- if (values.Length < Count)
- {
- throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, Vector<T>.Count, nameof(values)));
- }
- this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
+ Vector.ThrowInsufficientNumberOfElementsException(Vector<byte>.Count);
}
- else
+ this = Unsafe.ReadUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(values));
+ }
+
+ /// <summary>
+ /// Constructs a vector from the given <see cref="ReadOnlySpan{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector(ReadOnlySpan<T> values)
+ : this()
+ {
+ if (values.Length < Count)
{
- throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
+ }
+ this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
+ }
+
+ /// <summary>
+ /// Constructs a vector from the given <see cref="Span{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector(Span<T> values)
+ : this()
+ {
+ if (values.Length < Count)
+ {
+ Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
}
+ this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
}
#endif
#endregion Constructors
#region Public Instance Methods
/// <summary>
+ /// Copies the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination span</exception>
+ public void CopyTo(Span<byte> destination)
+ {
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ if ((uint)destination.Length < (uint)Vector<byte>.Count)
+ {
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+ Unsafe.WriteUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(destination), this);
+ }
+
+ /// <summary>
+ /// Copies the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination span</exception>
+ public void CopyTo(Span<T> destination)
+ {
+ if ((uint)destination.Length < (uint)Count)
+ {
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+
+ Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), this);
+ }
+
+ /// <summary>
/// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
/// </summary>
/// <param name="destination">The destination array which the values are copied into</param>
sb.Append('>');
return sb.ToString();
}
+
+ /// <summary>
+ /// Attempts to copy the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <returns>True if the source vector was successfully copied to <paramref name="destination"/>. False if
+ /// <paramref name="destination"/> is not large enough to hold the source vector.</returns>
+ public bool TryCopyTo(Span<byte> destination)
+ {
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ if ((uint)destination.Length < (uint)Vector<byte>.Count)
+ {
+ return false;
+ }
+
+ Unsafe.WriteUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(destination), this);
+ return true;
+ }
+
+ /// <summary>
+ /// Attempts to copy the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
+ /// </summary>
+ /// <param name="destination">The destination span which the values are copied into</param>
+ /// <returns>True if the source vector was successfully copied to <paramref name="destination"/>. False if
+ /// <paramref name="destination"/> is not large enough to hold the source vector.</returns>
+ public bool TryCopyTo(Span<T> destination)
+ {
+ if ((uint)destination.Length < (uint)Count)
+ {
+ return false;
+ }
+
+ Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), this);
+ return true;
+ }
#endregion Public Instance Methods
#region Arithmetic Operators
}
#>
#endregion Same-Size Conversion
+
+ #region Throw Helpers
+ internal static void ThrowInsufficientNumberOfElementsException(int requiredElementCount)
+ {
+ throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, requiredElementCount, "values"));
+ }
+ #endregion
}
}