/*
* This is part of HarfBuzz , a text shaping library .
*
* Permission is hereby granted , without written agreement and without
* license or royalty fees , to use , copy , modify , and distribute this
* software and its documentation for any purpose , provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software .
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT , INDIRECT , SPECIAL , INCIDENTAL , OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION , EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE .
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES , INCLUDING ,
* BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE . THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN " AS IS " BASIS , AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE , SUPPORT , UPDATES , ENHANCEMENTS , OR MODIFICATIONS .
*
* Author ( s ) : Behdad Esfahbod
*/
#ifndef HB_BIT_VECTOR_HH
#define HB_BIT_VECTOR_HH
#include "hb.hh"
#include "hb-atomic.hh"
struct hb_min_max_t
{
void add (hb_codepoint_t v) { min_v = hb_min (min_v, v); max_v = hb_max (max_v, v); }
void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
min_v = hb_min (min_v, a);
max_v = hb_max (max_v, b);
}
template <typename set_t>
void union_ (const set_t &set)
{
hb_codepoint_t set_min = set.get_min ();
if (unlikely (set_min == HB_CODEPOINT_INVALID))
return ;
hb_codepoint_t set_max = set.get_max ();
min_v = hb_min (min_v, set_min);
max_v = hb_max (max_v, set_max);
}
hb_codepoint_t get_min () const { return min_v; }
hb_codepoint_t get_max () const { return max_v; }
private :
hb_codepoint_t min_v = HB_CODEPOINT_INVALID;
hb_codepoint_t max_v = 0 ;
};
template <bool atomic = false >
struct hb_bit_vector_t
{
using int_t = uint64_t;
using elt_t = typename std::conditional<atomic, hb_atomic_t<int_t>, int_t>::type;
hb_bit_vector_t () = delete ;
hb_bit_vector_t (const hb_bit_vector_t &other) = delete ;
hb_bit_vector_t &operator = (const hb_bit_vector_t &other) = delete ;
// Move
hb_bit_vector_t (hb_bit_vector_t &&other)
: min_v (other.min_v), max_v (other.max_v), count (other.count), elts (other.elts)
{
other.min_v = other.max_v = other.count = 0 ;
other.elts = nullptr;
}
hb_bit_vector_t &operator = (hb_bit_vector_t &&other)
{
hb_swap (min_v, other.min_v);
hb_swap (max_v, other.max_v);
hb_swap (count, other.count);
hb_swap (elts, other.elts);
return *this ;
}
hb_bit_vector_t (unsigned min_v, unsigned max_v)
: min_v (min_v), max_v (max_v)
{
if (unlikely (min_v >= max_v))
{
min_v = max_v = count = 0 ;
return ;
}
unsigned num = (max_v - min_v + sizeof (int_t) * 8 ) / (sizeof (int_t) * 8 );
elts = (elt_t *) hb_calloc (num, sizeof (int_t));
if (unlikely (!elts))
{
min_v = max_v = count = 0 ;
return ;
}
count = max_v - min_v + 1 ;
}
~hb_bit_vector_t ()
{
hb_free (elts);
}
void add (hb_codepoint_t g) { elt (g) |= mask (g); }
void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
bool has (hb_codepoint_t g) const { return get (g); }
bool may_have (hb_codepoint_t g) const { return get (g); }
bool operator [] (hb_codepoint_t g) const { return get (g); }
bool operator () (hb_codepoint_t g) const { return get (g); }
void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
if (unlikely (!count || a > b || a < min_v || b > max_v))
return ;
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
*la |= (mask (b) << 1 ) - mask(a);
else
{
*la |= ~(mask (a) - 1 llu);
la++;
hb_memset (la, 0 xff, (char *) lb - (char *) la);
*lb |= ((mask (b) << 1 ) - 1 llu);
}
}
void del_range (hb_codepoint_t a, hb_codepoint_t b)
{
if (unlikely (!count || a > b || a < min_v || b > max_v))
return ;
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
*la &= ~((mask (b) << 1 llu) - mask(a));
else
{
*la &= mask (a) - 1 ;
la++;
hb_memset (la, 0 , (char *) lb - (char *) la);
*lb &= ~((mask (b) << 1 ) - 1 llu);
}
}
void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
{ if (v) add_range (a, b); else del_range (a, b); }
template <typename set_t>
void union_ (const set_t &set)
{
for (hb_codepoint_t g : set)
add (g);
}
static const unsigned int ELT_BITS = sizeof (elt_t) * 8 ;
static constexpr unsigned ELT_MASK = ELT_BITS - 1 ;
static constexpr elt_t zero = 0 ;
elt_t &elt (hb_codepoint_t g)
{
g -= min_v;
if (unlikely (g >= count))
return Crap(elt_t);
return elts[g / ELT_BITS];
}
const elt_t& elt (hb_codepoint_t g) const
{
g -= min_v;
if (unlikely (g >= count))
return Null(elt_t);
return elts[g / ELT_BITS];
}
static constexpr int_t mask (hb_codepoint_t g) { return elt_t (1 ) << (g & ELT_MASK); }
hb_codepoint_t min_v = 0 , max_v = 0 , count = 0 ;
elt_t *elts = nullptr;
};
#endif /* HB_BIT_VECTOR_HH */
Messung V0.5 in Prozent C=99 H=99 G=98
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland