core/set: Add new struct to act as a set
The glib library doesn't have a dedicated "set" container, so I need to create a wrapper around a hash table to accomplish the same results. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
9e0c4404fc
commit
4d065508cd
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2015 (c) Anna Schumaker.
|
||||
*/
|
||||
#ifndef OCARINA_CORE_SET_H
|
||||
#define OCARINA_CORE_SET_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
struct set {
|
||||
GHashTable *s_set;
|
||||
};
|
||||
|
||||
struct set_iter {
|
||||
unsigned int it_val;
|
||||
GHashTableIter it_iter;
|
||||
};
|
||||
|
||||
|
||||
#define SET_INIT() \
|
||||
{ \
|
||||
.s_set = g_hash_table_new(g_direct_hash, g_direct_equal), \
|
||||
}
|
||||
|
||||
|
||||
static inline void set_deinit(struct set *set)
|
||||
{
|
||||
g_hash_table_destroy(set->s_set);
|
||||
}
|
||||
|
||||
static inline void set_insert(struct set *set, unsigned int value)
|
||||
{
|
||||
g_hash_table_add(set->s_set, GUINT_TO_POINTER(value));
|
||||
}
|
||||
|
||||
static inline void set_remove(struct set *set, unsigned int value)
|
||||
{
|
||||
g_hash_table_remove(set->s_set, GUINT_TO_POINTER(value));
|
||||
}
|
||||
|
||||
static inline bool set_has(const struct set *set, unsigned int value)
|
||||
{
|
||||
return g_hash_table_contains(set->s_set, GUINT_TO_POINTER(value));
|
||||
}
|
||||
|
||||
static inline unsigned int set_size(struct set *set)
|
||||
{
|
||||
return g_hash_table_size(set->s_set);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline bool set_iter_next(struct set_iter *it)
|
||||
{
|
||||
gpointer key;
|
||||
bool ret = g_hash_table_iter_next(&it->it_iter, &key, NULL);
|
||||
it->it_val = GPOINTER_TO_INT(key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void set_iter_init(const struct set *set, struct set_iter *it)
|
||||
{
|
||||
g_hash_table_iter_init(&it->it_iter, set->s_set);
|
||||
}
|
||||
|
||||
#define set_for_each(set, it) \
|
||||
for (set_iter_init(set, it); set_iter_next(it); )
|
||||
|
||||
#endif /* OCARINA_CORE_SET_H */
|
|
@ -1,15 +1,16 @@
|
|||
version
|
||||
string
|
||||
file
|
||||
date
|
||||
audio
|
||||
database
|
||||
index
|
||||
filter
|
||||
idle
|
||||
random
|
||||
queue
|
||||
library
|
||||
playlist
|
||||
date
|
||||
deck
|
||||
driver
|
||||
audio
|
||||
file
|
||||
filter
|
||||
idle
|
||||
index
|
||||
library
|
||||
playlist
|
||||
queue
|
||||
random
|
||||
set
|
||||
string
|
||||
version
|
||||
|
|
|
@ -18,6 +18,7 @@ res += [ CoreTest("string", "string.c") ]
|
|||
res += [ CoreTest("random", "random.c") ]
|
||||
res += [ CoreTest("file", "file.c") ]
|
||||
res += [ CoreTest("date", "date.c") ]
|
||||
res += [ CoreTest("set", "set.c") ]
|
||||
res += [ CoreTest("database", "database.cpp") ]
|
||||
res += [ CoreTest("index", "index.cpp") ]
|
||||
res += [ CoreTest("filter", "filter.cpp") ]
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2015 (c) Anna Schumaker.
|
||||
*/
|
||||
#include <core/set.h>
|
||||
#include <tests/test.h>
|
||||
|
||||
|
||||
void test_set()
|
||||
{
|
||||
struct set set = SET_INIT();
|
||||
unsigned int i, N = 10;
|
||||
struct set_iter it;
|
||||
|
||||
/* Insert N items. */
|
||||
for (i = 0; i < N; i++) {
|
||||
set_insert(&set, i);
|
||||
set_insert(&set, i);
|
||||
test_loop_equal(set_size(&set), i + 1, i);
|
||||
test_loop_equal(set_has(&set, i), (bool)true, i);
|
||||
} test_loop_passed();
|
||||
|
||||
set_insert(&set, 0);
|
||||
test_equal(set_size(&set), N);
|
||||
|
||||
/* Remove even items. */
|
||||
for (i = 0; i < N; i += 2) {
|
||||
set_remove(&set, i);
|
||||
set_remove(&set, i);
|
||||
test_loop_equal(set_has(&set, i), (bool)false, i);
|
||||
} test_loop_passed();
|
||||
test_equal(set_size(&set), N / 2);
|
||||
|
||||
/* Test iterating. */
|
||||
i = 1;
|
||||
set_for_each(&set, &it) {
|
||||
test_loop_equal(it.it_val, i, i);
|
||||
i += 2;
|
||||
} test_loop_passed();
|
||||
|
||||
set_deinit(&set);
|
||||
}
|
||||
|
||||
DECLARE_UNIT_TESTS(
|
||||
UNIT_TEST("Set", test_set),
|
||||
);
|
Loading…
Reference in New Issue