Ejemplo n.º 1
0
        private static int Log2SoftwareFallbackPow2(uint value)
        {
            if ((value & (value - 1)) == 0) // Power of 2
            {
                // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
                return(Unsafe.AddByteOffset(
                           // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u
                           ref MemoryMarshal.GetReference(s_Log2DeBruijnPow2),
                           // long -> IntPtr cast on 32-bit platforms is expensive - it does overflow checks not needed here
                           (IntPtr)(int)((value * 0x077CB531u) >> 27)));
            }

            value |= value >> 01;
            value |= value >> 02;
            value |= value >> 04;
            value |= value >> 08;
            value |= value >> 16;

            // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
            return(Unsafe.AddByteOffset(
                       // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u
                       ref MemoryMarshal.GetReference(s_Log2DeBruijn),
                       // long -> IntPtr cast on 32-bit platforms is expensive - it does overflow checks not needed here
                       (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)));
        }
        private static Int64 ReadFast(ref MessagePackReader reader, ref byte position)
        {
            var value = Unsafe.AddByteOffset(ref position, (IntPtr)1);

            reader.AdvanceWithinSpan(2);
            return(value);
        }
        internal static void WriteRawBytes(ref byte destination, ref byte source, int sourceBytesToCopy, ref int idx)
        {
            //if (0u >= (uint)sourceBytesToCopy) { return; }

            MessagePackBinary.CopyMemory(ref source, ref Unsafe.AddByteOffset(ref destination, (IntPtr)idx), sourceBytesToCopy);
            idx += sourceBytesToCopy;
        }
Ejemplo n.º 4
0
        public Float64Bits(ref byte bigEndianBytes)
        {
            this = default(Float64Bits);

            IntPtr offset = (IntPtr)1;

            if (BitConverter.IsLittleEndian)
            {
                this.Byte0 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 7);
                this.Byte1 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 6);
                this.Byte2 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 5);
                this.Byte3 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 4);
                this.Byte4 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 3);
                this.Byte5 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 2);
                this.Byte6 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 1);
                this.Byte7 = Unsafe.AddByteOffset(ref bigEndianBytes, offset);
            }
            else
            {
                this.Byte0 = Unsafe.AddByteOffset(ref bigEndianBytes, offset);
                this.Byte1 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 1);
                this.Byte2 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 2);
                this.Byte3 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 3);
                this.Byte4 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 4);
                this.Byte5 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 5);
                this.Byte6 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 6);
                this.Byte7 = Unsafe.AddByteOffset(ref bigEndianBytes, offset + 7);
            }
        }
Ejemplo n.º 5
0
        private static int ViaUnsafe(uint value)
        {
            int log10 = Unsafe.AddByteOffset(
                ref MemoryMarshal.GetReference(s_Log10Ceiling32),
                (IntPtr)BitOps.LeadingZeroCount(value));

            //var u = Unsafe.AsRef<uint[]>(_foo);// s_Pow10Ceiling32);
            var u = new ReadOnlySpan <uint>(s_Pow10Ceiling32);

            //ReadOnlySpan<uint> u = stackalloc uint[12]
            //{
            //    0,
            //    1,
            //    10,
            //    100,
            //    1000,
            //    10000,
            //    100000,
            //    1000000,
            //    10000000,
            //    100000000,
            //    1000000000,
            //    0
            //};

            //fixed (uint* u = Unsafe.AsRef(_foo))
            {
                int diff = (int)((value - u[log10]) >> 31);
                //int diff = unchecked((int)((value - Unsafe.Add(ref s_Pow10Ceiling32.GetRawSzArrayData(), y)) >> 31));
                return((int)(log10 - diff));
            }
        }
Ejemplo n.º 6
0
 internal static ref byte ComputeEffectiveAddress(
     ref byte nativePtr,
     Index1 index,
     int elementSize) =>
 ref Unsafe.AddByteOffset(
     ref nativePtr,
     new IntPtr(index * elementSize));
Ejemplo n.º 7
0
        private static unsafe bool AreEqual_Current(ref byte first, ref byte second, int l)
        {
            IntPtr length = (IntPtr)l;

#if !NETSTANDARD2_0 && !NET461 && !NET47 && !NETCOREAPP2_1
            if (Avx2.IsSupported && (byte *)length == (byte *)64)
            {
                return
                    (Avx2.MoveMask(Avx2.CompareEqual(Unsafe.ReadUnaligned <Vector256 <byte> >(ref first), Unsafe.ReadUnaligned <Vector256 <byte> >(ref second))) == unchecked ((int)0b1111_1111_1111_1111_1111_1111_1111_1111)
                     & Avx2.MoveMask(Avx2.CompareEqual(Unsafe.ReadUnaligned <Vector256 <byte> >(ref Unsafe.AddByteOffset(ref first, (IntPtr)32)), Unsafe.ReadUnaligned <Vector256 <byte> >(ref Unsafe.AddByteOffset(ref second, (IntPtr)32)))) == unchecked ((int)0b1111_1111_1111_1111_1111_1111_1111_1111));
            }
            else if (Avx2.IsSupported && (byte *)length == (byte *)32)
            {
                return(Avx2.MoveMask(Avx2.CompareEqual(Unsafe.ReadUnaligned <Vector256 <byte> >(ref first), Unsafe.ReadUnaligned <Vector256 <byte> >(ref second))) == unchecked ((int)0b1111_1111_1111_1111_1111_1111_1111_1111));
            }
            else if (Sse2.IsSupported && (byte *)length == (byte *)16)
            {
                return(Sse2.MoveMask(Sse2.CompareEqual(Unsafe.ReadUnaligned <Vector128 <byte> >(ref first), Unsafe.ReadUnaligned <Vector128 <byte> >(ref second))) == 0b1111_1111_1111_1111);
            }
            else
#endif
            if (Vector.IsHardwareAccelerated && (byte *)length >= (byte *)Vector <byte> .Count)
            {
                Vector <byte> accumulator = new Vector <byte>();
                IntPtr        endOffset   = length - sizeof(Vector <byte>);
                ref byte      firstEnd    = ref Unsafe.AddByteOffset(ref first, endOffset);
                ref byte      secondEnd   = ref Unsafe.AddByteOffset(ref second, endOffset);
Ejemplo n.º 8
0
        private static int GetDigitValueInternalNoBoundsCheck(uint codePoint)
        {
            nuint offset   = GetNumericGraphemeTableOffsetNoBoundsChecks(codePoint);
            int   rawValue = Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(DigitValues), offset);

            return((rawValue & 0xF) - 1); // return the low nibble of the result, minus 1 so that "not a digit value" gets normalized to -1
        }
Ejemplo n.º 9
0
        private unsafe static void SetDecimal(ref byte start, decimal value)
        {
            var    bits   = decimal.GetBits(value);
            uint   lo     = (uint)bits[0];
            uint   mid    = (uint)bits[1];
            uint   high   = (uint)bits[2];
            uint   flags  = (uint)bits[3];
            IntPtr offset = (IntPtr)0;

            Unsafe.AddByteOffset(ref start, offset)      = (byte)(lo >> 24); // lo
            Unsafe.AddByteOffset(ref start, offset + 1)  = (byte)(lo >> 16);
            Unsafe.AddByteOffset(ref start, offset + 2)  = (byte)(lo >> 8);
            Unsafe.AddByteOffset(ref start, offset + 3)  = (byte)lo;
            Unsafe.AddByteOffset(ref start, offset + 4)  = (byte)(mid >> 24); // mid
            Unsafe.AddByteOffset(ref start, offset + 5)  = (byte)(mid >> 16);
            Unsafe.AddByteOffset(ref start, offset + 6)  = (byte)(mid >> 8);
            Unsafe.AddByteOffset(ref start, offset + 7)  = (byte)mid;
            Unsafe.AddByteOffset(ref start, offset + 8)  = (byte)(high >> 24); // high
            Unsafe.AddByteOffset(ref start, offset + 9)  = (byte)(high >> 16);
            Unsafe.AddByteOffset(ref start, offset + 10) = (byte)(high >> 8);
            Unsafe.AddByteOffset(ref start, offset + 11) = (byte)high;
            Unsafe.AddByteOffset(ref start, offset + 12) = (byte)(flags >> 24); // flags
            Unsafe.AddByteOffset(ref start, offset + 13) = (byte)(flags >> 16);
            Unsafe.AddByteOffset(ref start, offset + 14) = (byte)(flags >> 8);
            Unsafe.AddByteOffset(ref start, offset + 15) = (byte)flags;
        }
Ejemplo n.º 10
0
        public sbyte ReadFast(ref MessagePackReader reader, ref byte position)
        {
            var value = unchecked ((sbyte)Unsafe.AddByteOffset(ref position, (IntPtr)1));

            reader.AdvanceWithinSpan(2);
            return(value);
        }
Ejemplo n.º 11
0
        private static void _BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
        {
            Debug.Assert(byteCount > BulkMoveWithWriteBarrierChunk);

            if (Unsafe.AreSame(ref source, ref destination))
            {
                return;
            }

            // This is equivalent to: (destination - source) >= byteCount || (destination - source) < 0
            if ((nuint)(nint)Unsafe.ByteOffset(ref source, ref destination) >= byteCount)
            {
                // Copy forwards
                do
                {
                    byteCount -= BulkMoveWithWriteBarrierChunk;
                    __BulkMoveWithWriteBarrier(ref destination, ref source, BulkMoveWithWriteBarrierChunk);
                    destination = ref Unsafe.AddByteOffset(ref destination, BulkMoveWithWriteBarrierChunk);
                    source      = ref Unsafe.AddByteOffset(ref source, BulkMoveWithWriteBarrierChunk);
                }while (byteCount > BulkMoveWithWriteBarrierChunk);
            }
            else
            {
                // Copy backwards
                do
                {
                    byteCount -= BulkMoveWithWriteBarrierChunk;
                    __BulkMoveWithWriteBarrier(ref Unsafe.AddByteOffset(ref destination, byteCount), ref Unsafe.AddByteOffset(ref source, byteCount), BulkMoveWithWriteBarrierChunk);
                }while (byteCount > BulkMoveWithWriteBarrierChunk);
            }
            __BulkMoveWithWriteBarrier(ref destination, ref source, byteCount);
        }
Ejemplo n.º 12
0
        private unsafe static void SetDecimalLE(ref byte start, decimal value)
        {
            var  bits  = decimal.GetBits(value);
            uint lo    = (uint)bits[0];
            uint mid   = (uint)bits[1];
            uint high  = (uint)bits[2];
            uint flags = (uint)bits[3];

            nint offset = 0;

            Unsafe.AddByteOffset(ref start, offset)     = (byte)lo;
            Unsafe.AddByteOffset(ref start, offset + 1) = (byte)(lo >> 8);
            Unsafe.AddByteOffset(ref start, offset + 2) = (byte)(lo >> 16);
            Unsafe.AddByteOffset(ref start, offset + 3) = (byte)(lo >> 24); // lo
            Unsafe.AddByteOffset(ref start, offset + 4) = (byte)mid;
            Unsafe.AddByteOffset(ref start, offset + 5) = (byte)(mid >> 8);
            Unsafe.AddByteOffset(ref start, offset + 6) = (byte)(mid >> 16);
            Unsafe.AddByteOffset(ref start, offset + 7) = (byte)(mid >> 24); // mid
            offset += 8;
            Unsafe.AddByteOffset(ref start, offset)     = (byte)high;
            Unsafe.AddByteOffset(ref start, offset + 1) = (byte)(high >> 8);
            Unsafe.AddByteOffset(ref start, offset + 2) = (byte)(high >> 16);
            Unsafe.AddByteOffset(ref start, offset + 3) = (byte)(high >> 24); // high
            Unsafe.AddByteOffset(ref start, offset + 4) = (byte)flags;
            Unsafe.AddByteOffset(ref start, offset + 5) = (byte)(flags >> 8);
            Unsafe.AddByteOffset(ref start, offset + 6) = (byte)(flags >> 16);
            Unsafe.AddByteOffset(ref start, offset + 7) = (byte)(flags >> 24); // flags
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Clears the contents of this span.
        /// </summary>
        public unsafe void Clear()
        {
            int length = _length;

            if (length == 0)
            {
                return;
            }

            var byteLength = (UIntPtr)((uint)length * Unsafe.SizeOf <T>());

            if ((Unsafe.SizeOf <T>() & (sizeof(IntPtr) - 1)) != 0)
            {
                if (_pinnable == null)
                {
                    var ptr = (byte *)_byteOffset.ToPointer();

                    SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
                }
                else
                {
                    ref byte b = ref Unsafe.As <T, byte>(ref Unsafe.AddByteOffset <T>(ref _pinnable.Data, _byteOffset));

                    SpanHelpers.ClearLessThanPointerSized(ref b, byteLength);
                }
            }
Ejemplo n.º 14
0
        private static bool EqualsOrdinalIgnoreCaseNonAscii(ref char charA, ref char charB, int length)
        {
            //if (!GlobalizationMode.Invariant)
            //{
            //    return CompareStringOrdinalIgnoreCase(ref charA, length, ref charB, length) == 0;
            //}
            //else
            {
                // If we don't have localization tables to consult, we'll still perform a case-insensitive
                // check for ASCII characters, but if we see anything outside the ASCII range we'll immediately
                // fail if it doesn't have true bitwise equality.

                IntPtr byteOffset = IntPtr.Zero;
                while (length != 0)
                {
                    // Ordinal equals or lowercase equals if the result ends up in the a-z range
                    uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset);
                    uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset);

                    if (valueA == valueB ||
                        ((valueA | 0x20) == (valueB | 0x20) &&
                         (uint)((valueA | 0x20) - 'a') <= (uint)('z' - 'a')))
                    {
                        byteOffset += 2;
                        length--;
                    }
                    else
                    {
                        return(false);
                    }
                }

                return(true);
            }
        }
Ejemplo n.º 15
0
        public static long Make(ReadOnlySpan <byte> x)
        {
            unchecked
            {
                long hashCode = 0;

                var i8Span = MemoryMarshal.Cast <byte, long>(x);

                foreach (var v in i8Span)
                {
                    hashCode = (hashCode * 397) ^ v;
                }

                var remainingLength = x.Length & 7;

                var     i1Span = x.Slice(x.Length - remainingLength, remainingLength);
                ref var i1Ref  = ref MemoryMarshal.GetReference(i1Span);

                switch (remainingLength)
                {
                case 0:
                    break;

                case 1:
                    hashCode = (hashCode * 397) ^ i1Ref;
                    break;

                case 2:
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <ushort>(ref i1Ref);
                    break;

                case 3:
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <ushort>(ref i1Ref);
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <byte>(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr)2));
                    break;

                case 4:
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <uint>(ref i1Ref);
                    break;

                case 5:
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <uint>(ref i1Ref);
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <byte>(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr)4));
                    break;

                case 6:
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <uint>(ref i1Ref);
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <ushort>(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr)4));
                    break;

                case 7:
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <uint>(ref i1Ref);
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <ushort>(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr)4));
                    hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned <byte>(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr)6));
                    break;
                }

                return(hashCode);
            }
Ejemplo n.º 16
0
 public static uint32_t is_structural_or_whitespace(uint8_t c)
 {
     // Bypass bounds check as c can never
     // exceed the bounds of structural_or_whitespace
     return(Unsafe.AddByteOffset(
                ref MemoryMarshal.GetReference(structural_or_whitespace),
                (IntPtr)c));
 }
Ejemplo n.º 17
0
        private static ExtensionResult ReadFast(ref MessagePackReader reader, ref byte position)
        {
            var typeCode  = unchecked ((sbyte)Unsafe.AddByteOffset(ref position, (IntPtr)1));
            var valueSpan = reader.PeekFast(2, 1);

            reader.AdvanceWithinSpan(3);
            return(new ExtensionResult(typeCode, valueSpan));
        }
Ejemplo n.º 18
0
 private static uint8_t escape(uint8_t c)
 {
     // Bypass bounds check as c can never 
     // exceed the bounds of escape_map
     return Unsafe.AddByteOffset(
        ref MemoryMarshal.GetReference(escape_map),
        (IntPtr)c);
 }
        private static String ReadFast(ref MessagePackReader reader, ref byte position)
        {
            var length    = (int)Unsafe.AddByteOffset(ref position, (IntPtr)1);
            var valueSpan = reader.PeekFast(2, length);

            reader.AdvanceWithinSpan(length + 2);
            return(EncodingUtils.ToString(valueSpan));
        }
        private static Int16 ReadFast(ref MessagePackReader reader, ref byte position)
        {
            IntPtr offset = (IntPtr)1;
            var    value  = checked ((short)((Unsafe.AddByteOffset(ref position, offset) << 8) + Unsafe.AddByteOffset(ref position, offset + 1)));

            reader.AdvanceWithinSpan(3);
            return(value);
        }
Ejemplo n.º 21
0
        public static T Deserialize <T>(this JsonElement element, JsonSerializerOptions?options = null)
        {
            JsonDocument          documentRef = Unsafe.As <JsonElement, JsonDocument>(ref element);
            int                   idxPtr      = Unsafe.AddByteOffset(ref Unsafe.As <JsonElement, int>(ref element), new IntPtr(IntPtr.Size));
            ReadOnlyMemory <byte> memory      = _jsonDocumentGetRawdataDelegate(documentRef, idxPtr, true);

            return(JsonSerializer.Deserialize <T>(memory.Span, options) !);
        }
        private static Int64 ReadFast(ref MessagePackReader reader, ref byte position)
        {
            IntPtr offset = (IntPtr)1;
            var    value  = (Unsafe.AddByteOffset(ref position, offset) << 8) | Unsafe.AddByteOffset(ref position, offset + 1);

            reader.AdvanceWithinSpan(3);
            return(value);
        }
Ejemplo n.º 23
0
 public static bool is_not_structural_or_whitespace_or_exponent_or_decimal(uchar1 c)
 {
     // Bypass bounds check as c can never
     // exceed the bounds of structural_or_whitespace_or_exponent_or_decimal_negated
     return(Unsafe.AddByteOffset(
                ref MemoryMarshal.GetReference(structural_or_whitespace_or_exponent_or_decimal_negated),
                (IntPtr)c) == 1);
 }
Ejemplo n.º 24
0
        public void WriteIid(string name, Guid value)
        {
            if (_config.GenerateUnmanagedConstants)
            {
                AddUsingDirective("System");
                AddUsingDirective("System.Diagnostics");
                AddUsingDirective("System.Runtime.CompilerServices");
                AddUsingDirective("System.Runtime.InteropServices");

                WriteIndented("public static ref readonly Guid ");
                WriteLine(name);
                WriteBlockStart();

                WriteIndentedLine("get");
                WriteBlockStart();

                WriteIndentedLine("ReadOnlySpan<byte> data = new byte[] {");
                IncreaseIndentation();
                WriteIndentation();

                WriteValueAsBytes(Unsafe.As <Guid, uint>(ref value), 4);

                WriteLine(',');
                WriteIndentation();

                WriteValueAsBytes(Unsafe.As <Guid, ushort>(ref Unsafe.AddByteOffset(ref value, (nint)4)), 2);

                WriteLine(',');
                WriteIndentation();

                WriteValueAsBytes(Unsafe.As <Guid, ushort>(ref Unsafe.AddByteOffset(ref value, (nint)6)), 2);

                for (var i = 8; i < 16; i++)
                {
                    WriteLine(',');
                    WriteIndentation();

                    WriteValueAsBytes(Unsafe.As <Guid, ushort>(ref Unsafe.AddByteOffset(ref value, (nint)i)), 1);
                }

                WriteNewline();
                DecreaseIndentation();
                WriteIndentedLine("};");

                NeedsNewline = true;

                WriteIndentedLine("Debug.Assert(data.Length == Unsafe.SizeOf<Guid>());");
                WriteIndentedLine("return ref Unsafe.As<byte, Guid>(ref MemoryMarshal.GetReference(data));");

                WriteBlockEnd();
                WriteBlockEnd();
            }
            else
            {
                var valueString = value.ToString("X").ToUpperInvariant().Replace("{", "").Replace("}", "").Replace('X', 'x').Replace(",", ", ");
                WriteIid(name, valueString);
            }
        }
Ejemplo n.º 25
0
        private static void ReadFast(ref MessagePackReader reader, ref byte position)
        {
            IntPtr offset = (IntPtr)1;
            var    length = unchecked (
                (Unsafe.AddByteOffset(ref position, offset) << 8) |
                Unsafe.AddByteOffset(ref position, offset + 1));

            reader.AdvanceWithinSpan(length + 3);
        }
        private static String ReadFast(ref MessagePackReader reader, ref byte position)
        {
            IntPtr offset    = (IntPtr)1;
            var    length    = unchecked ((Unsafe.AddByteOffset(ref position, offset) << 8) + Unsafe.AddByteOffset(ref position, offset + 1));
            var    valueSpan = reader.PeekFast(3, length);

            reader.AdvanceWithinSpan(length + 3);
            return(EncodingUtils.ToString(valueSpan));
        }
Ejemplo n.º 27
0
        private unsafe static void SetMediumLE(ref byte start, int value)
        {
            uint unsignedValue = (uint)value;
            nint offset        = 0;

            Unsafe.AddByteOffset(ref start, offset)     = (byte)unsignedValue;
            Unsafe.AddByteOffset(ref start, offset + 1) = (byte)(unsignedValue >> 8);
            Unsafe.AddByteOffset(ref start, offset + 2) = (byte)(unsignedValue >> 16);
        }
Ejemplo n.º 28
0
        public static long UnsafeUnpackVInt(ref byte data, int len)
        {
            switch (len)
            {
            case 1:
                return((long)data - 0x80);

            case 2:
            {
                var sign = (long)((data & 0x80) >> 7) - 1;      // -1 for negative, 0 for positive
                return((0x1fffu & AsBigEndian(Unsafe.ReadUnaligned <ushort>(ref data))) - (0x2000 & sign));
            }

            case 3:
            {
                var sign = (long)((data & 0x80) >> 7) - 1;      // -1 for negative, 0 for positive
                var res  = (data & 0x0F) << 16;
                data = ref Unsafe.AddByteOffset(ref data, (IntPtr)1);
                return(res + AsBigEndian(Unsafe.ReadUnaligned <ushort>(ref data)) - (0x10_0000 & sign));
            }

            case 4:
            {
                var sign = (long)((data & 0x80) >> 7) - 1;      // -1 for negative, 0 for positive
                return((0x07ff_ffff & AsBigEndian(Unsafe.ReadUnaligned <uint>(ref data))) - (0x0800_0000 & sign));
            }

            case 5:
            {
                var sign = (long)((data & 0x80) >> 7) - 1;      // -1 for negative, 0 for positive
                var res  = (long)(data & 0x03u) << 32;
                data = ref Unsafe.AddByteOffset(ref data, (IntPtr)1);
                return(res + AsBigEndian(Unsafe.ReadUnaligned <uint>(ref data)) - (0x04_0000_0000 & sign));
            }

            case 6:
            {
                var sign = (long)((data & 0x80) >> 7) - 1;      // -1 for negative, 0 for positive
                var res  = (0x01ffL & AsBigEndian(Unsafe.ReadUnaligned <ushort>(ref data))) << 32;
                data = ref Unsafe.AddByteOffset(ref data, (IntPtr)2);
                return(res + AsBigEndian(Unsafe.ReadUnaligned <uint>(ref data)) - (0x0200_0000_0000 & sign));
            }

            case 7:
            {
                var sign = (long)((data & 0x80) >> 7) - 1;      // -1 for negative, 0 for positive
                data = ref Unsafe.AddByteOffset(ref data, (IntPtr)1);
                var res = (long)AsBigEndian(Unsafe.ReadUnaligned <ushort>(ref data)) << 32;
                data = ref Unsafe.AddByteOffset(ref data, (IntPtr)2);
                return(res + AsBigEndian(Unsafe.ReadUnaligned <uint>(ref data)) - (0x01_0000_0000_0000 & sign));
            }

            default:
                data = ref Unsafe.AddByteOffset(ref data, (IntPtr)1);
                return((long)AsBigEndian(Unsafe.ReadUnaligned <ulong>(ref data)));
            }
        }
Ejemplo n.º 29
0
 public static int TrailingZeroCount(uint value)
 {
     // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
     return(Unsafe.AddByteOffset(
                // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u
                ref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn),
                // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here
                (IntPtr)(int)(((value & (uint)-(int)value) * 0x077CB531u) >> 27))); // Multi-cast mitigates redundant conv.u8
 }
Ejemplo n.º 30
0
        /*
         * GetIsWhiteSpace
         * ===========================
         * Data derived from https://unicode.org/reports/tr44/#White_Space. Represents whether a code point
         * is listed as White_Space per PropList.txt.
         */

        internal static bool GetIsWhiteSpace(char ch)
        {
            // We don't need a (string, int) overload because all current white space chars are in the BMP.

            nuint offset = GetCategoryCasingTableOffsetNoBoundsChecks(ch);

            // High bit of each value in the 'CategoriesValues' array denotes whether this code point is white space.

            return((sbyte)Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(CategoriesValues), offset) < 0);
        }