1*32a50078SSiva Chandra Reddy //===-- Implementation of bsearch -----------------------------------------===// 2*32a50078SSiva Chandra Reddy // 3*32a50078SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*32a50078SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information. 5*32a50078SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*32a50078SSiva Chandra Reddy // 7*32a50078SSiva Chandra Reddy //===----------------------------------------------------------------------===// 8*32a50078SSiva Chandra Reddy 9*32a50078SSiva Chandra Reddy #include "src/stdlib/bsearch.h" 10*32a50078SSiva Chandra Reddy #include "src/__support/common.h" 11*32a50078SSiva Chandra Reddy 12*32a50078SSiva Chandra Reddy #include <stdint.h> 13*32a50078SSiva Chandra Reddy 14*32a50078SSiva Chandra Reddy namespace __llvm_libc { 15*32a50078SSiva Chandra Reddy 16*32a50078SSiva Chandra Reddy LLVM_LIBC_FUNCTION(void *, bsearch, 17*32a50078SSiva Chandra Reddy (const void *key, const void *array, size_t array_size, 18*32a50078SSiva Chandra Reddy size_t elem_size, 19*32a50078SSiva Chandra Reddy int (*compare)(const void *, const void *))) { 20*32a50078SSiva Chandra Reddy if (key == nullptr || array == nullptr || array_size == 0 || elem_size == 0) 21*32a50078SSiva Chandra Reddy return nullptr; 22*32a50078SSiva Chandra Reddy 23*32a50078SSiva Chandra Reddy while (array_size > 0) { 24*32a50078SSiva Chandra Reddy size_t mid = array_size / 2; 25*32a50078SSiva Chandra Reddy const void *elem = 26*32a50078SSiva Chandra Reddy reinterpret_cast<const uint8_t *>(array) + mid * elem_size; 27*32a50078SSiva Chandra Reddy int compare_result = compare(key, elem); 28*32a50078SSiva Chandra Reddy if (compare_result == 0) 29*32a50078SSiva Chandra Reddy return const_cast<void *>(elem); 30*32a50078SSiva Chandra Reddy 31*32a50078SSiva Chandra Reddy if (compare_result < 0) { 32*32a50078SSiva Chandra Reddy // This means that key is less than the element at |mid|. 33*32a50078SSiva Chandra Reddy // So, in the next iteration, we only compare elements less 34*32a50078SSiva Chandra Reddy // than mid. 35*32a50078SSiva Chandra Reddy array_size = mid; 36*32a50078SSiva Chandra Reddy } else { 37*32a50078SSiva Chandra Reddy // |mid| is strictly less than |array_size|. So, the below 38*32a50078SSiva Chandra Reddy // decrement in |array_size| will not lead to a wrap around. 39*32a50078SSiva Chandra Reddy array_size -= (mid + 1); 40*32a50078SSiva Chandra Reddy array = reinterpret_cast<const uint8_t *>(elem) + elem_size; 41*32a50078SSiva Chandra Reddy } 42*32a50078SSiva Chandra Reddy } 43*32a50078SSiva Chandra Reddy 44*32a50078SSiva Chandra Reddy return nullptr; 45*32a50078SSiva Chandra Reddy } 46*32a50078SSiva Chandra Reddy 47*32a50078SSiva Chandra Reddy } // namespace __llvm_libc 48