Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,118 @@

namespace System.Numerics
{
public readonly struct Vector2<T> : IEquatable<Vector2<T>>, IFormattable
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to need to be autogenerated via the ref assembly generator. Won't block on this though.

where T : struct
{
// Fields

public T X { get { throw null; } } // Should this have a setter, a Vector2 WithX(T value), or be a public field like Vector2
public T Y { get { throw null; } } // Should this have a setter, a Vector2 WithY(T value), or be a public field like Vector2

// Constructors

public Vector2(T value) { throw null; }
public Vector2(T x, T y) { throw null; }

public Vector2(T[] value) { throw null; } // Doesn't exist for Vector2
public Vector2(T[] value, int offset) { throw null; } // Doesn't exist for Vector2
public Vector2(ReadOnlySpan<T> value) { throw null; } // Doesn't exist for Vector2

// Static Properties

public static Vector2<T> One { get { throw null; } }
public static Vector2<T> UnitX { get { throw null; } }
public static Vector2<T> UnitY { get { throw null; } }
public static Vector2<T> Zero { get { throw null; } }

// With methods
public Vector2<T> WithX(T x) { throw null; }
public Vector2<T> WithY(T y) { throw null; }

// Operators

public static bool operator ==(Vector2<T> left, Vector2<T> right) { throw null; }
public static bool operator !=(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> operator +(Vector2<T> value) { throw null; } // Doesn't exist for Vector2
public static Vector2<T> operator -(Vector2<T> value) { throw null; }

public static Vector2<T> operator +(Vector2<T> left, Vector2<T> right) { throw null; }
public static Vector2<T> operator -(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> operator *(Vector2<T> left, Vector2<T> right) { throw null; }
public static Vector2<T> operator /(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> operator *(Vector2<T> left, T right) { throw null; }
public static Vector2<T> operator /(Vector2<T> left, T right) { throw null; }

public static Vector2<T> operator *(T left, Vector2<T> right) { throw null; }

// "Friendly" Operators

public static Vector2<T> Plus(Vector2<T> value) { throw null; } // Doesn't exist for Vector2
public static Vector2<T> Negate(Vector2<T> value) { throw null; }

public static Vector2<T> Add(Vector2<T> left, Vector2<T> right) { throw null; }
public static Vector2<T> Subtract(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> Multiply(Vector2<T> left, Vector2<T> right) { throw null; }
public static Vector2<T> Divide(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> Multiply(Vector2<T> left, T right) { throw null; }
public static Vector2<T> Divide(Vector2<T> left, T right) { throw null; }

public static Vector2<T> Multiply(T left, Vector2<T> right) { throw null; }

// Static Methods

public static Vector2<T> Abs(Vector2<T> value) { throw null; }

public static Vector2<T> Clamp(Vector2<T> value, Vector2<T> min, Vector2<T> max) { throw null; }

public static T Distance(Vector2<T> left, Vector2<T> right) { throw null; }
public static T DistanceSquared(Vector2<T> left, Vector2<T> right) { throw null; }

public static T Dot(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> Lerp(Vector2<T> min, Vector2<T> max, T amount) { throw null; }

public static Vector2<T> Min(Vector2<T> left, Vector2<T> right) { throw null; }
public static Vector2<T> Max(Vector2<T> left, Vector2<T> right) { throw null; }

public static Vector2<T> Normalize(Vector2<T> value) { throw null; }

public static Vector2<T> Reflect(Vector2<T> incident, Vector2<T> normal) { throw null; }

public static Vector2<T> SquareRoot(Vector2<T> value) { throw null; }

//public static Vector2<T> Transform(Vector2<T> position, Matrix3x2<T> matrix) { throw null; }
//public static Vector2<T> Transform(Vector2<T> position, Matrix4x4<T> matrix) { throw null; }

//public static Vector2<T> Transform(Vector2<T> position, Quaternion<T> rotation) { throw null; } // Rotate is a better name?

//public static Vector2<T> TransformNormal(Vector2<T> normal, Matrix3x2<T> matrix) { throw null; }
//public static Vector2<T> TransformNormal(Vector2<T> normal, Matrix4x4<T> matrix) { throw null; }

// Methods

public readonly void CopyTo(T[] array) { throw null; }
public readonly void CopyTo(T[] array, int index) { throw null; }
public readonly void CopyTo(Span<T> destination) { throw null; } // Doesn't exist for Vector2

public override readonly bool Equals(object? obj) { throw null; }
public readonly bool Equals(Vector2<T> other) { throw null; }

public override readonly int GetHashCode() { throw null; }

public readonly T Length() { throw null; } // Better as a property?
public readonly T LengthSquared() { throw null; } // Better as a property?

public readonly override string ToString() { throw null; }
public readonly string ToString(string? format) { throw null; }
public readonly string ToString(string? format, IFormatProvider? formatProvider) { throw null; }
}

public partial struct Matrix3x2 : System.IEquatable<System.Numerics.Matrix3x2>
{
public float M11;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

private string[] TestTypes = new[]
{
"Vector",
"Matrix3x2",
"Matrix4x4",
"Quaternion",
"Plane"
};

private string[][] SupportedTypes = new[]
{
new[] { "Single", "f" },
new[] { "Double", "d" }
};

void TestSingleType(string type)
{
if (type == "Vector")
{
TestVector();
return;
}

var file = type + ".template";

var templatedText = ReadFile(file);

GenerateFilesForSupportedType(type, templatedText);
}

void TestVector()
{
string shared = ReadFile("Vector_All.template");

for (var i = 2; i <= 4; i++)
{
var arifiedVector = "Vector" + i.ToString();

var specific = ReadFile(arifiedVector + ".template").Split('\n');
var correct = new StringBuilder(specific.Length);

// these add indenting to lines which need it
Console.WriteLine(specific.Length);
foreach (var line in specific)
{
if (!string.IsNullOrWhiteSpace(line))
{
correct.AppendLine(" " + line);
}
else
{
correct.AppendLine(line);
}
}


var withShared = shared.Replace("{Specifics}", correct.ToString());
GenerateFilesForSupportedType(arifiedVector, withShared);
}
}

void GenerateFilesForSupportedType(string typename, string template)
{
// Handle non-generic type first
var nonGenericText = template.Replace("{TestType}", typename);
nonGenericText = nonGenericText.Replace("{ScalarType}", "Single");
nonGenericText = nonGenericText.Replace("{ScalarSuffix}", "f");
nonGenericText = nonGenericText.Replace("{AssignX}", ".X = "); // non generic doesn't have With methods

nonGenericText = nonGenericText.Replace("{GenericSpecific}", "");

WriteToTestFile(typename, nonGenericText);

var genericFile = typename + "_Generic.template";

var genericTemplate = template.Replace("{GenericSpecific}", File.Exists(genericFile) ? ReadFile(genericFile) : "");

foreach (var supportedType in SupportedTypes)
{
// this means we can blindly change everything, including method names (as < and > are not allowed in them)
// namespace as we put this riiight at the start of the file, before the using
var alias = typename + supportedType[0];
var usingAlias = $"using {alias} = System.Numerics.{typename}<System.{supportedType[0]}>;{Environment.NewLine}";
var genericType = typename + '<' + supportedType[0] + '>';

var genericText = usingAlias + genericTemplate.Replace("{TestType}", alias);

genericText = genericText.Replace("{ScalarType}", supportedType[0]);
genericText = genericText.Replace("{ScalarSuffix}", supportedType[1]);
genericText = genericText.Replace("{AssignX}", " = b.WithX"); // generic uses with methods

WriteToTestFile(typename + "_" + supportedType[0], genericText);
}
}

string ReadFile(string name)
{
string license = "{EndLicense}";
string text = File.ReadAllText(name);
var ind = text.IndexOf(license);
if (ind != -1)
{
text = text.Substring(ind + license.Length);
}
return text;
}

void WriteToTestFile(string file, string text)
{
File.WriteAllText(Path.Combine("Test", file + "Tests.cs"), text);
}

foreach (var type in TestTypes)
{
TestSingleType(type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
{EndLicense}

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
{EndLicense}

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
{EndLicense}

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
{EndLicense}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Matrix3x2Double = System.Numerics.Matrix3x2<System.Double>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to not use using like this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is it becomes much hard to generate tests without it, as you can't simply insert the type name into the test name because <> are not legal chars in method name ofc

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, so use two different replacements. One is the name with <> and one is the name without



Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Matrix3x2Single = System.Numerics.Matrix3x2<System.Single>;


Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Matrix4x4Double = System.Numerics.Matrix4x4<System.Double>;


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Matrix4x4Single = System.Numerics.Matrix4x4<System.Single>;


Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using PlaneDouble = System.Numerics.Plane<System.Double>;


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using PlaneSingle = System.Numerics.Plane<System.Single>;


Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using QuaternionDouble = System.Numerics.Quaternion<System.Double>;


Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using QuaternionSingle = System.Numerics.Quaternion<System.Single>;


Loading