Skip to content

Consider expanding Vector<T> to support nint and nuint #36160

@tannergooding

Description

@tannergooding

Rationale

Today Vector<T> supports the following 10 primitive types: byte, sbyte, short, ushort, int, uint, long, ulong, float, and double.

C# 9 is introducing support for nint and nuint which are variable sized integers matching the bitness of the underlying platform. That is, they are 32-bits on 32-bit systems and 64-bits on 64-bit systems.

As such, it may be beneficial to expand Vector<T> to additionally support these types so we can get rid of the using aliases and support performing the cross-platform vector operations using these new primitive types.

Proposal

Extend Vector<T> to support nint and nuint as valid primitive types. This will extend a number of existing generic functions which take a Vector<T> to also support taking the new types rather than throwing a PlatformNotSupportedException.

Additionally, the following non-generic APIs should be added for parity with the existing surface area:

namespace System.Numerics
{
    public partial struct Vector<T>
    {
        public static explicit operator Vector<nint>(Vector<T> value);
        public static explicit operator Vector<nuint>(Vector<T> value);
    }

    public static partial class Vector
    {
        public static Vector<nint> AsVectorIntPtr<T>(Vector<T> value);
        public static Vector<nuint> AsVectorUIntPtr<T>(Vector<T> value);

        public static Vector<nint> Equals(Vector<nint> left, Vector<nint> right);
        public static Vector<nuint> Equals(Vector<nuint> left, Vector<nuint> right);

        public static Vector<nint> GreaterThan(Vector<nint> left, Vector<nint> right);
        public static Vector<nuint> GreaterThan(Vector<nuint> left, Vector<nuint> right);

        public static Vector<nint> GreaterThanOrEqual(Vector<nint> left, Vector<nint> right);
        public static Vector<nuint> GreaterThanOrEqual(Vector<nuint> left, Vector<nuint> right);

        public static Vector<nint> LessThan(Vector<nint> left, Vector<nint> right);
        public static Vector<nuint> LessThan(Vector<nuint> left, Vector<nuint> right);

        public static Vector<nint> LessThanOrEqual(Vector<nint> left, Vector<nint> right);
        public static Vector<nuint> LessThanOrEqual(Vector<nuint> left, Vector<nuint> right);
    }
}

Other Considerations

For API names, we have a guideline that states to use the framework name rather than the language keyword name (e.g. Int32 and Int64 rather than int and long). However, the framework name for nint is IntPtr but the operators exposed and general use case for the two types is somewhat different, as such a name such as NInt and NUInt may be a better alternative. Whatever we choose, it should likely become the standard for nint moving forward.

The same request could be made for System.Runtime.Intrinsics, but the API bloat for this would be much larger and would need further consideration. It might be worthwhile to allow nint/nuint as valid T without exposing the additional overloads initially as that would at least unblock users from providing such APIs themselves.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Cost:MWork that requires one engineer up to 2 weeksapi-approvedAPI was approved in API review, it can be implementedarea-System.Numerics

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions