Imported Upstream version 2.6.4
[platform/upstream/harfbuzz.git] / src / hb-set.hh
index 64a1363..36d11c0 100644 (file)
@@ -28,6 +28,7 @@
 #define HB_SET_HH
 
 #include "hb.hh"
+#include "hb-machinery.hh"
 
 
 /*
@@ -39,7 +40,7 @@
 
 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 (); }
 
@@ -62,21 +63,21 @@ struct hb_set_t
     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);
@@ -97,7 +98,7 @@ struct hb_set_t
     {
       unsigned int pop = 0;
       for (unsigned int i = 0; i < len (); i++)
-        pop += hb_popcount (v[i]);
+       pop += hb_popcount (v[i]);
       return pop;
     }
 
@@ -135,12 +136,17 @@ struct hb_set_t
       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;
@@ -148,14 +154,14 @@ struct hb_set_t
     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;
     }
@@ -186,7 +192,7 @@ struct hb_set_t
   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 ()
@@ -227,11 +233,18 @@ struct hb_set_t
     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);
@@ -241,7 +254,7 @@ struct hb_set_t
     unsigned int count = pages.length;
     for (unsigned int i = 0; i < count; i++)
       if (!pages[i].is_empty ())
-        return false;
+       return false;
     return true;
   }
 
@@ -301,7 +314,7 @@ struct hb_set_t
       {
        page->add (g);
 
-       array = (const T *) ((const char *) array + stride);
+       array = &StructAtOffsetUnaligned<T> (array, stride);
        count--;
       }
       while (count && (g = *array, start <= g && g < end));
@@ -325,9 +338,9 @@ struct hb_set_t
       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);
 
@@ -357,15 +370,26 @@ struct hb_set_t
     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;
@@ -396,7 +420,7 @@ struct hb_set_t
       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++;
     }
@@ -417,13 +441,13 @@ struct hb_set_t
     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;
 
@@ -439,21 +463,21 @@ struct hb_set_t
     {
       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)
@@ -463,7 +487,7 @@ struct hb_set_t
 
     if (count > pages.length)
       if (!resize (count))
-        return;
+       return;
     newCount = count;
 
     /* Process in-place backward. */
@@ -477,7 +501,7 @@ struct hb_set_t
        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)
       {
@@ -523,19 +547,19 @@ struct hb_set_t
 
   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
   {
@@ -654,7 +678,7 @@ struct hb_set_t
     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
@@ -662,7 +686,7 @@ struct hb_set_t
     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;
   }
 
@@ -671,27 +695,29 @@ struct hb_set_t
   /*
    * 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: