[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. * 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> template <typename V, typename K, typename ...Ts>
static inline bool static inline bool
hb_bsearch_impl (V** out, hb_bsearch_impl (V** out,
const K& key, V* base, const K& key,
size_t nmemb, size_t stride, V* base, size_t nmemb, size_t stride,
int (*compar)(const void *_key, const void *_item, Ts... _ds), int (*compar)(const void *_key, const void *_item, Ts... _ds),
Ts... ds) Ts... ds)
{ {
@ -666,25 +676,18 @@ hb_bsearch_impl (V** out,
return true; 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; 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> template <typename V, typename K>
static inline V* static inline V*
hb_bsearch (const K& key, V* base, hb_bsearch (const K& key, V* base,
size_t nmemb, size_t stride = sizeof (V), 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; V* p;
return hb_bsearch_impl (&p, key, base, nmemb, stride, compar) ? p : nullptr; 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; return bfind (x, &i) ? &this->arrayZ[i] : not_found;
} }
template <typename T> 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; Type* p;
const Type *array = this->arrayZ; bool ret = hb_bsearch_impl (&p,
while (min <= max) x,
{ this->arrayZ,
int mid = ((unsigned int) min + (unsigned int) max) / 2; this->length,
int c = array[mid].cmp (x); sizeof (Type),
if (c < 0) _hb_cmp_method<T, Type>);
max = mid - 1; *pos = p - this->arrayZ;
else if (c > 0) return ret;
min = mid + 1;
else
{
*pos = (unsigned) mid;
return true;
}
}
*pos = (unsigned) min;
return false;
} }
template <typename T> template <typename T>
bool bfind (const T &x, unsigned int *i = nullptr, bool bfind (const T &x, unsigned int *i = nullptr,
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
unsigned int to_store = (unsigned int) -1) const unsigned int to_store = (unsigned int) -1) const
{ {
unsigned int pos = 0; unsigned pos;
if (bsearch_impl (x, &pos)) if (bsearch_impl (x, &pos))
{ {