[algs/array] Consolidate the last two bsearch implementations!

Yay!  Seems to work.
This commit is contained in:
Behdad Esfahbod 2019-12-06 05:04:11 +00:00
parent ed35dea8c0
commit 48eef2724c
2 changed files with 28 additions and 34 deletions

View File

@ -637,11 +637,21 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
* Sort and search.
*/
template <typename K, typename V, typename ...Ts>
static int
_hb_cmp_method (const void *pkey, const void *pval, Ts... ds)
{
const K& key = * (const K*) pkey;
const V& val = * (const V*) pval;
return val.cmp (key, ds...);
}
template <typename V, typename K, typename ...Ts>
static inline bool
hb_bsearch_impl (V** out,
const K& key, V* base,
size_t nmemb, size_t stride,
const K& key,
V* base, size_t nmemb, size_t stride,
int (*compar)(const void *_key, const void *_item, Ts... _ds),
Ts... ds)
{
@ -666,25 +676,18 @@ hb_bsearch_impl (V** out,
return true;
}
}
*out = nullptr;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
*out = (V*) (((const char *) base) + (min * stride));
#pragma GCC diagnostic pop
return false;
}
template <typename K, typename V, typename ...Ts>
static int
_cmp_method (const void *pkey, const void *pval, Ts... ds)
{
const K& key = * (const K*) pkey;
const V& val = * (const V*) pval;
return val.cmp (key, ds...);
}
template <typename V, typename K>
static inline V*
hb_bsearch (const K& key, V* base,
size_t nmemb, size_t stride = sizeof (V),
int (*compar)(const void *_key, const void *_item) = _cmp_method<K, V>)
int (*compar)(const void *_key, const void *_item) = _hb_cmp_method<K, V>)
{
V* p;
return hb_bsearch_impl (&p, key, base, nmemb, stride, compar) ? p : nullptr;

View File

@ -297,33 +297,24 @@ struct hb_sorted_array_t :
return bfind (x, &i) ? &this->arrayZ[i] : not_found;
}
template <typename T>
bool bsearch_impl (const T &x, unsigned int *pos) const
bool bsearch_impl (const T &x, unsigned *pos) const
{
int min = 0, max = (int) this->length - 1;
const Type *array = this->arrayZ;
while (min <= max)
{
int mid = ((unsigned int) min + (unsigned int) max) / 2;
int c = array[mid].cmp (x);
if (c < 0)
max = mid - 1;
else if (c > 0)
min = mid + 1;
else
{
*pos = (unsigned) mid;
return true;
}
}
*pos = (unsigned) min;
return false;
Type* p;
bool ret = hb_bsearch_impl (&p,
x,
this->arrayZ,
this->length,
sizeof (Type),
_hb_cmp_method<T, Type>);
*pos = p - this->arrayZ;
return ret;
}
template <typename T>
bool bfind (const T &x, unsigned int *i = nullptr,
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
unsigned int to_store = (unsigned int) -1) const
{
unsigned int pos = 0;
unsigned pos;
if (bsearch_impl (x, &pos))
{