mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Expanded BinarySearch api, got rid of IComparable due to iOpComparable
This commit is contained in:
parent
b9debfe3bf
commit
90e4cf8825
11 changed files with 145 additions and 110 deletions
|
@ -21,7 +21,7 @@ namespace Beefy.widgets
|
|||
{
|
||||
public delegate T Interpolator(T from, T to, float pct);
|
||||
|
||||
public struct Entry
|
||||
public struct Entry : IOpComparable
|
||||
{
|
||||
public float mFrame;
|
||||
public T mValue;
|
||||
|
@ -30,20 +30,16 @@ namespace Beefy.widgets
|
|||
{
|
||||
return ((val1.mFrame == val2.mFrame) && (val1.mValue == val2.mValue));
|
||||
}
|
||||
}
|
||||
|
||||
public class EntryComparer : IComparer<Entry>
|
||||
{
|
||||
public int Compare(Entry ent1, Entry ent2)
|
||||
{
|
||||
return ent1.mFrame.CompareTo(ent2.mFrame);
|
||||
}
|
||||
public static int operator<=>(Entry lhs, Entry rhs)
|
||||
{
|
||||
return lhs.mFrame.CompareTo(rhs.mFrame);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Entry> mEntries;
|
||||
public Interpolator mInterpolator;
|
||||
public T mConstantValue;
|
||||
static EntryComparer sEntryComparer;
|
||||
public T mConstantValue;
|
||||
|
||||
public void SetValue(float frame, T value, out T oldValue, out bool isNewKeyframe)
|
||||
{
|
||||
|
@ -59,7 +55,7 @@ namespace Beefy.widgets
|
|||
entry.mFrame = frame;
|
||||
entry.mValue = value;
|
||||
|
||||
int index = mEntries.BinarySearch(entry, sEntryComparer);
|
||||
int index = mEntries.BinarySearch(entry);
|
||||
if (index >= 0)
|
||||
{
|
||||
isNewKeyframe = false;
|
||||
|
@ -80,7 +76,7 @@ namespace Beefy.widgets
|
|||
entry.mFrame = frame;
|
||||
entry.mValue = default(T);
|
||||
|
||||
int index = mEntries.BinarySearch(entry, sEntryComparer);
|
||||
int index = mEntries.BinarySearch(entry);
|
||||
mEntries.RemoveAt(index);
|
||||
}
|
||||
|
||||
|
@ -105,14 +101,11 @@ namespace Beefy.widgets
|
|||
{
|
||||
if ((mEntries == null) || (mEntries.Count == 0))
|
||||
return mConstantValue;
|
||||
|
||||
if (sEntryComparer == null)
|
||||
sEntryComparer = new EntryComparer();
|
||||
|
||||
Entry find;
|
||||
find.mValue = default(T);
|
||||
find.mFrame = frame;
|
||||
int index = mEntries.BinarySearch(find, sEntryComparer);
|
||||
int index = mEntries.BinarySearch(find);
|
||||
if (index >= 0)
|
||||
return mEntries[index].mValue;
|
||||
|
||||
|
|
|
@ -43,16 +43,16 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
public static int BinarySearch<T>(T* arr, int idx, int length, T value) where T : IComparable<T>
|
||||
public static int BinarySearch<T>(T* arr, int length, T value) where T : IOpComparable
|
||||
{
|
||||
int lo = idx;
|
||||
int hi = idx + length - 1;
|
||||
int lo = 0;
|
||||
int hi = length - 1;
|
||||
|
||||
while (lo <= hi)
|
||||
{
|
||||
int i = (lo + hi) / 2;
|
||||
T midVal = arr[i];
|
||||
int c = midVal.CompareTo(value);
|
||||
int c = midVal <=> value;
|
||||
if (c == 0) return i;
|
||||
if (c < 0)
|
||||
lo = i + 1;
|
||||
|
@ -62,16 +62,28 @@ namespace System
|
|||
return ~lo;
|
||||
}
|
||||
|
||||
public static int BinarySearch<T>(T* arr, int idx, int length, T value, IComparer<T> comp)
|
||||
public static int BinarySearch<T>(T[] arr, T value) where T : IOpComparable
|
||||
{
|
||||
int lo = idx;
|
||||
int hi = idx + length - 1;
|
||||
return BinarySearch(&arr.[Friend]GetRef(0), arr.mLength, value);
|
||||
}
|
||||
|
||||
public static int BinarySearch<T>(T[] arr, int idx, int length, T value) where T : IOpComparable
|
||||
{
|
||||
Debug.Assert((uint)idx <= (uint)arr.mLength);
|
||||
Debug.Assert(idx + length <= arr.mLength);
|
||||
return BinarySearch(&arr.[Friend]GetRef(idx), length, value);
|
||||
}
|
||||
|
||||
public static int BinarySearch<T>(T* arr, int length, T value, delegate int(T lhs, T rhs) comp)
|
||||
{
|
||||
int lo = 0;
|
||||
int hi = length - 1;
|
||||
|
||||
while (lo <= hi)
|
||||
{
|
||||
int i = (lo + hi) / 2;
|
||||
T midVal = arr[i];
|
||||
int c = comp.Compare(midVal, value);
|
||||
int c = comp(midVal, value);
|
||||
if (c == 0) return i;
|
||||
if (c < 0)
|
||||
lo = i + 1;
|
||||
|
@ -81,6 +93,18 @@ namespace System
|
|||
return ~lo;
|
||||
}
|
||||
|
||||
public static int BinarySearch<T>(T[] arr, T value, delegate int(T lhs, T rhs) comp)
|
||||
{
|
||||
return BinarySearch(&arr.[Friend]GetRef(0), arr.mLength, value, comp);
|
||||
}
|
||||
|
||||
public static int BinarySearch<T>(T[] arr, int idx, int length, T value, delegate int(T lhs, T rhs) comp)
|
||||
{
|
||||
Debug.Assert((uint)idx <= (uint)arr.mLength);
|
||||
Debug.Assert(idx + length <= arr.mLength);
|
||||
return BinarySearch(&arr.[Friend]GetRef(idx), length, value, comp);
|
||||
}
|
||||
|
||||
public static void Clear<T>(T[] arr, int idx, int length)
|
||||
{
|
||||
for (int i = idx; i < idx + length; i++)
|
||||
|
@ -92,12 +116,12 @@ namespace System
|
|||
if (((Object)arrayTo == (Object)arrayFrom) && (dstOffset > srcOffset))
|
||||
{
|
||||
for (int i = length - 1; i >= 0; i--)
|
||||
arrayTo.getRef(i + dstOffset) = (T2)arrayFrom.getRef(i + srcOffset);
|
||||
arrayTo.[Friend]GetRef(i + dstOffset) = (T2)arrayFrom.[Friend]GetRef(i + srcOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
arrayTo.getRef(i + dstOffset) = (T2)arrayFrom.getRef(i + srcOffset);
|
||||
arrayTo.[Friend]GetRef(i + dstOffset) = (T2)arrayFrom.[Friend]GetRef(i + srcOffset);
|
||||
}
|
||||
|
||||
public static void Sort<T>(T[] array, Comparison<T> comp)
|
||||
|
@ -129,13 +153,13 @@ namespace System
|
|||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRef(int idx)
|
||||
ref T GetRef(int idx)
|
||||
{
|
||||
return ref (&mFirstElement)[idx];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRefChecked(int idx)
|
||||
ref T GetRefChecked(int idx)
|
||||
{
|
||||
if ((uint)idx >= (uint)mLength)
|
||||
Internal.ThrowIndexOutOfRange(1);
|
||||
|
@ -168,7 +192,7 @@ namespace System
|
|||
public void CopyTo(T[] arrayTo)
|
||||
{
|
||||
Debug.Assert(arrayTo.mLength >= mLength);
|
||||
Internal.MemCpy(&arrayTo.getRef(0), &getRef(0), strideof(T) * mLength, alignof(T));
|
||||
Internal.MemCpy(&arrayTo.GetRef(0), &GetRef(0), strideof(T) * mLength, alignof(T));
|
||||
}
|
||||
|
||||
public void CopyTo(T[] arrayTo, int srcOffset, int dstOffset, int length)
|
||||
|
@ -176,7 +200,7 @@ namespace System
|
|||
Debug.Assert(length >= 0);
|
||||
Debug.Assert((uint)srcOffset + (uint)length <= (uint)mLength);
|
||||
Debug.Assert((uint)dstOffset + (uint)length <= (uint)arrayTo.mLength);
|
||||
Internal.MemCpy(&arrayTo.getRef(dstOffset), &getRef(srcOffset), strideof(T) * length, alignof(T));
|
||||
Internal.MemCpy(&arrayTo.GetRef(dstOffset), &GetRef(srcOffset), strideof(T) * length, alignof(T));
|
||||
}
|
||||
|
||||
public void CopyTo<T2>(T2[] arrayTo, int srcOffset, int dstOffset, int length) where T2 : var
|
||||
|
@ -188,12 +212,12 @@ namespace System
|
|||
if (((Object)arrayTo == (Object)this) && (dstOffset > srcOffset))
|
||||
{
|
||||
for (int i = length - 1; i >= 0; i--)
|
||||
arrayTo.getRef(i + dstOffset) = (T2)getRef(i + srcOffset);
|
||||
arrayTo.GetRef(i + dstOffset) = (T2)GetRef(i + srcOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
arrayTo.getRef(i + dstOffset) = (T2)getRef(i + srcOffset);
|
||||
arrayTo.GetRef(i + dstOffset) = (T2)GetRef(i + srcOffset);
|
||||
}
|
||||
|
||||
public Span<T>.Enumerator GetEnumerator()
|
||||
|
@ -352,19 +376,19 @@ namespace System
|
|||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRef(int idx)
|
||||
public ref T GetRef(int idx)
|
||||
{
|
||||
return ref (&mFirstElement)[idx];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRef(int idx0, int idx1, int idx2)
|
||||
public ref T GetRef(int idx0, int idx1, int idx2)
|
||||
{
|
||||
return ref (&mFirstElement)[(idx0*mLength1 + idx1)*mLength2 + idx2];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRefChecked(int idx)
|
||||
public ref T GetRefChecked(int idx)
|
||||
{
|
||||
if ((uint)idx >= (uint)mLength)
|
||||
Internal.ThrowIndexOutOfRange(1);
|
||||
|
@ -372,7 +396,7 @@ namespace System
|
|||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRefChecked(int idx0, int idx1, int idx2)
|
||||
public ref T GetRefChecked(int idx0, int idx1, int idx2)
|
||||
{
|
||||
int idx = (idx0*mLength1 + idx1)*mLength2 + idx2;
|
||||
if (((uint)idx >= (uint)mLength) ||
|
||||
|
@ -471,19 +495,19 @@ namespace System
|
|||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRef(int idx)
|
||||
public ref T GetRef(int idx)
|
||||
{
|
||||
return ref (&mFirstElement)[idx];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRef(int idx0, int idx1, int idx2, int idx3)
|
||||
public ref T GetRef(int idx0, int idx1, int idx2, int idx3)
|
||||
{
|
||||
return ref (&mFirstElement)[((idx0*mLength1 + idx1)*mLength2 + idx2)*mLength3 + idx3];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRefChecked(int idx)
|
||||
public ref T GetRefChecked(int idx)
|
||||
{
|
||||
if ((uint)idx >= (uint)mLength)
|
||||
Internal.ThrowIndexOutOfRange(1);
|
||||
|
@ -491,7 +515,7 @@ namespace System
|
|||
}
|
||||
|
||||
[Inline]
|
||||
public ref T getRefChecked(int idx0, int idx1, int idx2, int idx3)
|
||||
public ref T GetRefChecked(int idx0, int idx1, int idx2, int idx3)
|
||||
{
|
||||
int idx = ((idx0*mLength1 + idx1)*mLength2 + idx2)*mLength3 + idx3;
|
||||
if (((uint)idx >= (uint)mLength) ||
|
||||
|
|
|
@ -588,15 +588,6 @@ namespace System.Collections.Generic
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Searches a section of the list for a given element using a binary search
|
||||
/// algorithm. Elements of the list are compared to the search value using
|
||||
/// the given IComparer interface. If comparer is null, elements of
|
||||
/// the list are compared to the search value using the IComparable
|
||||
/// interface, which in that case must be implemented by all elements of the
|
||||
/// list and the given search value. This method assumes that the given
|
||||
/// section of the list is already sorted; if this is not the case, the
|
||||
/// result will be incorrect.
|
||||
///
|
||||
/// The method returns the index of the given value in the list. If the
|
||||
/// list does not contain the given value, the method returns a negative
|
||||
/// integer. The bitwise complement operator (~) can be applied to a
|
||||
|
@ -609,15 +600,16 @@ namespace System.Collections.Generic
|
|||
/// search.
|
||||
///
|
||||
/// @brief Searches a section of the list for a given element using a binary search algorithm.
|
||||
public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
|
||||
public int BinarySearch(T item, delegate int(T lhs, T rhs) comparer)
|
||||
{
|
||||
return (int_cosize)Array.BinarySearch(mItems, index, count, item, comparer);
|
||||
return Array.BinarySearch(mItems, Count, item, comparer);
|
||||
}
|
||||
|
||||
public int_cosize BinarySearch(T item, IComparer<T> comparer)
|
||||
public int BinarySearch(int index, int count, T item, delegate int(T lhs, T rhs) comparer)
|
||||
{
|
||||
//Contract.Ensures(Contract.Result<int>() <= Count);
|
||||
return (int_cosize)BinarySearch(0, Count, item, comparer);
|
||||
Debug.Assert((uint)index <= (uint)mSize);
|
||||
Debug.Assert(index + count <= mSize);
|
||||
return (int)Array.BinarySearch(mItems + index, count, item, comparer);
|
||||
}
|
||||
|
||||
public static operator Span<T>(List<T> list)
|
||||
|
@ -775,9 +767,16 @@ namespace System.Collections.Generic
|
|||
|
||||
extension List<T> where T : IOpComparable
|
||||
{
|
||||
public int_cosize BinarySearch(T item)
|
||||
public int BinarySearch(T item)
|
||||
{
|
||||
return (int_cosize)BinarySearch(0, Count, item, scope CompareWrapper<T>());
|
||||
return (int)Array.BinarySearch(mItems, Count, item);
|
||||
}
|
||||
|
||||
public int BinarySearch(int index, int count, T item)
|
||||
{
|
||||
Debug.Assert((uint)index <= (uint)mSize);
|
||||
Debug.Assert(index + count <= mSize);
|
||||
return (int)Array.BinarySearch(mItems + index, count, item);
|
||||
}
|
||||
|
||||
public void Sort()
|
||||
|
|
|
@ -1,23 +1,5 @@
|
|||
namespace System
|
||||
{
|
||||
interface IComparable<T>
|
||||
{
|
||||
int32 CompareTo(T other);
|
||||
}
|
||||
|
||||
public interface IComparer<T>
|
||||
{
|
||||
int Compare(T x, T y);
|
||||
}
|
||||
|
||||
public class CompareWrapper<T> : IComparer<T> where T : IOpComparable
|
||||
{
|
||||
public int Compare(T x, T y)
|
||||
{
|
||||
return x <=> y;
|
||||
}
|
||||
}
|
||||
|
||||
interface INumeric
|
||||
{
|
||||
static Self operator+(Self lhs, Self rhs);
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace System
|
|||
|
||||
public this(T[] array)
|
||||
{
|
||||
mPtr = &array.getRef(0);
|
||||
mPtr = &array.[Friend]GetRef(0);
|
||||
mLength = array.[Friend]mLength;
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ namespace System
|
|||
|
||||
public this(T[] array)
|
||||
{
|
||||
mPtr = &array.getRef(0);
|
||||
mPtr = &array.[Friend]GetRef(0);
|
||||
#if BF_OPTSPAN_LENGTH
|
||||
mLength = array.[Friend]mLength;
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue