[iter] Remove sort categorization

See comments.
This commit is contained in:
Behdad Esfahbod 2019-05-14 22:28:07 -07:00
parent b4eff38397
commit 889dc1eb06
4 changed files with 35 additions and 19 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; typedef hb_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
HB_ITER_USING (iter_base_t); HB_ITER_USING (iter_base_t);
static constexpr bool is_random_access_iterator = true; static constexpr bool is_random_access_iterator = true;
static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::SORTED; static constexpr bool is_sorted_iterator = true;
hb_sorted_array_t () : hb_array_t<Type> () {} hb_sorted_array_t () : hb_array_t<Type> () {}
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}

View File

@ -55,13 +55,6 @@
* type of .end()? * type of .end()?
*/ */
enum hb_sortedness_t
{
NOT_SORTED = 0,
SORTED,
STRICTLY_SORTED,
};
/* /*
* Base classes for iterators. * Base classes for iterators.
*/ */
@ -74,7 +67,7 @@ struct hb_iter_t
static constexpr unsigned item_size = hb_static_size (Item); static constexpr unsigned item_size = hb_static_size (Item);
static constexpr bool is_iterator = true; static constexpr bool is_iterator = true;
static constexpr bool is_random_access_iterator = false; static constexpr bool is_random_access_iterator = false;
static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::NOT_SORTED; static constexpr bool is_sorted_iterator = false;
private: private:
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@ -367,9 +360,10 @@ struct hb_map_iter_t :
typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_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_random_access_iterator = Iter::is_random_access_iterator;
static constexpr hb_sortedness_t is_sorted_iterator = static constexpr bool is_sorted_iterator =
Sorted == hb_function_sortedness_t::SORTED ? hb_sortedness_t::SORTED Sorted == hb_function_sortedness_t::SORTED ? true :
: Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator : hb_sortedness_t::NOT_SORTED; Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator :
false;
__item_t__ __item__ () const { return hb_get (f.get (), *it); } __item_t__ __item__ () const { return hb_get (f.get (), *it); }
__item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); } __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); }
bool __more__ () const { return bool (it); } bool __more__ () const { return bool (it); }
@ -436,7 +430,7 @@ struct hb_filter_iter_t :
{ while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; } { while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; }
typedef typename Iter::item_t __item_t__; typedef typename Iter::item_t __item_t__;
static constexpr hb_sortedness_t is_sorted_iterator = Iter::is_sorted_iterator; static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
__item_t__ __item__ () const { return *it; } __item_t__ __item__ () const { return *it; }
bool __more__ () const { return bool (it); } bool __more__ () const { return bool (it); }
void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
@ -520,9 +514,31 @@ struct hb_zip_iter_t :
static constexpr bool is_random_access_iterator = static constexpr bool is_random_access_iterator =
A::is_random_access_iterator && A::is_random_access_iterator &&
B::is_random_access_iterator; B::is_random_access_iterator;
static constexpr hb_sortedness_t is_sorted_iterator = /* Note. The following categorization is only valid if A is strictly sorted,
A::is_sorted_iterator == hb_sortedness_t::SORTED ? * ie. does NOT have duplicates. Previously I tried to categorize sortedness
B::is_sorted_iterator : A::is_sorted_iterator; * more granularly, see commits:
*
* 513762849a683914fc266a17ddf38f133cccf072
* 4d3cf2adb669c345cc43832d11689271995e160a
*
* However, that was not enough, since hb_sorted_array_t, hb_sorted_vector_t,
* SortedArrayOf, etc all needed to be updated to add more variants. At that
* point I saw it not worth the effort, and instead we now deem all sorted
* collections as essentially strictly-sorted for the purposes of zip.
*
* The above assumption is not as bad as it sounds. Our "sorted" comes with
* no guarantees. It's just a contract, put in place to help you remember,
* and think about, whether an iterator you receive is expected to be
* sorted or not. As such, it's not perfect by definition, and should not
* be treated so. The inaccuracy here just errs in the direction of being
* more permissive, so your code compiles instead of erring on the side of
* marking your zipped iterator unsorted in which case your code won't
* compile.
*
* This semantical limitation does NOT affect logic in any other place I
* know of as of this writing.
*/
static constexpr bool is_sorted_iterator = A::is_sorted_iterator;
__item_t__ __item__ () const { return __item_t__ (*a, *b); } __item_t__ __item__ () const { return __item_t__ (*a, *b); }
__item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); } __item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); }
@ -590,7 +606,7 @@ struct hb_counter_iter_t :
typedef T __item_t__; typedef T __item_t__;
static constexpr bool is_random_access_iterator = true; static constexpr bool is_random_access_iterator = true;
static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::STRICTLY_SORTED; static constexpr bool is_sorted_iterator = true;
__item_t__ __item__ () const { return +v; } __item_t__ __item__ () const { return +v; }
__item_t__ __item_at__ (unsigned j) const { return v + j * step; } __item_t__ __item_at__ (unsigned j) const { return v + j * step; }
bool __more__ () const { return v != end_; } 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> struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
{ {
static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::STRICTLY_SORTED; static constexpr bool is_sorted_iterator = true;
iter_t (const Coverage &c_ = Null(Coverage)) iter_t (const Coverage &c_ = Null(Coverage))
{ {
memset (this, 0, sizeof (*this)); 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> struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
{ {
static constexpr hb_sortedness_t is_sorted_iterator = hb_sortedness_t::STRICTLY_SORTED; static constexpr bool is_sorted_iterator = true;
iter_t (const hb_set_t &s_ = Null(hb_set_t)) : iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); } s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }