[arrays] Port hb_vector_t.bsearch/bfind to (new) hb_sorted_array_t's

This commit is contained in:
Behdad Esfahbod 2018-11-24 01:24:48 -05:00
parent 268eca2492
commit e604306f28
3 changed files with 89 additions and 43 deletions

View File

@ -564,7 +564,6 @@ struct hb_array_t
{
static_assert ((bool) (unsigned) hb_static_size (Type), "");
inline hb_array_t (void) : arrayZ (nullptr), len (0) {}
inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {}
inline Type& operator [] (unsigned int i) const
@ -576,7 +575,8 @@ struct hb_array_t
inline unsigned int get_size (void) const { return len * sizeof (Type); }
template <typename T>
inline Type *lsearch (const T &x, Type *not_found = nullptr)
inline Type *lsearch (const T &x,
Type *not_found = nullptr)
{
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
@ -585,7 +585,8 @@ struct hb_array_t
return not_found;
}
template <typename T>
inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const
inline const Type *lsearch (const T &x,
const Type *not_found = nullptr) const
{
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
@ -625,7 +626,61 @@ struct hb_array_t
unsigned int len;
};
template <typename T>
inline hb_array_t<T> hb_array (T *array, unsigned int len) { return hb_array_t<T> (array, len); }
inline hb_array_t<T> hb_array (T *array, unsigned int len)
{ return hb_array_t<T> (array, len); }
template <typename Type>
struct hb_sorted_array_t : hb_array_t<Type>
{
inline hb_sorted_array_t (Type *array_, unsigned int len_) : hb_array_t<Type> (array_, len_) {}
template <typename T>
inline Type *bsearch (const T &x,
Type *not_found = nullptr)
{
unsigned int i;
return bfind (x, &i) ? &this->arrayZ[i] : not_found;
}
template <typename T>
inline const Type *bsearch (const T &x,
const Type *not_found = nullptr) const
{
unsigned int i;
return bfind (x, &i) ? &this->arrayZ[i] : not_found;
}
template <typename T>
inline bool bfind (const T &x,
unsigned int *i = nullptr) const
{
int min = 0, max = (int) this->len - 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
{
if (i)
*i = mid;
return true;
}
}
if (i)
{
if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0))
max++;
*i = max;
}
return false;
}
};
template <typename T>
inline hb_sorted_array_t<T> hb_sorted_array (T *array, unsigned int len)
{ return hb_sorted_array_t<T> (array, len); }
struct HbOpOr

View File

@ -370,8 +370,10 @@ struct UnsizedArrayOf
inline unsigned int get_size (unsigned int len) const
{ return len * Type::static_size; }
inline hb_array_t<Type> as_array (unsigned int len) { return hb_array_t<Type> (arrayZ, len); }
inline hb_array_t<const Type> as_array (unsigned int len) const { return hb_array_t<const Type> (arrayZ, len); }
inline hb_array_t<Type> as_array (unsigned int len)
{ return hb_array (arrayZ, len); }
inline hb_array_t<const Type> as_array (unsigned int len) const
{ return hb_array (arrayZ, len); }
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
@ -483,8 +485,10 @@ struct ArrayOf
inline unsigned int get_size (void) const
{ return len.static_size + len * Type::static_size; }
inline hb_array_t<Type> as_array (void) { return hb_array_t<Type> (arrayZ, len); }
inline hb_array_t<const Type> as_array (void) const { return hb_array_t<const Type> (arrayZ, len); }
inline hb_array_t<Type> as_array (void)
{ return hb_array (arrayZ, len); }
inline hb_array_t<const Type> as_array (void) const
{ return hb_array (arrayZ, len); }
inline bool serialize (hb_serialize_context_t *c,
unsigned int items_len)

View File

@ -91,8 +91,15 @@ struct hb_vector_t
return arrayZ()[i];
}
inline hb_array_t<Type> as_array (void) { return hb_array_t<Type> (arrayZ(), len); }
inline hb_array_t<const Type> as_array (void) const { return hb_array_t<const Type> (arrayZ(), len); }
inline hb_array_t<Type> as_array (void)
{ return hb_array (arrayZ(), len); }
inline hb_array_t<const Type> as_array (void) const
{ return hb_array (arrayZ(), len); }
inline hb_sorted_array_t<Type> as_sorted_array (void)
{ return hb_sorted_array (arrayZ(), len); }
inline hb_sorted_array_t<const Type> as_sorted_array (void) const
{ return hb_sorted_array (arrayZ(), len); }
template <typename T> inline operator T * (void) { return arrayZ(); }
template <typename T> inline operator const T * (void) const { return arrayZ(); }
@ -229,55 +236,35 @@ struct hb_vector_t
}
template <typename T>
inline Type *lsearch (const T &x, Type *not_found = nullptr)
inline Type *lsearch (const T &x,
Type *not_found = nullptr)
{
return as_array ().lsearch (x, not_found);
}
template <typename T>
inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const
inline const Type *lsearch (const T &x,
const Type *not_found = nullptr) const
{
return as_array ().lsearch (x, not_found);
}
template <typename T>
inline Type *bsearch (const T &x)
inline Type *bsearch (const T &x,
Type *not_found = nullptr)
{
unsigned int i;
return bfind (x, &i) ? &arrayZ()[i] : nullptr;
return as_sorted_array ().bsearch (x, not_found);
}
template <typename T>
inline const Type *bsearch (const T &x) const
inline const Type *bsearch (const T &x,
const Type *not_found = nullptr) const
{
unsigned int i;
return bfind (x, &i) ? &arrayZ()[i] : nullptr;
return as_sorted_array ().bsearch (x, not_found);
}
template <typename T>
inline bool bfind (const T &x, unsigned int *i = nullptr) const
inline bool bfind (const T &x,
unsigned int *i = nullptr) const
{
int min = 0, max = (int) this->len - 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
{
if (i)
*i = mid;
return true;
}
}
if (i)
{
if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0))
max++;
*i = max;
}
return false;
return as_sorted_array ().bfind (x, i);
}
};