#define HB_SET_HH
#include "hb.hh"
+#include "hb-machinery.hh"
/*
struct hb_set_t
{
- HB_NO_COPY_ASSIGN (hb_set_t);
+ HB_DELETE_COPY_ASSIGN (hb_set_t);
hb_set_t () { init (); }
~hb_set_t () { fini (); }
bool is_empty () const
{
for (unsigned int i = 0; i < len (); i++)
- if (v[i])
+ if (v[i])
return false;
return true;
}
void add (hb_codepoint_t g) { elt (g) |= mask (g); }
void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
- bool has (hb_codepoint_t g) const { return !!(elt (g) & mask (g)); }
+ bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
- *la |= (mask (b) << 1) - mask(a);
+ *la |= (mask (b) << 1) - mask(a);
else
{
*la |= ~(mask (a) - 1);
{
unsigned int pop = 0;
for (unsigned int i = 0; i < len (); i++)
- pop += hb_popcount (v[i]);
+ pop += hb_popcount (v[i]);
return pop;
}
unsigned int j = m & ELT_MASK;
const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1);
- for (const elt_t *p = &vv; (int) i >= 0; p = &v[--i])
+ const elt_t *p = &vv;
+ while (true)
+ {
if (*p)
{
*codepoint = i * ELT_BITS + elt_get_max (*p);
return true;
}
+ if ((int) i <= 0) break;
+ p = &v[--i];
+ }
*codepoint = INVALID;
return false;
hb_codepoint_t get_min () const
{
for (unsigned int i = 0; i < len (); i++)
- if (v[i])
+ if (v[i])
return i * ELT_BITS + elt_get_min (v[i]);
return INVALID;
}
hb_codepoint_t get_max () const
{
for (int i = len () - 1; i >= 0; i--)
- if (v[i])
+ if (v[i])
return i * ELT_BITS + elt_get_max (v[i]);
return 0;
}
hb_object_header_t header;
bool successful; /* Allocations successful */
mutable unsigned int population;
- hb_vector_t<page_map_t> page_map;
+ hb_sorted_vector_t<page_map_t> page_map;
hb_vector_t<page_t> pages;
void init_shallow ()
return true;
}
- void clear ()
+ void reset ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
+ clear ();
successful = true;
+ }
+
+ void clear ()
+ {
+ if (unlikely (hb_object_is_immutable (this)))
+ return;
population = 0;
page_map.resize (0);
pages.resize (0);
unsigned int count = pages.length;
for (unsigned int i = 0; i < count; i++)
if (!pages[i].is_empty ())
- return false;
+ return false;
return true;
}
{
page->add (g);
- array = (const T *) ((const char *) array + stride);
+ array = &StructAtOffsetUnaligned<T> (array, stride);
count--;
}
while (count && (g = *array, start <= g && g < end));
unsigned int end = major_start (m + 1);
do
{
- /* If we try harder we can change the following comparison to <=;
+ /* If we try harder we can change the following comparison to <=;
* Not sure if it's worth it. */
- if (g < last_g) return false;
+ if (g < last_g) return false;
last_g = g;
page->add (g);
for (unsigned int i = a; i < b + 1; i++)
del (i);
}
- bool has (hb_codepoint_t g) const
+ bool get (hb_codepoint_t g) const
{
const page_t *page = page_for (g);
if (!page)
return false;
- return page->has (g);
+ return page->get (g);
}
- bool intersects (hb_codepoint_t first,
- hb_codepoint_t last) const
+
+ /* Has interface. */
+ static constexpr bool SENTINEL = false;
+ typedef bool value_t;
+ value_t operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ /* Predicate. */
+ bool operator () (hb_codepoint_t k) const { return has (k); }
+
+ /* Sink interface. */
+ hb_set_t& operator << (hb_codepoint_t v) { add (v); return *this; }
+
+ bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
{
hb_codepoint_t c = first - 1;
return next (&c) && c <= last;
if (other->page_at (b).is_empty ()) { b++; continue; }
if (page_map[a].major != other->page_map[b].major ||
!page_at (a).is_equal (&other->page_at (b)))
- return false;
+ return false;
a++;
b++;
}
hb_codepoint_t c = INVALID;
while (next (&c))
if (!larger_set->has (c))
- return false;
+ return false;
return true;
}
- template <class Op>
- void process (const hb_set_t *other)
+ template <typename Op>
+ void process (const Op& op, const hb_set_t *other)
{
if (unlikely (!successful)) return;
{
if (page_map[a].major == other->page_map[b].major)
{
- count++;
+ count++;
a++;
b++;
}
else if (page_map[a].major < other->page_map[b].major)
{
- if (Op::passthru_left)
+ if (Op::passthru_left)
count++;
- a++;
+ a++;
}
else
{
- if (Op::passthru_right)
+ if (Op::passthru_right)
count++;
- b++;
+ b++;
}
}
if (Op::passthru_left)
if (count > pages.length)
if (!resize (count))
- return;
+ return;
newCount = count;
/* Process in-place backward. */
b--;
count--;
page_map[count] = page_map[a];
- Op::process (page_at (count).v, page_at (a).v, other->page_at (b).v);
+ page_at (count).v = op (page_at (a).v, other->page_at (b).v);
}
else if (page_map[a - 1].major > other->page_map[b - 1].major)
{
void union_ (const hb_set_t *other)
{
- process<HbOpOr> (other);
+ process (hb_bitwise_or, other);
}
void intersect (const hb_set_t *other)
{
- process<HbOpAnd> (other);
+ process (hb_bitwise_and, other);
}
void subtract (const hb_set_t *other)
{
- process<HbOpMinus> (other);
+ process (hb_bitwise_sub, other);
}
void symmetric_difference (const hb_set_t *other)
{
- process<HbOpXor> (other);
+ process (hb_bitwise_xor, other);
}
bool next (hb_codepoint_t *codepoint) const
{
unsigned int count = pages.length;
for (unsigned int i = 0; i < count; i++)
if (!page_at (i).is_empty ())
- return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
+ return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
return INVALID;
}
hb_codepoint_t get_max () const
unsigned int count = pages.length;
for (int i = count - 1; i >= 0; i++)
if (!page_at (i).is_empty ())
- return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max ();
+ return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max ();
return INVALID;
}
/*
* Iterator implementation.
*/
- struct const_iter_t : hb_sorted_iter_t<const_iter_t, const hb_codepoint_t>
+ struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
{
- const_iter_t (const hb_set_t &s_) :
- s (s_), v (INVALID), l (s.get_population () + 1) { __next__ (); }
+ static constexpr bool is_sorted_iterator = true;
+ iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
+ s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }
- typedef hb_codepoint_t __item_type__;
+ typedef hb_codepoint_t __item_t__;
hb_codepoint_t __item__ () const { return v; }
bool __more__ () const { return v != INVALID; }
- void __next__ () { s.next (&v); if (l) l--; }
- void __prev__ () { s.previous (&v); }
- unsigned __len__ () { return l; }
+ void __next__ () { s->next (&v); if (l) l--; }
+ void __prev__ () { s->previous (&v); }
+ unsigned __len__ () const { return l; }
+ iter_t end () const { return iter_t (*s); }
+ bool operator != (const iter_t& o) const
+ { return s != o.s || v != o.v; }
protected:
- const hb_set_t &s;
+ const hb_set_t *s;
hb_codepoint_t v;
unsigned l;
};
- const_iter_t const_iter () const { return const_iter_t (*this); }
- operator const_iter_t () const { return const_iter (); }
- typedef const_iter_t iter_t;
- iter_t iter () const { return const_iter (); }
+ iter_t iter () const { return iter_t (*this); }
+ operator iter_t () const { return iter (); }
protected: