[algs/array] Consolidate the last two bsearch implementations!
Yay! Seems to work.
This commit is contained in:
parent
ed35dea8c0
commit
48eef2724c
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue