feat: added dictionary_try_get and _has_key
renamed get to get_raw and fixed a NULLreferenceexception
This commit is contained in:
parent
f4e0d89d0f
commit
afec949efd
|
@ -17,7 +17,7 @@ Dictionary dictionary_new(size_t element_size) {
|
||||||
|
|
||||||
Key* internal_dictionary_get(Dictionary* self, uintptr_t keyhash, size_t* out_index) {
|
Key* internal_dictionary_get(Dictionary* self, uintptr_t keyhash, size_t* out_index) {
|
||||||
if(self->list.len == 0) {
|
if(self->list.len == 0) {
|
||||||
*out_index = 0;
|
if(out_index) *out_index = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Key* element;
|
Key* element;
|
||||||
|
@ -37,10 +37,12 @@ Key* internal_dictionary_get(Dictionary* self, uintptr_t keyhash, size_t* out_in
|
||||||
return list_at_as(Key, &self->list, m);
|
return list_at_as(Key, &self->list, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* dictionary_get(Dictionary* self, const char* key) {
|
void* dictionary_get_raw(Dictionary* self, const char* key) {
|
||||||
uintptr_t hash = strhash(key);
|
uintptr_t hash = strhash(key);
|
||||||
Key* keyblock = internal_dictionary_get(self, hash, NULL);
|
Key* keyblock = internal_dictionary_get(self, hash, NULL);
|
||||||
return strcmp(key, keyblock->key) != 0 ? NULL : ((char*)keyblock) + sizeof(Key);
|
return keyblock == NULL || strcmp(key, keyblock->key) != 0
|
||||||
|
? NULL
|
||||||
|
: ((char*)keyblock) + sizeof(Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
|
@ -98,3 +100,15 @@ int dictionary_erase(Dictionary* self, const char* key) {
|
||||||
void dictionary_empty(Dictionary* self) {
|
void dictionary_empty(Dictionary* self) {
|
||||||
list_empty(&self->list);
|
list_empty(&self->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dictionary_has_key(Dictionary* self, const char* key) {
|
||||||
|
return dictionary_get_raw(self, key) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dictionary_try_get(Dictionary* self, const char* key, void* out) {
|
||||||
|
void* found = dictionary_get_raw(self, key);
|
||||||
|
if(found == NULL)
|
||||||
|
return 0;
|
||||||
|
memmove(out, found, self->element_size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -9,28 +9,39 @@ typedef struct Dictionary {
|
||||||
size_t element_size;
|
size_t element_size;
|
||||||
} Dictionary;
|
} Dictionary;
|
||||||
|
|
||||||
|
// returns a newly initialized dictionary
|
||||||
extern Dictionary dictionary_new(size_t element_size);
|
extern Dictionary dictionary_new(size_t element_size);
|
||||||
extern void* dictionary_get(Dictionary* self, const char* key);
|
// gets a voidptr to the value identified by key
|
||||||
|
extern void* dictionary_get_raw(Dictionary* self, const char* key);
|
||||||
|
// inserts or overwrites a new entry identified by key
|
||||||
extern int dictionary_set_raw(Dictionary* self, const char* key, void* data);
|
extern int dictionary_set_raw(Dictionary* self, const char* key, void* data);
|
||||||
|
// remove entry identified by key from dictionary
|
||||||
extern int dictionary_erase(Dictionary* self, const char* key);
|
extern int dictionary_erase(Dictionary* self, const char* key);
|
||||||
|
// clear the contents of the dictionary
|
||||||
|
// erases all heap-allocated memory, the dictionary can be safely freed after
|
||||||
extern void dictionary_empty(Dictionary* self);
|
extern void dictionary_empty(Dictionary* self);
|
||||||
|
// find out if the dictionary contains a value identified by this key
|
||||||
|
// returns 1 if the key was found
|
||||||
|
// returns 0 if the key was not found
|
||||||
|
extern int dictionary_has_key(Dictionary* self, const char* key);
|
||||||
|
// try to find value identified as key in the dictionary.
|
||||||
|
// return 1 if the value was found, 0 if not.
|
||||||
|
// if dictionary_try_get returns 0, memory at out will be unchanged,
|
||||||
|
// if dictionary_try_get returns 1, found value will be copied into out
|
||||||
|
extern int dictionary_try_get(Dictionary* self, const char* key, void* out);
|
||||||
|
|
||||||
static inline int dictionary_set_int(Dictionary* self, const char* key, int data) {
|
// insert or override value identified by key from a value type (supports rvalues)
|
||||||
return dictionary_set_raw(self, key, &data);
|
|
||||||
}
|
|
||||||
static inline int dictionary_set_unintptr(Dictionary* self, const char* key, uintptr_t data) {
|
|
||||||
return dictionary_set_raw(self, key, &data);
|
|
||||||
}
|
|
||||||
#define dictionary_set_value(Type_, Dict_, Key_, Value_)\
|
#define dictionary_set_value(Type_, Dict_, Key_, Value_)\
|
||||||
{ Type_ __value = (Type_)Value_; dictionary_set_raw(Dict_, Key_, &__value); }
|
{ Type_ __value = (Type_)Value_; dictionary_set_raw(Dict_, Key_, &__value); }
|
||||||
#define dictionary_check_size(Type_, Dict_)\
|
|
||||||
(Dict_)->element_size == sizeof(Type_)
|
|
||||||
|
|
||||||
|
// initialize dictionary to fit values of Type_
|
||||||
#define dictionary_from_type(Type_)\
|
#define dictionary_from_type(Type_)\
|
||||||
dictionary_new(sizeof(Type_))
|
dictionary_new(sizeof(Type_))
|
||||||
|
// get a pointer to value identified by Key_
|
||||||
#define dictionary_get_as(Type_, Dict_, Key_)\
|
#define dictionary_get_as(Type_, Dict_, Key_)\
|
||||||
(Type_*)dictionary_get(Dict_, Key_)
|
(Type_*)dictionary_get_raw(Dict_, Key_)
|
||||||
|
// get dereferenced value identified by Key_
|
||||||
#define dictionary_get_value(Type_, Dict_, Key_)\
|
#define dictionary_get_value(Type_, Dict_, Key_)\
|
||||||
*((Type_*)dictionary_get(Dict_, Key_))
|
*((Type_*)dictionary_get_raw(Dict_, Key_))
|
||||||
|
|
||||||
#endif // !_fencer_hash_map_h
|
#endif // !_fencer_hash_map_h
|
||||||
|
|
Loading…
Reference in a new issue