libc: Add bsearch (with a test!!)

This commit is contained in:
apio 2022-11-06 17:34:35 +01:00
parent 1025248cc7
commit c6ce7a5358
4 changed files with 53 additions and 3 deletions

View File

@ -116,7 +116,10 @@ extern "C"
/* Sorts the array pointed to by base of nmemb items of the specified size using the comparison function compar. */
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented.
/* Searches the sorted array base of nmemb items of the specified size for the given key using the comparison
* function compar. */
void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
int (*compar)(const void*, const void*));
size_t mbstowcs(wchar_t* dest, const char* src,
size_t n); // Not implemented.

View File

@ -122,6 +122,26 @@ static void quicksort(void* base, size_t start, size_t end, size_t size, int (*c
}
}
void* binary_search(const void* key, const void* base, size_t start, size_t end, size_t size,
int (*compar)(const void*, const void*))
{
auto atindex = [&base, &size](size_t index) { return (const void*)((const char*)base + (index * size)); };
if (end >= start)
{
size_t middle = start + (end - start) / 2;
int rc = compar(atindex(middle), key);
if (rc == 0) return const_cast<void*>(atindex(middle)); // we found it!!
if (rc < 0) return binary_search(key, base, middle + 1, end, size, compar);
return binary_search(key, base, start, middle - 1, size, compar);
}
return NULL;
}
extern "C"
{
__lc_noreturn void abort()
@ -225,9 +245,9 @@ extern "C"
quicksort(base, 0, nmemb - 1, size, compar);
}
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*))
void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*))
{
NOT_IMPLEMENTED("bsearch");
return binary_search(key, base, 0, nmemb - 1, size, compar);
}
size_t mbstowcs(wchar_t*, const char*, size_t)

View File

@ -26,6 +26,7 @@ DEFINE_TEST(malloc);
DEFINE_TEST(calloc);
DEFINE_TEST(mktemp);
DEFINE_TEST(qsort);
DEFINE_TEST(bsearch);
int main()
{
@ -55,4 +56,5 @@ int main()
RUN_TEST(calloc);
RUN_TEST(mktemp);
RUN_TEST(qsort);
RUN_TEST(bsearch);
}

View File

@ -207,3 +207,28 @@ DEFINE_TEST(qsort)
TEST_SUCCESS();
}
DEFINE_TEST(bsearch)
{
START_TEST(bsearch);
const char sorted[] = "abcdefjkl";
char key = 'j';
char* ptr = bsearch(&key, sorted, 9, sizeof(char), compare_char); // try with sorted array first
EXPECT_EQ(*ptr, 'j');
EXPECT_EQ(ptr, &sorted[6]);
int unsorted[] = {1500, 45, 3, 11, 41, 90, 6, 32, 5, 76};
qsort(unsorted, 10, sizeof(int), compare_int);
int key2 = 90;
int* ptr2 = bsearch(&key2, unsorted, 10, sizeof(int), compare_int);
EXPECT_EQ(*ptr2, 90);
EXPECT_EQ(ptr2, &unsorted[8]);
TEST_SUCCESS();
}