Re-abstract dictionary iterator interface
This commit is contained in:
36
src/dict.c
36
src/dict.c
@@ -125,7 +125,7 @@ int dict_find(const struct dict* d, const char* key, void** p_value) {
|
||||
while (ptr != NULL) {
|
||||
cmp = strcmp(key, ptr->key);
|
||||
if (cmp == 0) {
|
||||
*p_value = ptr->value;
|
||||
if (p_value) *p_value = ptr->value;
|
||||
return DICT_OK;
|
||||
} else if (cmp < 0) {
|
||||
ptr = ptr->left;
|
||||
@@ -137,21 +137,25 @@ int dict_find(const struct dict* d, const char* key, void** p_value) {
|
||||
return DICT_NOT_FOUND;
|
||||
}
|
||||
|
||||
const char* dict_iter_key(const struct dict_iter i) {
|
||||
return STACK_HEAD(i.stack)->key;
|
||||
const char* dict_iter_key(const struct dict_iter* i) {
|
||||
return STACK_HEAD(i->stack)->key;
|
||||
}
|
||||
|
||||
void* dict_iter_value(struct dict_iter i) {
|
||||
return STACK_HEAD(i.stack)->value;
|
||||
void* dict_iter_value(struct dict_iter* i) {
|
||||
return STACK_HEAD(i->stack)->value;
|
||||
}
|
||||
|
||||
struct dict_iter dict_iter_begin(struct dict* d) {
|
||||
struct dict_iter i;
|
||||
struct dict_iter* dict_iter_begin(struct dict* d) {
|
||||
struct dict_iter* i = malloc(sizeof(struct dict_iter));
|
||||
if (i == NULL) {
|
||||
perror("Could not allocate new dict_iter");
|
||||
exit(1);
|
||||
}
|
||||
struct dict_node* ptr = NULL;
|
||||
INIT_STACK(i.stack);
|
||||
INIT_STACK(i->stack);
|
||||
ptr = d->head;
|
||||
while (ptr != NULL) {
|
||||
PUSH_STACK(DictTraversalStack, i.stack, ptr);
|
||||
PUSH_STACK(DictTraversalStack, i->stack, ptr);
|
||||
ptr = ptr->left;
|
||||
}
|
||||
return i;
|
||||
@@ -167,8 +171,13 @@ void dict_iter_next(struct dict_iter* i) {
|
||||
}
|
||||
}
|
||||
|
||||
int dict_iter_done(const struct dict_iter i) {
|
||||
return STACK_HEIGHT(i.stack) == 0;
|
||||
int dict_iter_done(const struct dict_iter* i) {
|
||||
return STACK_HEIGHT(i->stack) == 0;
|
||||
}
|
||||
|
||||
void dict_iter_free(struct dict_iter* i) {
|
||||
DESTROY_STACK(DictTraversalStack, i->stack);
|
||||
free(i);
|
||||
}
|
||||
|
||||
void dict_free_cb(struct dict* d, void (*callback)(const char*, void*)) {
|
||||
@@ -225,7 +234,7 @@ void mycb(const char* key, void* value) {
|
||||
|
||||
int main() {
|
||||
struct dict* d = dict_init();
|
||||
struct dict_iter i;
|
||||
struct dict_iter* i;
|
||||
int64_t n;
|
||||
dict_add(d, "apples", (void*)1);
|
||||
dict_add(d, "foo", (void*)3);
|
||||
@@ -235,9 +244,10 @@ int main() {
|
||||
printf("Failed to add duplicate (which is good)\n");
|
||||
}
|
||||
printf("{ ");
|
||||
for (i = dict_iter_begin(d); !dict_iter_done(i); dict_iter_next(&i)) {
|
||||
for (i = dict_iter_begin(d); !dict_iter_done(i); dict_iter_next(i)) {
|
||||
printf("\"%s\" : %lld, ", dict_iter_key(i), (int64_t)dict_iter_value(i));
|
||||
}
|
||||
dict_iter_free(i);
|
||||
printf(" }\n");
|
||||
for (ptr = test_keys; *ptr != NULL; ptr++) {
|
||||
if (dict_find(d, *ptr, (void**)&n) == DICT_OK) {
|
||||
|
||||
@@ -51,11 +51,12 @@ unsigned int dict_size(const struct dict*);
|
||||
/*
|
||||
* a dict_iter keeps state for an in-order traversal of the dictionary
|
||||
*/
|
||||
const char* dict_iter_key(const struct dict_iter);
|
||||
void* dict_iter_value(struct dict_iter);
|
||||
const char* dict_iter_key(const struct dict_iter*);
|
||||
void* dict_iter_value(struct dict_iter*);
|
||||
|
||||
struct dict_iter dict_iter_begin(struct dict*);
|
||||
struct dict_iter* dict_iter_begin(struct dict*);
|
||||
void dict_iter_next(struct dict_iter*);
|
||||
int dict_iter_done(const struct dict_iter);
|
||||
int dict_iter_done(const struct dict_iter*);
|
||||
void dict_iter_free(struct dict_iter*);
|
||||
|
||||
#endif /* !def(_DICT_H) */
|
||||
|
||||
Reference in New Issue
Block a user