[set] Implement iteration using bitop intrinsics
This commit is contained in:
parent
6a91a2eb04
commit
f18b9fbf65
|
@ -109,21 +109,16 @@ struct hb_set_t
|
||||||
unsigned int i = m / ELT_BITS;
|
unsigned int i = m / ELT_BITS;
|
||||||
unsigned int j = m & ELT_MASK;
|
unsigned int j = m & ELT_MASK;
|
||||||
|
|
||||||
for (; j < ELT_BITS; j++)
|
const elt_t vv = v[i] & ~((elt_t (1) << j) - 1);
|
||||||
if (v[i] & (elt_t (1) << j))
|
for (const elt_t *p = &vv; i < len (); p = &v[++i])
|
||||||
goto found;
|
if (*p)
|
||||||
for (i++; i < len (); i++)
|
{
|
||||||
if (v[i])
|
*codepoint = i * ELT_BITS + elt_get_min (*p);
|
||||||
for (j = 0; j < ELT_BITS; j++)
|
return true;
|
||||||
if (v[i] & (elt_t (1) << j))
|
}
|
||||||
goto found;
|
|
||||||
|
|
||||||
*codepoint = INVALID;
|
*codepoint = INVALID;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
found:
|
|
||||||
*codepoint = i * ELT_BITS + j;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
inline bool previous (hb_codepoint_t *codepoint) const
|
inline bool previous (hb_codepoint_t *codepoint) const
|
||||||
{
|
{
|
||||||
|
@ -136,44 +131,29 @@ struct hb_set_t
|
||||||
unsigned int i = m / ELT_BITS;
|
unsigned int i = m / ELT_BITS;
|
||||||
unsigned int j = m & ELT_MASK;
|
unsigned int j = m & ELT_MASK;
|
||||||
|
|
||||||
for (; (int) j >= 0; j--)
|
const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1);
|
||||||
if (v[i] & (elt_t (1) << j))
|
for (const elt_t *p = &vv; (int) i >= 0; p = &v[--i])
|
||||||
goto found;
|
if (*p)
|
||||||
for (i--; (int) i >= 0; i--)
|
{
|
||||||
if (v[i])
|
*codepoint = i * ELT_BITS + elt_get_max (*p);
|
||||||
for (j = ELT_BITS - 1; (int) j >= 0; j--)
|
return true;
|
||||||
if (v[i] & (elt_t (1) << j))
|
}
|
||||||
goto found;
|
|
||||||
|
|
||||||
*codepoint = INVALID;
|
*codepoint = INVALID;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
found:
|
|
||||||
*codepoint = i * ELT_BITS + j;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
inline hb_codepoint_t get_min (void) const
|
inline hb_codepoint_t get_min (void) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < len (); i++)
|
for (unsigned int i = 0; i < len (); i++)
|
||||||
if (v[i])
|
if (v[i])
|
||||||
{
|
return i * ELT_BITS + elt_get_min (v[i]);
|
||||||
elt_t e = v[i];
|
|
||||||
for (unsigned int j = 0; j < ELT_BITS; j++)
|
|
||||||
if (e & (elt_t (1) << j))
|
|
||||||
return i * ELT_BITS + j;
|
|
||||||
}
|
|
||||||
return INVALID;
|
return INVALID;
|
||||||
}
|
}
|
||||||
inline hb_codepoint_t get_max (void) const
|
inline hb_codepoint_t get_max (void) const
|
||||||
{
|
{
|
||||||
for (int i = len () - 1; i >= 0; i--)
|
for (int i = len () - 1; i >= 0; i--)
|
||||||
if (v[i])
|
if (v[i])
|
||||||
{
|
return i * ELT_BITS + elt_get_max (v[i]);
|
||||||
elt_t e = v[i];
|
|
||||||
for (int j = ELT_BITS - 1; j >= 0; j--)
|
|
||||||
if (e & (elt_t (1) << j))
|
|
||||||
return i * ELT_BITS + j;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +161,9 @@ struct hb_set_t
|
||||||
static const unsigned int PAGE_BITS = 1024;
|
static const unsigned int PAGE_BITS = 1024;
|
||||||
static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
|
static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
|
||||||
|
|
||||||
|
static inline unsigned int elt_get_min (const elt_t &elt) { return _hb_ctz (elt); }
|
||||||
|
static inline unsigned int elt_get_max (const elt_t &elt) { return _hb_bit_storage (elt) - 1; }
|
||||||
|
|
||||||
#if 0 && HAVE_VECTOR_SIZE
|
#if 0 && HAVE_VECTOR_SIZE
|
||||||
/* The vectorized version does not work with clang as non-const
|
/* The vectorized version does not work with clang as non-const
|
||||||
* elt() errs "non-const reference cannot bind to vector element". */
|
* elt() errs "non-const reference cannot bind to vector element". */
|
||||||
|
|
Loading…
Reference in New Issue