public static int BinarySearch(List <SharpLangEETypePtr> types, ref SharpLangTypeSearchKey key) { int start = 0; int end = types.Count - 1; while (start <= end) { int middle = start + ((end - start) >> 1); var compareResult = Compare(types[middle], ref key); if (compareResult == 0) { return(middle); } if (compareResult < 0) { start = middle + 1; } else { end = middle - 1; } } return(~start); }
public static unsafe int Compare(SharpLangEETypePtr x, ref SharpLangTypeSearchKey y) { // Order by kind var kindDiff = x.Value->GetKind() - y.Kind; if (kindDiff != 0) { return(kindDiff); } switch (x.Value->GetKind()) { case SharpLangEEType.Kind.TypeDef: { return(Compare(x.Value->TypeDefinition, y.TypeDefinition)); } case SharpLangEEType.Kind.Generics: { // Compare generic type definition var genericTypeComparison = Compare(x.Value->TypeDefinition, y.TypeDefinition); if (genericTypeComparison != 0) { return(genericTypeComparison); } // Compare generic argument list var xGenericArgument = (SharpLangEEType **)x.Value->GetElementType(); var yGenericArgumentIndex = 0; while (*xGenericArgument != null && yGenericArgumentIndex < y.GenericArguments.Length) { var genericArgumentComparison = Default.Compare(*xGenericArgument++, y.GenericArguments[yGenericArgumentIndex++].EEType); if (genericArgumentComparison != 0) { return(genericArgumentComparison); } } // If one list was longer than the other, use it if (*xGenericArgument != null) { return(1); } if (yGenericArgumentIndex < y.GenericArguments.Length) { return(-1); } // Generic types are the same return(0); } case SharpLangEEType.Kind.Array: case SharpLangEEType.Kind.Pointer: case SharpLangEEType.Kind.ByRef: { // Compare element types return(Default.Compare(x.Value->GetElementType(), y.ElementType.EEType)); } default: throw new ArgumentOutOfRangeException(); } }