Code review my binary search! It isn't supposed to be superfast or anything. It's optimized for clarity and only sorts arrays of pointers. Also in the same style is my quicksort code review question: Yet another quicksort.
/*
used as the base case of bsearch.
*/
static void const* misc_bsearch_linear(void const** A, void const** Z, void const* K, bool (*cmp)(void const*, void const*))
{
/*
burn forward while *A < K. if there is anything left, it will have
to be that *A >= K.
*/
while ((A < Z) && cmp(*A, K)) A++;
/*
if there is nothing left, we're done.
*/
if (!(A < Z)) return NULL;
/*
now we know *A >= K.
*/
{
if (cmp(K, *A)) {
/* when K < *A */
/* this means *A > K, so no dice */
return NULL;
} else {
/* when K >= *A */
/* this means *A == K, so return it */
return *A;
}
}
}
static void const* misc_bsearch_internal(void const** A, void const** Z, void const* K, bool (*cmp)(void const*, void const*))
{
/*
must stop loop when there are 3 or fewer elements, otherwise it
could go on forever in the bottom case.
*/
while ((Z - A) > 3) {
void const** M = (A + ((Z - A) >> 1));
if (cmp(*M, K)) {
/* when *M < K */
A = M + 1;
} else {
/* when *M >= K */
Z = M + 1;
}
}
/*
we're down to at most 3 elements, to downgrade to linear search to
finish up.
*/
return misc_bsearch_linear(A, Z, K, cmp);
}
/*
cmp should return true iff [arg1] < [arg2] (strictly).
*/
static INLINE void const* misc_bsearch(void const** A, uintptr_t L, void const* K, bool (*cmp)(void const*, void const*))
{
return misc_bsearch_internal(A, (A + L), K, cmp);
}
#define MISC_BSEARCH_VARIANT(s, t) \
static INLINE t* misc_bsearch_##s(t** A, uintptr_t L, t const* K, bool (*cmp)(t const*, t const*)) \
{ \
return ((t*)(misc_bsearch(((void const**)(A)), L, K, ((bool (*)(void const*, void const*))(cmp))))); \
}