diff --git a/README.md b/README.md index 6e71095..17e2ffd 100644 --- a/README.md +++ b/README.md @@ -201,12 +201,16 @@ Creates an owning object for the specified range of bytes. The range should be s Creates an owning object from the given C string. The string should be safe to pass to `free(3)` function. Destination is assigned using `str_assign` semantics. -#### sorting +#### sorting and searching `void str_sort(const str_cmp_func cmp, str* const array, const size_t count)`
Sorts the given array of `str` objects. A number of typically used sorting functions is provided (see `str.h` file). +`const str* str_search(const str key, const str* const array, const size_t count)`
+Binary search for the given key. The input array must be sorted using `str_order_asc`. +Returns a pointer to the string matching the key, or NULL. + #### Memory allocation By default the library uses `malloc(3)` for memory allocations, and calls `abort(3)` if the allocation fails. This behaviour can be changed by hash-defining `STR_EXT_ALLOC` diff --git a/str.c b/str.c index 3d33520..7904eb8 100644 --- a/str.c +++ b/str.c @@ -326,4 +326,16 @@ void str_sort(const str_cmp_func cmp, str* const array, const size_t count) { if(array && cmp && count > 1) qsort(array, count, sizeof(array[0]), cmp); +} + +// searching +const str* str_search(const str key, const str* const array, const size_t count) +{ + if(!array || count == 0) + return NULL; + + if(count == 1) + return str_eq(key, array[0]) ? array : NULL; + + return bsearch(&key, array, count, sizeof(str), str_order_asc); } \ No newline at end of file diff --git a/str.h b/str.h index a57f856..bbff328 100644 --- a/str.h +++ b/str.h @@ -179,6 +179,9 @@ int str_order_desc_ci(const void* const s1, const void* const s2); // sort array of strings void str_sort(const str_cmp_func cmp, str* const array, const size_t count); +// searching +const str* str_search(const str key, const str* const array, const size_t count); + #ifdef __cplusplus } #endif diff --git a/str_test.c b/str_test.c index 777275c..31371ac 100644 --- a/str_test.c +++ b/str_test.c @@ -305,6 +305,21 @@ void test_sort_ci(void) assert(str_eq_ci(src[3], str_lit("aaa"))); } +static +void test_search(void) +{ + str src[] = { str_lit("z"), str_lit("zzz"), str_lit("aaa"), str_lit("bbb") }; + const size_t count = sizeof(src)/sizeof(src[0]); + + str_sort(str_order_asc, src, count); + + assert(str_search(src[0], src, count) == &src[0]); + assert(str_search(src[1], src, count) == &src[1]); + assert(str_search(src[2], src, count) == &src[2]); + assert(str_search(src[3], src, count) == &src[3]); + assert(str_search(str_lit("xxx"), src, count) == NULL); +} + int main(void) { // tests @@ -322,6 +337,7 @@ int main(void) test_composition(); test_sort(); test_sort_ci(); + test_search(); return puts("OK.") < 0; }