Skip to content

Commit

Permalink
Merge pull request #122 from linksplatform/csharp/feature/use_generic…
Browse files Browse the repository at this point in the history
…_math

Csharp/feature/use generic math
  • Loading branch information
FreePhoenix888 authored Dec 28, 2022
2 parents c70c8e3 + 37316ed commit 699a67d
Show file tree
Hide file tree
Showing 13 changed files with 72 additions and 67 deletions.
10 changes: 5 additions & 5 deletions csharp/Platform.Data.Tests/LinksConstantsTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Numerics;
using Xunit;
using Platform.Reflection;
using Platform.Converters;
Expand Down Expand Up @@ -41,12 +42,11 @@ public static void ExternalReferencesTest()
TestExternalReferences<ushort, short>();
TestExternalReferences<byte, sbyte>();
}
private static void TestExternalReferences<TUnsigned, TSigned>()
private static void TestExternalReferences<TUnsigned, TSigned>() where TUnsigned : IUnsignedNumber<TUnsigned> where TSigned : ISignedNumber<TSigned>
{
var unsingedOne = Arithmetic.Increment(default(TUnsigned));
var converter = UncheckedConverter<TSigned, TUnsigned>.Default;
var half = converter.Convert(NumericType<TSigned>.MaxValue);
LinksConstants<TUnsigned> constants = new LinksConstants<TUnsigned>((unsingedOne, half), (Arithmetic.Add(half, unsingedOne), NumericType<TUnsigned>.MaxValue));
var unsingedOne = TUnsigned.One;
var half = TUnsigned.CreateTruncating((NumericType<TSigned>.MaxValue));
LinksConstants<TUnsigned> constants = new LinksConstants<TUnsigned>((unsingedOne, half), (half+unsingedOne, NumericType<TUnsigned>.MaxValue));

var minimum = new Hybrid<TUnsigned>(default, isExternal: true);
var maximum = new Hybrid<TUnsigned>(half, isExternal: true);
Expand Down
28 changes: 13 additions & 15 deletions csharp/Platform.Data/Hybrid.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using Platform.Exceptions;
using Platform.Reflection;
using Platform.Converters;
using Platform.Numbers;
using Math = System.Math;

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

Expand All @@ -16,13 +18,9 @@ namespace Platform.Data
/// </para>
/// <para></para>
/// </summary>
public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>>
public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>> where TLinkAddress:IUnsignedNumber<TLinkAddress>
{
private static readonly EqualityComparer<TLinkAddress> _equalityComparer = EqualityComparer<TLinkAddress>.Default;
private static readonly UncheckedSignExtendingConverter<TLinkAddress, long> _addressToInt64Converter = UncheckedSignExtendingConverter<TLinkAddress, long>.Default;
private static readonly UncheckedConverter<long, TLinkAddress> _int64ToAddressConverter = UncheckedConverter<long, TLinkAddress>.Default;
private static readonly UncheckedConverter<TLinkAddress, ulong> _addressToUInt64Converter = UncheckedConverter<TLinkAddress, ulong>.Default;
private static readonly UncheckedConverter<ulong, TLinkAddress> _uInt64ToAddressConverter = UncheckedConverter<ulong, TLinkAddress>.Default;
private static readonly UncheckedConverter<object, long> _objectToInt64Converter = UncheckedConverter<object, long>.Default;

/// <summary>
Expand All @@ -31,14 +29,14 @@ public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>>
/// </para>
/// <para></para>
/// </summary>
public static readonly ulong HalfOfNumberValuesRange = _addressToUInt64Converter.Convert(NumericType<TLinkAddress>.MaxValue) / 2;
public static readonly TLinkAddress HalfOfNumberValuesRange = (NumericType<TLinkAddress>.MaxValue) / TLinkAddress.CreateTruncating(2);
/// <summary>
/// <para>
/// The half of number values range.
/// </para>
/// <para></para>
/// </summary>
public static readonly TLinkAddress ExternalZero = _uInt64ToAddressConverter.Convert(HalfOfNumberValuesRange + 1UL);
public static readonly TLinkAddress ExternalZero = (HalfOfNumberValuesRange + TLinkAddress.CreateTruncating(1));

/// <summary>
/// <para>
Expand All @@ -57,7 +55,7 @@ public struct Hybrid<TLinkAddress> : IEquatable<Hybrid<TLinkAddress>>
public bool IsNothing
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _equalityComparer.Equals(Value, ExternalZero) || SignedValue == 0;
get => (Value == ExternalZero) || SignedValue == 0;
}

/// <summary>
Expand All @@ -81,7 +79,7 @@ public bool IsInternal
public bool IsExternal
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _equalityComparer.Equals(Value, ExternalZero) || SignedValue < 0;
get => (Value == ExternalZero) || SignedValue < 0;
}

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

/// <summary>
Expand Down Expand Up @@ -142,15 +140,15 @@ public Hybrid(TLinkAddress value)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Hybrid(TLinkAddress value, bool isExternal)
{
if (_equalityComparer.Equals(value, default) && isExternal)
if ((value == default) && isExternal)
{
Value = ExternalZero;
}
else
{
if (isExternal)
{
Value = Math<TLinkAddress>.Negate(value);
Value = -(value);
}
else
{
Expand All @@ -170,7 +168,7 @@ public Hybrid(TLinkAddress value, bool isExternal)
/// <para></para>
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Hybrid(object value) => Value = _int64ToAddressConverter.Convert(_objectToInt64Converter.Convert(value));
public Hybrid(object value) => Value = TLinkAddress.CreateTruncating(_objectToInt64Converter.Convert(value));

/// <summary>
/// <para>
Expand All @@ -197,7 +195,7 @@ public Hybrid(object value, bool isExternal)
else
{
var absoluteValue = System.Math.Abs(signedValue);
Value = isExternal ? _int64ToAddressConverter.Convert(-absoluteValue) : _int64ToAddressConverter.Convert(absoluteValue);
Value = isExternal ? TLinkAddress.CreateTruncating(-absoluteValue) : TLinkAddress.CreateTruncating(absoluteValue);
}
}

Expand Down Expand Up @@ -283,7 +281,7 @@ public Hybrid(object value, bool isExternal)
/// <para></para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Hybrid<TLinkAddress> other) => _equalityComparer.Equals(Value, other.Value);
public bool Equals(Hybrid<TLinkAddress> other) => (Value == other.Value);

/// <summary>
/// <para>
Expand Down
2 changes: 2 additions & 0 deletions csharp/Platform.Data/ILinks.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using Platform.Delegates;

Expand All @@ -16,6 +17,7 @@ namespace Platform.Data
/// <para>Этот интерфейс не зависит от размера содержимого связи, а значит подходит как для дуплетов, триплетов и последовательностей связей любого размера.</para>
/// </remarks>
public interface ILinks<TLinkAddress, TConstants>
where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
#region Constants
Expand Down
27 changes: 14 additions & 13 deletions csharp/Platform.Data/ILinksExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using Platform.Setters;
using Platform.Data.Exceptions;
Expand All @@ -17,27 +18,27 @@ namespace Platform.Data
/// </summary>
public static class ILinksExtensions
{
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links) => links.Create(null);
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links) where TLinkAddress : IUnsignedNumber<TLinkAddress> => links.Create(null);

public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? substitution)
public static TLinkAddress Create<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? substitution) where TLinkAddress : IUnsignedNumber<TLinkAddress>
{
var constants = links.Constants;
Setter<TLinkAddress, TLinkAddress> setter = new Setter<TLinkAddress, TLinkAddress>(constants.Continue, constants.Break, constants.Null);
links.Create(substitution, setter.SetFirstFromNonNullSecondListAndReturnTrue);
return setter.Result;
}

public static TLinkAddress Update<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction, IList<TLinkAddress>? substitution)
public static TLinkAddress Update<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction, IList<TLinkAddress>? substitution) where TLinkAddress : IUnsignedNumber<TLinkAddress>
{
var constants = links.Constants;
Setter<TLinkAddress, TLinkAddress> setter = new(constants.Continue, constants.Break, constants.Null);
links.Update(restriction, substitution, setter.SetFirstFromNonNullSecondListAndReturnTrue);
return setter.Result;
}

public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, TLinkAddress linkToDelete) => Delete(links, (IList<TLinkAddress>?)new LinkAddress<TLinkAddress>(linkToDelete));
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));

public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction)
public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksConstants<TLinkAddress>> links, IList<TLinkAddress>? restriction) where TLinkAddress : IUnsignedNumber<TLinkAddress>
{
var constants = links.Constants;
Setter<TLinkAddress, TLinkAddress> setter = new Setter<TLinkAddress, TLinkAddress>(constants.Continue, constants.Break, constants.Null);
Expand Down Expand Up @@ -72,7 +73,7 @@ public static TLinkAddress Delete<TLinkAddress>(this ILinks<TLinkAddress, LinksC
/// <para></para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLinkAddress Count<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, params TLinkAddress[] restrictions)
public static TLinkAddress Count<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, params TLinkAddress[] restrictions) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
=> links.Count(restrictions);

Expand All @@ -83,7 +84,7 @@ public static TLinkAddress Count<TLinkAddress, TConstants>(this ILinks<TLinkAddr
/// <param name="link">Индекс проверяемой на существование связи.</param>
/// <returns>Значение, определяющее существует ли связь.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Exists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
public static bool Exists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
var constants = links.Constants;
Expand All @@ -96,7 +97,7 @@ public static bool Exists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TC
/// TODO: May be move to EnsureExtensions or make it both there and here
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
if (!links.Exists(link))
Expand All @@ -109,7 +110,7 @@ public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkA
/// <param name="link">Индекс проверяемой на существование связи.</param>
/// <param name="argumentName">Имя аргумента, в который передаётся индекс связи.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link, string argumentName)
public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link, string argumentName) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
if (!links.Exists(link))
Expand All @@ -126,7 +127,7 @@ public static void EnsureLinkExists<TLinkAddress, TConstants>(this ILinks<TLinkA
/// <param name="restrictions">Ограничения на содержимое связей. Каждое ограничение может иметь значения: Constants.Null - 0-я связь, обозначающая ссылку на пустоту, Any - отсутствие ограничения, 1..∞ конкретный индекс связи.</param>
/// <returns>True, в случае если проход по связям не был прерван и False в обратном случае.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, ReadHandler<TLinkAddress>? handler, params TLinkAddress[] restrictions)
public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, ReadHandler<TLinkAddress>? handler, params TLinkAddress[] restrictions) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
=> links.Each(restrictions, handler);

Expand All @@ -137,7 +138,7 @@ public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddre
/// <param name="link">Индекс связи.</param>
/// <returns>Уникальную связь.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IList<TLinkAddress>? GetLink<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
public static IList<TLinkAddress>? GetLink<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
var constants = links.Constants;
Expand Down Expand Up @@ -175,7 +176,7 @@ public static TLinkAddress Each<TLinkAddress, TConstants>(this ILinks<TLinkAddre
/// И наоборот этот же метод поможет, если уже существует точка, но нам нужна пара.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsFullPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
public static bool IsFullPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
if (links.Constants.IsExternalReference(link))
Expand All @@ -195,7 +196,7 @@ public static bool IsFullPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddres
/// Также в будущем можно будет проверять и всех родителей, чтобы проверить есть ли ссылки на себя (на эту связь).
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsPartialPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link)
public static bool IsPartialPoint<TLinkAddress, TConstants>(this ILinks<TLinkAddress, TConstants> links, TLinkAddress link) where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TConstants : LinksConstants<TLinkAddress>
{
if (links.Constants.IsExternalReference(link))
Expand Down
2 changes: 2 additions & 0 deletions csharp/Platform.Data/ISynchronizedLinks.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Numerics;
using Platform.Threading.Synchronization;

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
Expand All @@ -13,6 +14,7 @@ namespace Platform.Data
/// <seealso cref="ISynchronized{TLinks}"/>
/// <seealso cref="ILinks{TLinkAddress, TConstants}"/>
public interface ISynchronizedLinks<TLinkAddress, TLinks, TConstants> : ISynchronized<TLinks>, ILinks<TLinkAddress, TConstants>
where TLinkAddress : IUnsignedNumber<TLinkAddress>
where TLinks : ILinks<TLinkAddress, TConstants>
where TConstants : LinksConstants<TLinkAddress>
{
Expand Down
10 changes: 5 additions & 5 deletions csharp/Platform.Data/LinkAddress.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;

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

/// <summary>
/// <para>
Expand Down Expand Up @@ -129,7 +129,7 @@ public bool IsReadOnly
/// <para></para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual bool Contains(TLinkAddress item) => _equalityComparer.Equals(item, Index);
public virtual bool Contains(TLinkAddress item) => (item == Index);

/// <summary>
/// <para>
Expand Down Expand Up @@ -179,7 +179,7 @@ public IEnumerator<TLinkAddress> GetEnumerator()
/// <para></para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual int IndexOf(TLinkAddress item) => _equalityComparer.Equals(item, Index) ? 0 : -1;
public virtual int IndexOf(TLinkAddress item) => (item == Index) ? 0 : -1;

/// <summary>
/// <para>
Expand Down Expand Up @@ -259,7 +259,7 @@ IEnumerator IEnumerable.GetEnumerator()
/// <para></para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual bool Equals(LinkAddress<TLinkAddress> other) => other != null && _equalityComparer.Equals(Index, other.Index);
public virtual bool Equals(LinkAddress<TLinkAddress> other) => other != null && (Index == other.Index);

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

0 comments on commit 699a67d

Please sign in to comment.