Std

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

Functions.cs (29981B)


      1 using Std.Maybe;
      2 using System.Runtime.Intrinsics.X86;
      3 #region Namespaces
      4 namespace Std.Num {
      5     #region Types
      6     public static class Functions {
      7 
      8         #region Type-level Constructors
      9         #endregion
     10 
     11         #region Instance Constructors
     12         #endregion
     13 
     14         #region Type-level Fields
     15         #endregion
     16 
     17         #region Instance Fields
     18         #endregion
     19 
     20         #region Type-level Properties
     21         #endregion
     22 
     23         #region Instance Properties
     24         #endregion
     25 
     26         #region Type-level Functions
     27         public static Maybe<byte> CheckedAdd(this byte self, byte other) {
     28 
     29             var val = self.WrappingAdd(other);
     30             return val < self ? Maybe<byte>.None() : new(val);
     31         }
     32         public static Maybe<I128> CheckedAdd(this I128 self, I128 other) {
     33             
     34             var val = self.WrappingAdd(other);
     35             return (self >= I128.Zero, other >= I128.Zero) switch {
     36                 (true, true) => val < self ? Maybe<I128>.None() : new(val),
     37                 (false, false) => val >= I128.Zero ? Maybe<I128>.None() : new(val),
     38                 _ => new(val),
     39             };
     40         }
     41         public static Maybe<int> CheckedAdd(this int self, int other) {
     42 
     43             var val = self.WrappingAdd(other);
     44             return (self >= 0, other >= 0) switch {
     45                 (true, true) => val < self ? Maybe<int>.None() : new(val),
     46                 (false, false) => val >= 0 ? Maybe<int>.None() : new(val),
     47                 _ => new(val),
     48             };
     49         }
     50         public static Maybe<long> CheckedAdd(this long self, long other) {
     51 
     52             var val = self.WrappingAdd(other);
     53             return (self >= 0, other >= 0) switch {
     54                 (true, true) => val < self ? Maybe<long>.None() : new(val),
     55                 (false, false) => val >= 0 ? Maybe<long>.None() : new(val),
     56                 _ => new(val),
     57             };
     58         }
     59         public static Maybe<sbyte> CheckedAdd(this sbyte self, sbyte other) {
     60 
     61             var val = self.WrappingAdd(other);
     62             return (self >= 0, other >= 0) switch {
     63                 (true, true) => val < self ? Maybe<sbyte>.None() : new(val),
     64                 (false, false) => val >= 0 ? Maybe<sbyte>.None() : new(val),
     65                 _ => new(val),
     66             };
     67         }
     68         public static Maybe<short> CheckedAdd(this short self, short other) {
     69 
     70             var val = self.WrappingAdd(other);
     71             return (self >= 0, other >= 0) switch {
     72                 (true, true) => val < self ? Maybe<short>.None() : new(val),
     73                 (false, false) => val >= 0 ? Maybe<short>.None() : new(val),
     74                 _ => new(val),
     75             };
     76         }
     77         public static Maybe<U128> CheckedAdd(this U128 self, U128 other) {
     78 
     79             var val = self.WrappingAdd(other);
     80             return val < self ? Maybe<U128>.None() : new(val);
     81         }
     82         public static Maybe<uint> CheckedAdd(this uint self, uint other) {
     83 
     84             var val = self.WrappingAdd(other);
     85             return val < self ? Maybe<uint>.None() : new(val);
     86         }
     87         public static Maybe<ulong> CheckedAdd(this ulong self, ulong other) {
     88 
     89             var val = self.WrappingAdd(other);
     90             return val < self ? Maybe<ulong>.None() : new(val);
     91         }
     92         public static Maybe<ushort> CheckedAdd(this ushort self, ushort other) {
     93             
     94             var val = self.WrappingAdd(other);
     95             return val < self ? Maybe<ushort>.None() : new(val);
     96         }
     97         public static Maybe<byte> CheckedNextPowerOfTwo(this byte self) {
     98 
     99             var val = self.NextPowerOfTwo();
    100             return val == byte.MinValue ? Maybe<byte>.None() : new(val);
    101         }
    102         public static Maybe<U128> CheckedNextPowerOfTwo(this U128 self) {
    103 
    104             var val = self.NextPowerOfTwo();
    105             return val == U128.MinValue ? Maybe<U128>.None() : new(val);
    106         }
    107         public static Maybe<uint> CheckedNextPowerOfTwo(this uint self) {
    108 
    109             var val = self.NextPowerOfTwo();
    110             return val == uint.MinValue ? Maybe<uint>.None() : new(val);
    111         }
    112         public static Maybe<ulong> CheckedNextPowerOfTwo(this ulong self) {
    113 
    114             var val = self.NextPowerOfTwo();
    115             return val == ulong.MinValue ? Maybe<ulong>.None() : new(val);
    116         }
    117         public static Maybe<ushort> CheckedNextPowerOfTwo(this ushort self) {
    118 
    119             var val = self.NextPowerOfTwo();
    120             return val == ushort.MinValue ? Maybe<ushort>.None() : new(val);
    121         }
    122         public static Maybe<byte> CheckedSub(this byte self, byte other) {
    123 
    124             var val = self.WrappingSub(other);
    125             return val > self ? Maybe<byte>.None() : new(val);
    126         }
    127         public static Maybe<I128> CheckedSub(this I128 self, I128 other) {
    128 
    129             var val = self.WrappingSub(other);
    130             return (self >= I128.Zero, other >= I128.Zero) switch {
    131                 (true, false) => val <= self ? Maybe<I128>.None() : new(val),
    132                 (false, true) => val > self ? Maybe<I128>.None() : new(val),
    133                 _ => new(val),
    134             };
    135         }
    136         public static Maybe<int> CheckedSub(this int self, int other) {
    137 
    138             var val = self.WrappingSub(other);
    139             return (self >= 0, other >= 0) switch {
    140                 (true, false) => val <= self ? Maybe<int>.None() : new(val),
    141                 (false, true) => val > self ? Maybe<int>.None() : new(val),
    142                 _ => new(val),
    143             };
    144         }
    145         public static Maybe<long> CheckedSub(this long self, long other) {
    146 
    147             var val = self.WrappingSub(other);
    148             return (self >= 0L, other >= 0L) switch {
    149                 (true, false) => val <= self ? Maybe<long>.None() : new(val),
    150                 (false, true) => val > self ? Maybe<long>.None() : new(val),
    151                 _ => new(val),
    152             };
    153         }
    154         public static Maybe<sbyte> CheckedSub(this sbyte self, sbyte other) {
    155 
    156             var val = self.WrappingSub(other);
    157             return (self >= 0, other >= 0) switch {
    158                 (true, false) => val <= self ? Maybe<sbyte>.None() : new(val),
    159                 (false, true) => val > self ? Maybe<sbyte>.None() : new(val),
    160                 _ => new(val),
    161             };
    162         }
    163         public static Maybe<short> CheckedSub(this short self, short other) {
    164 
    165             var val = self.WrappingSub(other);
    166             return (self >= 0, other >= 0) switch {
    167                 (true, false) => val <= self ? Maybe<short>.None() : new(val),
    168                 (false, true) => val > self ? Maybe<short>.None() : new(val),
    169                 _ => new(val),
    170             };
    171         }
    172         public static Maybe<U128> CheckedSub(this U128 self, U128 other) {
    173 
    174             var val = self.WrappingSub(other);
    175             return val > self ? Maybe<U128>.None() : new(val);
    176         }
    177         public static Maybe<uint> CheckedSub(this uint self, uint other) {
    178 
    179             var val = self.WrappingSub(other);
    180             return val > self ? Maybe<uint>.None() : new(val);
    181         }
    182         public static Maybe<ulong> CheckedSub(this ulong self, ulong other) {
    183 
    184             var val = self.WrappingSub(other);
    185             return val > self ? Maybe<ulong>.None() : new(val);
    186         }
    187         public static Maybe<ushort> CheckedSub(this ushort self, ushort other) {
    188 
    189             var val = self.WrappingSub(other);
    190             return val > self ? Maybe<ushort>.None() : new(val);
    191         }
    192         public static bool IsPowerOfTwo(this byte self) => (((uint)self & (self.WrappingSub(1))) == uint.MinValue) && self != uint.MinValue;
    193         public static bool IsPowerOfTwo(this U128 self) => ((self & (self.WrappingSub(new U128(1ul)))) == U128.MinValue) && self != U128.MinValue;
    194         public static bool IsPowerOfTwo(this uint self) => ((self & (self.WrappingSub(1u))) == uint.MinValue) && self != uint.MinValue;
    195         public static bool IsPowerOfTwo(this ulong self) => ((self & (self.WrappingSub(1ul))) == ulong.MinValue) && self != ulong.MinValue;
    196         public static bool IsPowerOfTwo(this ushort self) => (((uint)self & (self.WrappingSub(1))) == uint.MinValue) && self != uint.MinValue;
    197         public static uint LeadingZeros(this byte self) => Lzcnt.LeadingZeroCount(self) - 24u;
    198         public static uint LeadingZeros(this I128 self) => ((U128)self).LeadingZeros();
    199         public static uint LeadingZeros(this int self) => Lzcnt.LeadingZeroCount((uint)self);
    200         public static uint LeadingZeros(this long self) => (uint)Lzcnt.X64.LeadingZeroCount((ulong)self);
    201         public static uint LeadingZeros(this sbyte self) => Lzcnt.LeadingZeroCount((uint)self) - 24u;
    202         public static uint LeadingZeros(this short self) => Lzcnt.LeadingZeroCount((uint)self) - 16u;
    203         public static uint LeadingZeros(this U128 self) => self.High > ulong.MinValue ? (uint)Lzcnt.X64.LeadingZeroCount(self.High) : 64u + (uint)Lzcnt.X64.LeadingZeroCount(self.Low);
    204         public static uint LeadingZeros(this uint self) => Lzcnt.LeadingZeroCount(self);
    205         public static uint LeadingZeros(this ulong self) => (uint)Lzcnt.X64.LeadingZeroCount(self);
    206         public static uint LeadingZeros(this ushort self) => Lzcnt.LeadingZeroCount(self) - 16u;
    207         public static byte NextPowerOfTwo(this byte self) => self > uint.MinValue && (self & (self - 1u)) == uint.MinValue ? self : (byte)(0x80000000u >> (int)(Lzcnt.LeadingZeroCount(self) - 1u));
    208         public static U128 NextPowerOfTwo(this U128 self) {
    209 
    210             if (self > U128.MinValue && (self & (self - new U128(1ul))) == U128.MinValue) {
    211                 return self;
    212             } else if (self > new U128(ulong.MinValue, 0x8000000000000000ul)) {
    213                 return U128.MinValue;
    214             } else {
    215                 var shift = Lzcnt.X64.LeadingZeroCount(self.High);
    216                 shift += shift == 64ul ? Lzcnt.X64.LeadingZeroCount(self.Low) : ulong.MinValue;
    217                 return new U128(ulong.MinValue, 0x8000000000000000ul) >> (int)shift;
    218             }
    219         }
    220         public static uint NextPowerOfTwo(this uint self) => self > uint.MinValue && (self & (self - 1u)) == uint.MinValue ? self : (uint)(0x8000000000000000ul >> (int)(Lzcnt.X64.LeadingZeroCount(self) - 1ul));
    221         public static ulong NextPowerOfTwo(this ulong self) => self > ulong.MinValue && (self & (self - 1ul)) == ulong.MinValue ? self : self > 0x8000000000000000ul ? ulong.MinValue : 0x8000000000000000ul >> (int)(Lzcnt.X64.LeadingZeroCount(self) - 1ul);
    222         public static ushort NextPowerOfTwo(this ushort self) => self > uint.MinValue && (self & (self - 1u)) == uint.MinValue ? self : (ushort)(0x80000000u >> (int)(Lzcnt.LeadingZeroCount(self) - 1u));
    223         public static Prod<bool, byte> OverflowingAdd(this byte self, byte other) {
    224 
    225             var val = self.WrappingAdd(other);
    226             return new(val < self, val);
    227         }
    228         public static Prod<bool, I128> OverflowingAdd(this I128 self, I128 other) {
    229 
    230             var val = self.WrappingAdd(other);
    231             return (self >= I128.Zero, other >= I128.Zero) switch {
    232                 (true, true) => new(val < self, val),
    233                 (false, false) => new(val >= I128.Zero, val),
    234                 _ => new(false, val),
    235             };
    236         }
    237         public static Prod<bool, int> OverflowingAdd(this int self, int other) {
    238 
    239             var val = self.WrappingAdd(other);
    240             return (self >= 0, other >= 0) switch {
    241                 (true, true) => new(val < self, val),
    242                 (false, false) => new(val >= 0, val),
    243                 _ => new(false, val),
    244             };
    245         }
    246         public static Prod<bool, long> OverflowingAdd(this long self, long other) {
    247 
    248             var val = self.WrappingAdd(other);
    249             return (self >= 0L, other >= 0L) switch {
    250                 (true, true) => new(val < self, val),
    251                 (false, false) => new(val >= 0L, val),
    252                 _ => new(false, val),
    253             };
    254         }
    255         public static Prod<bool, sbyte> OverflowingAdd(this sbyte self, sbyte other) {
    256 
    257             var val = self.WrappingAdd(other);
    258             return (self >= 0, other >= 0) switch {
    259                 (true, true) => new(val < self, val),
    260                 (false, false) => new(val >= 0, val),
    261                 _ => new(false, val),
    262             };
    263         }
    264         public static Prod<bool, short> OverflowingAdd(this short self, short other) {
    265 
    266             var val = self.WrappingAdd(other);
    267             return (self >= 0, other >= 0) switch {
    268                 (true, true) => new(val < self, val),
    269                 (false, false) => new(val >= 0, val),
    270                 _ => new(false, val),
    271             };
    272         }
    273         public static Prod<bool, U128> OverflowingAdd(this U128 self, U128 other) {
    274 
    275             var val = self.WrappingAdd(other);
    276             return new(val < self, val);
    277         }
    278         public static Prod<bool, uint> OverflowingAdd(this uint self, uint other) {
    279 
    280             var val = self.WrappingAdd(other);
    281             return new(val < self, val);
    282         }
    283         public static Prod<bool, ulong> OverflowingAdd(this ulong self, ulong other) {
    284 
    285             var val = self.WrappingAdd(other);
    286             return new(val < self, val);
    287         }
    288         public static Prod<bool, ushort> OverflowingAdd(this ushort self, ushort other) {
    289 
    290             var val = self.WrappingAdd(other);
    291             return new(val < self, val);
    292         }
    293         public static Prod<bool, byte> OverflowingSub(this byte self, byte other) {
    294 
    295             var val = self.WrappingSub(other);
    296             return new(val > self, val);
    297         }
    298         public static Prod<bool, I128> OverflowingSub(this I128 self, I128 other) {
    299 
    300             var val = self.WrappingSub(other);
    301             return (self >= I128.Zero, other >= I128.Zero) switch {
    302                 (true, false) => new(val <= self, val),
    303                 (false, true) => new(val > self, val),
    304                 _ => new(false, val),
    305             };
    306         }
    307         public static Prod<bool, int> OverflowingSub(this int self, int other) {
    308 
    309             var val = self.WrappingSub(other);
    310             return (self >= 0, other >= 0) switch {
    311                 (true, false) => new(val <= self, val),
    312                 (false, true) => new(val > self, val),
    313                 _ => new(false, val),
    314             };
    315         }
    316         public static Prod<bool, long> OverflowingSub(this long self, long other) {
    317 
    318             var val = self.WrappingSub(other);
    319             return (self >= 0L, other >= 0L) switch {
    320                 (true, false) => new(val <= self, val),
    321                 (false, true) => new(val > self, val),
    322                 _ => new(false, val),
    323             };
    324         }
    325         public static Prod<bool, sbyte> OverflowingSub(this sbyte self, sbyte other) {
    326 
    327             var val = self.WrappingSub(other);
    328             return (self >= 0, other >= 0) switch {
    329                 (true, false) => new(val <= self, val),
    330                 (false, true) => new(val > self, val),
    331                 _ => new(false, val),
    332             };
    333         }
    334         public static Prod<bool, short> OverflowingSub(this short self, short other) {
    335 
    336             var val = self.WrappingSub(other);
    337             return (self >= 0, other >= 0) switch {
    338                 (true, false) => new(val <= self, val),
    339                 (false, true) => new(val > self, val),
    340                 _ => new(false, val),
    341             };
    342         }
    343         public static Prod<bool, U128> OverflowingSub(this U128 self, U128 other) {
    344 
    345             var val = self.WrappingSub(other);
    346             return new(val > self, val);
    347         }
    348         public static Prod<bool, uint> OverflowingSub(this uint self, uint other) {
    349 
    350             var val = self.WrappingSub(other);
    351             return new(val > self, val);
    352         }
    353         public static Prod<bool, ulong> OverflowingSub(this ulong self, ulong other) {
    354 
    355             var val = self.WrappingSub(other);
    356             return new(val > self, val);
    357         }
    358         public static Prod<bool, ushort> OverflowingSub(this ushort self, ushort other) {
    359 
    360             var val = self.WrappingSub(other);
    361             return new(val > self, val);
    362         }
    363         public static byte RotateLeft(this byte self, uint n) => (byte)(((uint)self << (int)n) | ((uint)self >> (int)(8u - n)));
    364         public static I128 RotateLeft(this I128 self, uint n) => (self << (int)n) | (self >> (int)(128u - n));
    365         public static int RotateLeft(this int self, uint n) => (self << (int)n) | (self >> (int)(32u - n));
    366         public static long RotateLeft(this long self, uint n) => (self << (int)n) | (self >> (int)(64u - n));
    367         public static sbyte RotateLeft(this sbyte self, uint n) => (sbyte)((self << (int)n) | (self >> (int)(8u - n)));
    368         public static short RotateLeft(this short self, uint n) => (short)((self << (int)n) | (self >> (int)(16u - n)));
    369         public static U128 RotateLeft(this U128 self, uint n) => (self << (int)n) | (self >> (int)(128u - n));
    370         public static uint RotateLeft(this uint self, uint n) => (self << (int)n) | (self >> (int)(32u - n));
    371         public static ulong RotateLeft(this ulong self, uint n) => (self << (int)n) | (self >> (int)(64u - n));
    372         public static ushort RotateLeft(this ushort self, uint n) => (ushort)(((uint)self << (int)n) | ((uint)self >> (int)(16u - n)));
    373         public static byte RotateRight(this byte self, uint n) => (byte)(((uint)self >> (int)n) | ((uint)self << (int)(8u - n)));
    374         public static I128 RotateRight(this I128 self, uint n) => (self >> (int)n) | (self << (int)(128u - n));
    375         public static int RotateRight(this int self, uint n) => (self >> (int)n) | (self << (int)(32u - n));
    376         public static long RotateRight(this long self, uint n) => (self >> (int)n) | (self << (int)(64u - n));
    377         public static sbyte RotateRight(this sbyte self, uint n) => (sbyte)((self >> (int)n) | (self << (int)(8u - n)));
    378         public static short RotateRight(this short self, uint n) => (short)((self >> (int)n) | (self << (int)(16u - n)));
    379         public static U128 RotateRight(this U128 self, uint n) => (self >> (int)n) | (self << (int)(128u - n));
    380         public static uint RotateRight(this uint self, uint n) => (self >> (int)n) | (self << (int)(32u - n));
    381         public static ulong RotateRight(this ulong self, uint n) => (self >> (int)n) | (self << (int)(64u - n));
    382         public static ushort RotateRight(this ushort self, uint n) => (ushort)(((uint)self >> (int)n) | ((uint)self << (int)(16u - n)));
    383         public static byte SaturatingAdd(this byte self, byte other) {
    384 
    385             var val = self.WrappingAdd(other);
    386             return val < self ? byte.MaxValue : val;
    387         }
    388         public static I128 SaturatingAdd(this I128 self, I128 other) {
    389 
    390             var val = self.WrappingAdd(other);
    391             return (self >= I128.Zero, other >= I128.Zero) switch {
    392                 (true, true) => val < self ? I128.MaxValue : val,
    393                 (false, false) => val >= I128.Zero ? I128.MinValue : val,
    394                 _ => val,
    395             };
    396         }
    397         public static int SaturatingAdd(this int self, int other) {
    398 
    399             var val = self.WrappingAdd(other);
    400             return (self >= 0, other >= 0) switch {
    401                 (true, true) => val < self ? int.MaxValue : val,
    402                 (false, false) => val >= 0 ? int.MinValue : val,
    403                 _ => val,
    404             };
    405         }
    406         public static long SaturatingAdd(this long self, long other) {
    407 
    408             var val = self.WrappingAdd(other);
    409             return (self >= 0L, other >= 0L) switch {
    410                 (true, true) => val < self ? long.MaxValue : val,
    411                 (false, false) => val >= 0 ? long.MinValue : val,
    412                 _ => val,
    413             };
    414         }
    415         public static sbyte SaturatingAdd(this sbyte self, sbyte other) {
    416 
    417             var val = self.WrappingAdd(other);
    418             return (self >= 0, other >= 0) switch {
    419                 (true, true) => val < self ? sbyte.MaxValue : val,
    420                 (false, false) => val >= 0 ? sbyte.MinValue : val,
    421                 _ => val,
    422             };
    423         }
    424         public static short SaturatingAdd(this short self, short other) {
    425 
    426             var val = self.WrappingAdd(other);
    427             return (self >= 0, other >= 0) switch {
    428                 (true, true) => val < self ? short.MaxValue : val,
    429                 (false, false) => val >= 0 ? short.MinValue : val,
    430                 _ => val,
    431             };
    432         }
    433         public static U128 SaturatingAdd(this U128 self, U128 other) {
    434 
    435             var val = self.WrappingAdd(other);
    436             return val < self ? U128.MaxValue : val;
    437         }
    438         public static uint SaturatingAdd(this uint self, uint other) {
    439 
    440             var val = self.WrappingAdd(other);
    441             return val < self ? uint.MaxValue : val;
    442         }
    443         public static ulong SaturatingAdd(this ulong self, ulong other) {
    444 
    445             var val = self.WrappingAdd(other);
    446             return val < self ? ulong.MaxValue : val;
    447         }
    448         public static ushort SaturatingAdd(this ushort self, ushort other) {
    449 
    450             var val = self.WrappingAdd(other);
    451             return val < self ? ushort.MaxValue : val;
    452         }
    453         public static byte SaturatingSub(this byte self, byte other) {
    454 
    455             var val = self.WrappingSub(other);
    456             return val > self ? byte.MinValue : val;
    457         }
    458         public static I128 SaturatingSub(this I128 self, I128 other) {
    459 
    460             var val = self.WrappingSub(other);
    461             return (self >= I128.Zero, other >= I128.Zero) switch {
    462                 (true, false) => val <= self ? I128.MaxValue : val,
    463                 (false, true) => val > self ? I128.MinValue : val,
    464                 _ => val,
    465             };
    466         }
    467         public static int SaturatingSub(this int self, int other) {
    468 
    469             var val = self.WrappingSub(other);
    470             return (self >= 0, other >= 0) switch {
    471                 (true, false) => val <= self ? int.MaxValue : val,
    472                 (false, true) => val > self ? int.MinValue : val,
    473                 _ => val,
    474             };
    475         }
    476         public static long SaturatingSub(this long self, long other) {
    477 
    478             var val = self.WrappingSub(other);
    479             return (self >= 0L, other >= 0L) switch {
    480                 (true, false) => val <= self ? long.MaxValue : val,
    481                 (false, true) => val > self ? long.MinValue : val,
    482                 _ => val,
    483             };
    484         }
    485         public static sbyte SaturatingSub(this sbyte self, sbyte other) {
    486 
    487             var val = self.WrappingSub(other);
    488             return (self >= 0, other >= 0) switch {
    489                 (true, false) => val <= self ? sbyte.MaxValue : val,
    490                 (false, true) => val > self ? sbyte.MinValue : val,
    491                 _ => val,
    492             };
    493         }
    494         public static short SaturatingSub(this short self, short other) {
    495 
    496             var val = self.WrappingSub(other);
    497             return (self >= 0, other >= 0) switch {
    498                 (true, false) => val <= self ? short.MaxValue : val,
    499                 (false, true) => val > self ? short.MinValue : val,
    500                 _ => val,
    501             };
    502         }
    503         public static U128 SaturatingSub(this U128 self, U128 other) {
    504 
    505             var val = self.WrappingSub(other);
    506             return val > self ? U128.MinValue : val;
    507         }
    508         public static uint SaturatingSub(this uint self, uint other) {
    509 
    510             var val = self.WrappingSub(other);
    511             return val > self ? uint.MinValue : val;
    512         }
    513         public static ulong SaturatingSub(this ulong self, ulong other) {
    514 
    515             var val = self.WrappingSub(other);
    516             return val > self ? ulong.MinValue : val;
    517         }
    518         public static ushort SaturatingSub(this ushort self, ushort other) {
    519 
    520             var val = self.WrappingSub(other);
    521             return val > self ? ushort.MinValue : val;
    522         }
    523         public static uint TrailingZeros(this byte self) => self == uint.MinValue ? 8u : Bmi1.TrailingZeroCount(self);
    524         public static uint TrailingZeros(this I128 self) => ((U128)self).TrailingZeros();
    525         public static uint TrailingZeros(this int self) => Bmi1.TrailingZeroCount((uint)self);
    526         public static uint TrailingZeros(this long self) => (uint)Bmi1.X64.TrailingZeroCount((ulong)self);
    527         public static uint TrailingZeros(this sbyte self) => self == 0 ? 8u : Bmi1.TrailingZeroCount((uint)self);
    528         public static uint TrailingZeros(this short self) => self == 0 ? 16u : Bmi1.TrailingZeroCount((uint)self);
    529         public static uint TrailingZeros(this U128 self) => self.Low > ulong.MinValue ? (uint)Bmi1.X64.TrailingZeroCount(self.Low) : 64u + (uint)Bmi1.X64.TrailingZeroCount(self.High);
    530         public static uint TrailingZeros(this uint self) => Bmi1.TrailingZeroCount(self);
    531         public static uint TrailingZeros(this ulong self) => (uint)Bmi1.X64.TrailingZeroCount(self);
    532         public static uint TrailingZeros(this ushort self) => self == uint.MinValue ? 16u : Bmi1.TrailingZeroCount(self);
    533         public static byte WrappingAdd(this byte self, byte other) {
    534             unchecked { return (byte)((uint)self + other); }
    535         }
    536         public static I128 WrappingAdd(this I128 self, I128 other) => new(self.Value.WrappingAdd(other.Value));
    537         public static int WrappingAdd(this int self, int other) {
    538             unchecked { return self + other; }
    539         }
    540         public static long WrappingAdd(this long self, long other) {
    541             unchecked { return self + other; }
    542         }
    543         public static sbyte WrappingAdd(this sbyte self, sbyte other) {
    544             unchecked { return (sbyte)(self + other); }
    545         }
    546         public static short WrappingAdd(this short self, short other) {
    547             unchecked { return (short)(self + other); }
    548         }
    549         public static U128 WrappingAdd(this U128 self, U128 other) {
    550             unchecked {
    551                 var low = self.Low + other.Low;
    552                 return new(low, self.High + other.High + (low < self.Low ? 1ul : ulong.MinValue));
    553             }
    554         }
    555         public static uint WrappingAdd(this uint self, uint other) {
    556             unchecked { return self + other; }
    557         }
    558         public static ulong WrappingAdd(this ulong self, ulong other) {
    559             unchecked { return self + other; }
    560         }
    561         public static ushort WrappingAdd(this ushort self, ushort other) {
    562             unchecked { return (ushort)(self + other); }
    563         }
    564         public static byte WrappingMul(this byte self, byte other) {
    565             unchecked { return (byte)((uint)self * other); }
    566         }
    567         public static I128 WrappingMul(this I128 self, I128 other) => new(self.Value.WrappingMul(other.Value));
    568         public static int WrappingMul(this int self, int other) {
    569             unchecked { return self * other; }
    570         }
    571         public static long WrappingMul(this long self, long other) {
    572             unchecked { return self * other; }
    573         }
    574         public static sbyte WrappingMul(this sbyte self, sbyte other) {
    575             unchecked { return (sbyte)(self * other); }
    576         }
    577         public static short WrappingMul(this short self, short other) {
    578             unchecked { return (short)(self * other); }
    579         }
    580         public static U128 WrappingMul(this U128 self, U128 other) {
    581             unchecked {
    582                 var u0 = self.Low & 0xFFFFFFFFul;
    583                 var v0 = other.Low & 0xFFFFFFFFul;
    584                 var carry = u0 * v0;
    585                 var r0 = carry & 0xFFFFFFFFul;
    586                 var v1 = other.Low >> 32;
    587                 carry = (carry >> 32) + (u0 * v1);
    588                 var r1 = carry >> 32;
    589                 var u1 = self.Low >> 32;
    590                 carry = (carry & 0xFFFFFFFFul) + (u1 * v0);
    591                 return new((carry << 32) | r0, (carry >> 32) + r1 + (u1 * v1) + (self.High * other.Low) + (self.Low * other.High));
    592             }
    593         }
    594         public static uint WrappingMul(this uint self, uint other) {
    595             unchecked { return self * other; }
    596         }
    597         public static ulong WrappingMul(this ulong self, ulong other) {
    598             unchecked { return self * other; }
    599         }
    600         public static ushort WrappingMul(this ushort self, ushort other) {
    601             unchecked { return (ushort)(self * other); }
    602         }
    603         public static byte WrappingSub(this byte self, byte other) {
    604             unchecked { return (byte)((uint)self - other); }
    605         }
    606         public static I128 WrappingSub(this I128 self, I128 other) => new(self.Value.WrappingSub(other.Value));
    607         public static int WrappingSub(this int self, int other) {
    608             unchecked { return self - other; }
    609         }
    610         public static long WrappingSub(this long self, long other) {
    611             unchecked { return self - other; }
    612         }
    613         public static sbyte WrappingSub(this sbyte self, sbyte other) {
    614             unchecked { return (sbyte)(self - other); }
    615         }
    616         public static short WrappingSub(this short self, short other) {
    617             unchecked { return (short)(self - other); }
    618         }
    619         public static U128 WrappingSub(this U128 self, U128 other) {
    620             unchecked { return new(self.Low - other.Low, self.High - other.High - (self.Low < other.Low ? 1ul : ulong.MinValue)); }
    621         }
    622         public static uint WrappingSub(this uint self, uint other) {
    623             unchecked { return self - other; }
    624         }
    625         public static ulong WrappingSub(this ulong self, ulong other) {
    626             unchecked { return self - other; }
    627         }
    628         public static ushort WrappingSub(this ushort self, ushort other) {
    629             unchecked { return (ushort)((uint)self - other); }
    630         }
    631         #endregion
    632 
    633         #region Instance Functions
    634         #endregion
    635 
    636         #region Operators
    637         #endregion
    638 
    639         #region Types
    640         #endregion
    641     }
    642     #endregion
    643 
    644     #region Namespaces
    645     #endregion
    646 }
    647 #endregion