map_value_impl.c.h (1740B)
1 #include "nvim/assert_defs.h" 2 #include "nvim/map_defs.h" 3 4 #if !defined(KEY_NAME) || !defined(VAL_NAME) 5 // Don't error out. it is nice to type-check the file in isolation, in clangd or otherwise 6 # define KEY_NAME(x) x##int 7 # define VAL_NAME(x) quasiquote(x, ptr_t) 8 #endif 9 10 #define after_underscore(x) quasiquote(x, _) 11 #define MAP_NAME(x) VAL_NAME(after_underscore(KEY_NAME(x))) 12 #define MAP_TYPE MAP_NAME(Map_) 13 #define KEY_TYPE KEY_NAME() 14 #define VALUE_TYPE VAL_NAME() 15 #define INITIALIZER VAL_NAME(value_init_) 16 17 VALUE_TYPE *MAP_NAME(map_ref_)(MAP_TYPE *map, KEY_TYPE key, KEY_TYPE **key_alloc) 18 { 19 uint32_t k = KEY_NAME(mh_get_)(&map->set, key); 20 if (k == MH_TOMBSTONE) { 21 return NULL; 22 } 23 if (key_alloc) { 24 *key_alloc = &map->set.keys[k]; 25 } 26 return &map->values[k]; 27 } 28 29 VALUE_TYPE *MAP_NAME(map_put_ref_)(MAP_TYPE *map, KEY_TYPE key, KEY_TYPE **key_alloc, 30 bool *new_item) 31 { 32 MHPutStatus status; 33 uint32_t k = KEY_NAME(mh_put_)(&map->set, key, &status); 34 if (status != kMHExisting) { 35 if (status == kMHNewKeyRealloc) { 36 map->values = xrealloc(map->values, map->set.h.keys_capacity * sizeof(VALUE_TYPE)); 37 } 38 map->values[k] = INITIALIZER; 39 } 40 if (new_item) { 41 *new_item = (status != kMHExisting); 42 } 43 if (key_alloc) { 44 *key_alloc = &map->set.keys[k]; 45 } 46 return &map->values[k]; 47 } 48 49 VALUE_TYPE MAP_NAME(map_del_)(MAP_TYPE *map, KEY_TYPE key, KEY_TYPE *key_alloc) 50 { 51 VALUE_TYPE rv = INITIALIZER; 52 uint32_t k = KEY_NAME(mh_delete_)(&map->set, &key); 53 if (k == MH_TOMBSTONE) { 54 return rv; 55 } 56 57 if (key_alloc) { 58 *key_alloc = key; 59 } 60 rv = map->values[k]; 61 if (k != map->set.h.n_keys) { 62 map->values[k] = map->values[map->set.h.n_keys]; 63 } 64 return rv; 65 }