burkey.co /docs/libflint/set
index set
~/docs/libflint/set.md
libflint

Set

libflint·Data Structures

A small collection of unique void * values. Membership is linear in the size of the set. Use the set functions to preserve uniqueness. For hashed membership, see hashset.

Usage#

Initialize the set with an equality callback and an optional payload destructor. The equality callback returns 0 for equal values. This example passes NULL for the destructor because its payloads are stack allocated.

int int_match(const void *a, const void *b) {
    return *(const int *)a == *(const int *)b ? 0 : 1;
}

Set set;
if (set_init(&set, int_match, NULL) == 0) {
    int value = 1;
    int duplicate = 1;
    set_insert(&set, &value);
    set_insert(&set, &duplicate); /* Keeps value if the first insert succeeded. */
    set_destroy(&set);
}

set_destroy frees the nodes and calls the destructor on remaining payloads. It does not free the Set handle. Keep values unchanged in ways that affect equality while stored.

Structs#

Set#

typedef struct {
    List impl;
} Set;

match is required at set_init. It returns 0 if two elements are equal (the same convention as strcmp). Compare with ==, not subtraction, so signed overflow is not an issue.

Functions#

set_init#

Initializes the set. The user owns the Set handle. match is required; destroy is optional and is called on members only by set_destroy. Returns 0 on success, -1 if set or match is NULL.

int set_init(Set *set, int (*match)(const void *a, const void *b),
             void (*destroy)(void *data));

/* Usage */
int int_match(const void *a, const void *b) {
    return *(const int *)a == *(const int *)b ? 0 : 1;
}

Set set;
set_init(&set, int_match, NULL);

set_destroy#

Destroys the nodes inside a Set and calls the deallocation function on the data if one was provided. Does not destroy the set itself, that is left up to the user.

void set_destroy(Set *set);

/* Usage */
set_destroy(&set);

set_insert#

Inserts data into the set. If data is already a member (determined by the match function), the insertion is skipped and 1 is returned. Returns 0 on successful insertion, -1 on error. Duplicate and failed inserts leave the payload with the caller.

int set_insert(Set *set, const void *data);

/* Usage */
int a = 1;
int b = 1;
set_insert(&set, &a); /* returns 0, inserted */
set_insert(&set, &b); /* returns 1, duplicate skipped */

set_remove#

Removes the element matching *data from the set. data is updated to point to the removed element's data so the user can manage its memory. The destructor is not called. Returns 0 on success, -1 if the element is not found or if data is NULL.

int set_remove(Set *set, void **data);

/* Usage */
int key = 1;
void *removed = &key;
set_remove(&set, &removed);

Algebra (borrowed)#

set_union, set_intersection, and set_difference write into a destination you initialize. The destination must be empty, use the same match as a and b, and have destroy == NULL. Result members alias the payloads in a and b. Do not destroy a or b while the result is in use. dest cannot be a or b. Returns 0 on success, -1 on error. Allocation failure leaves the destination empty and initialized.

int set_union(Set *dest, const Set *a, const Set *b);
int set_intersection(Set *dest, const Set *a, const Set *b);
int set_difference(Set *dest, const Set *a, const Set *b);

/* Usage */
Set result;
set_init(&result, int_match, NULL);
set_union(&result, &set1, &set2);
/* use result, then: */
set_destroy(&result); /* nodes only; payloads still owned by set1/set2 */

Union contains every element from a or b. Intersection contains elements present in both. Difference is elements in a that are not in b.

set_is_member#

Returns 1 if data is a member of the set, 0 otherwise.

int set_is_member(const Set *set, const void *data);

set_is_subset#

Returns 1 if a is a subset of b (every element in a is also in b), 0 otherwise.

int set_is_subset(const Set *a, const Set *b);

set_is_equal#

Returns 1 if sets a and b contain the same elements, 0 otherwise.

int set_is_equal(const Set *a, const Set *b);

Macros#

set_size#

Returns the number of elements in the set.

#define set_size(s) ((s)->impl.size)