#ifndef _UTIL_DICT_H #define _UTIL_DICT_H #include "linked_list.h" template struct dict_entry { T key; V value; }; template struct Dict { struct dict_entry d; struct Dict* prev; struct Dict* next; }; template size_t dict_count(struct Dict* d) { return linked_list_count((struct LinkedList>*)d); } template void dict_free(struct Dict*& d, void(*free_func)(struct dict_entry) = nullptr) { return linked_list_clear((struct LinkedList>*&)d, free_func); } template bool dict_get_internal(struct dict_entry o, K key) { return o.key == key; } template struct dict_entry* dict_get(struct Dict* d, K key) { struct Dict* re = (struct Dict*)linked_list_get((struct LinkedList>*)d, key, &dict_get_internal); if (!re) return nullptr; return &re->d; } template V dict_get_value(struct Dict* d, K key) { struct dict_entry* re = dict_get(d, key); if (!re) return nullptr; return re->value; } template bool dict_heve_key_internal(struct dict_entry origin, K key) { return key == origin.key; } template bool dict_have_key(struct Dict* d, K key) { return linked_list_have((struct LinkedList>*)d, key, &dict_heve_key_internal); } template void dict_iter(struct Dict* d, void(*callback)(K key, V value, Args... args), Args... args) { if (!d || !callback) return; struct Dict* t = d; callback(t->d.key, t->d.value, args...); while (t->next) { t = t->next; callback(t->d.key, t->d.value, args...); } } template void dict_iter(struct Dict* d, void(*callback)(size_t index, K key, V value, Args... args), Args... args) { if (!d || !callback) return; struct Dict* t = d; size_t i = 0; callback(i, t->d.key, t->d.value, args...); while (t->next) { t = t->next; i++; callback(i, t->d.key, t->d.value, args...); } } template bool dict_set(struct Dict*& d, K key, V value, void(*free_func)(V) = nullptr) { if (!d) { struct dict_entry v = { key, value }; return linked_list_append((struct LinkedList>*&)d, &v); } struct Dict* t = d; if (t->d.key == key) { if (free_func) free_func(t->d.value); t->d.value = value; return true; } while (t->next) { t = t->next; if (t->d.key == key) { if (free_func) free_func(t->d.value); t->d.value = value; return true; } } struct dict_entry v = { key, value }; return linked_list_append((struct LinkedList>*&)d, &v); } template bool dict_set(struct Dict*& d, K key, V value, void(*value_copy_func)(V, V), void(*free_func)(V) = nullptr) { if (!value_copy_func) return false; if (!d) { struct dict_entry v; v.key = key; value_copy_func(v.value, value); return linked_list_append((struct LinkedList>*&)d, &v); } struct Dict* t = d; if (t->d.key == key) { if (free_func) free_func(t->d.value); value_copy_func(t->d.value, value); return true; } while (t->next) { t = t->next; if (t->d.key == key) { if (free_func) free_func(t->d.value); value_copy_func(t->d.value, value); return true; } } struct dict_entry v; v.key = key; value_copy_func(v.value, value); return linked_list_append((struct LinkedList>*&)d, &v); } #endif