Exemplo n.º 1
0
        public static Icon Parse(Stream stream)
        {
            if (stream is null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            UnsafeEx.SkipInitIfPossible(out ICONDIR icondir);   // 6 bytes
            stream.SafeRead(UnsafeEx.AsBytes(ref icondir));

            if (icondir.idCount < 0)
            {
                ThrowHelper.ThrowFormatException();
            }

            using var entries = new UnsafeRawArray <ICONDIRENTRY>(icondir.idCount, false);
            stream.SafeRead(entries.AsBytes());

            return(Icon.Create(icondir.idCount, (stream, entries), static (images, state) =>
            {
                var(stream, entries) = state;
                for (int i = 0; i < images.Length; i++)
                {
                    images[i] = ParseImage(stream, entries[i]);
                }
            }));
        }
Exemplo n.º 2
0
        public void CeqCgtCltWork()
        {
            // int32
            Assert.AreEqual(1, UnsafeEx.Ceq(1, 1));
            Assert.AreEqual(0, UnsafeEx.Ceq(1, 2));

            Assert.AreEqual(1, UnsafeEx.Cgt(2, 1));
            Assert.AreEqual(0, UnsafeEx.Cgt(1, 1));
            Assert.AreEqual(0, UnsafeEx.Cgt(0, 1));

            Assert.AreEqual(1, UnsafeEx.Clt(1, 2));
            Assert.AreEqual(0, UnsafeEx.Clt(1, 1));
            Assert.AreEqual(0, UnsafeEx.Clt(1, 0));

            // int64
            Assert.AreEqual(1, UnsafeEx.Ceq(1L, 1L));
            Assert.AreEqual(0, UnsafeEx.Ceq(1L, 2L));

            Assert.AreEqual(1, UnsafeEx.Cgt(2L, 1L));
            Assert.AreEqual(0, UnsafeEx.Cgt(1L, 1L));
            Assert.AreEqual(0, UnsafeEx.Cgt(0L, 1L));

            Assert.AreEqual(1, UnsafeEx.Clt(1L, 2L));
            Assert.AreEqual(0, UnsafeEx.Clt(1L, 1L));
            Assert.AreEqual(0, UnsafeEx.Clt(1L, 0L));

            // explicit int32 -> int64
            Assert.AreEqual(1, UnsafeEx.Ceq(1, 1L));
            Assert.AreEqual(0, UnsafeEx.Ceq(1, 2L));

            Assert.AreEqual(1, UnsafeEx.Cgt(2, 1L));
            Assert.AreEqual(0, UnsafeEx.Cgt(1, 1L));
            Assert.AreEqual(0, UnsafeEx.Cgt(0, 1L));

            Assert.AreEqual(1, UnsafeEx.Clt(1, 2L));
            Assert.AreEqual(0, UnsafeEx.Clt(1, 1L));
            Assert.AreEqual(0, UnsafeEx.Clt(1, 0L));

            // IntPtr
            Assert.AreEqual(1, UnsafeEx.Ceq((IntPtr)1, (IntPtr)1));
            Assert.AreEqual(0, UnsafeEx.Ceq((IntPtr)1, (IntPtr)2));

            Assert.AreEqual(1, UnsafeEx.Cgt((IntPtr)2, (IntPtr)1));
            Assert.AreEqual(0, UnsafeEx.Cgt((IntPtr)1, (IntPtr)1));
            Assert.AreEqual(0, UnsafeEx.Cgt((IntPtr)0, (IntPtr)1));

            Assert.AreEqual(1, UnsafeEx.Clt((IntPtr)1, (IntPtr)2));
            Assert.AreEqual(0, UnsafeEx.Clt((IntPtr)1, (IntPtr)1));
            Assert.AreEqual(0, UnsafeEx.Clt((IntPtr)1, (IntPtr)0));

            // Float
            Assert.AreEqual(1, UnsafeEx.Ceq(1.23, 1.23));
            Assert.AreEqual(0, UnsafeEx.Ceq(1.23, 1.24));

            Assert.AreEqual(1, UnsafeEx.Ceq(1.23f, 1.23f));
            Assert.AreEqual(0, UnsafeEx.Ceq(1.23f, 1.24f));

            Assert.AreEqual(1, UnsafeEx.BoolAsInt(true));
            Assert.AreEqual(0, UnsafeEx.BoolAsInt(false));
        }
Exemplo n.º 3
0
        public void CouldUseIDisposableMethods()
        {
            var disposable = new TestDisposable();

            UnsafeEx.DisposeConstrained(ref disposable);

            Assert.True(disposable.Disposed);
        }
Exemplo n.º 4
0
        public void ComparerInterfaceAndCachedConstrainedComparer()
        {
            var c = Comparer <long> .Default;
            IComparer <long> ic = Comparer <long> .Default;
            var cc = KeyComparer <long> .Default;

            const int count = 100000000;

            for (int r = 0; r < 10; r++)
            {
                var sum = 0L;

                using (Benchmark.Run("Binary", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        sum += c.Compare(i, i - 1);
                    }
                }

                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("Interface", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        sum += ic.Compare(i, i - 1);
                    }
                }
                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("KeyComparer", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        sum += cc.Compare(i, i - 1);
                    }
                }
                Assert.True(sum > 0);

                sum = 0L;
                using (Benchmark.Run("Unsafe", count))
                {
                    for (int i = 0; i < count; i++)
                    {
                        var other = i - 1;
                        sum += UnsafeEx.CompareToConstrained(ref i, ref other);
                    }
                }
            }

            Benchmark.Dump();
        }
Exemplo n.º 5
0
        public void CouldUseGetHashCodeMethods()
        {
            var v  = 1;
            var vh = UnsafeEx.GetHashCodeConstrained(ref v);

            Assert.AreEqual(v, vh);

            var d  = new TestDisposable();
            var dh = UnsafeEx.GetHashCodeConstrained(ref d);

            Assert.AreEqual(42, dh);
        }
Exemplo n.º 6
0
        public void CouldUseIDiffableMethods()
        {
            var first = new LongDiffable {
                Value = 123
            };
            var second = new LongDiffable {
                Value = 456
            };

            var diff = 456 - 123;

            Assert.AreEqual(diff, UnsafeEx.DiffLongConstrained(ref first, ref second));
            Assert.AreEqual(second, UnsafeEx.AddLongConstrained(ref first, diff));
        }
Exemplo n.º 7
0
        public void CouldUseCompareAndEqualsMethods()
        {
            var v1 = new CompEq(1);
            var v2 = new CompEq(2);
            var v3 = new CompEq(2);

            Assert.AreEqual(-1, UnsafeEx.CompareToConstrained(ref v1, ref v2));
            Assert.AreEqual(1, UnsafeEx.CompareToConstrained(ref v2, ref v1));
            Assert.AreEqual(0, UnsafeEx.CompareToConstrained(ref v2, ref v3));
            Assert.AreEqual(1, UnsafeEx.CompareToConstrained(ref v3, ref v1));

            Assert.True(UnsafeEx.EqualsConstrained(ref v2, ref v3));
            Assert.False(UnsafeEx.EqualsConstrained(ref v1, ref v3));
        }
Exemplo n.º 8
0
        public static int BinaryLookup <T>(ref T searchSpace, int offset, int length, ref T value, Lookup lookup, KeyComparer <T> comparer = default)
        {
            Debug.Assert(length >= 0);

            var i = BinarySearch(ref searchSpace, offset, length, value, comparer);

            var li = SearchToLookup2(offset, length, lookup, i);

            if (li != i & li >= offset) // not &&
            {
                value = UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, li));
            }

            return(li);
        }
Exemplo n.º 9
0
        public void CouldUseIDeltaMethods()
        {
            var first = new IntDelta {
                Value = 123
            };
            var second = new IntDelta {
                Value = 456
            };

            var delta = new IntDelta {
                Value = 456 - 123
            };

            Assert.AreEqual(delta, UnsafeEx.GetDeltaConstrained(ref first, ref second));
            Assert.AreEqual(second, UnsafeEx.AddDeltaConstrained(ref first, ref delta));
        }
Exemplo n.º 10
0
        internal static int BinarySearchClassic <T>(ref T searchSpace, int offset, int length, T value, KeyComparer <T> comparer = default)
        {
            unchecked
            {
                int lo = offset;
                int hi = offset + length - 1;
                // If length == 0, hi == -1, and loop will not be entered
                while (lo <= hi)
                {
                    // PERF: `lo` or `hi` will never be negative inside the loop,
                    //       so computing median using uints is safe since we know
                    //       `length <= int.MaxValue`, and indices are >= 0
                    //       and thus cannot overflow an uint.
                    //       Saves one subtraction per loop compared to
                    //       `int i = lo + ((hi - lo) >> 1);`
                    int i = (int)(((uint)hi + (uint)lo) >> 1);

                    int c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                    if (c == 0)
                    {
                        return(i);
                    }

                    if (c > 0)
                    {
                        lo = i + 1;
                    }
                    else
                    {
                        hi = i - 1;
                    }
                }

                // If none found, then a negative number that is the bitwise complement
                // of the index of the next element that is larger than or, if there is
                // no larger element, the bitwise complement of `length`, which
                // is `lo` at this point.
                return(~lo);
            }
        }
Exemplo n.º 11
0
        internal static int BinarySearchHybrid <T>(ref T searchSpace, int offset, int length, T value, KeyComparer <T> comparer = default)
        {
            unchecked
            {
                int c;
                int lo = offset;
                int hi = offset + length - 1;
                while (hi - lo > 7)
                {
                    int i = (int)(((uint)hi + (uint)lo) >> 1);

                    c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                    if (c > 0)
                    {
                        lo = i + 1;
                    }
                    else
                    {
                        if (c == 0)
                        {
                            goto RETURN;
                        }

                        hi = i - 1;
                    }
                }

                while ((c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, lo)))) > 0 &&
                       ++lo <= hi)
                {
                }

RETURN:
                var ceq1 = -UnsafeEx.Ceq(c, 0);
                return((ceq1 & lo) | (~ceq1 & ~lo));
            }
        }
Exemplo n.º 12
0
 public static TValue Unpack <TValue>(ref TValue value, int from, int to)
 {
     if (typeof(TValue) == typeof(sbyte) || typeof(TValue) == typeof(byte))
     {
         return(UnsafeEx.As <byte, TValue>(BitHelper.Unpack(Unsafe.As <TValue, byte>(ref value), from, to)));
     }
     else if (typeof(TValue) == typeof(short) || typeof(TValue) == typeof(ushort))
     {
         return(UnsafeEx.As <ushort, TValue>(BitHelper.Unpack(Unsafe.As <TValue, ushort>(ref value), from, to)));
     }
     else if (typeof(TValue) == typeof(int) || typeof(TValue) == typeof(uint))
     {
         return(UnsafeEx.As <uint, TValue>(BitHelper.Unpack(Unsafe.As <TValue, uint>(ref value), from, to)));
     }
     else if (typeof(TValue) == typeof(long) || typeof(TValue) == typeof(ulong))
     {
         return(UnsafeEx.As <ulong, TValue>(BitHelper.Unpack(Unsafe.As <TValue, ulong>(ref value), from, to)));
     }
     else
     {
         throw new ArgumentException(nameof(TValue));
     }
 }
Exemplo n.º 13
0
        // TODO WTF is this externallyOwned on slice? See RdM Clone
        /// <summary>
        /// Returns new VectorStorage instance with the same memory source but (optionally) different memory start and length.
        /// Increments underlying memory reference count unless <paramref name="externallyOwned"/> is true.
        /// </summary>
        public RetainedVec Clone(int start, int length, bool externallyOwned = false)
        {
            // see CLR Span.Slice comment
            if (IntPtr.Size == 8)
            {
                if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)_length)
                {
                    ThrowHelper.ThrowArgumentOutOfRangeException();
                }
            }
            else
            {
                if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
                {
                    ThrowHelper.ThrowArgumentOutOfRangeException();
                }
            }

            if (!externallyOwned)
            {
                _memoryOwner?.Increment();
            }

            var slice = new RetainedVec(
                externallyOwned ? null : _memoryOwner,
                _array,
                UnsafeEx.Add(_pointerOrOffset,
                             _array == null
                        ? start * VecTypeHelper.GetInfo(_runtimeTypeId).ElemSize
                        : start),
                length,
                _runtimeTypeId
                );

            return(slice);
        }
Exemplo n.º 14
0
        public T Add(T value, long diff)
        {
            if (typeof(T) == typeof(byte))
            {
                var value1 = (byte)(object)(value);
                return((T)(object)(checked ((byte)((sbyte)value1 + diff))));
            }

            if (typeof(T) == typeof(sbyte))
            {
                var value1 = (sbyte)(object)(value);
                return((T)(object)(checked ((sbyte)(value1 + diff))));
            }

            if (typeof(T) == typeof(char))
            {
                var value1 = (char)(object)(value);
                return((T)(object)(checked ((char)(value1 + diff))));
            }

            if (typeof(T) == typeof(short))
            {
                var value1 = (short)(object)(value);
                return((T)(object)(checked ((short)(value1 + diff))));
            }

            if (typeof(T) == typeof(ushort))
            {
                var value1 = (ushort)(object)(value);
                return((T)(object)(checked ((ushort)((short)value1 + diff))));
            }

            if (typeof(T) == typeof(int))
            {
                var value1 = (int)(object)(value);
                return((T)(object)(checked ((int)(value1 + diff))));
            }

            if (typeof(T) == typeof(uint))
            {
                var value1 = (uint)(object)(value);
                return((T)(object)(checked ((uint)((int)value1 + diff))));
            }

            if (typeof(T) == typeof(long))
            {
                var value1 = (long)(object)(value);
                return((T)(object)(checked (value1 + diff)));
            }

            if (typeof(T) == typeof(ulong))
            {
                var value1 = (ulong)(object)(value);
                return((T)(object)(checked ((ulong)((long)value1 + diff))));
            }

            if (typeof(T) == typeof(DateTime))
            {
                var value1 = (DateTime)(object)(value);
                return((T)(object)value1.AddTicks(diff));
            }

            if (typeof(T) == typeof(Timestamp))
            {
                var value1 = (Timestamp)(object)(value);
                return((T)(object)(new Timestamp(value1.Nanos + diff)));
            }

            // TODO SmallDecimal

            if (IsIInt64Diffable)
            {
                return(UnsafeEx.AddLongConstrained(ref value, diff));
            }

            if (_keyComparer != null)
            {
                return(AddViaInterface(value, diff));
            }

            ThrowHelper.ThrowNotSupportedException();
            return(default(T));
        }
Exemplo n.º 15
0
        public int Compare(T x, T y)
        {
            // For our purposes this method is "normal", i.e. known types are compared normally
            // TODO (docs) It is easy to compare known types in a custom way - just implement a wrapper struct and IComparable<T>. This also will be faster than a comparable.

            if (typeof(T) == typeof(bool))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (bool)(object)(x);
                var y1 = (bool)(object)(y);
                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(byte))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (byte)(object)(x);
                var y1 = (byte)(object)(y);
                return(x1 - y1);
            }

            if (typeof(T) == typeof(sbyte))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (sbyte)(object)(x);
                var y1 = (sbyte)(object)(y);
                return(x1 - y1);
            }

            if (typeof(T) == typeof(char))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (char)(object)(x);
                var y1 = (char)(object)(y);
                return(x1 - y1);
            }

            if (typeof(T) == typeof(short))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (short)(object)(x);
                var y1 = (short)(object)(y);
                return(x1 - y1);
            }

            if (typeof(T) == typeof(ushort))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (ushort)(object)(x);
                var y1 = (ushort)(object)(y);

                // ReSharper disable RedundantCast
                return((int)x1 - (int)y1);
                // ReSharper restore RedundantCast
            }

            if (typeof(T) == typeof(int))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (int)(object)(x);
                var y1 = (int)(object)(y);
                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(uint))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (uint)(object)(x);
                var y1 = (uint)(object)(y);

                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(long))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (long)(object)(x);
                var y1 = (long)(object)(y);

                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(ulong))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (ulong)(object)(x);
                var y1 = (ulong)(object)(y);
                return(x1.CompareTo(y1));
            }

            if (typeof(T) == typeof(float))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (float)(object)(x);
                var y1 = (float)(object)(y);

                if (x1 < y1)
                {
                    return(-1);
                }
                if (x1 > y1)
                {
                    return(1);
                }
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (x1 == y1)
                {
                    return(0);
                }

                // At least one of the values is NaN.
                if (float.IsNaN(x1))
                {
                    return(float.IsNaN(y1) ? 0 : -1);
                }
                else // f is NaN.
                {
                    return(1);
                }
            }

            if (typeof(T) == typeof(double))
            {
                // x1.CompareTo(y1) is not inlined, copy manually
                // https://github.com/dotnet/corefx/blob/5fe165ab631675273f5d19bebc15b5733ef1354d/src/Common/src/CoreLib/System/Double.cs#L147
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (double)(object)(x);
                var y1 = (double)(object)(y);

                if (x1 < y1)
                {
                    return(-1);
                }
                if (x1 > y1)
                {
                    return(1);
                }
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (x1 == y1)
                {
                    return(0);
                }

                // At least one of the values is NaN.
                if (double.IsNaN(x1))
                {
                    return(double.IsNaN(y1) ? 0 : -1);
                }
                else
                {
                    return(1);
                }
            }

            if (typeof(T) == typeof(decimal))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (decimal)(object)(x);
                var y1 = (decimal)(object)(y);

                return(decimal.Compare(x1, y1));
            }

            if (typeof(T) == typeof(DateTime))
            {
                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = (DateTime)(object)(x);
                var y1 = (DateTime)(object)(y);
                return(DateTime.Compare(x1, y1));
            }

            if (typeof(T) == typeof(Timestamp))
            {
                // TODO for TS we could use sub in normal cases

                Debug.Assert(_keyComparer == null, "Known types should not have a comparer");

                var x1 = ((Timestamp)(object)(x)).Nanos;
                var y1 = ((Timestamp)(object)(y)).Nanos;

                return(x1.CompareTo(y1));
            }

            // NB all primitive types are IComparable, all custom types could be easily made such
            // This optimization using Spreads.Unsafe package works for any type that implements
            // the interface and is as fast as `typeof(T) == typeof(...)` approach.
            // The special cases above are left for scenarios when the "static readonly" optimization
            // doesn't work, e.g. AOT. See discussion #100.
            if (IsIComparable)
            {
                return(UnsafeEx.CompareToConstrained(ref x, ref y));
            }

            if (_keyComparer != null)
            {
                return(_keyComparer.Compare(x, y));
            }

            return(CompareSlow(x, y));
        }
Exemplo n.º 16
0
        internal static int InterpolationSearchGeneric <T>(ref T searchSpace, int offset, int length, T value, KeyComparer <T> comparer = default)
        {
            // Try interpolation only for big-enough lengths and do minimal job,
            // just find the range with exponential search with minimal branches
            // and switch to binary search.
            unchecked
            {
                int i;
                int lo = offset;
                int hi = offset + length - 1;

                if (hi - lo > 16)
                {
                    var  vlo    = UnsafeEx.ReadUnaligned(ref searchSpace);
                    var  vhi    = UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, hi));
                    int  range  = hi - lo;
                    long vRange = comparer.Diff(vhi, vlo);

                    // (hi - lo) <= int32.MaxValue
                    // vlo could be zero while value could easily be close to int64.MaxValue (nanos in unix time, we are now between 60 and 61 bit at 60.4)
                    // convert to double here to avoid overflow and for much faster calculations
                    // (only 4 cycles vs 25 cycles https://lemire.me/blog/2017/11/16/fast-exact-integer-divisions-using-floating-point-operations/)
                    double nominator = (hi - lo) * (double)comparer.Diff(value, vlo);

                    i = (int)(nominator / vRange);

                    if ((uint)i > range)
                    {
                        i = i < 0 ? 0 : range;
                    }
                    // make i relative to vecStart
                    i += lo;

                    int c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                    if (c == 0)
                    {
                        goto FOUND;
                    }

                    var step = 1;

                    if (c > 0)
                    {
                        while (true)
                        {
                            i += step;

                            if (i > hi)
                            {
                                break;
                            }

                            c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                            if (c <= 0)
                            {
                                if (c == 0)
                                {
                                    goto FOUND;
                                }

                                hi = i - 1;
                                break;
                            }

                            step <<= 1;
                        }

                        lo = i - step + 1;
                    }
                    else
                    {
                        while (true)
                        {
                            i -= step;

                            if (i < lo)
                            {
                                break;
                            }

                            c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                            if (c >= 0)
                            {
                                if (c == 0)
                                {
                                    goto FOUND;
                                }

                                lo = i + 1;
                                break;
                            }

                            step <<= 1;
                        }

                        hi = i + step - 1;
                    }
                }

                return(BinarySearch(ref searchSpace, lo, 1 + hi - lo, value));

FOUND:
                return(i);
            }
        }
Exemplo n.º 17
0
        public static int SearchToLookup <T>(int offset, int length, Lookup lookup, int i, ref T searchSpace, ref T value)
        {
            if (i >= offset)
            {
                if (lookup.IsEqualityOK())
                {
                    goto RETURN;
                }

                if (lookup == Lookup.LT)
                {
                    if (i == offset)
                    {
                        goto RETURN_O;
                    }

                    i--;
                }
                else // depends on if (eqOk) above
                {
                    Debug.Assert(lookup == Lookup.GT);
                    if (i == offset + length - 1)
                    {
                        goto RETURN_OL;
                    }

                    i++;
                }
            }
            else
            {
                if (lookup == Lookup.EQ)
                {
                    goto RETURN;
                }

                i = ~i;

                // LT or LE
                if (((uint)lookup & (uint)Lookup.LT) != 0)
                {
                    // i is idx of element that is larger, nothing here for LE/LT
                    if (i == offset)
                    {
                        goto RETURN_O;
                    }

                    i--;
                }
                else
                {
                    Debug.Assert(((uint)lookup & (uint)Lookup.GT) != 0);
                    Debug.Assert(i <= offset + length);
                    // if was negative, if it was ~length then there are no more elements for GE/GT
                    if (i == offset + length)
                    {
                        goto RETURN_OL;
                    }
                    // i is the same, ~i is idx of element that is GT the value
                }
            }

            value = UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i));

RETURN:
            Debug.Assert(unchecked ((uint)i) - offset < unchecked ((uint)length));
            return(i);

RETURN_O:
            return(~offset);

RETURN_OL:
            return(~(offset + length));
        }
Exemplo n.º 18
0
            public void GetValuesViaCalli <K, V>(DataBlock block, int index, ref K key, ref V value)
            {
                var dlg = Unsafe.As <Getter <K, V> >(Getter);

                UnsafeEx.CalliDataBlock(dlg, block, index, ref key, ref value, GetterPtr);
            }
Exemplo n.º 19
0
        public long Diff(T minuend, T subtrahend)
        {
            // ReSharper disable RedundantCast
            if (typeof(T) == typeof(byte))
            {
                var x1 = (byte)(object)(minuend);
                var y1 = (byte)(object)(subtrahend);

                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(sbyte))
            {
                var x1 = (sbyte)(object)(minuend);
                var y1 = (sbyte)(object)(subtrahend);
                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(char))
            {
                var x1 = (char)(object)(minuend);
                var y1 = (char)(object)(subtrahend);
                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(short))
            {
                var x1 = (short)(object)(minuend);
                var y1 = (short)(object)(subtrahend);
                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(ushort))
            {
                var x1 = (ushort)(object)(minuend);
                var y1 = (ushort)(object)(subtrahend);
                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(int))
            {
                var x1 = (int)(object)(minuend);
                var y1 = (int)(object)(subtrahend);
                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(uint))
            {
                var x1 = (uint)(object)(minuend);
                var y1 = (uint)(object)(subtrahend);
                return(checked ((long)(x1) - y1));
            }

            if (typeof(T) == typeof(long))
            {
                var x1 = (long)(object)(minuend);
                var y1 = (long)(object)(subtrahend);

                return(checked (x1 - y1));
            }

            if (typeof(T) == typeof(ulong))
            {
                var x1 = (ulong)(object)(minuend);
                var y1 = (ulong)(object)(subtrahend);
                return(checked ((long)(x1) - (long)y1));
            }

            if (typeof(T) == typeof(DateTime))
            {
                var x1 = (DateTime)(object)(minuend);
                var y1 = (DateTime)(object)(subtrahend);

                return(checked (x1.Ticks - y1.Ticks));
            }

            if (typeof(T) == typeof(Timestamp))
            {
                var x1 = (Timestamp)(object)(minuend);
                var y1 = (Timestamp)(object)(subtrahend);

                return(checked (x1.Nanos - y1.Nanos));
            }

            // ReSharper restore RedundantCast
            // TODO SmallDecimal

            if (IsIInt64Diffable)
            {
                return(UnsafeEx.DiffLongConstrained(ref minuend, ref subtrahend));
            }

            if (_keyComparer != null)
            {
                return(DiffViaInterface(minuend, subtrahend));
            }

            ThrowHelper.ThrowNotSupportedException();
            return(0L);
        }