[iter] Track strictly-sorted iterators

This make output of hb_enumerate() sorted regardless of input iterator.
This commit is contained in:
Behdad Esfahbod 2019-05-13 15:36:14 -07:00
parent 7e02063f32
commit 513762849a
4 changed files with 24 additions and 12 deletions

View File

@ -226,7 +226,7 @@ struct hb_sorted_array_t :
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_) {}

View File

@ -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 @@ struct hb_iter_t
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 @@ struct hb_map_iter_t :
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 @@ struct hb_filter_iter_t :
{ 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 @@ struct hb_zip_iter_t :
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 @@ struct hb_counter_iter_t :
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_; }

View File

@ -1115,7 +1115,7 @@ struct Coverage
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));

View File

@ -691,7 +691,7 @@ struct hb_set_t
*/
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__ (); }