#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_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