[iter] Track strictly-sorted iterators
This make output of hb_enumerate() sorted regardless of input iterator.
diff --git a/src/hb-array.hh b/src/hb-array.hh
index 705bc6a..6f6fd7f 100644
--- a/src/hb-array.hh
+++ b/src/hb-array.hh
@@ -226,7 +226,7 @@
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;
+ static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::SORTED;
hb_sorted_array_t () : hb_array_t<Type> () {}
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
diff --git a/src/hb-iter.hh b/src/hb-iter.hh
index d749d4a..a1fe904 100644
--- a/src/hb-iter.hh
+++ b/src/hb-iter.hh
@@ -55,6 +55,12 @@
* type of .end()?
*/
+enum hb_sortedness_t
+{
+ NOT_SORTED = 0,
+ SORTED,
+ STRICTLY_SORTED,
+};
/*
* Base classes for iterators.
@@ -68,7 +74,7 @@
static constexpr unsigned item_size = hb_static_size (Item);
static constexpr bool is_iterator = true;
static constexpr bool is_random_access_iterator = false;
- static constexpr bool is_sorted_iterator = false;
+ static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::NOT_SORTED;
private:
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@@ -361,9 +367,9 @@
typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__;
static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
- static constexpr bool is_sorted_iterator =
- Sorted == hb_function_sortedness_t::SORTED ? true
- : Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator : false;
+ static constexpr hb_sortedness_t is_sorted_iterator =
+ Sorted == hb_function_sortedness_t::SORTED ? hb_sortedness_t::SORTED
+ : Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator : hb_sortedness_t::NOT_SORTED;
__item_t__ __item__ () const { return hb_get (f.get (), *it); }
__item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); }
bool __more__ () const { return bool (it); }
@@ -430,7 +436,7 @@
{ while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; }
typedef typename Iter::item_t __item_t__;
- static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
+ static constexpr hb_sortedness_t is_sorted_iterator = Iter::is_sorted_iterator;
__item_t__ __item__ () const { return *it; }
bool __more__ () const { return bool (it); }
void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
@@ -514,9 +520,15 @@
static constexpr bool is_random_access_iterator =
A::is_random_access_iterator &&
B::is_random_access_iterator;
- static constexpr bool is_sorted_iterator =
- A::is_sorted_iterator &&
- B::is_sorted_iterator;
+ static constexpr hb_sortedness_t is_sorted_iterator =
+ (A::is_sorted_iterator == hb_sortedness_t::NOT_SORTED ||
+ B::is_sorted_iterator == hb_sortedness_t::NOT_SORTED) ?
+ hb_sortedness_t::NOT_SORTED :
+ (A::is_sorted_iterator == hb_sortedness_t::STRICTLY_SORTED ||
+ B::is_sorted_iterator == hb_sortedness_t::STRICTLY_SORTED) ?
+ hb_sortedness_t::STRICTLY_SORTED :
+ hb_sortedness_t::SORTED;
+
__item_t__ __item__ () const { return __item_t__ (*a, *b); }
__item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); }
bool __more__ () const { return bool (a) && bool (b); }
@@ -583,7 +595,7 @@
typedef T __item_t__;
static constexpr bool is_random_access_iterator = true;
- static constexpr bool is_sorted_iterator = true;
+ static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::STRICTLY_SORTED;
__item_t__ __item__ () const { return +v; }
__item_t__ __item_at__ (unsigned j) const { return v + j * step; }
bool __more__ () const { return v != end_; }
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index 71c0ca4..67f2617 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -1115,7 +1115,7 @@
struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
{
- static constexpr bool is_sorted_iterator = true;
+ static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::STRICTLY_SORTED;
iter_t (const Coverage &c_ = Null(Coverage))
{
memset (this, 0, sizeof (*this));
diff --git a/src/hb-set.hh b/src/hb-set.hh
index 332e07b..d9ffded 100644
--- a/src/hb-set.hh
+++ b/src/hb-set.hh
@@ -691,7 +691,7 @@
*/
struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
{
- static constexpr bool is_sorted_iterator = true;
+ static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::STRICTLY_SORTED;
iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }