crossxtex/PlatformSupport/ClangBsearch.hpp

125 lines
5.2 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*------------------------------------------------------------------
* bsearch_s.c
*
* September 2017, Reini Urban
*
* Copyright (c) 2017 by Reini Urban
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*------------------------------------------------------------------
*/
#pragma once
#include <stdlib.h>
/**
* @def bsearch_s(key,base,nmemb,size,compar,context)
* @brief
* The \c bsearch_s function finds an element equal to element pointed to
* by key in an array pointed to by base. The array contains count elements
* of size bytes and must be partitioned with respect to key, that is, all
* the elements that compare less than must appear before all the elements
* that compare equal to, and those must appear before all the elements
* that compare greater than the key object. A fully sorted array satisfies
* these requirements. The elements are compared using function pointed to
* by comp. The behavior is undefined if the array is not already
* partitioned with respect to *key in ascending order according to the
* same criterion that compar uses.
*
* @remark SPECIFIED IN
* * C11 standard (ISO/IEC 9899:2011):
* K.3.6.3.1 The bsearch_s function (p: 608-609)
* http://en.cppreference.com/w/c/algorithm/bsearch
*
* @param[in] key pointer to the element to search for
* @param[in] base pointer to the array to examine
* @param[in] nmemb number of elements in the array
* @param[in] size size of each element in the array in bytes
* @param[in] compar comparison function which returns a negative integer
* value if the first argument is less than the second, a
* positive integer value if the first argument is greater
* than the second and zero if the arguments are equal. key
* is passed as the first argument, an element from the
* array as the second. The signature of the comparison
* function should be equivalent to the following: int
* cmp(const void *a, const void *b); The function must not
* modify the objects passed to it and must return
* consistent results when called for the same objects,
* regardless of their positions in the array.
* @param[in] context additional information (e.g., collating sequence), passed
* to compar as the third argument
*
* @pre key, base or compar shall not be a null pointer (unless nmemb is zero).
* @pre nmemb or size shall not be greater than RSIZE_MAX_MEM.
*
* If the array contains several elements that compar would indicate as
* equal to the element searched for, then it is unspecified which element the
* function will return as the result.
*
* @return Pointer to an element in the array that compares equal to *key, or
* null pointer if such element has not been found, or any run-time
* constraint violation.
*
* @note
* Despite the name, neither C nor POSIX standards require this function to
* be implemented using binary search or make any complexity guarantees.
* Unlike other bounds-checked functions, bsearch_s does not treat arrays
* of zero size as a runtime constraint violation and instead indicates
* element not found (the other function that accepts arrays of zero size
* is qsort_s).
*
* @retval NULL when not found or any error
*
* errno values:
* ESNULLP when key, base or compar are a NULL pointer, and nmemb is > 0
* ESLEMAX when nmemb or size > RSIZE_MAX_MEM
*
* @see
* qsort_s()
*/
static void *
bsearch_s(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar)(void *k, const void *key, const void *val),
void *context)
{
errno = 0;
while (nmemb > 0) {
void *ptry = (char *)base + size * (nmemb / 2);
int sign = compar(context, key, ptry);
if (!sign)
return ptry;
else if (nmemb == 1)
break;
else if (sign < 0) {
nmemb /= 2;
} else {
base = ptry;
nmemb -= nmemb / 2;
}
}
return NULL;
}