// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Runtime.CompilerServices;
namespace System.Numerics
{
// This file contains the definitions for all of the JIT intrinsic methods and properties that are recognized by the current x64 JIT compiler.
// The implementation defined here is used in any circumstance where the JIT fails to recognize these members as intrinsic.
// The JIT recognizes these methods and properties by name and signature: if either is changed, the JIT will no longer recognize the member.
// Some methods declared here are not strictly intrinsic, but delegate to an intrinsic method. For example, only one overload of CopyTo()
public partial struct Vector4
{
///
/// The X component of the vector.
///
public Single X;
///
/// The Y component of the vector.
///
public Single Y;
///
/// The Z component of the vector.
///
public Single Z;
///
/// The W component of the vector.
///
public Single W;
#region Constructors
///
/// Constructs a vector whose elements are all the single specified value.
///
/// The element to fill the vector with.
[JitIntrinsic]
public Vector4(Single value)
: this(value, value, value, value)
{
}
///
/// Constructs a vector with the given individual elements.
///
/// W component.
/// X component.
/// Y component.
/// Z component.
[JitIntrinsic]
public Vector4(Single x, Single y, Single z, Single w)
{
W = w;
X = x;
Y = y;
Z = z;
}
///
/// Constructs a Vector4 from the given Vector2 and a Z and W component.
///
/// The vector to use as the X and Y components.
/// The Z component.
/// The W component.
public Vector4(Vector2 value, Single z, Single w)
{
X = value.X;
Y = value.Y;
Z = z;
W = w;
}
///
/// Constructs a Vector4 from the given Vector3 and a W component.
///
/// The vector to use as the X, Y, and Z components.
/// The W component.
public Vector4(Vector3 value, Single w)
{
X = value.X;
Y = value.Y;
Z = value.Z;
W = w;
}
#endregion Constructors
#region Public Instance Methods
///
/// Copies the contents of the vector into the given array.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void CopyTo(Single[] array)
{
CopyTo(array, 0);
}
///
/// Copies the contents of the vector into the given array, starting from index.
///
/// If array is null.
/// If array is multidimensional.
/// If index is greater than end of the array or index is less than zero.
/// If number of elements in source vector is greater than those available in destination array.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void CopyTo(Single[] array, int index)
{
if (array == null)
{
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
throw new NullReferenceException(SR.GetString("Arg_NullArgumentNullRef"));
}
if (index < 0 || index >= array.Length)
{
throw new ArgumentOutOfRangeException(SR.GetString("Arg_ArgumentOutOfRangeException", index));
}
if ((array.Length - index) < 4)
{
throw new ArgumentException(SR.GetString("Arg_ElementsInSourceIsGreaterThanDestination", index));
}
array[index] = X;
array[index + 1] = Y;
array[index + 2] = Z;
array[index + 3] = W;
}
///
/// Returns a boolean indicating whether the given Vector4 is equal to this Vector4 instance.
///
/// The Vector4 to compare this instance to.
/// True if the other Vector4 is equal to this instance; False otherwise.
[JitIntrinsic]
public bool Equals(Vector4 other)
{
return this.X == other.X
&& this.Y == other.Y
&& this.Z == other.Z
&& this.W == other.W;
}
#endregion Public Instance Methods
#region Public Static Methods
///
/// Returns the dot product of two vectors.
///
/// The first vector.
/// The second vector.
/// The dot product.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Dot(Vector4 vector1, Vector4 vector2)
{
return vector1.X * vector2.X +
vector1.Y * vector2.Y +
vector1.Z * vector2.Z +
vector1.W * vector2.W;
}
///
/// Returns a vector whose elements are the minimum of each of the pairs of elements in the two source vectors.
///
/// The first source vector.
/// The second source vector.
/// The minimized vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Min(Vector4 value1, Vector4 value2)
{
return new Vector4(
(value1.X < value2.X) ? value1.X : value2.X,
(value1.Y < value2.Y) ? value1.Y : value2.Y,
(value1.Z < value2.Z) ? value1.Z : value2.Z,
(value1.W < value2.W) ? value1.W : value2.W);
}
///
/// Returns a vector whose elements are the maximum of each of the pairs of elements in the two source vectors.
///
/// The first source vector.
/// The second source vector.
/// The maximized vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Max(Vector4 value1, Vector4 value2)
{
return new Vector4(
(value1.X > value2.X) ? value1.X : value2.X,
(value1.Y > value2.Y) ? value1.Y : value2.Y,
(value1.Z > value2.Z) ? value1.Z : value2.Z,
(value1.W > value2.W) ? value1.W : value2.W);
}
///
/// Returns a vector whose elements are the absolute values of each of the source vector's elements.
///
/// The source vector.
/// The absolute value vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Abs(Vector4 value)
{
return new Vector4(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W));
}
///
/// Returns a vector whose elements are the square root of each of the source vector's elements.
///
/// The source vector.
/// The square root vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 SquareRoot(Vector4 value)
{
return new Vector4((Single)Math.Sqrt(value.X), (Single)Math.Sqrt(value.Y), (Single)Math.Sqrt(value.Z), (Single)Math.Sqrt(value.W));
}
#endregion Public Static Methods
#region Public static operators
///
/// Adds two vectors together.
///
/// The first source vector.
/// The second source vector.
/// The summed vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator +(Vector4 left, Vector4 right)
{
return new Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
}
///
/// Subtracts the second vector from the first.
///
/// The first source vector.
/// The second source vector.
/// The difference vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator -(Vector4 left, Vector4 right)
{
return new Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
}
///
/// Multiplies two vectors together.
///
/// The first source vector.
/// The second source vector.
/// The product vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator *(Vector4 left, Vector4 right)
{
return new Vector4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
}
///
/// Multiplies a vector by the given scalar.
///
/// The source vector.
/// The scalar value.
/// The scaled vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator *(Vector4 left, Single right)
{
return left * new Vector4(right);
}
///
/// Multiplies a vector by the given scalar.
///
/// The scalar value.
/// The source vector.
/// The scaled vector.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator *(Single left, Vector4 right)
{
return new Vector4(left) * right;
}
///
/// Divides the first vector by the second.
///
/// The first source vector.
/// The second source vector.
/// The vector resulting from the division.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator /(Vector4 left, Vector4 right)
{
return new Vector4(left.X / right.X, left.Y / right.Y, left.Z / right.Z, left.W / right.W);
}
///
/// Divides the vector by the given scalar.
///
/// The source vector.
/// The scalar value.
/// The result of the division.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator /(Vector4 value1, float value2)
{
float invDiv = 1.0f / value2;
return new Vector4(
value1.X * invDiv,
value1.Y * invDiv,
value1.Z * invDiv,
value1.W * invDiv);
}
///
/// Negates a given vector.
///
/// The source vector.
/// The negated vector.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 operator -(Vector4 value)
{
return Zero - value;
}
///
/// Returns a boolean indicating whether the two given vectors are equal.
///
/// The first vector to compare.
/// The second vector to compare.
/// True if the vectors are equal; False otherwise.
[JitIntrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vector4 left, Vector4 right)
{
return left.Equals(right);
}
///
/// Returns a boolean indicating whether the two given vectors are not equal.
///
/// The first vector to compare.
/// The second vector to compare.
/// True if the vectors are not equal; False if they are equal.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vector4 left, Vector4 right)
{
return !(left == right);
}
#endregion Public static operators
}
}