hb-set-private.hh revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2012  Google, Inc.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  This is part of HarfBuzz, a text shaping library.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_SET_PRIVATE_HH
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_SET_PRIVATE_HH
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-private.hh"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-set.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-object-private.hh"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_set_digest_common_bits_t
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_POD ();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef unsigned int mask_t;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void init (void) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask = ~0;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value = (mask_t) -1;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add (hb_codepoint_t g) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (value == (mask_t) -1)) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value = g;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask ^= (g & mask) ^ value;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value &= mask;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The negation here stands for ~(x-1). */
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask &= -(1 << _hb_bit_storage (a ^ b));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value &= mask;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool may_have (hb_codepoint_t g) const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (g & mask) == value;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mask_t mask;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mask_t value;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_set_digest_lowest_bits_t
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_POD ();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef unsigned long mask_t;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void init (void) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add (hb_codepoint_t g) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mask |= mask_for (g);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (b - a >= sizeof (mask_t) * 8 - 1)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mask = (mask_t) -1;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mask_t ma = mask_for (a);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mask_t mb = mask_for (b);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mask |= mb + (mb - ma) - (mb < ma);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool may_have (hb_codepoint_t g) const {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !!(mask & mask_for (g));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static inline mask_t mask_for (hb_codepoint_t g) { return ((mask_t) 1) << (g & (sizeof (mask_t) * 8 - 1)); }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mask_t mask;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_set_digest_t
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_POD ();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void init (void) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest1.init ();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest2.init ();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add (hb_codepoint_t g) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest1.add (g);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest2.add (g);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest1.add_range (a, b);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest2.add_range (a, b);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool may_have (hb_codepoint_t g) const {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return digest1.may_have (g) && digest2.may_have (g);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_set_digest_common_bits_t digest1;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_set_digest_lowest_bits_t digest2;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TODO Make this faster and memmory efficient. */
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_set_t
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_object_header_t header;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_POD ();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_error;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void init (void) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header.init ();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    clear ();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void fini (void) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void clear (void) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (hb_object_is_inert (this)))
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    in_error = false;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset (elts, 0, sizeof elts);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool is_empty (void) const {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (elts[i])
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add (hb_codepoint_t g)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (g == SENTINEL)) return;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (g > MAX_G)) return;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elt (g) |= mask (g);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* TODO Speedup */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = a; i < b + 1; i++)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      add (i);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void del (hb_codepoint_t g)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (g > MAX_G)) return;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elt (g) &= ~mask (g);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* TODO Speedup */
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned int i = a; i < b + 1; i++)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      del (i);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool has (hb_codepoint_t g) const
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (g > MAX_G)) return false;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !!(elt (g) & mask (g));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool intersects (hb_codepoint_t first,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  hb_codepoint_t last) const
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (first > MAX_G)) return false;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (last  > MAX_G)) last = MAX_G;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int end = last + 1;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (hb_codepoint_t i = first; i < end; i++)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (has (i))
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool is_equal (const hb_set_t *other) const
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (elts[i] != other->elts[i])
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void set (const hb_set_t *other)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      elts[i] = other->elts[i];
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void union_ (const hb_set_t *other)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      elts[i] |= other->elts[i];
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void intersect (const hb_set_t *other)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      elts[i] &= other->elts[i];
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void subtract (const hb_set_t *other)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      elts[i] &= ~other->elts[i];
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void symmetric_difference (const hb_set_t *other)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      elts[i] ^= other->elts[i];
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline void invert (void)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (unlikely (in_error)) return;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      elts[i] = ~elts[i];
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool next (hb_codepoint_t *codepoint) const
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (*codepoint == SENTINEL)) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hb_codepoint_t i = get_min ();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (i != SENTINEL) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *codepoint = i;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return true;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (has (i)) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *codepoint = i;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return true;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    hb_codepoint_t i;
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    i = *last;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!next (&i))
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *last = *first = i;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (next (&i) && i == *last + 1)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*last)++;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline unsigned int get_population (void) const
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned int count = 0;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      count += _hb_popcount32 (elts[i]);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return count;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline hb_codepoint_t get_min (void) const
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = 0; i < ELTS; i++)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (elts[i])
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (unsigned int j = 0; i < BITS; j++)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  if (elts[i] & (1 << j))
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return i * BITS + j;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SENTINEL;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline hb_codepoint_t get_max (void) const
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (unsigned int i = ELTS; i; i--)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (elts[i - 1])
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (unsigned int j = BITS; j; j--)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  if (elts[i - 1] & (1 << (j - 1)))
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return (i - 1) * BITS + (j - 1);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SENTINEL;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef uint32_t elt_t;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int SHIFT = 5;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int BITS = (1 << SHIFT);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int MASK = BITS - 1;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static  const hb_codepoint_t SENTINEL = (hb_codepoint_t) -1;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  elt_t elts[ELTS]; /* XXX 8kb */
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_SET_PRIVATE_HH */
325