Use bsearch where applicable
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 59c7866..9cc0518 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -394,6 +394,7 @@
inline operator Type(void) const { return v; }
inline bool operator == (const IntType<Type> &o) const { return v == o.v; }
inline bool operator != (const IntType<Type> &o) const { return v != o.v; }
+ inline int cmp (Type b) const { Type a = v; return b < a ? -1 : b == a ? 0 : +1; }
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE ();
return likely (c->check_struct (this));
@@ -707,4 +708,52 @@
};
+/* An array with sorted elements. Supports binary searching. */
+template <typename Type>
+struct SortedArrayOf : ArrayOf<Type> {
+
+ template <typename SearchType>
+ inline int search (const SearchType &x) const {
+ class Cmp {
+ public: static int cmp (const void *p1, const void *p2) {
+ const SearchType *a = (const SearchType *) p1;
+ const Type *b = (const Type *) p2;
+ return b->cmp (*a);
+ }
+ };
+ const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (this->array[0]), Cmp::cmp);
+ return p ? p - this->array : -1;
+ }
+
+ inline bool sanitize_order (hb_sanitize_context_t *c) {
+ /* Make sure the list is sorted, since we bsearch in it. */
+ unsigned int count = this->len;
+ for (unsigned int i = 1; i < count; i++)
+ if (unlikely (this->array[i].cmp (this->array[i-1]) > 0)) {
+ /* We need to sort the entries. */
+ if (!c->can_edit (this, this->get_size ())) return false;
+ class Cmp {
+ public: static int cmp (const void *p1, const void *p2) {
+ const Type *a = (const Type *) p1;
+ const Type *b = (const Type *) p2;
+ return b->cmp (*a);
+ }
+ };
+ qsort (this->array, this->len, sizeof (this->array[0]), Cmp::cmp);
+ }
+ return true;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE ();
+ return ArrayOf<Type>::sanitize (c) && sanitize_order (c);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE ();
+ return ArrayOf<Type>::sanitize (c, base) && sanitize_order (c);
+ }
+};
+
+
#endif /* HB_OPEN_TYPE_PRIVATE_HH */