parent
b4eff38397
commit
889dc1eb06
|
@ -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_) {}
|
||||||
|
|
|
@ -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_; }
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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__ (); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue