[bit-set-invertible] Implement set algebra

This commit is contained in:
Behdad Esfahbod 2021-08-19 00:48:00 -06:00
parent 6afefe1dc3
commit b94f24ec79
3 changed files with 93 additions and 12 deletions

View File

@ -1178,11 +1178,35 @@ struct
} }
HB_FUNCOBJ (hb_bitwise_xor); HB_FUNCOBJ (hb_bitwise_xor);
struct struct
{ HB_PARTIALIZE(2);
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a & b)
}
HB_FUNCOBJ (hb_bitwise_lt);
struct
{ HB_PARTIALIZE(2); { HB_PARTIALIZE(2);
template <typename T> constexpr auto template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b) operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
} }
HB_FUNCOBJ (hb_bitwise_sub); HB_FUNCOBJ (hb_bitwise_gt); // aka sub
struct
{ HB_PARTIALIZE(2);
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a & ~b)
}
HB_FUNCOBJ (hb_bitwise_non);
struct
{ HB_PARTIALIZE(2);
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a | b)
}
HB_FUNCOBJ (hb_bitwise_le);
struct
{ HB_PARTIALIZE(2);
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | ~b)
}
HB_FUNCOBJ (hb_bitwise_ge);
struct struct
{ {
template <typename T> constexpr auto template <typename T> constexpr auto
@ -1203,6 +1227,12 @@ struct
} }
HB_FUNCOBJ (hb_sub); HB_FUNCOBJ (hb_sub);
struct struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (b - a)
}
HB_FUNCOBJ (hb_rsub);
struct
{ HB_PARTIALIZE(2); { HB_PARTIALIZE(2);
template <typename T, typename T2> constexpr auto template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b) operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)

View File

@ -108,18 +108,69 @@ struct hb_bit_set_invertible_t
return inverted ? larger_set.s.is_subset (s) : s.is_subset (larger_set.s); return inverted ? larger_set.s.is_subset (s) : s.is_subset (larger_set.s);
} }
protected:
template <typename Op> template <typename Op>
void process (const Op& op, const hb_bit_set_invertible_t &other) void process (const Op& op, const hb_bit_set_invertible_t &other)
{ s.process (op, other.s); } {
s.process (op, other.s);
/*XXX(inverted)*/ inverted = bool (op (int (inverted), int (other.inverted)));
void union_ (const hb_bit_set_invertible_t &other) { process (hb_bitwise_or, other); } }
/*XXX(inverted)*/ public:
void intersect (const hb_bit_set_invertible_t &other) { process (hb_bitwise_and, other); } void union_ (const hb_bit_set_invertible_t &other)
/*XXX(inverted)*/ {
void subtract (const hb_bit_set_invertible_t &other) { process (hb_bitwise_sub, other); } if (inverted == other.inverted)
/*XXX(inverted)*/ {
void symmetric_difference (const hb_bit_set_invertible_t &other) { process (hb_bitwise_xor, other); } if (inverted)
process (hb_bitwise_and, other);
else
process (hb_bitwise_or, other); /* Main branch. */
}
else
{
if (inverted)
process (hb_bitwise_gt, other);
else
process (hb_bitwise_lt, other);
}
}
void intersect (const hb_bit_set_invertible_t &other)
{
if (inverted == other.inverted)
{
if (inverted)
process (hb_bitwise_or, other);
else
process (hb_bitwise_and, other); /* Main branch. */
}
else
{
if (inverted)
process (hb_bitwise_ge, other);
else
process (hb_bitwise_le, other);
}
}
void subtract (const hb_bit_set_invertible_t &other)
{
if (inverted == other.inverted)
{
if (inverted)
process (hb_bitwise_lt, other);
else
process (hb_bitwise_gt, other); /* Main branch. */
}
else
{
if (inverted)
process (hb_bitwise_non, other);
else
process (hb_bitwise_and, other);
}
}
void symmetric_difference (const hb_bit_set_invertible_t &other)
{
process (hb_bitwise_xor, other);
}
bool next (hb_codepoint_t *codepoint) const bool next (hb_codepoint_t *codepoint) const
{ {

View File

@ -577,7 +577,7 @@ struct hb_bit_set_t
void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); } void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); }
void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); } void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); }
void subtract (const hb_bit_set_t &other) { process (hb_bitwise_sub, other); } void subtract (const hb_bit_set_t &other) { process (hb_bitwise_gt, other); }
void symmetric_difference (const hb_bit_set_t &other) { process (hb_bitwise_xor, other); } void symmetric_difference (const hb_bit_set_t &other) { process (hb_bitwise_xor, other); }
bool next (hb_codepoint_t *codepoint) const bool next (hb_codepoint_t *codepoint) const