mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 12:02:21 +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 delegate T Interpolator(T from, T to, float pct);
|
||||||
|
|
||||||
public struct Entry
|
public struct Entry : IOpComparable
|
||||||
{
|
{
|
||||||
public float mFrame;
|
public float mFrame;
|
||||||
public T mValue;
|
public T mValue;
|
||||||
|
@ -30,20 +30,16 @@ namespace Beefy.widgets
|
||||||
{
|
{
|
||||||
return ((val1.mFrame == val2.mFrame) && (val1.mValue == val2.mValue));
|
return ((val1.mFrame == val2.mFrame) && (val1.mValue == val2.mValue));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class EntryComparer : IComparer<Entry>
|
public static int operator<=>(Entry lhs, Entry rhs)
|
||||||
{
|
{
|
||||||
public int Compare(Entry ent1, Entry ent2)
|
return lhs.mFrame.CompareTo(rhs.mFrame);
|
||||||
{
|
|
||||||
return ent1.mFrame.CompareTo(ent2.mFrame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Entry> mEntries;
|
public List<Entry> mEntries;
|
||||||
public Interpolator mInterpolator;
|
public Interpolator mInterpolator;
|
||||||
public T mConstantValue;
|
public T mConstantValue;
|
||||||
static EntryComparer sEntryComparer;
|
|
||||||
|
|
||||||
public void SetValue(float frame, T value, out T oldValue, out bool isNewKeyframe)
|
public void SetValue(float frame, T value, out T oldValue, out bool isNewKeyframe)
|
||||||
{
|
{
|
||||||
|
@ -59,7 +55,7 @@ namespace Beefy.widgets
|
||||||
entry.mFrame = frame;
|
entry.mFrame = frame;
|
||||||
entry.mValue = value;
|
entry.mValue = value;
|
||||||
|
|
||||||
int index = mEntries.BinarySearch(entry, sEntryComparer);
|
int index = mEntries.BinarySearch(entry);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
isNewKeyframe = false;
|
isNewKeyframe = false;
|
||||||
|
@ -80,7 +76,7 @@ namespace Beefy.widgets
|
||||||
entry.mFrame = frame;
|
entry.mFrame = frame;
|
||||||
entry.mValue = default(T);
|
entry.mValue = default(T);
|
||||||
|
|
||||||
int index = mEntries.BinarySearch(entry, sEntryComparer);
|
int index = mEntries.BinarySearch(entry);
|
||||||
mEntries.RemoveAt(index);
|
mEntries.RemoveAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +102,10 @@ namespace Beefy.widgets
|
||||||
if ((mEntries == null) || (mEntries.Count == 0))
|
if ((mEntries == null) || (mEntries.Count == 0))
|
||||||
return mConstantValue;
|
return mConstantValue;
|
||||||
|
|
||||||
if (sEntryComparer == null)
|
|
||||||
sEntryComparer = new EntryComparer();
|
|
||||||
|
|
||||||
Entry find;
|
Entry find;
|
||||||
find.mValue = default(T);
|
find.mValue = default(T);
|
||||||
find.mFrame = frame;
|
find.mFrame = frame;
|
||||||
int index = mEntries.BinarySearch(find, sEntryComparer);
|
int index = mEntries.BinarySearch(find);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
return mEntries[index].mValue;
|
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 lo = 0;
|
||||||
int hi = idx + length - 1;
|
int hi = length - 1;
|
||||||
|
|
||||||
while (lo <= hi)
|
while (lo <= hi)
|
||||||
{
|
{
|
||||||
int i = (lo + hi) / 2;
|
int i = (lo + hi) / 2;
|
||||||
T midVal = arr[i];
|
T midVal = arr[i];
|
||||||
int c = midVal.CompareTo(value);
|
int c = midVal <=> value;
|
||||||
if (c == 0) return i;
|
if (c == 0) return i;
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
lo = i + 1;
|
lo = i + 1;
|
||||||
|
@ -62,16 +62,28 @@ namespace System
|
||||||
return ~lo;
|
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;
|
return BinarySearch(&arr.[Friend]GetRef(0), arr.mLength, value);
|
||||||
int hi = idx + length - 1;
|
}
|
||||||
|
|
||||||
|
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)
|
while (lo <= hi)
|
||||||
{
|
{
|
||||||
int i = (lo + hi) / 2;
|
int i = (lo + hi) / 2;
|
||||||
T midVal = arr[i];
|
T midVal = arr[i];
|
||||||
int c = comp.Compare(midVal, value);
|
int c = comp(midVal, value);
|
||||||
if (c == 0) return i;
|
if (c == 0) return i;
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
lo = i + 1;
|
lo = i + 1;
|
||||||
|
@ -81,6 +93,18 @@ namespace System
|
||||||
return ~lo;
|
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)
|
public static void Clear<T>(T[] arr, int idx, int length)
|
||||||
{
|
{
|
||||||
for (int i = idx; i < idx + length; i++)
|
for (int i = idx; i < idx + length; i++)
|
||||||
|
@ -92,12 +116,12 @@ namespace System
|
||||||
if (((Object)arrayTo == (Object)arrayFrom) && (dstOffset > srcOffset))
|
if (((Object)arrayTo == (Object)arrayFrom) && (dstOffset > srcOffset))
|
||||||
{
|
{
|
||||||
for (int i = length - 1; i >= 0; i--)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
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)
|
public static void Sort<T>(T[] array, Comparison<T> comp)
|
||||||
|
@ -129,13 +153,13 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public ref T getRef(int idx)
|
ref T GetRef(int idx)
|
||||||
{
|
{
|
||||||
return ref (&mFirstElement)[idx];
|
return ref (&mFirstElement)[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public ref T getRefChecked(int idx)
|
ref T GetRefChecked(int idx)
|
||||||
{
|
{
|
||||||
if ((uint)idx >= (uint)mLength)
|
if ((uint)idx >= (uint)mLength)
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
Internal.ThrowIndexOutOfRange(1);
|
||||||
|
@ -168,7 +192,7 @@ namespace System
|
||||||
public void CopyTo(T[] arrayTo)
|
public void CopyTo(T[] arrayTo)
|
||||||
{
|
{
|
||||||
Debug.Assert(arrayTo.mLength >= mLength);
|
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)
|
public void CopyTo(T[] arrayTo, int srcOffset, int dstOffset, int length)
|
||||||
|
@ -176,7 +200,7 @@ namespace System
|
||||||
Debug.Assert(length >= 0);
|
Debug.Assert(length >= 0);
|
||||||
Debug.Assert((uint)srcOffset + (uint)length <= (uint)mLength);
|
Debug.Assert((uint)srcOffset + (uint)length <= (uint)mLength);
|
||||||
Debug.Assert((uint)dstOffset + (uint)length <= (uint)arrayTo.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
|
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))
|
if (((Object)arrayTo == (Object)this) && (dstOffset > srcOffset))
|
||||||
{
|
{
|
||||||
for (int i = length - 1; i >= 0; i--)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
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()
|
public Span<T>.Enumerator GetEnumerator()
|
||||||
|
@ -352,19 +376,19 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public ref T getRef(int idx)
|
public ref T GetRef(int idx)
|
||||||
{
|
{
|
||||||
return ref (&mFirstElement)[idx];
|
return ref (&mFirstElement)[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[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];
|
return ref (&mFirstElement)[(idx0*mLength1 + idx1)*mLength2 + idx2];
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public ref T getRefChecked(int idx)
|
public ref T GetRefChecked(int idx)
|
||||||
{
|
{
|
||||||
if ((uint)idx >= (uint)mLength)
|
if ((uint)idx >= (uint)mLength)
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
Internal.ThrowIndexOutOfRange(1);
|
||||||
|
@ -372,7 +396,7 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[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;
|
int idx = (idx0*mLength1 + idx1)*mLength2 + idx2;
|
||||||
if (((uint)idx >= (uint)mLength) ||
|
if (((uint)idx >= (uint)mLength) ||
|
||||||
|
@ -471,19 +495,19 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public ref T getRef(int idx)
|
public ref T GetRef(int idx)
|
||||||
{
|
{
|
||||||
return ref (&mFirstElement)[idx];
|
return ref (&mFirstElement)[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[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];
|
return ref (&mFirstElement)[((idx0*mLength1 + idx1)*mLength2 + idx2)*mLength3 + idx3];
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public ref T getRefChecked(int idx)
|
public ref T GetRefChecked(int idx)
|
||||||
{
|
{
|
||||||
if ((uint)idx >= (uint)mLength)
|
if ((uint)idx >= (uint)mLength)
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
Internal.ThrowIndexOutOfRange(1);
|
||||||
|
@ -491,7 +515,7 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[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;
|
int idx = ((idx0*mLength1 + idx1)*mLength2 + idx2)*mLength3 + idx3;
|
||||||
if (((uint)idx >= (uint)mLength) ||
|
if (((uint)idx >= (uint)mLength) ||
|
||||||
|
|
|
@ -588,15 +588,6 @@ namespace System.Collections.Generic
|
||||||
return false;
|
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
|
/// 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
|
/// list does not contain the given value, the method returns a negative
|
||||||
/// integer. The bitwise complement operator (~) can be applied to a
|
/// integer. The bitwise complement operator (~) can be applied to a
|
||||||
|
@ -609,15 +600,16 @@ namespace System.Collections.Generic
|
||||||
/// search.
|
/// search.
|
||||||
///
|
///
|
||||||
/// @brief Searches a section of the list for a given element using a binary search algorithm.
|
/// @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);
|
Debug.Assert((uint)index <= (uint)mSize);
|
||||||
return (int_cosize)BinarySearch(0, Count, item, comparer);
|
Debug.Assert(index + count <= mSize);
|
||||||
|
return (int)Array.BinarySearch(mItems + index, count, item, comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static operator Span<T>(List<T> list)
|
public static operator Span<T>(List<T> list)
|
||||||
|
@ -775,9 +767,16 @@ namespace System.Collections.Generic
|
||||||
|
|
||||||
extension List<T> where T : IOpComparable
|
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()
|
public void Sort()
|
||||||
|
|
|
@ -1,23 +1,5 @@
|
||||||
namespace System
|
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
|
interface INumeric
|
||||||
{
|
{
|
||||||
static Self operator+(Self lhs, Self rhs);
|
static Self operator+(Self lhs, Self rhs);
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace System
|
||||||
|
|
||||||
public this(T[] array)
|
public this(T[] array)
|
||||||
{
|
{
|
||||||
mPtr = &array.getRef(0);
|
mPtr = &array.[Friend]GetRef(0);
|
||||||
mLength = array.[Friend]mLength;
|
mLength = array.[Friend]mLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ namespace System
|
||||||
|
|
||||||
public this(T[] array)
|
public this(T[] array)
|
||||||
{
|
{
|
||||||
mPtr = &array.getRef(0);
|
mPtr = &array.[Friend]GetRef(0);
|
||||||
#if BF_OPTSPAN_LENGTH
|
#if BF_OPTSPAN_LENGTH
|
||||||
mLength = array.[Friend]mLength;
|
mLength = array.[Friend]mLength;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1857,11 +1857,18 @@ void BfAutoComplete::CheckInvocation(BfAstNode* invocationNode, BfTokenNode* ope
|
||||||
target = memberTarget->mMemberName;
|
target = memberTarget->mMemberName;
|
||||||
}
|
}
|
||||||
else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(target))
|
else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(target))
|
||||||
|
{
|
||||||
|
if (qualifiedTypeRef->mRight != NULL)
|
||||||
target = qualifiedTypeRef->mRight;
|
target = qualifiedTypeRef->mRight;
|
||||||
|
}
|
||||||
else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
|
else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||||
|
{
|
||||||
|
if (qualifiedNameNode->mRight != NULL)
|
||||||
target = qualifiedNameNode->mRight;
|
target = qualifiedNameNode->mRight;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto attributedMember = BfNodeDynCast<BfAttributedIdentifierNode>(target))
|
if (auto attributedMember = BfNodeDynCast<BfAttributedIdentifierNode>(target))
|
||||||
|
if (attributedMember->mIdentifier != NULL)
|
||||||
target = attributedMember->mIdentifier;
|
target = attributedMember->mIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12122,11 +12122,6 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
|
auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
|
||||||
if (genericArg->IsVar())
|
if (genericArg->IsVar())
|
||||||
continue;
|
continue;
|
||||||
/*if (genericArg->IsPrimitiveType())
|
|
||||||
{
|
|
||||||
auto primType = (BfPrimitiveType*)genericArg;
|
|
||||||
genericArg = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
BfAstNode* paramSrc;
|
BfAstNode* paramSrc;
|
||||||
if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
|
if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
|
||||||
|
@ -12149,7 +12144,6 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance.mMethodInstance->mMethodDef->GetRefNode());
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance.mMethodInstance->mMethodDef->GetRefNode());
|
||||||
}
|
}
|
||||||
return BfModuleMethodInstance();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6471,6 +6471,20 @@ String BfModule::GenericParamSourceToString(const BfGenericParamSource & generic
|
||||||
|
|
||||||
bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs, BfError** errorOut)
|
bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs, BfError** errorOut)
|
||||||
{
|
{
|
||||||
|
Array<String> methodParamNameOverrides;
|
||||||
|
auto _TypeToString = [&](BfType* type)
|
||||||
|
{
|
||||||
|
if (methodParamNameOverrides.IsEmpty())
|
||||||
|
{
|
||||||
|
if (genericParamSource.mMethodInstance != NULL)
|
||||||
|
{
|
||||||
|
for (auto genericParam : genericParamSource.mMethodInstance->mMethodDef->mGenericParams)
|
||||||
|
methodParamNameOverrides.Add(genericParam->mName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TypeToString(type, &methodParamNameOverrides);
|
||||||
|
};
|
||||||
|
|
||||||
bool ignoreErrors = mIgnoreErrors || (errorOut == NULL) ||
|
bool ignoreErrors = mIgnoreErrors || (errorOut == NULL) ||
|
||||||
((genericParamSource.mMethodInstance == NULL) && (genericParamSource.mTypeInstance == NULL));
|
((genericParamSource.mMethodInstance == NULL) && (genericParamSource.mTypeInstance == NULL));
|
||||||
|
|
||||||
|
@ -6511,7 +6525,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("The type '%s' must be a value type in order to use it as parameter '%s' for '%s'",
|
*errorOut = Fail(StrFormat("The type '%s' must be a value type in order to use it as parameter '%s' for '%s'",
|
||||||
TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6520,7 +6534,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("The type '%s' must be a pointer type in order to use it as parameter '%s' for '%s'",
|
*errorOut = Fail(StrFormat("The type '%s' must be a pointer type in order to use it as parameter '%s' for '%s'",
|
||||||
TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6529,7 +6543,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("The type '%s' must be a reference type in order to use it as parameter '%s' for '%s'",
|
*errorOut = Fail(StrFormat("The type '%s' must be a reference type in order to use it as parameter '%s' for '%s'",
|
||||||
TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6539,7 +6553,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("The type '%s' must be a const value in order to use it as parameter '%s' for '%s'",
|
*errorOut = Fail(StrFormat("The type '%s' must be a const value in order to use it as parameter '%s' for '%s'",
|
||||||
TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6549,7 +6563,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("The value '%s' cannot be used for generic type parameter '%s' for '%s'",
|
*errorOut = Fail(StrFormat("The value '%s' cannot be used for generic type parameter '%s' for '%s'",
|
||||||
TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6591,7 +6605,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with const '%lld', does not fit into const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with const '%lld', does not fit into const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
||||||
constExprValueType->mValue.mInt64, TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
constExprValueType->mValue.mInt64, _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6599,7 +6613,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with integer const '%lld', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with integer const '%lld', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
||||||
constExprValueType->mValue.mInt64, TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
constExprValueType->mValue.mInt64, _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6611,7 +6625,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
ExactMinimalDoubleToStr(constExprValueType->mValue.mDouble, valStr);
|
ExactMinimalDoubleToStr(constExprValueType->mValue.mDouble, valStr);
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with floating point const '%s', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with floating point const '%s', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
||||||
valStr, TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
valStr, _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6670,8 +6684,8 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must derive from '%s'", genericParamInst->GetName().c_str(),
|
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must derive from '%s'", genericParamInst->GetName().c_str(),
|
||||||
TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(), TypeToString(convCheckConstraint).c_str(),
|
_TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(), TypeToString(convCheckConstraint).c_str(),
|
||||||
TypeToString(genericParamInst->mTypeConstraint).c_str()), checkArgTypeRef);
|
_TypeToString(genericParamInst->mTypeConstraint).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6685,7 +6699,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be concrete interface '%s' for '%s', must be a concrete type", genericParamInst->GetName().c_str(),
|
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be concrete interface '%s' for '%s', must be a concrete type", genericParamInst->GetName().c_str(),
|
||||||
TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6726,7 +6740,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must implement '%s'", genericParamInst->GetName().c_str(),
|
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must implement '%s'", genericParamInst->GetName().c_str(),
|
||||||
TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(), TypeToString(checkConstraint).c_str()), checkArgTypeRef);
|
_TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(), _TypeToString(checkConstraint).c_str()), checkArgTypeRef);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1438,7 +1438,7 @@ public:
|
||||||
BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false);
|
BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false);
|
||||||
BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external);
|
BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external);
|
||||||
void VariantToString(StringImpl& str, const BfVariant& variant);
|
void VariantToString(StringImpl& str, const BfVariant& variant);
|
||||||
StringT<128> TypeToString(BfType* resolvedType);
|
StringT<128> TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides = NULL);
|
||||||
StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodParamNameOverrides = NULL);
|
StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodParamNameOverrides = NULL);
|
||||||
void DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None, Array<String>* genericMethodParamNameOverrides = NULL);
|
void DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None, Array<String>* genericMethodParamNameOverrides = NULL);
|
||||||
String MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags = BfMethodNameFlag_ResolveGenericParamNames, BfTypeVector* methodGenericArgs = NULL);
|
String MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags = BfMethodNameFlag_ResolveGenericParamNames, BfTypeVector* methodGenericArgs = NULL);
|
||||||
|
|
|
@ -5478,6 +5478,15 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect
|
||||||
return CreateRefType(elementType, refType->mRefKind);
|
return CreateRefType(elementType, refType->mRefKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unspecializedType->IsPointer())
|
||||||
|
{
|
||||||
|
auto ptrType = (BfPointerType*)unspecializedType;
|
||||||
|
auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), methodGenericArguments, allowFail);
|
||||||
|
if (elementType == NULL)
|
||||||
|
return NULL;
|
||||||
|
return CreatePointerType(elementType);
|
||||||
|
}
|
||||||
|
|
||||||
if (unspecializedType->IsArray())
|
if (unspecializedType->IsArray())
|
||||||
{
|
{
|
||||||
auto arrayType = (BfArrayType*)unspecializedType;
|
auto arrayType = (BfArrayType*)unspecializedType;
|
||||||
|
@ -9274,7 +9283,6 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
"Unable to implicitly cast '%s' to '%s'";
|
"Unable to implicitly cast '%s' to '%s'";
|
||||||
|
|
||||||
String errStr = StrFormat(errStrF, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str());
|
String errStr = StrFormat(errStrF, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str());
|
||||||
printf("Err: %s\n", errStr.c_str());
|
|
||||||
auto error = Fail(errStr, srcNode);
|
auto error = Fail(errStr, srcNode);
|
||||||
if ((error != NULL) && (srcNode != NULL))
|
if ((error != NULL) && (srcNode != NULL))
|
||||||
{
|
{
|
||||||
|
@ -9807,14 +9815,14 @@ bool BfModule::IsTypeMoreSpecific(BfType* leftType, BfType* rightType)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringT<128> BfModule::TypeToString(BfType* resolvedType)
|
StringT<128> BfModule::TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides)
|
||||||
{
|
{
|
||||||
BfTypeNameFlags flags = BfTypeNameFlags_None;
|
BfTypeNameFlags flags = BfTypeNameFlags_None;
|
||||||
if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsUnspecializedTypeVariation()))
|
if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsUnspecializedTypeVariation()))
|
||||||
flags = BfTypeNameFlag_ResolveGenericParamNames;
|
flags = BfTypeNameFlag_ResolveGenericParamNames;
|
||||||
|
|
||||||
StringT<128> str;
|
StringT<128> str;
|
||||||
DoTypeToString(str, resolvedType, flags);
|
DoTypeToString(str, resolvedType, flags, genericMethodParamNameOverrides);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9956,8 +9964,10 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
str += ", ";
|
str += ", ";
|
||||||
auto paramDef = methodDef->mParams[paramIdx];
|
auto paramDef = methodDef->mParams[paramIdx];
|
||||||
BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
|
BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
|
||||||
if (delegateType->mIsUnspecializedTypeVariation)
|
|
||||||
innerFlags = (BfTypeNameFlags)(innerFlags & ~BfTypeNameFlag_ResolveGenericParamNames);
|
//TODO: Why was this necessary? It made some errors show incorrectly
|
||||||
|
// if (delegateType->mIsUnspecializedTypeVariation)
|
||||||
|
// innerFlags = (BfTypeNameFlags)(innerFlags & ~BfTypeNameFlag_ResolveGenericParamNames);
|
||||||
DoTypeToString(str, delegateType->mParams[paramIdx], innerFlags, genericMethodNameOverrides);
|
DoTypeToString(str, delegateType->mParams[paramIdx], innerFlags, genericMethodNameOverrides);
|
||||||
str += " ";
|
str += " ";
|
||||||
str += paramDef->mName;
|
str += paramDef->mName;
|
||||||
|
@ -10240,14 +10250,27 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
bool doResolveGenericParams = (typeNameFlags & BfTypeNameFlag_ResolveGenericParamNames) != 0;
|
bool doResolveGenericParams = (typeNameFlags & BfTypeNameFlag_ResolveGenericParamNames) != 0;
|
||||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
|
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
|
||||||
doResolveGenericParams = false;
|
doResolveGenericParams = false;
|
||||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation))
|
|
||||||
doResolveGenericParams = false;
|
|
||||||
|
|
||||||
auto genericParam = (BfGenericParamType*)resolvedType;
|
auto genericParam = (BfGenericParamType*)resolvedType;
|
||||||
|
if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
|
||||||
|
{
|
||||||
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation))
|
||||||
|
doResolveGenericParams = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!doResolveGenericParams)
|
if (!doResolveGenericParams)
|
||||||
{
|
{
|
||||||
if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
|
if (genericParam->mGenericParamKind == BfGenericParamKind_Method)
|
||||||
{
|
{
|
||||||
|
if (genericMethodNameOverrides != NULL)
|
||||||
|
{
|
||||||
|
BF_ASSERT(genericParam->mGenericParamIdx < genericMethodNameOverrides->mSize);
|
||||||
|
if (genericParam->mGenericParamIdx < genericMethodNameOverrides->mSize)
|
||||||
|
{
|
||||||
|
str += (*genericMethodNameOverrides)[genericParam->mGenericParamIdx];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
str += StrFormat("@M%d", genericParam->mGenericParamIdx);
|
str += StrFormat("@M%d", genericParam->mGenericParamIdx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2436,8 +2436,7 @@ BfTypeDef* BfSystem::FindTypeDefEx(const StringImpl& fullTypeName)
|
||||||
if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project)) &&
|
if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project)) &&
|
||||||
(!typeDef->mIsPartial))
|
(!typeDef->mIsPartial))
|
||||||
{
|
{
|
||||||
if (typeDef->mGenericParamDefs.size() != numGenericArgs)
|
if (typeDef->mGenericParamDefs.size() == numGenericArgs)
|
||||||
continue;
|
|
||||||
return typeDef;
|
return typeDef;
|
||||||
}
|
}
|
||||||
itr.MoveToNextHashMatch();
|
itr.MoveToNextHashMatch();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue