[algs] Streamline bsearch() API more towards hb_array_t::bsearch_impl()

Preparing to merge the two finally!
This commit is contained in:
Behdad Esfahbod 2019-12-06 03:35:24 +00:00
parent fd6df520a1
commit bd55d4b49f
9 changed files with 47 additions and 68 deletions

View File

@ -172,11 +172,7 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
const hb_aat_feature_mapping_t * const hb_aat_feature_mapping_t *
hb_aat_layout_find_feature_mapping (hb_tag_t tag) hb_aat_layout_find_feature_mapping (hb_tag_t tag)
{ {
return (const hb_aat_feature_mapping_t *) hb_bsearch (&tag, return hb_bsearch (tag, feature_mappings, ARRAY_LENGTH (feature_mappings));
feature_mappings,
ARRAY_LENGTH (feature_mappings),
sizeof (feature_mappings[0]),
hb_aat_feature_mapping_t::cmp);
} }
#endif #endif

View File

@ -39,14 +39,8 @@ struct hb_aat_feature_mapping_t
hb_aat_layout_feature_selector_t selectorToEnable; hb_aat_layout_feature_selector_t selectorToEnable;
hb_aat_layout_feature_selector_t selectorToDisable; hb_aat_layout_feature_selector_t selectorToDisable;
HB_INTERNAL static int cmp (const void *key_, const void *entry_) int cmp (hb_tag_t key) const
{ { return key < otFeatureTag ? -1 : key > otFeatureTag ? 1 : 0; }
hb_tag_t key = * (unsigned int *) key_;
const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_;
return key < entry->otFeatureTag ? -1 :
key > entry->otFeatureTag ? 1 :
0;
}
}; };
HB_INTERNAL const hb_aat_feature_mapping_t * HB_INTERNAL const hb_aat_feature_mapping_t *

View File

@ -636,25 +636,36 @@ 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 ...Ts>
static inline void * template <typename K, typename V, typename ...Ts>
hb_bsearch (const void *key, const void *base, static int
size_t nmemb, size_t size, _cmp_method (const void *pkey, const void *pval, Ts... ds)
int (*compar)(const void *_key, const void *_item, 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 V*
hb_bsearch (const K& key, V* base,
size_t nmemb, size_t stride = sizeof (V),
int (*compar)(const void *_key, const void *_item, Ts... _ds) = _cmp_method<K, V, Ts...>,
Ts... ds) Ts... ds)
{ {
int min = 0, max = (int) nmemb - 1; int min = 0, max = (int) nmemb - 1;
while (min <= max) while (min <= max)
{ {
int mid = ((unsigned int) min + (unsigned int) max) / 2; int mid = ((unsigned int) min + (unsigned int) max) / 2;
const void *p = (const void *) (((const char *) base) + (mid * size)); V* p = (V*) (((const char *) base) + (mid * stride));
int c = compar (key, p, ds...); int c = compar ((const void *) &key, (const void *) p, ds...);
if (c < 0) if (c < 0)
max = mid - 1; max = mid - 1;
else if (c > 0) else if (c > 0)
min = mid + 1; min = mid + 1;
else else
return (void *) p; return p;
} }
return nullptr; return nullptr;
} }

View File

@ -37,12 +37,8 @@
struct hb_ot_language_map_t struct hb_ot_language_map_t
{ {
static int cmp (const void *key, const void *item) int cmp (unsigned int key) const
{ { return key < code ? -1 : key > code ? +1 : 0; }
unsigned int a = * (unsigned int *) key;
unsigned int b = ((const hb_ot_language_map_t *) item)->code;
return a < b ? -1 : a > b ? +1 : 0;
}
uint16_t code; uint16_t code;
char lang[6]; char lang[6];
@ -433,12 +429,7 @@ _hb_ot_name_language_for (unsigned int code,
#ifdef HB_NO_OT_NAME_LANGUAGE #ifdef HB_NO_OT_NAME_LANGUAGE
return HB_LANGUAGE_INVALID; return HB_LANGUAGE_INVALID;
#endif #endif
const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) auto *entry = hb_bsearch (code, array, len);
hb_bsearch (&code,
array,
len,
sizeof (array[0]),
hb_ot_language_map_t::cmp);
if (entry) if (entry)
return hb_language_from_string (entry->lang, -1); return hb_language_from_string (entry->lang, -1);

View File

@ -281,16 +281,14 @@ struct name
this->table.destroy (); this->table.destroy ();
} }
int get_index (hb_ot_name_id_t name_id, int get_index (hb_ot_name_id_t name_id,
hb_language_t language, hb_language_t language,
unsigned int *width=nullptr) const unsigned int *width=nullptr) const
{ {
const hb_ot_name_entry_t key = {name_id, {0}, language}; const hb_ot_name_entry_t key = {name_id, {0}, language};
const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *) const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
hb_bsearch (&key,
(const hb_ot_name_entry_t *) this->names,
this->names.length, this->names.length,
sizeof (key), sizeof (hb_ot_name_entry_t),
_hb_ot_name_entry_cmp_key); _hb_ot_name_entry_cmp_key);
if (!entry) if (!entry)
return -1; return -1;

View File

@ -33,19 +33,8 @@ namespace OT {
struct OS2Range struct OS2Range
{ {
static int int cmp (hb_codepoint_t key) const
cmp (const void *_key, const void *_item) { return (key < start) ? -1 : key <= end ? 0 : +1; }
{
hb_codepoint_t cp = *((hb_codepoint_t *) _key);
const OS2Range *range = (OS2Range *) _item;
if (cp < range->start)
return -1;
else if (cp <= range->end)
return 0;
else
return +1;
}
hb_codepoint_t start; hb_codepoint_t start;
hb_codepoint_t end; hb_codepoint_t end;
@ -233,10 +222,7 @@ static const OS2Range _hb_os2_unicode_ranges[] =
static unsigned int static unsigned int
_hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp) _hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
{ {
OS2Range *range = (OS2Range*) hb_bsearch (&cp, _hb_os2_unicode_ranges, auto* range = hb_bsearch (cp, _hb_os2_unicode_ranges, ARRAY_LENGTH (_hb_os2_unicode_ranges));
ARRAY_LENGTH (_hb_os2_unicode_ranges),
sizeof (OS2Range),
OS2Range::cmp);
if (range != nullptr) if (range != nullptr)
return range->bit; return range->bit;
return -1; return -1;

View File

@ -165,8 +165,7 @@ struct post
} }
hb_bytes_t st (name, len); hb_bytes_t st (name, len);
const uint16_t *gid = (const uint16_t *) hb_bsearch (hb_addressof (st), gids, count, auto* gid = hb_bsearch (hb_addressof (st), gids, count, sizeof (gids[0]), cmp_key, (void *) this);
sizeof (gids[0]), cmp_key, (void *) this);
if (gid) if (gid)
{ {
*glyph = *gid; *glyph = *gid;

View File

@ -77,7 +77,9 @@ struct MVAR
const int *coords, unsigned int coord_count) const const int *coords, unsigned int coord_count) const
{ {
const VariationValueRecord *record; const VariationValueRecord *record;
record = (VariationValueRecord *) hb_bsearch (&tag, valuesZ.arrayZ, record = (VariationValueRecord *) hb_bsearch (tag,
(const VariationValueRecord *)
(const HBUINT8 *) valuesZ,
valueRecordCount, valueRecordSize, valueRecordCount, valueRecordSize,
tag_compare); tag_compare);
if (!record) if (!record)

View File

@ -136,20 +136,22 @@ hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u) if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
{ {
uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0); uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
uint32_t *v = (uint32_t*) hb_bsearch (&k, _hb_ucd_dm2_u32_map, const uint32_t *v = hb_bsearch (k,
ARRAY_LENGTH (_hb_ucd_dm2_u32_map), _hb_ucd_dm2_u32_map,
sizeof (*_hb_ucd_dm2_u32_map), ARRAY_LENGTH (_hb_ucd_dm2_u32_map),
_cmp_pair_11_7_14); sizeof (*_hb_ucd_dm2_u32_map),
_cmp_pair_11_7_14);
if (likely (!v)) return false; if (likely (!v)) return false;
u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v); u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v);
} }
else else
{ {
uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0); uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
uint64_t *v = (uint64_t*) hb_bsearch (&k, _hb_ucd_dm2_u64_map, const uint64_t *v = hb_bsearch (k,
ARRAY_LENGTH (_hb_ucd_dm2_u64_map), _hb_ucd_dm2_u64_map,
sizeof (*_hb_ucd_dm2_u64_map), ARRAY_LENGTH (_hb_ucd_dm2_u64_map),
_cmp_pair); sizeof (*_hb_ucd_dm2_u64_map),
_cmp_pair);
if (likely (!v)) return false; if (likely (!v)) return false;
u = HB_CODEPOINT_DECODE3_3 (*v); u = HB_CODEPOINT_DECODE3_3 (*v);
} }