// 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) throw new ArgumentNullException("values"); 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 } }