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) {
|
while (ptr != NULL) {
|
||||||
cmp = strcmp(key, ptr->key);
|
cmp = strcmp(key, ptr->key);
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
*p_value = ptr->value;
|
if (p_value) *p_value = ptr->value;
|
||||||
return DICT_OK;
|
return DICT_OK;
|
||||||
} else if (cmp < 0) {
|
} else if (cmp < 0) {
|
||||||
ptr = ptr->left;
|
ptr = ptr->left;
|
||||||
@@ -137,21 +137,25 @@ int dict_find(const struct dict* d, const char* key, void** p_value) {
|
|||||||
return DICT_NOT_FOUND;
|
return DICT_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* dict_iter_key(const struct dict_iter i) {
|
const char* dict_iter_key(const struct dict_iter* i) {
|
||||||
return STACK_HEAD(i.stack)->key;
|
return STACK_HEAD(i->stack)->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* dict_iter_value(struct dict_iter i) {
|
void* dict_iter_value(struct dict_iter* i) {
|
||||||
return STACK_HEAD(i.stack)->value;
|
return STACK_HEAD(i->stack)->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dict_iter dict_iter_begin(struct dict* d) {
|
struct dict_iter* dict_iter_begin(struct dict* d) {
|
||||||
struct dict_iter i;
|
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;
|
struct dict_node* ptr = NULL;
|
||||||
INIT_STACK(i.stack);
|
INIT_STACK(i->stack);
|
||||||
ptr = d->head;
|
ptr = d->head;
|
||||||
while (ptr != NULL) {
|
while (ptr != NULL) {
|
||||||
PUSH_STACK(DictTraversalStack, i.stack, ptr);
|
PUSH_STACK(DictTraversalStack, i->stack, ptr);
|
||||||
ptr = ptr->left;
|
ptr = ptr->left;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
@@ -167,8 +171,13 @@ void dict_iter_next(struct dict_iter* i) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dict_iter_done(const struct dict_iter i) {
|
int dict_iter_done(const struct dict_iter* i) {
|
||||||
return STACK_HEIGHT(i.stack) == 0;
|
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*)) {
|
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() {
|
int main() {
|
||||||
struct dict* d = dict_init();
|
struct dict* d = dict_init();
|
||||||
struct dict_iter i;
|
struct dict_iter* i;
|
||||||
int64_t n;
|
int64_t n;
|
||||||
dict_add(d, "apples", (void*)1);
|
dict_add(d, "apples", (void*)1);
|
||||||
dict_add(d, "foo", (void*)3);
|
dict_add(d, "foo", (void*)3);
|
||||||
@@ -235,9 +244,10 @@ int main() {
|
|||||||
printf("Failed to add duplicate (which is good)\n");
|
printf("Failed to add duplicate (which is good)\n");
|
||||||
}
|
}
|
||||||
printf("{ ");
|
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));
|
printf("\"%s\" : %lld, ", dict_iter_key(i), (int64_t)dict_iter_value(i));
|
||||||
}
|
}
|
||||||
|
dict_iter_free(i);
|
||||||
printf(" }\n");
|
printf(" }\n");
|
||||||
for (ptr = test_keys; *ptr != NULL; ptr++) {
|
for (ptr = test_keys; *ptr != NULL; ptr++) {
|
||||||
if (dict_find(d, *ptr, (void**)&n) == DICT_OK) {
|
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
|
* a dict_iter keeps state for an in-order traversal of the dictionary
|
||||||
*/
|
*/
|
||||||
const char* dict_iter_key(const struct dict_iter);
|
const char* dict_iter_key(const struct dict_iter*);
|
||||||
void* dict_iter_value(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*);
|
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) */
|
#endif /* !def(_DICT_H) */
|
||||||
|
|||||||
Reference in New Issue
Block a user