Changeset 70ce016 in mainline
- Timestamp:
- 2010-09-26T18:56:40Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2aa15d4, ec1bdc8
- Parents:
- 820ab55c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/adt/int_map.h
r820ab55c r70ce016 43 43 #include <unistd.h> 44 44 45 /** Internal magic value for a map consistency check. 46 */ 47 #define INT_MAP_MAGIC_VALUE 0x11223344 48 49 /** Internal magic value for an item consistency check. 50 */ 45 /** Internal magic value for a map consistency check. */ 46 #define INT_MAP_MAGIC_VALUE 0x11223344 47 48 /** Internal magic value for an item consistency check. */ 51 49 #define INT_MAP_ITEM_MAGIC_VALUE 0x55667788 52 50 53 51 /** Integer to generic type map declaration. 54 * @param[in] name Name of the map.55 * @param[in] type Inner object type.56 * /57 #define INT_MAP_DECLARE(name, type) \ 58 59 typedef struct name name##_t;\60 typedef name##_t * name##_ref;\61 typedef struct name##_item name##_item_t;\62 typedef name##_item_t * name##_item_ref;\63 64 struct name##_item{\65 int key;\66 type * value;\67 int magic;\68 };\69 70 struct name{\71 int size;\72 int next;\73 name##_item_ref items;\74 int magic;\75 };\76 77 int name##_add(name##_ref map, int key, type * value);\78 void name##_clear(name##_ref map);\79 int name##_count(name##_ref map);\80 void name##_destroy(name##_ref map);\81 void name##_exclude(name##_ref map, int key);\82 void name##_exclude_index(name##_ref map, int index);\83 type * name##_find(name##_ref map, int key);\84 int name##_update(name##_ref map, int key, int new_key);\85 type * name##_get_index(name##_ref map, int index);\86 int name##_initialize(name##_ref map);\87 int name##_is_valid(name##_ref map);\88 void name##_item_destroy(name##_item_ref item);\89 int name##_item_is_valid(name##_item_ref item);52 * 53 * @param[in] name Name of the map. 54 * @param[in] type Inner object type. 55 */ 56 #define INT_MAP_DECLARE(name, type) \ 57 typedef struct name name##_t; \ 58 typedef name##_t *name##_ref; \ 59 typedef struct name##_item name##_item_t; \ 60 typedef name##_item_t *name##_item_ref; \ 61 \ 62 struct name##_item { \ 63 int key; \ 64 type *value; \ 65 int magic; \ 66 }; \ 67 \ 68 struct name { \ 69 int size; \ 70 int next; \ 71 name##_item_ref items; \ 72 int magic; \ 73 }; \ 74 \ 75 int name##_add(name##_ref, int, type *); \ 76 void name##_clear(name##_ref); \ 77 int name##_count(name##_ref); \ 78 void name##_destroy(name##_ref); \ 79 void name##_exclude(name##_ref, int); \ 80 void name##_exclude_index(name##_ref, int); \ 81 type *name##_find(name##_ref, int); \ 82 int name##_update(name##_ref, int, int); \ 83 type *name##_get_index(name##_ref, int); \ 84 int name##_initialize(name##_ref); \ 85 int name##_is_valid(name##_ref); \ 86 void name##_item_destroy(name##_item_ref); \ 87 int name##_item_is_valid(name##_item_ref); 90 88 91 89 /** Integer to generic type map implementation. 92 * Should follow declaration with the same parameters. 93 * @param[in] name Name of the map. 94 * @param[in] type Inner object type. 95 */ 96 #define INT_MAP_IMPLEMENT(name, type) \ 97 \ 98 int name##_add(name##_ref map, int key, type * value){ \ 99 if(name##_is_valid(map)){ \ 100 if(map->next == (map->size - 1)){ \ 101 name##_item_ref tmp; \ 102 \ 103 tmp = (name##_item_ref) realloc(map->items, sizeof(name##_item_t) * 2 * map->size); \ 104 if(! tmp){ \ 105 return ENOMEM; \ 106 } \ 107 map->size *= 2; \ 108 map->items = tmp; \ 109 } \ 110 map->items[map->next].key = key; \ 111 map->items[map->next].value = value; \ 112 map->items[map->next].magic = INT_MAP_ITEM_MAGIC_VALUE; \ 113 ++ map->next; \ 114 map->items[map->next].magic = 0; \ 115 return map->next - 1; \ 116 } \ 117 return EINVAL; \ 118 } \ 119 \ 120 void name##_clear(name##_ref map){ \ 121 if(name##_is_valid(map)){ \ 122 int index; \ 123 \ 124 /* map->magic = 0;*/ \ 125 for(index = 0; index < map->next; ++ index){ \ 126 if(name##_item_is_valid(&(map->items[index]))){ \ 127 name##_item_destroy(&(map->items[index])); \ 128 } \ 129 } \ 130 map->next = 0; \ 131 map->items[map->next].magic = 0; \ 132 /* map->magic = INT_MAP_MAGIC_VALUE;*/ \ 133 } \ 134 } \ 135 \ 136 int name##_count(name##_ref map){ \ 137 return name##_is_valid(map) ? map->next : -1; \ 138 } \ 139 \ 140 void name##_destroy(name##_ref map){ \ 141 if(name##_is_valid(map)){ \ 142 int index; \ 143 \ 144 map->magic = 0; \ 145 for(index = 0; index < map->next; ++ index){ \ 146 if(name##_item_is_valid(&(map->items[index]))){ \ 147 name##_item_destroy(&(map->items[index])); \ 148 } \ 149 } \ 150 free(map->items); \ 151 } \ 152 } \ 153 \ 154 void name##_exclude(name##_ref map, int key){ \ 155 if(name##_is_valid(map)){ \ 156 int index; \ 157 \ 158 for(index = 0; index < map->next; ++ index){ \ 159 if(name##_item_is_valid(&(map->items[index])) && (map->items[index].key == key)){ \ 160 name##_item_destroy(&(map->items[index])); \ 161 } \ 162 } \ 163 } \ 164 } \ 165 \ 166 void name##_exclude_index(name##_ref map, int index){ \ 167 if(name##_is_valid(map) && (index >= 0) && (index < map->next) && name##_item_is_valid(&(map->items[index]))){ \ 168 name##_item_destroy(&(map->items[index])); \ 169 } \ 170 } \ 171 \ 172 type * name##_find(name##_ref map, int key){ \ 173 if(name##_is_valid(map)){ \ 174 int index; \ 175 \ 176 for(index = 0; index < map->next; ++ index){ \ 177 if(name##_item_is_valid(&(map->items[index])) && (map->items[index].key == key)){ \ 178 return map->items[index].value; \ 179 } \ 180 } \ 181 } \ 182 return NULL; \ 183 } \ 184 \ 185 int name##_update(name##_ref map, int key, int new_key){ \ 186 if(name##_is_valid(map)){ \ 187 int index; \ 188 \ 189 for(index = 0; index < map->next; ++ index){ \ 190 if(name##_item_is_valid(&(map->items[index]))){ \ 191 if(map->items[index].key == new_key){ \ 192 return EEXIST; \ 193 }else if(map->items[index].key == key){ \ 194 map->items[index].key = new_key; \ 195 return EOK; \ 196 } \ 197 } \ 198 } \ 199 } \ 200 return ENOENT; \ 201 } \ 202 \ 203 type * name##_get_index(name##_ref map, int index){ \ 204 if(name##_is_valid(map) && (index >= 0) && (index < map->next) && name##_item_is_valid(&(map->items[index]))){ \ 205 return map->items[index].value; \ 206 } \ 207 return NULL; \ 208 } \ 209 \ 210 int name##_initialize(name##_ref map){ \ 211 if(! map){ \ 212 return EINVAL; \ 213 } \ 214 map->size = 2; \ 215 map->next = 0; \ 216 map->items = (name##_item_ref) malloc(sizeof(name##_item_t) * map->size); \ 217 if(! map->items){ \ 218 return ENOMEM; \ 219 } \ 220 map->items[map->next].magic = 0; \ 221 map->magic = INT_MAP_MAGIC_VALUE; \ 222 return EOK; \ 223 } \ 224 \ 225 int name##_is_valid(name##_ref map){ \ 226 return map && (map->magic == INT_MAP_MAGIC_VALUE); \ 227 } \ 228 \ 229 void name##_item_destroy(name##_item_ref item){ \ 230 if(name##_item_is_valid(item)){ \ 231 item->magic = 0; \ 232 if(item->value){ \ 233 free(item->value); \ 234 item->value = NULL; \ 235 } \ 236 } \ 237 } \ 238 \ 239 int name##_item_is_valid(name##_item_ref item){ \ 240 return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE); \ 241 } 90 * 91 * Should follow declaration with the same parameters. 92 * 93 * @param[in] name Name of the map. 94 * @param[in] type Inner object type. 95 */ 96 #define INT_MAP_IMPLEMENT(name, type) \ 97 int name##_add(name##_ref map, int key, type *value) \ 98 { \ 99 if (name##_is_valid(map)) { \ 100 if (map->next == (map->size - 1)) { \ 101 name##_item_ref tmp; \ 102 tmp = (name##_item_ref) realloc(map->items, \ 103 sizeof(name##_item_t) * 2 * map->size); \ 104 if (!tmp) \ 105 return ENOMEM; \ 106 map->size *= 2; \ 107 map->items = tmp; \ 108 } \ 109 map->items[map->next].key = key; \ 110 map->items[map->next].value = value; \ 111 map->items[map->next].magic = INT_MAP_ITEM_MAGIC_VALUE; \ 112 ++map->next; \ 113 map->items[map->next].magic = 0; \ 114 return map->next - 1; \ 115 } \ 116 return EINVAL; \ 117 } \ 118 \ 119 void name##_clear(name##_ref map) \ 120 { \ 121 if (name##_is_valid(map)) { \ 122 int index; \ 123 for (index = 0; index < map->next; ++index) { \ 124 if (name##_item_is_valid(&map->items[index])) { \ 125 name##_item_destroy( \ 126 &map->items[index]); \ 127 } \ 128 } \ 129 map->next = 0; \ 130 map->items[map->next].magic = 0; \ 131 } \ 132 } \ 133 \ 134 int name##_count(name##_ref map) \ 135 { \ 136 return name##_is_valid(map) ? map->next : -1; \ 137 } \ 138 \ 139 void name##_destroy(name##_ref map) \ 140 { \ 141 if (name##_is_valid(map)) { \ 142 int index; \ 143 map->magic = 0; \ 144 for (index = 0; index < map->next; ++index) { \ 145 if (name##_item_is_valid(&map->items[index])) { \ 146 name##_item_destroy( \ 147 &map->items[index]); \ 148 } \ 149 } \ 150 free(map->items); \ 151 } \ 152 } \ 153 \ 154 void name##_exclude(name##_ref map, int key) \ 155 { \ 156 if (name##_is_valid(map)) { \ 157 int index; \ 158 for (index = 0; index < map->next; ++index) { \ 159 if (name##_item_is_valid(&map->items[index]) && \ 160 (map->items[index].key == key)) { \ 161 name##_item_destroy( \ 162 &map->items[index]); \ 163 } \ 164 } \ 165 } \ 166 } \ 167 \ 168 void name##_exclude_index(name##_ref map, int index) \ 169 { \ 170 if (name##_is_valid(map) && (index >= 0) && \ 171 (index < map->next) && \ 172 name##_item_is_valid(&map->items[index])) { \ 173 name##_item_destroy(&map->items[index]); \ 174 } \ 175 } \ 176 \ 177 type *name##_find(name##_ref map, int key) \ 178 { \ 179 if (name##_is_valid(map)) { \ 180 int index; \ 181 for (index = 0; index < map->next; ++index) { \ 182 if (name##_item_is_valid(&map->items[index]) && \ 183 (map->items[index].key == key)) { \ 184 return map->items[index].value; \ 185 } \ 186 } \ 187 } \ 188 return NULL; \ 189 } \ 190 \ 191 int name##_update(name##_ref map, int key, int new_key) \ 192 { \ 193 if (name##_is_valid(map)) { \ 194 int index; \ 195 for (index = 0; index < map->next; ++index) { \ 196 if (name##_item_is_valid(&map->items[index])) { \ 197 if (map->items[index].key == new_key) \ 198 return EEXIST; \ 199 if (map->items[index].key == key) { \ 200 map->items[index].key = \ 201 new_key; \ 202 return EOK; \ 203 } \ 204 } \ 205 } \ 206 } \ 207 return ENOENT; \ 208 } \ 209 \ 210 type *name##_get_index(name##_ref map, int index) \ 211 { \ 212 if (name##_is_valid(map) && (index >= 0) && \ 213 (index < map->next) && \ 214 name##_item_is_valid(&map->items[index])) { \ 215 return map->items[index].value; \ 216 } \ 217 return NULL; \ 218 } \ 219 \ 220 int name##_initialize(name##_ref map) \ 221 { \ 222 if (!map) \ 223 return EINVAL; \ 224 map->size = 2; \ 225 map->next = 0; \ 226 map->items = (name##_item_ref) malloc(sizeof(name##_item_t) * \ 227 map->size); \ 228 if (!map->items) \ 229 return ENOMEM; \ 230 map->items[map->next].magic = 0; \ 231 map->magic = INT_MAP_MAGIC_VALUE; \ 232 return EOK; \ 233 } \ 234 \ 235 int name##_is_valid(name##_ref map) \ 236 { \ 237 return map && (map->magic == INT_MAP_MAGIC_VALUE); \ 238 } \ 239 \ 240 void name##_item_destroy(name##_item_ref item) \ 241 { \ 242 if (name##_item_is_valid(item)) { \ 243 item->magic = 0; \ 244 if (item->value) { \ 245 free(item->value); \ 246 item->value = NULL; \ 247 } \ 248 } \ 249 } \ 250 \ 251 int name##_item_is_valid(name##_item_ref item) \ 252 { \ 253 return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE); \ 254 } 242 255 243 256 #endif
Note:
See TracChangeset
for help on using the changeset viewer.