diff options
author | James Prestwood <prestwoj@gmail.com> | 2022-07-22 13:27:46 -0700 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2022-07-22 16:07:16 -0500 |
commit | cad32b1fde3b5e6121a3aeb52b5060a0a6c5252b (patch) | |
tree | 1ac871a53b92d2db728881478304dd838c95ca99 | |
parent | b014ee914bcc931b0dd4c0bfb9f43b971550eb81 (diff) |
uintset: add l_uintset_subtract
This subtracts set_b from set_a, and returns the new set.
-rw-r--r-- | ell/ell.sym | 1 | ||||
-rw-r--r-- | ell/uintset.c | 37 | ||||
-rw-r--r-- | ell/uintset.h | 3 |
3 files changed, 41 insertions, 0 deletions
diff --git a/ell/ell.sym b/ell/ell.sym index 8f4e59d7..f4549219 100644 --- a/ell/ell.sym +++ b/ell/ell.sym @@ -537,6 +537,7 @@ global: l_uintset_foreach; l_uintset_clone; l_uintset_intersect; + l_uintset_subtract; l_uintset_isempty; l_uintset_size; /* uuid */ diff --git a/ell/uintset.c b/ell/uintset.c index 863bc560..4837bcf0 100644 --- a/ell/uintset.c +++ b/ell/uintset.c @@ -533,6 +533,43 @@ LIB_EXPORT struct l_uintset *l_uintset_intersect(const struct l_uintset *set_a, } /** + * l_uintset_subtract: + * @set_a: The set of numbers + * @set_b: The set of numbers to subtract from set_a + * + * Subtracts two sets of numbers of an equal base, e.g.: + * l_uintset_get_min(set_a) must be equal to l_uintset_get_min(set_b) and + * l_uintset_get_max(set_a) must be equal to l_uintset_get_max(set_b) + * + * Returns: A newly allocated l_uintset containing set_a - set_b + */ +LIB_EXPORT struct l_uintset *l_uintset_subtract(const struct l_uintset *set_a, + const struct l_uintset *set_b) +{ + struct l_uintset *subtraction; + uint32_t offset; + uint32_t offset_max; + + if (unlikely(!set_a || !set_b)) + return NULL; + + if (unlikely(set_a->min != set_b->min || set_a->max != set_b->max)) + return NULL; + + subtraction = l_uintset_new_from_range(set_a->min, set_a->max); + + offset_max = (set_a->size + BITS_PER_LONG - 1) / BITS_PER_LONG; + + /* Subtract by: set_a & ~set_b */ + for (offset = 0; offset < offset_max; offset++) { + subtraction->bits[offset] = + set_a->bits[offset] & ~(set_b->bits[offset]); + } + + return subtraction; +} + +/** * l_uintset_isempty * @set: The set of numbers * diff --git a/ell/uintset.h b/ell/uintset.h index aa9de48d..86ce8f7b 100644 --- a/ell/uintset.h +++ b/ell/uintset.h @@ -60,6 +60,9 @@ void l_uintset_foreach(const struct l_uintset *set, struct l_uintset *l_uintset_clone(const struct l_uintset *original); struct l_uintset *l_uintset_intersect(const struct l_uintset *set_a, const struct l_uintset *set_b); +struct l_uintset *l_uintset_subtract(const struct l_uintset *set_a, + const struct l_uintset *set_b); + bool l_uintset_isempty(const struct l_uintset *set); uint32_t l_uintset_size(const struct l_uintset *set); |