Skip to content

Commit

Permalink
Refactoring IShiftOperators to take a TOther (#71405)
Browse files Browse the repository at this point in the history
* Refactoring IShiftOperators to take a `TOther`

* Break IShiftOperators typeloading cycle

Co-authored-by: Jan Kotas <[email protected]>
  • Loading branch information
tannergooding and jkotas authored Jul 5, 2022
1 parent 5384c95 commit 6b0d373
Show file tree
Hide file tree
Showing 20 changed files with 136 additions and 132 deletions.
3 changes: 3 additions & 0 deletions src/coreclr/vm/appdomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,9 @@ void SystemDomain::LoadBaseSystemClasses()
// We have delayed allocation of CoreLib's static handles until we load the object class
CoreLibBinder::GetModule()->AllocateRegularStaticHandles(DefaultDomain());

// Int32 has to be loaded first to break cycle in IShiftOperators
CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_I4);

// Make sure all primitive types are loaded
for (int et = ELEMENT_TYPE_VOID; et <= ELEMENT_TYPE_R8; et++)
CoreLibBinder::LoadPrimitiveType((CorElementType)et);
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/Common/tests/System/GenericMathHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ public static class RootFunctionsHelper<TSelf>
}

public static class ShiftOperatorsHelper<TSelf, TResult>
where TSelf : IShiftOperators<TSelf, TResult>
where TSelf : IShiftOperators<TSelf, int, TResult>
{
public static TResult op_LeftShift(TSelf value, int shiftAmount) => value << shiftAmount;

Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/Byte.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,14 +1015,14 @@ static bool INumberBase<byte>.TryConvertToTruncating<TOther>(byte value, [NotNul
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static byte IShiftOperators<byte, byte>.operator <<(byte value, int shiftAmount) => (byte)(value << shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static byte IShiftOperators<byte, int, byte>.operator <<(byte value, int shiftAmount) => (byte)(value << shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static byte IShiftOperators<byte, byte>.operator >>(byte value, int shiftAmount) => (byte)(value >> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static byte IShiftOperators<byte, int, byte>.operator >>(byte value, int shiftAmount) => (byte)(value >> shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static byte IShiftOperators<byte, byte>.operator >>>(byte value, int shiftAmount) => (byte)(value >>> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static byte IShiftOperators<byte, int, byte>.operator >>>(byte value, int shiftAmount) => (byte)(value >>> shiftAmount);

//
// ISpanParsable
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/Char.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1863,14 +1863,14 @@ static bool INumberBase<char>.TryParse(ReadOnlySpan<char> s, NumberStyles style,
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static char IShiftOperators<char, char>.operator <<(char value, int shiftAmount) => (char)(value << shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static char IShiftOperators<char, int, char>.operator <<(char value, int shiftAmount) => (char)(value << shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static char IShiftOperators<char, char>.operator >>(char value, int shiftAmount) => (char)(value >> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static char IShiftOperators<char, int, char>.operator >>(char value, int shiftAmount) => (char)(value >> shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static char IShiftOperators<char, char>.operator >>>(char value, int shiftAmount) => (char)(value >>> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static char IShiftOperators<char, int, char>.operator >>>(char value, int shiftAmount) => (char)(value >>> shiftAmount);

//
// ISpanParsable
Expand Down
6 changes: 3 additions & 3 deletions src/libraries/System.Private.CoreLib/src/System/Int128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1848,7 +1848,7 @@ static bool INumberBase<Int128>.TryConvertToTruncating<TOther>(Int128 value, [No
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
public static Int128 operator <<(Int128 value, int shiftAmount)
{
// C# automatically masks the shift amount for UInt64 to be 0x3F. So we
Expand Down Expand Up @@ -1881,7 +1881,7 @@ static bool INumberBase<Int128>.TryConvertToTruncating<TOther>(Int128 value, [No
}
}

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
public static Int128 operator >>(Int128 value, int shiftAmount)
{
// C# automatically masks the shift amount for UInt64 to be 0x3F. So we
Expand Down Expand Up @@ -1916,7 +1916,7 @@ static bool INumberBase<Int128>.TryConvertToTruncating<TOther>(Int128 value, [No
}
}

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
public static Int128 operator >>>(Int128 value, int shiftAmount)
{
// C# automatically masks the shift amount for UInt64 to be 0x3F. So we
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/Int16.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,14 +1143,14 @@ static bool INumberBase<short>.TryConvertToTruncating<TOther>(short value, [NotN
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static short IShiftOperators<short, short>.operator <<(short value, int shiftAmount) => (short)(value << shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static short IShiftOperators<short, int, short>.operator <<(short value, int shiftAmount) => (short)(value << shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static short IShiftOperators<short, short>.operator >>(short value, int shiftAmount) => (short)(value >> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static short IShiftOperators<short, int, short>.operator >>(short value, int shiftAmount) => (short)(value >> shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static short IShiftOperators<short, short>.operator >>>(short value, int shiftAmount) => (short)((ushort)value >>> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static short IShiftOperators<short, int, short>.operator >>>(short value, int shiftAmount) => (short)((ushort)value >>> shiftAmount);

//
// ISignedNumber
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/Int32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,14 +1136,14 @@ static bool INumberBase<int>.TryConvertToTruncating<TOther>(int value, [NotNullW
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static int IShiftOperators<int, int>.operator <<(int value, int shiftAmount) => value << shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static int IShiftOperators<int, int, int>.operator <<(int value, int shiftAmount) => value << shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static int IShiftOperators<int, int>.operator >>(int value, int shiftAmount) => value >> shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static int IShiftOperators<int, int, int>.operator >>(int value, int shiftAmount) => value >> shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static int IShiftOperators<int, int>.operator >>>(int value, int shiftAmount) => value >>> shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static int IShiftOperators<int, int, int>.operator >>>(int value, int shiftAmount) => value >>> shiftAmount;

//
// ISignedNumber
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/Int64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,14 +1129,14 @@ static bool INumberBase<long>.TryConvertToTruncating<TOther>(long value, [NotNul
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static long IShiftOperators<long, long>.operator <<(long value, int shiftAmount) => value << shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static long IShiftOperators<long, int, long>.operator <<(long value, int shiftAmount) => value << shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static long IShiftOperators<long, long>.operator >>(long value, int shiftAmount) => value >> shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static long IShiftOperators<long, int, long>.operator >>(long value, int shiftAmount) => value >> shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static long IShiftOperators<long, long>.operator >>>(long value, int shiftAmount) => value >>> shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static long IShiftOperators<long, int, long>.operator >>>(long value, int shiftAmount) => value >>> shiftAmount;

//
// ISignedNumber
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1090,14 +1090,14 @@ static bool INumberBase<nint>.TryConvertToTruncating<TOther>(nint value, [NotNul
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static nint IShiftOperators<nint, nint>.operator <<(nint value, int shiftAmount) => value << shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static nint IShiftOperators<nint, int, nint>.operator <<(nint value, int shiftAmount) => value << shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static nint IShiftOperators<nint, nint>.operator >>(nint value, int shiftAmount) => value >> shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static nint IShiftOperators<nint, int, nint>.operator >>(nint value, int shiftAmount) => value >> shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static nint IShiftOperators<nint, nint>.operator >>>(nint value, int shiftAmount) => value >>> shiftAmount;
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static nint IShiftOperators<nint, int, nint>.operator >>>(nint value, int shiftAmount) => value >>> shiftAmount;

//
// ISignedNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace System.Numerics
/// <typeparam name="TSelf">The type that implements the interface.</typeparam>
public interface IBinaryInteger<TSelf>
: IBinaryNumber<TSelf>,
IShiftOperators<TSelf, TSelf>
IShiftOperators<TSelf, int, TSelf>
where TSelf : IBinaryInteger<TSelf>
{
/// <summary>Computes the quotient and remainder of two values.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,29 @@ namespace System.Numerics
{
/// <summary>Defines a mechanism for shifting a value by another value.</summary>
/// <typeparam name="TSelf">The type that implements this interface.</typeparam>
/// <typeparam name="TOther">The type used to specify the amount by which <typeparamref name="TSelf" /> should be shifted.</typeparam>
/// <typeparam name="TResult">The type that contains the result of shifting <typeparamref name="TSelf" /> by <typeparamref name="TResult" />.</typeparam>
public interface IShiftOperators<TSelf, TResult>
where TSelf : IShiftOperators<TSelf, TResult>
public interface IShiftOperators<TSelf, TOther, TResult>
where TSelf : IShiftOperators<TSelf, TOther, TResult>
{
/// <summary>Shifts a value left by a given amount.</summary>
/// <param name="value">The value which is shifted left by <paramref name="shiftAmount" />.</param>
/// <param name="shiftAmount">The amount by which <paramref name="value" /> is shifted left.</param>
/// <returns>The result of shifting <paramref name="value" /> left by <paramref name="shiftAmount" />.</returns>
static abstract TResult operator <<(TSelf value, int shiftAmount); // TODO_GENERIC_MATH: shiftAmount should be TOther
static abstract TResult operator <<(TSelf value, TOther shiftAmount);

/// <summary>Shifts a value right by a given amount.</summary>
/// <param name="value">The value which is shifted right by <paramref name="shiftAmount" />.</param>
/// <param name="shiftAmount">The amount by which <paramref name="value" /> is shifted right.</param>
/// <returns>The result of shifting <paramref name="value" /> right by <paramref name="shiftAmount" />.</returns>
/// <remarks>This operation is meant to perform a signed (otherwise known as an arithmetic) right shift on signed types.</remarks>
static abstract TResult operator >>(TSelf value, int shiftAmount); // TODO_GENERIC_MATH: shiftAmount should be TOther
static abstract TResult operator >>(TSelf value, TOther shiftAmount);

/// <summary>Shifts a value right by a given amount.</summary>
/// <param name="value">The value which is shifted right by <paramref name="shiftAmount" />.</param>
/// <param name="shiftAmount">The amount by which <paramref name="value" /> is shifted right.</param>
/// <returns>The result of shifting <paramref name="value" /> right by <paramref name="shiftAmount" />.</returns>
/// <remarks>This operation is meant to perform n unsigned (otherwise known as a logical) right shift on all types.</remarks>
static abstract TResult operator >>>(TSelf value, int shiftAmount); // TODO_GENERIC_MATH: shiftAmount should be TOther
static abstract TResult operator >>>(TSelf value, TOther shiftAmount);
}
}
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/SByte.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,14 +1150,14 @@ static bool INumberBase<sbyte>.TryConvertToTruncating<TOther>(sbyte value, [NotN
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static sbyte IShiftOperators<sbyte, sbyte>.operator <<(sbyte value, int shiftAmount) => (sbyte)(value << shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static sbyte IShiftOperators<sbyte, int, sbyte>.operator <<(sbyte value, int shiftAmount) => (sbyte)(value << shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static sbyte IShiftOperators<sbyte, sbyte>.operator >>(sbyte value, int shiftAmount) => (sbyte)(value >> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static sbyte IShiftOperators<sbyte, int, sbyte>.operator >>(sbyte value, int shiftAmount) => (sbyte)(value >> shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static sbyte IShiftOperators<sbyte, sbyte>.operator >>>(sbyte value, int shiftAmount) => (sbyte)((byte)value >>> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static sbyte IShiftOperators<sbyte, int, sbyte>.operator >>>(sbyte value, int shiftAmount) => (sbyte)((byte)value >>> shiftAmount);

//
// ISignedNumber
Expand Down
6 changes: 3 additions & 3 deletions src/libraries/System.Private.CoreLib/src/System/UInt128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1845,7 +1845,7 @@ static bool INumberBase<UInt128>.TryConvertToTruncating<TOther>(UInt128 value, [
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
public static UInt128 operator <<(UInt128 value, int shiftAmount)
{
// C# automatically masks the shift amount for UInt64 to be 0x3F. So we
Expand Down Expand Up @@ -1878,10 +1878,10 @@ static bool INumberBase<UInt128>.TryConvertToTruncating<TOther>(UInt128 value, [
}
}

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
public static UInt128 operator >>(UInt128 value, int shiftAmount) => value >>> shiftAmount;

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
public static UInt128 operator >>>(UInt128 value, int shiftAmount)
{
// C# automatically masks the shift amount for UInt64 to be 0x3F. So we
Expand Down
12 changes: 6 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/UInt16.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,14 +1009,14 @@ static bool INumberBase<ushort>.TryConvertToTruncating<TOther>(ushort value, [No
// IShiftOperators
//

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_LeftShift(TSelf, int)" />
static ushort IShiftOperators<ushort, ushort>.operator <<(ushort value, int shiftAmount) => (ushort)(value << shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static ushort IShiftOperators<ushort, int, ushort>.operator <<(ushort value, int shiftAmount) => (ushort)(value << shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_RightShift(TSelf, int)" />
static ushort IShiftOperators<ushort, ushort>.operator >>(ushort value, int shiftAmount) => (ushort)(value >> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static ushort IShiftOperators<ushort, int, ushort>.operator >>(ushort value, int shiftAmount) => (ushort)(value >> shiftAmount);

/// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" />
static ushort IShiftOperators<ushort, ushort>.operator >>>(ushort value, int shiftAmount) => (ushort)(value >>> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static ushort IShiftOperators<ushort, int, ushort>.operator >>>(ushort value, int shiftAmount) => (ushort)(value >>> shiftAmount);

//
// ISpanParsable
Expand Down
Loading

0 comments on commit 6b0d373

Please sign in to comment.