diff --git a/src/hb-algs.hh b/src/hb-algs.hh index ce17bd44d..edafeab3f 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -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 +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 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 -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 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) + int (*compar)(const void *_key, const void *_item) = _hb_cmp_method) { V* p; return hb_bsearch_impl (&p, key, base, nmemb, stride, compar) ? p : nullptr; diff --git a/src/hb-array.hh b/src/hb-array.hh index dfd8ed841..cca6f5165 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -297,33 +297,24 @@ struct hb_sorted_array_t : return bfind (x, &i) ? &this->arrayZ[i] : not_found; } template - 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); + *pos = p - this->arrayZ; + return ret; } template 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)) {