mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-23 00:58:48 +00:00
Compare commits
No commits in common. "4c91ec436f45a8a6a3aacd967c1da66c40b05efc" and "b84d9c734aa4fa5c52228505e15420755f70591c" have entirely different histories.
4c91ec436f
...
b84d9c734a
4
.github/workflows/dotnet.yml
vendored
4
.github/workflows/dotnet.yml
vendored
@ -23,6 +23,7 @@ jobs:
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: |
|
||||
3.1.x
|
||||
6.0.x
|
||||
7.0.x
|
||||
|
||||
@ -35,6 +36,9 @@ jobs:
|
||||
- name: Build
|
||||
run: dotnet build --no-restore --configuration Release
|
||||
|
||||
- name: Test .NET Core 3.1
|
||||
run: dotnet test --no-build --verbosity normal --configuration Release --framework netcoreapp3.1
|
||||
|
||||
- name: Test .NET 6
|
||||
run: dotnet test --no-build --verbosity normal --configuration Release --framework net6.0
|
||||
|
||||
|
@ -46,8 +46,6 @@ TypeInitializationException.
|
||||
|
||||
- X10D: Removed `IEnumerable<T>.ConcatOne` - this functionality already exists with `Append`.
|
||||
- X10D: Removed `Endianness` enum.
|
||||
- X10D: Removed .NET Standard 2.1 target.
|
||||
- X10D.Hosting: Removed .NET Standard 2.1 target.
|
||||
- X10D.DSharpPlus: Complete sunset of library. This library will not be updated to support DSharpPlus v5.0.0 (#83).
|
||||
- X10D.Unity: Complete sunset of library. This library will not be updated effective immediately (#86).
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0;net6.0;netstandard2.1</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0;net6.0;netcoreapp3.1</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<CoverletOutputFormat>json,cobertura</CoverletOutputFormat>
|
||||
|
@ -47,6 +47,7 @@ internal class ByteTests
|
||||
});
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void UnpackInternal_Fallback_ShouldUnpackToSpanCorrectly()
|
||||
{
|
||||
@ -91,6 +92,7 @@ internal class ByteTests
|
||||
Assert.That(bits[7], Is.True);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void Unpack_ShouldRepackEqually()
|
||||
|
@ -1,4 +1,6 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
#endif
|
||||
using NUnit.Framework;
|
||||
using X10D.Collections;
|
||||
|
||||
@ -82,6 +84,7 @@ internal class Int16Tests
|
||||
});
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void UnpackInternal_Ssse3_ShouldUnpackToSpanCorrectly()
|
||||
{
|
||||
@ -112,6 +115,7 @@ internal class Int16Tests
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void Unpack_ShouldRepackEqually()
|
||||
|
@ -1,4 +1,6 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
#endif
|
||||
using NUnit.Framework;
|
||||
using X10D.Collections;
|
||||
|
||||
@ -83,6 +85,7 @@ internal class Int32Tests
|
||||
});
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void UnpackInternal_Ssse3_ShouldUnpackToSpanCorrectly()
|
||||
{
|
||||
@ -142,6 +145,7 @@ internal class Int32Tests
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void Unpack_ShouldRepackEqually()
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using NUnit.Framework;
|
||||
@ -222,3 +223,4 @@ internal class IntrinsicTests
|
||||
Assert.That(result, Is.EqualTo(expectedResult));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,7 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
#endif
|
||||
using NUnit.Framework;
|
||||
using X10D.Core;
|
||||
|
||||
@ -207,6 +209,7 @@ internal class SpanTest
|
||||
Assert.That(actual, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void PackByteInternal_Sse2_ShouldReturnCorrectByte_GivenReadOnlySpan_Using()
|
||||
{
|
||||
@ -238,6 +241,7 @@ internal class SpanTest
|
||||
|
||||
Assert.That(actual, Is.EqualTo(expected));
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void PackInt16_ShouldReturnSameAsPackByte_WhenSpanHasLength8()
|
||||
@ -264,6 +268,7 @@ internal class SpanTest
|
||||
Assert.That(actual, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void PackInt16Internal_Sse2_ShouldReturnCorrectInt16_GivenReadOnlySpan_Using()
|
||||
{
|
||||
@ -282,6 +287,7 @@ internal class SpanTest
|
||||
|
||||
Assert.That(actual, Is.EqualTo(expected));
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void PackInt32Internal_Fallback_ShouldReturnCorrectInt32_GivenReadOnlySpan()
|
||||
@ -298,6 +304,7 @@ internal class SpanTest
|
||||
Assert.That(actual, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void PackInt32Internal_Sse2_ShouldReturnCorrectInt32_GivenReadOnlySpan()
|
||||
{
|
||||
@ -357,6 +364,7 @@ internal class SpanTest
|
||||
|
||||
Assert.That(actual, Is.EqualTo(expected));
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void PackInt32_ShouldReturnSameAsPackByte_WhenSpanHasLength8_UsingReadOnlySpan()
|
||||
|
@ -207,7 +207,9 @@ internal class ColorTests
|
||||
Assert.That(Color.Plum.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkGray));
|
||||
Assert.That(Color.PowderBlue.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkGray));
|
||||
Assert.That(Color.Purple.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkMagenta));
|
||||
#if NET6_0_OR_GREATER
|
||||
Assert.That(Color.RebeccaPurple.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkMagenta));
|
||||
#endif
|
||||
Assert.That(Color.Red.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.Red));
|
||||
Assert.That(Color.RosyBrown.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkGray));
|
||||
Assert.That(Color.RoyalBlue.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkCyan));
|
||||
|
@ -6,6 +6,7 @@ namespace X10D.Tests.Text;
|
||||
[TestFixture]
|
||||
internal class CoreTests
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void ToJsonShouldNotBeEmpty()
|
||||
{
|
||||
@ -23,4 +24,5 @@ internal class CoreTests
|
||||
CollectionAssert.AreEqual(source, target);
|
||||
CollectionAssert.AreEquivalent(source, target);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using X10D.Text;
|
||||
@ -89,3 +90,4 @@ internal class RuneTests
|
||||
Assert.That(repeated, Is.EqualTo("𐀀𐀀𐀀𐀀𐀀𐀀"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System.Text;
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Text.Json.Serialization;
|
||||
#endif
|
||||
using NUnit.Framework;
|
||||
using X10D.Text;
|
||||
|
||||
@ -416,6 +418,7 @@ internal class StringTests
|
||||
Assert.Throws<ArgumentException>(() => _ = " ".EnumParse<DayOfWeek>());
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Test]
|
||||
public void FromJson_ShouldDeserializeCorrectly_GivenJsonString()
|
||||
{
|
||||
@ -431,6 +434,7 @@ internal class StringTests
|
||||
Assert.That(target.Values[2], Is.EqualTo(3));
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void GetBytes_ShouldReturnUtf8Bytes_GivenHelloWorld()
|
||||
@ -1002,9 +1006,11 @@ internal class StringTests
|
||||
});
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
private struct SampleStructure
|
||||
{
|
||||
[JsonPropertyName("values")]
|
||||
public int[] Values { get; set; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET6_0_OR_GREATER
|
||||
using NUnit.Framework;
|
||||
using X10D.Time;
|
||||
|
||||
@ -229,3 +230,4 @@ internal class DateOnlyTests
|
||||
Assert.That(date.ToUnixTimeSeconds(time), Is.EqualTo(946684800));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using NUnit.Framework;
|
||||
using X10D.Time;
|
||||
|
||||
@ -51,3 +52,4 @@ internal class DoubleTests
|
||||
Assert.That((_negativeOne).Weeks() < TimeSpan.Zero);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0;net6.0;netstandard2.1</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,9 +1,12 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using X10D.CompilerServices;
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using X10D.CompilerServices;
|
||||
#endif
|
||||
|
||||
namespace X10D.Collections;
|
||||
|
||||
@ -43,11 +46,13 @@ public static class ByteExtensions
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
if (Sse3.IsSupported)
|
||||
{
|
||||
UnpackInternal_Ssse3(value, destination);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
UnpackInternal_Fallback(value, destination);
|
||||
}
|
||||
@ -61,6 +66,7 @@ public static class ByteExtensions
|
||||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal unsafe static void UnpackInternal_Ssse3(this byte value, Span<bool> destination)
|
||||
{
|
||||
@ -81,4 +87,5 @@ public static class ByteExtensions
|
||||
Sse2.StoreScalar((long*)pDestination, correctness.AsInt64());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
using System.Web;
|
||||
|
||||
namespace X10D.Collections;
|
||||
@ -45,10 +47,23 @@ public static class DictionaryExtensions
|
||||
throw new ArgumentNullException(nameof(updateValueFactory));
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
ref var value = ref CollectionsMarshal.GetValueRefOrAddDefault(dictionary, key, out bool exists);
|
||||
// DO NOT CHANGE. reassigning value is necessary to mutate the dictionary, due to ref return above.
|
||||
// mutation of the dictionary is INTENDED BEHAVIOUR. this is not a mistake.
|
||||
return value = exists ? updateValueFactory(key, value!) : addValue;
|
||||
#else
|
||||
if (dictionary.TryGetValue(key, out TValue? old))
|
||||
{
|
||||
TValue updated = updateValueFactory(key, old);
|
||||
dictionary[key] = updated;
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
dictionary.Add(key, addValue);
|
||||
return addValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -142,10 +157,25 @@ public static class DictionaryExtensions
|
||||
throw new ArgumentNullException(nameof(updateValueFactory));
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
ref TValue? value = ref CollectionsMarshal.GetValueRefOrAddDefault(dictionary, key, out bool exists);
|
||||
// DO NOT CHANGE. reassigning value is necessary to mutate the dictionary, due to ref return above.
|
||||
// mutation of the dictionary is INTENDED BEHAVIOUR. this is not a mistake.
|
||||
return value = exists ? updateValueFactory(key, value!) : addValueFactory(key);
|
||||
#else
|
||||
if (dictionary.TryGetValue(key, out TValue? old))
|
||||
{
|
||||
TValue updated = updateValueFactory(key, old);
|
||||
dictionary[key] = updated;
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
TValue add = addValueFactory(key);
|
||||
dictionary.Add(key, add);
|
||||
|
||||
return add;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -254,10 +284,25 @@ public static class DictionaryExtensions
|
||||
throw new ArgumentNullException(nameof(updateValueFactory));
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
ref TValue? value = ref CollectionsMarshal.GetValueRefOrAddDefault(dictionary, key, out bool exists);
|
||||
// DO NOT CHANGE. reassigning value is necessary to mutate the dictionary, due to ref return above.
|
||||
// mutation of the dictionary is INTENDED BEHAVIOUR. this is not a mistake.
|
||||
return value = exists ? updateValueFactory(key, value!, factoryArgument) : addValueFactory(key, factoryArgument);
|
||||
#else
|
||||
if (dictionary.TryGetValue(key, out TValue? old))
|
||||
{
|
||||
TValue updated = updateValueFactory(key, old, factoryArgument);
|
||||
dictionary[key] = updated;
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
TValue add = addValueFactory(key, factoryArgument);
|
||||
dictionary.Add(key, add);
|
||||
|
||||
return add;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,9 +1,12 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using X10D.CompilerServices;
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using X10D.CompilerServices;
|
||||
#endif
|
||||
|
||||
namespace X10D.Collections;
|
||||
|
||||
@ -43,11 +46,13 @@ public static class Int16Extensions
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
if (Sse3.IsSupported)
|
||||
{
|
||||
UnpackInternal_Ssse3(value, destination);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
UnpackInternal_Fallback(value, destination);
|
||||
}
|
||||
@ -61,6 +66,7 @@ public static class Int16Extensions
|
||||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal unsafe static void UnpackInternal_Ssse3(this short value, Span<bool> destination)
|
||||
{
|
||||
@ -83,4 +89,5 @@ public static class Int16Extensions
|
||||
Sse2.Store((byte*)pDestination, correctness);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using X10D.CompilerServices;
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using X10D.CompilerServices;
|
||||
#endif
|
||||
|
||||
namespace X10D.Collections;
|
||||
|
||||
@ -43,6 +46,7 @@ public static class Int32Extensions
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
if (Avx2.IsSupported)
|
||||
{
|
||||
UnpackInternal_Avx2(value, destination);
|
||||
@ -54,6 +58,7 @@ public static class Int32Extensions
|
||||
UnpackInternal_Ssse3(value, destination);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
UnpackInternal_Fallback(value, destination);
|
||||
}
|
||||
@ -67,6 +72,7 @@ public static class Int32Extensions
|
||||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal static unsafe void UnpackInternal_Ssse3(this int value, Span<bool> destination)
|
||||
{
|
||||
@ -124,4 +130,5 @@ public static class Int32Extensions
|
||||
Avx.Store((byte*)pDestination, correctness);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -4,6 +4,10 @@ namespace X10D.CompilerServices;
|
||||
|
||||
internal static class CompilerResources
|
||||
{
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
public const MethodImplOptions MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining |
|
||||
System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization;
|
||||
#else
|
||||
public const MethodImplOptions MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining;
|
||||
#endif
|
||||
}
|
||||
|
@ -20,7 +20,11 @@ public static class EnumExtensions
|
||||
public static T Next<T>(this T value)
|
||||
where T : struct, Enum
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
T[] values = Enum.GetValues<T>();
|
||||
#else
|
||||
T[] values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
|
||||
#endif
|
||||
int index = Array.IndexOf(values, value) + 1;
|
||||
index %= values.Length;
|
||||
return values[index];
|
||||
@ -40,7 +44,11 @@ public static class EnumExtensions
|
||||
public static T NextUnchecked<T>(this T value)
|
||||
where T : struct, Enum
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
T[] values = Enum.GetValues<T>();
|
||||
#else
|
||||
T[] values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
|
||||
#endif
|
||||
int index = Array.IndexOf(values, value) + 1;
|
||||
return values[index];
|
||||
}
|
||||
@ -58,7 +66,11 @@ public static class EnumExtensions
|
||||
public static T Previous<T>(this T value)
|
||||
where T : struct, Enum
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
T[] values = Enum.GetValues<T>();
|
||||
#else
|
||||
T[] values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
|
||||
#endif
|
||||
int index = Array.IndexOf(values, value) - 1;
|
||||
int length = values.Length;
|
||||
|
||||
@ -82,7 +94,11 @@ public static class EnumExtensions
|
||||
public static T PreviousUnchecked<T>(this T value)
|
||||
where T : struct, Enum
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
T[] values = Enum.GetValues<T>();
|
||||
#else
|
||||
T[] values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
|
||||
#endif
|
||||
int index = Array.IndexOf(values, value) - 1;
|
||||
return values[index];
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -187,3 +188,4 @@ public static class IntrinsicExtensions
|
||||
return Sse2.Shuffle(vector.AsDouble(), vector.AsDouble(), 0b01).AsUInt64();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -182,22 +184,34 @@ public static class IntrinsicUtility
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal static Vector64<T> GetUninitializedVector64<T>() where T : struct
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
Unsafe.SkipInit(out Vector64<T> output);
|
||||
return output;
|
||||
#else
|
||||
return default;
|
||||
#endif
|
||||
}
|
||||
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal static Vector128<T> GetUninitializedVector128<T>() where T : struct
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
Unsafe.SkipInit(out Vector128<T> output);
|
||||
return output;
|
||||
#else
|
||||
return default;
|
||||
#endif
|
||||
}
|
||||
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal static Vector256<T> GetUninitializedVector256<T>() where T : struct
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
Unsafe.SkipInit(out Vector256<T> output);
|
||||
return output;
|
||||
#else
|
||||
return default;
|
||||
#endif
|
||||
}
|
||||
|
||||
[Pure]
|
||||
@ -301,3 +315,5 @@ public static class IntrinsicUtility
|
||||
return Avx2.Add(high, ac);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,10 @@ namespace X10D.Core;
|
||||
/// </summary>
|
||||
public static class RandomExtensions
|
||||
{
|
||||
#if !NET6_0_OR_GREATER
|
||||
private static readonly Random Shared = new();
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random value that defined in a specified enum.
|
||||
/// </summary>
|
||||
@ -501,6 +505,10 @@ public static class RandomExtensions
|
||||
|
||||
internal static Random GetShared()
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return Random.Shared;
|
||||
#else
|
||||
return Shared;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,13 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using X10D.CompilerServices;
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
using X10D.CompilerServices;
|
||||
#endif
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Diagnostics;
|
||||
@ -18,6 +21,7 @@ namespace X10D.Core;
|
||||
/// </summary>
|
||||
public static class SpanExtensions
|
||||
{
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
private const ulong IntegerPackingMagic = 0x0102040810204080;
|
||||
|
||||
[ExcludeFromCodeCoverage]
|
||||
@ -31,6 +35,7 @@ public static class SpanExtensions
|
||||
{
|
||||
get => Vector256.Create(IntegerPackingMagic);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether a specific enumeration value is contained with the current span of elements.
|
||||
@ -66,6 +71,7 @@ public static class SpanExtensions
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
public static bool Contains<T>(this ReadOnlySpan<T> span, T value) where T : struct, Enum
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
unsafe
|
||||
{
|
||||
#pragma warning disable CS8500
|
||||
@ -108,6 +114,17 @@ public static class SpanExtensions
|
||||
// dotcover enable
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (var it in span)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(it, value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -144,6 +161,7 @@ public static class SpanExtensions
|
||||
return PackByteInternal_Fallback(source);
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
return PackByteInternal_Fallback(source);
|
||||
@ -158,6 +176,7 @@ public static class SpanExtensions
|
||||
{
|
||||
return PackByteInternal_AdvSimd(source);
|
||||
}
|
||||
#endif
|
||||
|
||||
return PackByteInternal_Fallback(source);
|
||||
}
|
||||
@ -198,10 +217,12 @@ public static class SpanExtensions
|
||||
goto default;
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
return PackInt16Internal_Sse2(source);
|
||||
}
|
||||
#endif
|
||||
|
||||
goto default;
|
||||
case < 16:
|
||||
@ -248,6 +269,7 @@ public static class SpanExtensions
|
||||
return PackInt16(source);
|
||||
|
||||
case 32:
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
goto default;
|
||||
@ -267,6 +289,7 @@ public static class SpanExtensions
|
||||
{
|
||||
return PackInt32Internal_AdvSimd(source);
|
||||
}
|
||||
#endif
|
||||
goto default;
|
||||
|
||||
default:
|
||||
@ -360,6 +383,7 @@ public static class SpanExtensions
|
||||
return result;
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
internal static byte PackByteInternal_Sse2(this ReadOnlySpan<bool> source)
|
||||
@ -475,6 +499,7 @@ public static class SpanExtensions
|
||||
}
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
// dotcover disable
|
||||
//NOSONAR
|
||||
[Pure]
|
||||
@ -492,4 +517,6 @@ public static class SpanExtensions
|
||||
}
|
||||
//NOSONAR
|
||||
// dotcover enable
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -72,9 +72,17 @@ public static class ColorExtensions
|
||||
double blue = color.B;
|
||||
var delta = double.MaxValue;
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
foreach (ConsoleColor consoleColor in Enum.GetValues<ConsoleColor>())
|
||||
#else
|
||||
foreach (ConsoleColor consoleColor in Enum.GetValues(typeof(ConsoleColor)))
|
||||
#endif
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
string name = Enum.GetName(consoleColor)!;
|
||||
#else
|
||||
string name = Enum.GetName(typeof(ConsoleColor), consoleColor)!;
|
||||
#endif
|
||||
Color currentColor = Color.FromName(name == "DarkYellow" ? "Orange" : name); // bug fix
|
||||
double r = currentColor.R - red;
|
||||
double g = currentColor.G - green;
|
||||
|
@ -93,7 +93,13 @@ public static class DecimalExtensions
|
||||
|
||||
private static void GetBits(decimal value, Span<int> destination)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
_ = decimal.GetBits(value, destination);
|
||||
#else
|
||||
Span<byte> buffer = stackalloc byte[16];
|
||||
MemoryMarshal.Write(buffer, ref value);
|
||||
WriteBits(destination, buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
|
@ -43,7 +43,17 @@ public static class DoubleExtensions
|
||||
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
|
||||
public static bool TryWriteBigEndianBytes(this double value, Span<byte> destination)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.TryWriteDoubleBigEndian(destination, value);
|
||||
#else
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
|
||||
return MemoryMarshal.TryWrite(destination, ref tmp);
|
||||
}
|
||||
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -54,6 +64,16 @@ public static class DoubleExtensions
|
||||
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
|
||||
public static bool TryWriteLittleEndianBytes(this double value, Span<byte> destination)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.TryWriteDoubleLittleEndian(destination, value);
|
||||
#else
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
|
||||
return MemoryMarshal.TryWrite(destination, ref tmp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,17 @@ public static class SingleExtensions
|
||||
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
|
||||
public static bool TryWriteBigEndianBytes(this float value, Span<byte> destination)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.TryWriteSingleBigEndian(destination, value);
|
||||
#else
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
int tmp = BinaryPrimitives.ReverseEndianness(BitConverter.SingleToInt32Bits(value));
|
||||
return MemoryMarshal.TryWrite(destination, ref tmp);
|
||||
}
|
||||
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -56,6 +66,16 @@ public static class SingleExtensions
|
||||
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
|
||||
public static bool TryWriteLittleEndianBytes(this float value, Span<byte> destination)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.TryWriteSingleLittleEndian(destination, value);
|
||||
#else
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
int tmp = BinaryPrimitives.ReverseEndianness(BitConverter.SingleToInt32Bits(value));
|
||||
return MemoryMarshal.TryWrite(destination, ref tmp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace X10D.IO;
|
||||
|
||||
@ -39,7 +40,11 @@ public static partial class StreamExtensions
|
||||
buffer.Reverse();
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
return new decimal(buffer);
|
||||
#else
|
||||
return new decimal(buffer.ToArray());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -77,7 +82,11 @@ public static partial class StreamExtensions
|
||||
buffer.Reverse();
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
return new decimal(buffer);
|
||||
#else
|
||||
return new decimal(buffer.ToArray());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -101,7 +110,16 @@ public static partial class StreamExtensions
|
||||
|
||||
Span<byte> buffer = stackalloc byte[8];
|
||||
_ = stream.Read(buffer);
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.ReadDoubleBigEndian(buffer);
|
||||
#else
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
buffer.Reverse();
|
||||
}
|
||||
|
||||
return MemoryMarshal.Read<double>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -126,7 +144,16 @@ public static partial class StreamExtensions
|
||||
|
||||
Span<byte> buffer = stackalloc byte[8];
|
||||
_ = stream.Read(buffer);
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.ReadDoubleLittleEndian(buffer);
|
||||
#else
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
buffer.Reverse();
|
||||
}
|
||||
|
||||
return MemoryMarshal.Read<double>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -296,7 +323,16 @@ public static partial class StreamExtensions
|
||||
|
||||
Span<byte> buffer = stackalloc byte[4];
|
||||
_ = stream.Read(buffer);
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.ReadSingleBigEndian(buffer);
|
||||
#else
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
buffer.Reverse();
|
||||
}
|
||||
|
||||
return MemoryMarshal.Read<float>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -322,7 +358,16 @@ public static partial class StreamExtensions
|
||||
|
||||
Span<byte> buffer = stackalloc byte[4];
|
||||
_ = stream.Read(buffer);
|
||||
#if NET5_0_OR_GREATER
|
||||
return BinaryPrimitives.ReadSingleLittleEndian(buffer);
|
||||
#else
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
buffer.Reverse();
|
||||
}
|
||||
|
||||
return MemoryMarshal.Read<float>(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,4 +1,6 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
namespace X10D.Linq;
|
||||
|
||||
@ -387,9 +389,11 @@ public static class EnumerableExtensions
|
||||
span = array;
|
||||
break;
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
case List<TSource> list:
|
||||
span = CollectionsMarshal.AsSpan(list);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
span = default;
|
||||
|
@ -253,7 +253,15 @@ public static class MathUtility
|
||||
public static float Pulse(float value, float lowerBound, float upperBound)
|
||||
{
|
||||
bool result = lowerBound <= value && value <= upperBound;
|
||||
#if NET6_0_OR_GREATER
|
||||
return Unsafe.As<bool, int>(ref result);
|
||||
#else
|
||||
unsafe
|
||||
{
|
||||
var pResult = (int*)&result;
|
||||
return *pResult;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -269,7 +277,15 @@ public static class MathUtility
|
||||
public static double Pulse(double value, double lowerBound, double upperBound)
|
||||
{
|
||||
bool result = lowerBound <= value && value <= upperBound;
|
||||
#if NET6_0_OR_GREATER
|
||||
return Unsafe.As<bool, int>(ref result);
|
||||
#else
|
||||
unsafe
|
||||
{
|
||||
var pResult = (int*)&result;
|
||||
return *pResult;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -24,7 +24,20 @@ public static class UInt32Extensions
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
public static int PopCount(this uint value)
|
||||
{
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
return BitOperations.PopCount(value);
|
||||
#else
|
||||
const uint c1 = 0x_55555555u;
|
||||
const uint c2 = 0x_33333333u;
|
||||
const uint c3 = 0x_0F0F0F0Fu;
|
||||
const uint c4 = 0x_01010101u;
|
||||
|
||||
value -= (value >> 1) & c1;
|
||||
value = (value & c2) + ((value >> 2) & c2);
|
||||
value = (((value + (value >> 4)) & c3) * c4) >> 24;
|
||||
|
||||
return (int)value;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -69,6 +82,17 @@ public static class UInt32Extensions
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
public static uint RoundUpToPowerOf2(this uint value)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return BitOperations.RoundUpToPowerOf2(value);
|
||||
#else
|
||||
// Based on https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--value;
|
||||
value |= value >> 1;
|
||||
value |= value >> 2;
|
||||
value |= value >> 4;
|
||||
value |= value >> 8;
|
||||
value |= value >> 16;
|
||||
return value + 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,20 @@ public static class UInt64Extensions
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
public static int PopCount(this ulong value)
|
||||
{
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
return BitOperations.PopCount(value);
|
||||
#else
|
||||
const ulong c1 = 0x_55555555_55555555ul;
|
||||
const ulong c2 = 0x_33333333_33333333ul;
|
||||
const ulong c3 = 0x_0F0F0F0F_0F0F0F0Ful;
|
||||
const ulong c4 = 0x_01010101_01010101ul;
|
||||
|
||||
value -= (value >> 1) & c1;
|
||||
value = (value & c2) + ((value >> 2) & c2);
|
||||
value = (((value + (value >> 4)) & c3) * c4) >> 56;
|
||||
|
||||
return (int)value;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -69,6 +82,18 @@ public static class UInt64Extensions
|
||||
[MethodImpl(CompilerResources.MethodImplOptions)]
|
||||
public static ulong RoundUpToPowerOf2(this ulong value)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return BitOperations.RoundUpToPowerOf2(value);
|
||||
#else
|
||||
// Based on https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--value;
|
||||
value |= value >> 1;
|
||||
value |= value >> 2;
|
||||
value |= value >> 4;
|
||||
value |= value >> 8;
|
||||
value |= value >> 16;
|
||||
value |= value >> 32;
|
||||
return value + 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -55,10 +55,12 @@ public static class EnumerableExtensions
|
||||
throw new ArgumentNullException(nameof(pattern));
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
if (source.TryGetNonEnumeratedCount(out int count) && count == 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
#endif
|
||||
|
||||
var options = RegexOptions.Compiled | (ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None);
|
||||
var regex = new Regex(pattern, options, Regex.InfiniteMatchTimeout);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
@ -24,3 +25,4 @@ public static class Extensions
|
||||
return JsonSerializer.Serialize(value, options);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Globalization;
|
||||
@ -105,10 +106,11 @@ public static class RuneExtensions
|
||||
#if NET7_0_OR_GREATER
|
||||
throw new UnreachableException(message);
|
||||
#else
|
||||
throw new InvalidOperationException(message);
|
||||
throw new InvalidOperationException(message);
|
||||
#endif
|
||||
//NOSONAR
|
||||
// dotcover enable
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2,7 +2,9 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Text.Json;
|
||||
#endif
|
||||
using X10D.Collections;
|
||||
using X10D.CompilerServices;
|
||||
using X10D.Core;
|
||||
@ -573,6 +575,7 @@ public static class StringExtensions
|
||||
return Enum.Parse<T>(value, ignoreCase);
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns an object from the specified JSON string.
|
||||
/// </summary>
|
||||
@ -587,6 +590,7 @@ public static class StringExtensions
|
||||
{
|
||||
return JsonSerializer.Deserialize<T>(value, options);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="byte" />[] representing the value the <see cref="string" /> with
|
||||
@ -684,6 +688,7 @@ public static class StringExtensions
|
||||
|
||||
for (var index = 0; index < value.Length; index++)
|
||||
{
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
var rune = new Rune(value[index]);
|
||||
|
||||
if (!Rune.IsLetter(rune))
|
||||
@ -695,6 +700,19 @@ public static class StringExtensions
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
char current = value[index];
|
||||
|
||||
if (!char.IsLetter(current))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!char.IsLower(current))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -759,6 +777,7 @@ public static class StringExtensions
|
||||
|
||||
for (int index = 0, endIndex = value.Length - 1; index < value.Length; index++, endIndex--)
|
||||
{
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
Rune startRune = new Rune(value[index]);
|
||||
Rune endRune = new Rune(value[endIndex]);
|
||||
|
||||
@ -778,6 +797,27 @@ public static class StringExtensions
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
char startChar = value[index];
|
||||
char endChar = value[endIndex];
|
||||
|
||||
if (!char.IsLetter(startChar) && !char.IsNumber(startChar))
|
||||
{
|
||||
endIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!char.IsLetter(endChar) && !char.IsNumber(endChar))
|
||||
{
|
||||
index--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char.ToUpperInvariant(startChar) != char.ToUpperInvariant(endChar))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -801,6 +841,7 @@ public static class StringExtensions
|
||||
|
||||
for (var index = 0; index < value.Length; index++)
|
||||
{
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
var rune = new Rune(value[index]);
|
||||
|
||||
if (!Rune.IsLetter(rune))
|
||||
@ -812,6 +853,19 @@ public static class StringExtensions
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
char current = value[index];
|
||||
|
||||
if (!char.IsLetter(current))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!char.IsUpper(current))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -197,3 +198,4 @@ public static class DateOnlyExtensions
|
||||
return value.ToDateTime(time).ToUnixTimeSeconds();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using X10D.CompilerServices;
|
||||
@ -91,3 +92,4 @@ public static class HalfExtensions
|
||||
return TimeSpan.FromDays((float)value * 7);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0;net6.0;netcoreapp3.1</TargetFrameworks>
|
||||
<Configuration>Release</Configuration>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Optimize>true</Optimize>
|
||||
|
Loading…
Reference in New Issue
Block a user