Example #1
0
        /// <summary>
        /// Determines whether two sequences overlap in memory and outputs the element offset.
        /// </summary>
        public static bool Overlaps <T>(this ReadOnlySpan <T> first, ReadOnlySpan <T> second, out int elementOffset)
        {
            if (first.IsEmpty || second.IsEmpty)
            {
                elementOffset = 0;
                return(false);
            }

            IntPtr byteOffset = Unsafe.ByteOffset(
                ref MemoryMarshal.GetReference(first),
                ref MemoryMarshal.GetReference(second));

            if (Unsafe.SizeOf <IntPtr>() == sizeof(int))
            {
                if ((uint)byteOffset < (uint)(first.Length * Unsafe.SizeOf <T>()) ||
                    (uint)byteOffset > (uint)-(second.Length * Unsafe.SizeOf <T>()))
                {
                    if ((int)byteOffset % Unsafe.SizeOf <T>() != 0)
                    {
                        ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
                    }

                    elementOffset = (int)byteOffset / Unsafe.SizeOf <T>();
                    return(true);
                }
                else
                {
                    elementOffset = 0;
                    return(false);
                }
            }
            else
            {
                if ((ulong)byteOffset < (ulong)((long)first.Length * Unsafe.SizeOf <T>()) ||
                    (ulong)byteOffset > (ulong)-((long)second.Length * Unsafe.SizeOf <T>()))
                {
                    if ((long)byteOffset % Unsafe.SizeOf <T>() != 0)
                    {
                        ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
                    }

                    elementOffset = (int)((long)byteOffset / Unsafe.SizeOf <T>());
                    return(true);
                }
                else
                {
                    elementOffset = 0;
                    return(false);
                }
            }
        }