summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh113
1 files changed, 92 insertions, 21 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
index 52b775e9569..587000cd428 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
@@ -28,7 +28,7 @@
#define HB_ARRAY_HH
#include "hb.hh"
-#include "hb-dsalgs.hh"
+#include "hb-algs.hh"
#include "hb-iter.hh"
#include "hb-null.hh"
@@ -37,22 +37,31 @@ template <typename Type>
struct hb_sorted_array_t;
template <typename Type>
-struct hb_array_t :
- hb_iter_t<hb_array_t<Type>, Type>,
- hb_iter_mixin_t<hb_array_t<Type>, Type>
+struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
{
/*
* Constructors.
*/
- hb_array_t () : arrayZ (nullptr), length (0) {}
- hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
- template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
+ hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {}
+ hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {}
+ template <unsigned int length_>
+ hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {}
+ template <typename U,
+ hb_enable_if (hb_is_cr_convertible(U, Type))>
+ hb_array_t (const hb_array_t<U> &o) :
+ hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
+ arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
+ template <typename U,
+ hb_enable_if (hb_is_cr_convertible(U, Type))>
+ hb_array_t& operator = (const hb_array_t<U> &o)
+ { arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; }
/*
* Iterator implementation.
*/
- typedef Type __item_type__;
+ typedef Type& __item_t__;
+ static constexpr bool is_random_access_iterator = true;
Type& __item_at__ (unsigned i) const
{
if (unlikely (i >= length)) return CrapOrNull (Type);
@@ -63,16 +72,25 @@ struct hb_array_t :
if (unlikely (n > length))
n = length;
length -= n;
+ backwards_length += n;
arrayZ += n;
}
void __rewind__ (unsigned n)
{
- if (unlikely (n > length))
- n = length;
- length -= n;
+ if (unlikely (n > backwards_length))
+ n = backwards_length;
+ length += n;
+ backwards_length -= n;
+ arrayZ -= n;
}
unsigned __len__ () const { return length; }
- bool __random_access__ () const { return true; }
+ /* Ouch. The operator== compares the contents of the array. For range-based for loops,
+ * it's best if we can just compare arrayZ, though comparing contents is still fast,
+ * but also would require that Type has operator==. As such, we optimize this operator
+ * for range-based for loop and just compare arrayZ. No need to compare length, as we
+ * assume we're only compared to .end(). */
+ bool operator != (const hb_array_t& o) const
+ { return arrayZ != o.arrayZ; }
/* Extra operators.
*/
@@ -80,6 +98,9 @@ struct hb_array_t :
operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
template <typename T> operator T * () const { return arrayZ; }
+ HB_INTERNAL bool operator == (const hb_array_t &o) const;
+ HB_INTERNAL uint32_t hash () const;
+
/*
* Compare, Sort, and Search.
*/
@@ -91,7 +112,7 @@ struct hb_array_t :
return (int) a.length - (int) length;
return hb_memcmp (a.arrayZ, arrayZ, get_size ());
}
- static int cmp (const void *pa, const void *pb)
+ HB_INTERNAL static int cmp (const void *pa, const void *pb)
{
hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
@@ -131,7 +152,7 @@ struct hb_array_t :
}
void qsort (unsigned int start, unsigned int end)
{
- end = MIN (end, length);
+ end = hb_min (end, length);
assert (start <= end);
if (likely (start < end))
::qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
@@ -154,7 +175,7 @@ struct hb_array_t :
else
count -= start_offset;
if (seg_count)
- count = *seg_count = MIN (count, *seg_count);
+ count = *seg_count = hb_min (count, *seg_count);
return hb_array_t<Type> (arrayZ + start_offset, count);
}
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
@@ -164,6 +185,17 @@ struct hb_array_t :
void free ()
{ ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
+ template <typename hb_serialize_context_t>
+ hb_array_t copy (hb_serialize_context_t *c) const
+ {
+ TRACE_SERIALIZE (this);
+ auto* out = c->start_embed (arrayZ);
+ if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ());
+ for (unsigned i = 0; i < length; i++)
+ out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
+ return_trace (hb_array_t (out, length));
+ }
+
template <typename hb_sanitize_context_t>
bool sanitize (hb_sanitize_context_t *c) const
{ return c->check_array (arrayZ, length); }
@@ -175,6 +207,7 @@ struct hb_array_t :
public:
Type *arrayZ;
unsigned int length;
+ unsigned int backwards_length;
};
template <typename T> inline hb_array_t<T>
hb_array (T *array, unsigned int length)
@@ -183,7 +216,6 @@ template <typename T, unsigned int length_> inline hb_array_t<T>
hb_array (T (&array_)[length_])
{ return hb_array_t<T> (array_); }
-
enum hb_bfind_not_found_t
{
HB_BFIND_NOT_FOUND_DONT_STORE,
@@ -193,14 +225,32 @@ enum hb_bfind_not_found_t
template <typename Type>
struct hb_sorted_array_t :
- hb_sorted_iter_t<hb_sorted_array_t<Type>, Type>,
- hb_array_t<Type>,
- hb_iter_mixin_t<hb_sorted_array_t<Type>, Type>
+ hb_iter_t<hb_sorted_array_t<Type>, Type&>,
+ hb_array_t<Type>
{
+ typedef hb_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
+ HB_ITER_USING (iter_base_t);
+ static constexpr bool is_random_access_iterator = true;
+ static constexpr bool is_sorted_iterator = true;
+
hb_sorted_array_t () : hb_array_t<Type> () {}
- hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
- template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+ template <unsigned int length_>
+ hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+
+ template <typename U,
+ hb_enable_if (hb_is_cr_convertible(U, Type))>
+ hb_sorted_array_t (const hb_array_t<U> &o) :
+ hb_iter_t<hb_sorted_array_t<Type>, Type&> (),
+ hb_array_t<Type> (o) {}
+ template <typename U,
+ hb_enable_if (hb_is_cr_convertible(U, Type))>
+ hb_sorted_array_t& operator = (const hb_array_t<U> &o)
+ { hb_array_t<Type> (*this) = o; return *this; }
+
+ /* Iterator implementation. */
+ bool operator != (const hb_sorted_array_t& o) const
+ { return this->arrayZ != o.arrayZ || this->length != o.length; }
hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
{ return hb_sorted_array_t<Type> (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
@@ -269,9 +319,30 @@ template <typename T, unsigned int length_> inline hb_sorted_array_t<T>
hb_sorted_array (T (&array_)[length_])
{ return hb_sorted_array_t<T> (array_); }
+template <typename T>
+bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
+{
+ return length == o.length &&
+ + hb_zip (*this, o)
+ | hb_map ([] (hb_pair_t<T&, T&> &&_) { return _.first == _.second; })
+ | hb_all
+ ;
+}
+template <typename T>
+uint32_t hb_array_t<T>::hash () const
+{
+ return
+ + hb_iter (*this)
+ | hb_map (hb_hash)
+ | hb_reduce ([] (uint32_t a, uint32_t b) { return a * 31 + b; }, 0)
+ ;
+}
typedef hb_array_t<const char> hb_bytes_t;
typedef hb_array_t<const unsigned char> hb_ubytes_t;
+/* TODO Specialize opeator==/hash() for hb_bytes_t and hb_ubytes_t. */
+//template <>
+//uint32_t hb_array_t<const char>::hash () const { return 0; }
#endif /* HB_ARRAY_HH */