Skip to content

Commit 699a67d

Browse files
Merge pull request #122 from linksplatform/csharp/feature/use_generic_math
Csharp/feature/use generic math
2 parents c70c8e3 + 37316ed commit 699a67d

13 files changed

Lines changed: 72 additions & 67 deletions

csharp/Platform.Data.Tests/LinksConstantsTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Numerics;
12
using Xunit;
23
using Platform.Reflection;
34
using Platform.Converters;
@@ -41,12 +42,11 @@ public static void ExternalReferencesTest()
4142
TestExternalReferences<ushort, short>();
4243
TestExternalReferences<byte, sbyte>();
4344
}
44-
private static void TestExternalReferences<TUnsigned, TSigned>()
45+
private static void TestExternalReferences<TUnsigned, TSigned>() where TUnsigned : IUnsignedNumber<TUnsigned> where TSigned : ISignedNumber<TSigned>
4546
{
46-
var unsingedOne = Arithmetic.Increment(default(TUnsigned));
47-
var converter = UncheckedConverter<TSigned, TUnsigned>.Default;
48-
var half = converter.Convert(NumericType<TSigned>.MaxValue);
49-
LinksConstants<TUnsigned> constants = new LinksConstants<TUnsigned>((unsingedOne, half), (Arithmetic.Add(half, unsingedOne), NumericType<TUnsigned>.MaxValue));
47+
var unsingedOne = TUnsigned.One;
48+
var half = TUnsigned.CreateTruncating((NumericType<TSigned>.MaxValue));
49+
LinksConstants<TUnsigned> constants = new LinksConstants<TUnsigned>((unsingedOne, half), (half+unsingedOne, NumericType<TUnsigned>.MaxValue));
5050

5151
var minimum = new Hybrid<TUnsigned>(default, isExternal: true);
5252
var maximum = new Hybrid<TUnsigned>(half, isExternal: true);

csharp/Platform.Data/Hybrid.cs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Numerics;
34
using System.Runtime.CompilerServices;
45
using Platform.Exceptions;
56
using Platform.Reflection;
67
using Platform.Converters;
78
using Platform.Numbers;
9+
using Math = System.Math;
810

911
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
1012

@@ -16,13 +18,9 @@ namespace Platform.Data
1618
/// </para>
1719
/// <para></para>
1820
/// </summary>
19-
public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>>
21+
public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>> where TLinkAddress:IUnsignedNumber<TLinkAddress>
2022
{
21-
private static readonly EqualityComparer<TLinkAddress> _equalityComparer = EqualityComparer<TLinkAddress>.Default;
2223
private static readonly UncheckedSignExtendingConverter<TLinkAddress, long> _addressToInt64Converter = UncheckedSignExtendingConverter<TLinkAddress, long>.Default;
23-
private static readonly UncheckedConverter<long, TLinkAddress> _int64ToAddressConverter = UncheckedConverter<long, TLinkAddress>.Default;
24-
private static readonly UncheckedConverter<TLinkAddress, ulong> _addressToUInt64Converter = UncheckedConverter<TLinkAddress, ulong>.Default;
25-
private static readonly UncheckedConverter<ulong, TLinkAddress> _uInt64ToAddressConverter = UncheckedConverter<ulong, TLinkAddress>.Default;
2624
private static readonly UncheckedConverter<object, long> _objectToInt64Converter = UncheckedConverter<object, long>.Default;
2725

2826
/// <summary>
@@ -31,14 +29,14 @@ public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>>
3129
/// </para>
3230
/// <para></para>
3331
/// </summary>
34-
public static readonly ulong HalfOfNumberValuesRange = _addressToUInt64Converter.Convert(NumericType<TLinkAddress>.MaxValue) / 2;
32+
public static readonly TLinkAddress HalfOfNumberValuesRange = (NumericType<TLinkAddress>.MaxValue) / TLinkAddress.CreateTruncating(2);
3533
/// <summary>
3634
/// <para>
3735
/// The half of number values range.
3836
/// </para>
3937
/// <para></para>
4038
/// </summary>
41-
public static readonly TLinkAddress ExternalZero = _uInt64ToAddressConverter.Convert(HalfOfNumberValuesRange + 1UL);
39+
public static readonly TLinkAddress ExternalZero = (HalfOfNumberValuesRange + TLinkAddress.CreateTruncating(1));
4240

4341
/// <summary>
4442
/// <para>
@@ -57,7 +55,7 @@ public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>>
5755
public bool IsNothing
5856
{
5957
[MethodImpl(MethodImplOptions.AggressiveInlining)]
60-
get => _equalityComparer.Equals(Value, ExternalZero) || SignedValue == 0;
58+
get => (Value == ExternalZero) || SignedValue == 0;
6159
}
6260

6361
/// <summary>
@@ -81,7 +79,7 @@ public bool IsInternal
8179
public bool IsExternal
8280
{
8381
[MethodImpl(MethodImplOptions.AggressiveInlining)]
84-
get => _equalityComparer.Equals(Value, ExternalZero) || SignedValue < 0;
82+
get => (Value == ExternalZero) || SignedValue < 0;
8583
}
8684

8785
/// <summary>
@@ -105,7 +103,7 @@ public long SignedValue
105103
public long AbsoluteValue
106104
{
107105
[MethodImpl(MethodImplOptions.AggressiveInlining)]
108-
get => _equalityComparer.Equals(Value, ExternalZero) ? 0 : Platform.Numbers.Math.Abs(SignedValue);
106+
get => (Value == ExternalZero) ? 0 : System.Math.Abs(SignedValue);
109107
}
110108

111109
/// <summary>
@@ -142,15 +140,15 @@ public Hybrid(TLinkAddress value)
142140
[MethodImpl(MethodImplOptions.AggressiveInlining)]
143141
public Hybrid(TLinkAddress value, bool isExternal)
144142
{
145-
if (_equalityComparer.Equals(value, default) && isExternal)
143+
if ((value == default) && isExternal)
146144
{
147145
Value = ExternalZero;
148146
}
149147
else
150148
{
151149
if (isExternal)
152150
{
153-
Value = Math<TLinkAddress>.Negate(value);
151+
Value = -(value);
154152
}
155153
else
156154
{
@@ -170,7 +168,7 @@ public Hybrid(TLinkAddress value, bool isExternal)
170168
/// <para></para>
171169
/// </param>
172170
[MethodImpl(MethodImplOptions.AggressiveInlining)]
173-
public Hybrid(object value) => Value = _int64ToAddressConverter.Convert(_objectToInt64Converter.Convert(value));
171+
public Hybrid(object value) => Value = TLinkAddress.CreateTruncating(_objectToInt64Converter.Convert(value));
174172

175173
/// <summary>
176174
/// <para>
@@ -197,7 +195,7 @@ public Hybrid(object value, bool isExternal)
197195
else
198196
{
199197
var absoluteValue = System.Math.Abs(signedValue);
200-
Value = isExternal ? _int64ToAddressConverter.Convert(-absoluteValue) : _int64ToAddressConverter.Convert(absoluteValue);
198+
Value = isExternal ? TLinkAddress.CreateTruncating(-absoluteValue) : TLinkAddress.CreateTruncating(absoluteValue);
201199
}
202200
}
203201

@@ -283,7 +281,7 @@ public Hybrid(object value, bool isExternal)
283281
/// <para></para>
284282
/// </returns>
285283
[MethodImpl(MethodImplOptions.AggressiveInlining)]
286-
public bool Equals(Hybrid<TLinkAddress> other) => _equalityComparer.Equals(Value, other.Value);
284+
public bool Equals(Hybrid<TLinkAddress> other) => (Value == other.Value);
287285

288286
/// <summary>
289287
/// <para>

csharp/Platform.Data/ILinks.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Numerics;
34
using System.Runtime.CompilerServices;
45
using Platform.Delegates;
56

@@ -16,6 +17,7 @@ namespace Platform.Data
1617
/// <para>Этот интерфейс не зависит от размера содержимого связи, а значит подходит как для дуплетов, триплетов и последовательностей связей любого размера.</para>
1718
/// </remarks>
1819
public interface ILinks<TLinkAddress, TConstants>
20+
where TLinkAddress : IUnsignedNumber<TLinkAddress>
1921
where TConstants : LinksConstants<TLinkAddress>
2022
{
2123
#region Constants

csharp/Platform.Data/ILinksExtensions.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Numerics;
34
using System.Runtime.CompilerServices;
45
using Platform.Setters;
56
using Platform.Data.Exceptions;
@@ -17,27 +18,27 @@ namespace Platform.Data
1718
/// </summary>
1819
public static class ILinksExtensions
1920
{
20-
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links) => links.Create(null);
21+
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links) where TLinkAddress : IUnsignedNumber<TLinkAddress> => links.Create(null);
2122

22-
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? substitution)
23+
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? substitution) where TLinkAddress : IUnsignedNumber<TLinkAddress>
2324
{
2425
var constants = links.Constants;
2526
Setter<TLinkAddress, TLinkAddress> setter = new Setter<TLinkAddress, TLinkAddress>(constants.Continue, constants.Break, constants.Null);
2627
links.Create(substitution, setter.SetFirstFromNonNullSecondListAndReturnTrue);
2728
return setter.Result;
2829
}
2930

30-
public static TLinkAddress Update<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction, IList<TLinkAddress>? substitution)
31+
public static TLinkAddress Update<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction, IList<TLinkAddress>? substitution) where TLinkAddress : IUnsignedNumber<TLinkAddress>
3132
{
3233
var constants = links.Constants;
3334
Setter<TLinkAddress, TLinkAddress> setter = new(constants.Continue, constants.Break, constants.Null);
3435
links.Update(restriction, substitution, setter.SetFirstFromNonNullSecondListAndReturnTrue);
3536
return setter.Result;
3637
}
3738

38-
public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, TLinkAddress linkToDelete) => Delete(links, (IList<TLinkAddress>?)new LinkAddress<TLinkAddress>(linkToDelete));
39+
public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, TLinkAddress linkToDelete) where TLinkAddress : IUnsignedNumber<TLinkAddress> => Delete(links, (IList<TLinkAddress>?)new LinkAddress<TLinkAddress>(linkToDelete));
3940

40-
public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction)
41+
public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction) where TLinkAddress : IUnsignedNumber<TLinkAddress>
4142
{
4243
var constants = links.Constants;
4344
Setter<TLinkAddress, TLinkAddress> setter = new Setter<TLinkAddress, TLinkAddress>(constants.Continue, constants.Break, constants.Null);
@@ -72,7 +73,7 @@ public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksC
7273
/// <para></para>
7374
/// </returns>
7475
[MethodImpl(MethodImplOptions.AggressiveInlining)]
75-
public static TLinkAddress Count<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, params TLinkAddress[] restrictions)
76+
public static TLinkAddress Count<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, params TLinkAddress[] restrictions) where TLinkAddress : IUnsignedNumber<TLinkAddress>
7677
where TConstants : LinksConstants<TLinkAddress>
7778
=> links.Count(restrictions);
7879

@@ -83,7 +84,7 @@ public static TLinkAddress Count<TLinkAddress, TConstants>(this ILinks<TLinkAddr
8384
/// <param name="link">Индекс проверяемой на существование связи.</param>
8485
/// <returns>Значение, определяющее существует ли связь.</returns>
8586
[MethodImpl(MethodImplOptions.AggressiveInlining)]
86-
public static bool Exists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
87+
public static bool Exists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
8788
where TConstants : LinksConstants<TLinkAddress>
8889
{
8990
var constants = links.Constants;
@@ -96,7 +97,7 @@ public static bool Exists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TC
9697
/// TODO: May be move to EnsureExtensions or make it both there and here
9798
/// </remarks>
9899
[MethodImpl(MethodImplOptions.AggressiveInlining)]
99-
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
100+
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
100101
where TConstants : LinksConstants<TLinkAddress>
101102
{
102103
if (!links.Exists(link))
@@ -109,7 +110,7 @@ public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkA
109110
/// <param name="link">Индекс проверяемой на существование связи.</param>
110111
/// <param name="argumentName">Имя аргумента, в который передаётся индекс связи.</param>
111112
[MethodImpl(MethodImplOptions.AggressiveInlining)]
112-
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link, string argumentName)
113+
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link, string argumentName) where TLinkAddress : IUnsignedNumber<TLinkAddress>
113114
where TConstants : LinksConstants<TLinkAddress>
114115
{
115116
if (!links.Exists(link))
@@ -126,7 +127,7 @@ public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkA
126127
/// <param name="restrictions">Ограничения на содержимое связей. Каждое ограничение может иметь значения: Constants.Null - 0-я связь, обозначающая ссылку на пустоту, Any - отсутствие ограничения, 1..∞ конкретный индекс связи.</param>
127128
/// <returns>True, в случае если проход по связям не был прерван и False в обратном случае.</returns>
128129
[MethodImpl(MethodImplOptions.AggressiveInlining)]
129-
public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, ReadHandler<TLinkAddress>? handler, params TLinkAddress[] restrictions)
130+
public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, ReadHandler<TLinkAddress>? handler, params TLinkAddress[] restrictions) where TLinkAddress : IUnsignedNumber<TLinkAddress>
130131
where TConstants : LinksConstants<TLinkAddress>
131132
=> links.Each(restrictions, handler);
132133

@@ -137,7 +138,7 @@ public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddre
137138
/// <param name="link">Индекс связи.</param>
138139
/// <returns>Уникальную связь.</returns>
139140
[MethodImpl(MethodImplOptions.AggressiveInlining)]
140-
public static IList<TLinkAddress>? GetLink<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
141+
public static IList<TLinkAddress>? GetLink<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
141142
where TConstants : LinksConstants<TLinkAddress>
142143
{
143144
var constants = links.Constants;
@@ -175,7 +176,7 @@ public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddre
175176
/// И наоборот этот же метод поможет, если уже существует точка, но нам нужна пара.
176177
/// </remarks>
177178
[MethodImpl(MethodImplOptions.AggressiveInlining)]
178-
public static bool IsFullPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
179+
public static bool IsFullPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
179180
where TConstants : LinksConstants<TLinkAddress>
180181
{
181182
if (links.Constants.IsExternalReference(link))
@@ -195,7 +196,7 @@ public static bool IsFullPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddres
195196
/// Также в будущем можно будет проверять и всех родителей, чтобы проверить есть ли ссылки на себя (на эту связь).
196197
/// </remarks>
197198
[MethodImpl(MethodImplOptions.AggressiveInlining)]
198-
public static bool IsPartialPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
199+
public static bool IsPartialPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
199200
where TConstants : LinksConstants<TLinkAddress>
200201
{
201202
if (links.Constants.IsExternalReference(link))

csharp/Platform.Data/ISynchronizedLinks.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Numerics;
12
using Platform.Threading.Synchronization;
23

34
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
@@ -13,6 +14,7 @@ namespace Platform.Data
1314
/// <seealso cref="ISynchronized{TLinks}"/>
1415
/// <seealso cref="ILinks{TLinkAddress, TConstants}"/>
1516
public interface ISynchronizedLinks<TLinkAddress, TLinks, TConstants> : ISynchronized<TLinks>, ILinks<TLinkAddress, TConstants>
17+
where TLinkAddress : IUnsignedNumber<TLinkAddress>
1618
where TLinks : ILinks<TLinkAddress, TConstants>
1719
where TConstants : LinksConstants<TLinkAddress>
1820
{

csharp/Platform.Data/LinkAddress.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Numerics;
45
using System.Runtime.CompilerServices;
56

67
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
@@ -15,9 +16,8 @@ namespace Platform.Data
1516
/// </summary>
1617
/// <seealso cref="IEquatable{LinkAddress{TLinkAddress}}"/>
1718
/// <seealso cref="IList{TLinkAddress}"/>
18-
public class LinkAddress<TLinkAddress> : IEquatable<LinkAddress<TLinkAddress>>, IList<TLinkAddress>
19+
public class LinkAddress<TLinkAddress> : IEquatable<LinkAddress<TLinkAddress>>, IList<TLinkAddress> where TLinkAddress : IUnsignedNumber<TLinkAddress>
1920
{
20-
private static readonly EqualityComparer<TLinkAddress> _equalityComparer = EqualityComparer<TLinkAddress>.Default;
2121

2222
/// <summary>
2323
/// <para>
@@ -129,7 +129,7 @@ public bool IsReadOnly
129129
/// <para></para>
130130
/// </returns>
131131
[MethodImpl(MethodImplOptions.AggressiveInlining)]
132-
public virtual bool Contains(TLinkAddress item) => _equalityComparer.Equals(item, Index);
132+
public virtual bool Contains(TLinkAddress item) => (item == Index);
133133

134134
/// <summary>
135135
/// <para>
@@ -179,7 +179,7 @@ public IEnumerator<TLinkAddress> GetEnumerator()
179179
/// <para></para>
180180
/// </returns>
181181
[MethodImpl(MethodImplOptions.AggressiveInlining)]
182-
public virtual int IndexOf(TLinkAddress item) => _equalityComparer.Equals(item, Index) ? 0 : -1;
182+
public virtual int IndexOf(TLinkAddress item) => (item == Index) ? 0 : -1;
183183

184184
/// <summary>
185185
/// <para>
@@ -259,7 +259,7 @@ IEnumerator IEnumerable.GetEnumerator()
259259
/// <para></para>
260260
/// </returns>
261261
[MethodImpl(MethodImplOptions.AggressiveInlining)]
262-
public virtual bool Equals(LinkAddress<TLinkAddress> other) => other != null && _equalityComparer.Equals(Index, other.Index);
262+
public virtual bool Equals(LinkAddress<TLinkAddress> other) => other != null && (Index == other.Index);
263263

264264
[MethodImpl(MethodImplOptions.AggressiveInlining)]
265265
public static implicit operator TLinkAddress(LinkAddress<TLinkAddress> linkAddress) => linkAddress.Index;

0 commit comments

Comments
 (0)