132a50078SSiva Chandra Reddy //===-- Implementation of bsearch -----------------------------------------===// 232a50078SSiva Chandra Reddy // 332a50078SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 432a50078SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 532a50078SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 632a50078SSiva Chandra Reddy // 732a50078SSiva Chandra Reddy //===----------------------------------------------------------------------===// 832a50078SSiva Chandra Reddy 932a50078SSiva Chandra Reddy #include "src/stdlib/bsearch.h" 1032a50078SSiva Chandra Reddy #include "src/__support/common.h" 11*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 1232a50078SSiva Chandra Reddy 1332a50078SSiva Chandra Reddy #include <stdint.h> 1432a50078SSiva Chandra Reddy 15*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 1632a50078SSiva Chandra Reddy 1732a50078SSiva Chandra Reddy LLVM_LIBC_FUNCTION(void *, bsearch, 1832a50078SSiva Chandra Reddy (const void *key, const void *array, size_t array_size, 1932a50078SSiva Chandra Reddy size_t elem_size, 2032a50078SSiva Chandra Reddy int (*compare)(const void *, const void *))) { 2132a50078SSiva Chandra Reddy if (key == nullptr || array == nullptr || array_size == 0 || elem_size == 0) 2232a50078SSiva Chandra Reddy return nullptr; 2332a50078SSiva Chandra Reddy 2432a50078SSiva Chandra Reddy while (array_size > 0) { 2532a50078SSiva Chandra Reddy size_t mid = array_size / 2; 2632a50078SSiva Chandra Reddy const void *elem = 2732a50078SSiva Chandra Reddy reinterpret_cast<const uint8_t *>(array) + mid * elem_size; 2832a50078SSiva Chandra Reddy int compare_result = compare(key, elem); 2932a50078SSiva Chandra Reddy if (compare_result == 0) 3032a50078SSiva Chandra Reddy return const_cast<void *>(elem); 3132a50078SSiva Chandra Reddy 3232a50078SSiva Chandra Reddy if (compare_result < 0) { 3332a50078SSiva Chandra Reddy // This means that key is less than the element at |mid|. 3432a50078SSiva Chandra Reddy // So, in the next iteration, we only compare elements less 3532a50078SSiva Chandra Reddy // than mid. 3632a50078SSiva Chandra Reddy array_size = mid; 3732a50078SSiva Chandra Reddy } else { 3832a50078SSiva Chandra Reddy // |mid| is strictly less than |array_size|. So, the below 3932a50078SSiva Chandra Reddy // decrement in |array_size| will not lead to a wrap around. 4032a50078SSiva Chandra Reddy array_size -= (mid + 1); 4132a50078SSiva Chandra Reddy array = reinterpret_cast<const uint8_t *>(elem) + elem_size; 4232a50078SSiva Chandra Reddy } 4332a50078SSiva Chandra Reddy } 4432a50078SSiva Chandra Reddy 4532a50078SSiva Chandra Reddy return nullptr; 4632a50078SSiva Chandra Reddy } 4732a50078SSiva Chandra Reddy 48*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 49