Std

Mainly a port of Rust's std.
git clone https://git.philomathiclife.com/repos/Std
Log | Files | Refs | README

I128.cs (14670B)


      1 using Std.Clone;
      2 using Std.Cmp;
      3 using Std.Convert;
      4 using Std.Hashing;
      5 using Std.Maybe;
      6 using static Std.Maybe.Maybe<Std.Cmp.Ordering>;
      7 using static Std.Maybe.Maybe<uint>;
      8 using Std.Result;
      9 using static Std.Result.Result<Std.Num.I128, Std.Bottom>;
     10 using static Std.Result.Result<string, Std.Bottom>;
     11 using System;
     12 using System.Runtime.CompilerServices;
     13 using System.Runtime.InteropServices;
     14 #region Namespaces
     15 namespace Std.Num {
     16     #region Types
     17     [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 8, Size = 16)]
     18     public readonly struct I128: IClone<I128>, IEquality<I128>, IHashable, IInto<I128>, IInto<string>, IOrd<I128>, ITryInto<U128, TryIntoIntError>, ITryInto<NonZeroI128, TryIntoIntError>, ITryInto<byte, TryIntoIntError>, ITryInto<int, TryIntoIntError>, ITryInto<long, TryIntoIntError>, ITryInto<sbyte, TryIntoIntError>, ITryInto<short, TryIntoIntError>, ITryInto<uint, TryIntoIntError>, ITryInto<ulong, TryIntoIntError>, ITryInto<ushort, TryIntoIntError>, IFrom<I128, bool>, IFrom<I128, sbyte>, IFrom<I128, byte>, IFrom<I128, short>, IFrom<I128, ushort>, IFrom<I128, int>, IFrom<I128, uint>, IFrom<I128, long>, IFrom<I128, ulong> {
     19 
     20         #region Type-level Constructors
     21         #endregion
     22 
     23         #region Instance Constructors
     24         [MethodImpl(MethodImplOptions.AggressiveInlining)]
     25         public I128() => Value = U128.MinValue;
     26         [MethodImpl(MethodImplOptions.AggressiveInlining)]
     27         internal I128(U128 val) => Value = val;
     28         [MethodImpl(MethodImplOptions.AggressiveInlining)]
     29         public I128(long low) => Value = low < 0L ? new((ulong)low, ulong.MaxValue) : new((ulong)low);
     30         [MethodImpl(MethodImplOptions.AggressiveInlining)]
     31         public I128(long low, long high) => Value = new((ulong)low, (ulong)high);
     32         #endregion
     33 
     34         #region Type-level Fields
     35         public static readonly I128 Zero = new();
     36         public static readonly I128 MaxValue = new(-1L, long.MaxValue);
     37         public static readonly I128 MinValue = new(0L, long.MinValue);
     38         #endregion
     39 
     40         #region Instance Fields
     41         [FieldOffset(0)] public readonly U128 Value;
     42         #endregion
     43 
     44         #region Type-level Properties
     45         #endregion
     46 
     47         #region Instance Properties
     48         #endregion
     49 
     50         #region Type-level Functions
     51         public static U128 Abs(I128 val) => val >= Zero ? val.Value : (MinValue - (val - MinValue)).Value;
     52         public static Prod<I128, I128> DivRem(I128 dividend, I128 divisor) {
     53 
     54             var val = U128.DivRem(Abs(dividend), Abs(divisor));
     55             return dividend < Zero ? divisor < Zero ? new(new I128(val.Item0), -new I128(val.Item1)) : new(-new I128(val.Item0), -new I128(val.Item1)) : divisor < Zero ? new(-new I128(val.Item0), new I128(val.Item1)) : new(new I128(val.Item0), new I128(val.Item1));
     56         }
     57         public static Prod<I128, I128> DivRem(I128 dividend, NonZeroI128 divisor) {
     58             var val = U128.DivRem(Abs(dividend), new NonZeroU128(Abs(divisor.Value)));
     59             return dividend < Zero ? divisor.Value < Zero ? new(new I128(val.Item0), -new I128(val.Item1)) : new(-new I128(val.Item0), -new I128(val.Item1)) : divisor.Value < Zero ? new(-new I128(val.Item0), new I128(val.Item1)) : new(new I128(val.Item0), new I128(val.Item1));
     60         }
     61         public static I128 FromBEBytes(ReadOnlySpan<byte> val) => new(U128.FromBEBytes(val));
     62         public static I128 FromLEBytes(ReadOnlySpan<byte> val) => new(U128.FromLEBytes(val));
     63         public static Result<I128, ParseIntError> TryFrom(ReadOnlySpan<char> val) => val.Length is 0 or > 40 ? (new(ParseIntError.InvalidLength)) : val[0] == '-' ? val.Length == 1 ? (new(ParseIntError.InvalidDigit)) : U128.TryFrom(val[1..]).AndThen((v) => v.TryIntoI128().MapErr((_) => ParseIntError.OverflowOrUnderflow)).Map((v) => -v) : U128.TryFrom(val).AndThen((v) => v.TryIntoI128().MapErr((_) => ParseIntError.OverflowOrUnderflow));
     64         public static Result<I128, ParseIntError> TryFromAllowLeading0s(ReadOnlySpan<char> val) => val.Length == 0 ? (new(ParseIntError.InvalidLength)) : val[0] == '-' ? val.Length == 1 ? (new(ParseIntError.InvalidDigit)) : U128.TryFromAllowLeading0s(val[1..]).AndThen((v) => v.TryIntoI128().MapErr((_) => ParseIntError.OverflowOrUnderflow)).Map((v) => -v) : U128.TryFromAllowLeading0s(val).AndThen((v) => v.TryIntoI128().MapErr((_) => ParseIntError.OverflowOrUnderflow));
     65         public static I128 New(long low) => new(low);
     66         public static I128 New(long low, long high) => new(low, high);
     67         public static I128 From(bool val) => new(U128.From(val));
     68         public static I128 From(byte val) => new(val);
     69         public static I128 From(int val) => new(val);
     70         public static I128 From(long val) => new(val);
     71         public static I128 From(sbyte val) => new(val);
     72         public static I128 From(short val) => new(val);
     73         public static I128 From(uint val) => new(val);
     74         public static I128 From(ulong val) => new(new U128(val));
     75         public static I128 From(ushort val) => new(val);
     76         static Result<I128, Bottom> ITryFrom<I128, bool, Bottom>.TryFrom(bool val) => new(From(val));
     77         static Result<I128, Bottom> ITryFrom<I128, byte, Bottom>.TryFrom(byte val) => new(From(val));
     78         static Result<I128, Bottom> ITryFrom<I128, int, Bottom>.TryFrom(int val) => new(From(val));
     79         static Result<I128, Bottom> ITryFrom<I128, long, Bottom>.TryFrom(long val) => new(From(val));
     80         static Result<I128, Bottom> ITryFrom<I128, sbyte, Bottom>.TryFrom(sbyte val) => new(From(val));
     81         static Result<I128, Bottom> ITryFrom<I128, short, Bottom>.TryFrom(short val) => new(From(val));
     82         public static Result<I128, ParseIntError> TryFrom(string val) => TryFrom(val.AsSpan());
     83         static Result<I128, Bottom> ITryFrom<I128, uint, Bottom>.TryFrom(uint val) => new(From(val));
     84         static Result<I128, Bottom> ITryFrom<I128, ulong, Bottom>.TryFrom(ulong val) => new(From(val));
     85         static Result<I128, Bottom> ITryFrom<I128, ushort, Bottom>.TryFrom(ushort val) => new(From(val));
     86         #endregion
     87 
     88         #region Instance Functions
     89         public readonly I128 Clone() => this;
     90         public readonly Ordering Cmp(in I128 other) => (this - MinValue).Value.Cmp((other - MinValue).Value);
     91         public readonly bool Equals(in I128 other) => this == other;
     92         public override readonly bool Equals(object? _) => false;
     93         public override readonly int GetHashCode() => 0;
     94         public readonly Unit Hash<THasher>(ref THasher hasher) where THasher: notnull, IHasher => hasher.WriteUnsafe(this);
     95         public readonly I128 Into() => this;
     96         public readonly byte[] IntoBEBytes() => Value.IntoBEBytes();
     97         public readonly Unit IntoBEBytes(Span<byte> bytes) => Value.IntoBEBytes(bytes);
     98         public readonly byte[] IntoLEBytes() => Value.IntoLEBytes();
     99         public readonly Unit IntoLEBytes(Span<byte> bytes) => Value.IntoLEBytes(bytes);
    100         public readonly string IntoString() => ToString();
    101         readonly string IInto<string>.Into() => IntoString();
    102         public readonly Maybe<Ordering> PartialCmp(in I128 other) => Some(Cmp(in other));
    103         public override readonly string ToString() => this < Zero ? $"-{Abs(this).ToString()}" : $"{Value.ToString()}";
    104         readonly Result<I128, Bottom> ITryInto<I128, Bottom>.TryInto() => OK(this);
    105         readonly Result<string, Bottom> ITryInto<string, Bottom>.TryInto() => new(ToString());
    106         readonly Result<U128, TryIntoIntError> ITryInto<U128, TryIntoIntError>.TryInto() => TryIntoU128();
    107         readonly Result<NonZeroI128, TryIntoIntError> ITryInto<NonZeroI128, TryIntoIntError>.TryInto() => TryIntoNonZeroI128();
    108         readonly Result<byte, TryIntoIntError> ITryInto<byte, TryIntoIntError>.TryInto() => TryIntoByte();
    109         readonly Result<int, TryIntoIntError> ITryInto<int, TryIntoIntError>.TryInto() => TryIntoInt();
    110         readonly Result<long, TryIntoIntError> ITryInto<long, TryIntoIntError>.TryInto() => TryIntoLong();
    111         readonly Result<sbyte, TryIntoIntError> ITryInto<sbyte, TryIntoIntError>.TryInto() => TryIntoSbyte();
    112         readonly Result<short, TryIntoIntError> ITryInto<short, TryIntoIntError>.TryInto() => TryIntoShort();
    113         readonly Result<uint, TryIntoIntError> ITryInto<uint, TryIntoIntError>.TryInto() => TryIntoUint();
    114         readonly Result<ulong, TryIntoIntError> ITryInto<ulong, TryIntoIntError>.TryInto() => TryIntoUlong();
    115         readonly Result<ushort, TryIntoIntError> ITryInto<ushort, TryIntoIntError>.TryInto() => TryIntoUshort();
    116         public readonly Result<U128, TryIntoIntError> TryIntoU128() => this < Zero ? new(TryIntoIntError.Overflow) : new((U128)this);
    117         public readonly Result<NonZeroI128, TryIntoIntError> TryIntoNonZeroI128() => NonZeroI128.New(this).OKOr(TryIntoIntError.Overflow);
    118         public readonly Result<byte, TryIntoIntError> TryIntoByte() => this > (I128)byte.MaxValue ? new(TryIntoIntError.Overflow) : new((byte)this);
    119         public readonly Result<int, TryIntoIntError> TryIntoInt() => this > (I128)int.MaxValue ? new(TryIntoIntError.Overflow) : new((int)this);
    120         public readonly Result<long, TryIntoIntError> TryIntoLong() => this > (I128)long.MaxValue ? new(TryIntoIntError.Overflow) : new((long)this);
    121         public readonly Result<sbyte, TryIntoIntError> TryIntoSbyte() => this > (I128)sbyte.MaxValue ? new(TryIntoIntError.Overflow) : new((sbyte)this);
    122         public readonly Result<short, TryIntoIntError> TryIntoShort() => this > (I128)short.MaxValue ? new(TryIntoIntError.Overflow) : new((short)this);
    123         public readonly Result<uint, TryIntoIntError> TryIntoUint() => this > (I128)uint.MaxValue ? new(TryIntoIntError.Overflow) : new((uint)this);
    124         public readonly Result<ulong, TryIntoIntError> TryIntoUlong() => this > (I128)ulong.MaxValue ? new(TryIntoIntError.Overflow) : new((ulong)this);
    125         public readonly Result<ushort, TryIntoIntError> TryIntoUshort() => this > (I128)ushort.MaxValue ? new(TryIntoIntError.Overflow) : new((ushort)this);
    126         #endregion
    127 
    128         #region Operators
    129         public static bool operator !=(I128 val0, I128 val1) => !(val0 == val1);
    130         public static I128 operator %(I128 dividend, I128 divisor) => DivRem(dividend, divisor).Item1;
    131         public static I128 operator %(I128 dividend, NonZeroI128 divisor) => DivRem(dividend, divisor).Item1;
    132         public static I128 operator &(I128 val0, I128 val1) => new(val0.Value & val1.Value);
    133         public static I128 operator *(I128 val0, I128 val1) => new(val0.Value * val1.Value);
    134         public static I128 operator +(I128 val) => val;
    135         public static I128 operator +(I128 val0, I128 val1) => new(val0.Value + val1.Value);
    136         public static I128 operator ++(I128 val) => val + new I128(1L);
    137         public static I128 operator -(I128 val) => new(-val.Value);
    138         public static I128 operator -(I128 val0, I128 val1) => new(val0.Value - val1.Value);
    139         public static I128 operator --(I128 val) => val - new I128(1L);
    140         public static I128 operator /(I128 dividend, I128 divisor) => DivRem(dividend, divisor).Item0;
    141         public static I128 operator /(I128 dividend, NonZeroI128 divisor) => DivRem(dividend, divisor).Item0;
    142         public static bool operator <(I128 val0, I128 val1) => (val0 - MinValue).Value < (val1 - MinValue).Value;
    143         public static I128 operator <<(I128 val, int shift) => new(val.Value << shift);
    144         public static bool operator <=(I128 val0, I128 val1) => !(val0 > val1);
    145         public static bool operator ==(I128 val0, I128 val1) => val0.Value == val1.Value;
    146         public static bool operator >(I128 val0, I128 val1) => (val0 - MinValue).Value > (val1 - MinValue).Value;
    147         public static bool operator >=(I128 val0, I128 val1) => !(val0 < val1);
    148         public static I128 operator >>(I128 val, int shift) {
    149 
    150             shift &= 127;
    151             return val >= Zero ? new(val.Value >> shift) : shift == 0 ? val : new((val.Value >> shift) | (U128.MaxValue << (128 - shift)));
    152         }
    153         public static I128 operator ^(I128 val0, I128 val1) => new(val0.Value ^ val1.Value);
    154         public static I128 operator |(I128 val0, I128 val1) => new(val0.Value | val1.Value);
    155         public static I128 operator |(I128 val0, NonZeroI128 val1) => val0 | val1.Value;
    156         public static I128 operator ~(I128 val) => new(~val.Value);
    157         public static explicit operator I128(byte val) => new((U128)val);
    158         public static explicit operator I128(decimal val) {
    159 
    160             var u128 = (U128)Math.Abs(val);
    161             return val < decimal.Zero ? u128 >= MinValue.Value ? MinValue : -new I128(u128) : u128 >= MaxValue.Value ? MaxValue : new I128(u128);
    162         }
    163         public static explicit operator I128(double val) {
    164 
    165             var u128 = (U128)Math.Abs(val);
    166             return val < 0d ? u128 >= MinValue.Value ? MinValue : -new I128(u128) : u128 >= MaxValue.Value ? MaxValue : new I128(u128);
    167         }
    168         public static explicit operator I128(float val) => (I128)(double)val;
    169         public static explicit operator I128(U128 val) => new(val);
    170         public static explicit operator I128(int val) => new((U128)val);
    171         public static explicit operator I128(long val) => new((U128)val);
    172         public static explicit operator I128(sbyte val) => new((U128)val);
    173         public static explicit operator byte(I128 val) => (byte)val.Value;
    174         public static explicit operator decimal(I128 val) => val < Zero ? -(decimal)Abs(val) : (decimal)Abs(val);
    175         public static explicit operator double(I128 val) => val < Zero ? -(double)Abs(val) : (double)Abs(val);
    176         public static explicit operator float(I128 val) => (float)(double)val;
    177         public static explicit operator U128(I128 val) => val.Value;
    178         public static explicit operator int(I128 val) => (int)val.Value;
    179         public static explicit operator long(I128 val) => (long)val.Value;
    180         public static explicit operator sbyte(I128 val) => (sbyte)val.Value;
    181         public static explicit operator short(I128 val) => (short)val.Value;
    182         public static explicit operator uint(I128 val) => (uint)val.Value;
    183         public static explicit operator ulong(I128 val) => (ulong)val.Value;
    184         public static explicit operator ushort(I128 val) => (ushort)val.Value;
    185         public static explicit operator I128(uint val) => new((U128)val);
    186         public static explicit operator I128(ulong val) => new((U128)val);
    187         public static explicit operator I128(ushort val) => new((U128)val);
    188         #endregion
    189 
    190         #region Types
    191         #endregion
    192     }
    193     #endregion
    194 
    195     #region Namespaces
    196     #endregion
    197 }
    198 #endregion