source: mainline/uspace/lib/c/include/adt/int_map.h@ 4edd39fc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4edd39fc was 2544442, checked in by Jakub Jermar <jakub@…>, 15 years ago

Fix doxygen doc groups (libc vs. net) and header guards.

  • Property mode set to 100644
File size: 8.9 KB
RevLine 
[21580dd]1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[2544442]29/** @addtogroup libc
[21580dd]30 * @{
31 */
32
33/** @file
34 * Integer to generic type map.
35 */
36
[2544442]37#ifndef LIBC_INT_MAP_H_
38#define LIBC_INT_MAP_H_
[21580dd]39
40#include <errno.h>
41#include <malloc.h>
42#include <mem.h>
43#include <unistd.h>
44
45/** Internal magic value for a&nbsp;map consistency check.
46 */
47#define INT_MAP_MAGIC_VALUE 0x11223344
48
49/** Internal magic value for an item consistency check.
50 */
51#define INT_MAP_ITEM_MAGIC_VALUE 0x55667788
52
53/** Integer to generic type map declaration.
54 * @param[in] name Name of the map.
55 * @param[in] type Inner object type.
56 */
[aadf01e]57#define INT_MAP_DECLARE(name, type) \
[21580dd]58 \
59typedef struct name name##_t; \
60typedef name##_t * name##_ref; \
61typedef struct name##_item name##_item_t; \
62typedef name##_item_t * name##_item_ref; \
63 \
64struct name##_item{ \
[aadf01e]65 int key; \
66 type * value; \
67 int magic; \
[21580dd]68}; \
69 \
70struct name{ \
[aadf01e]71 int size; \
72 int next; \
73 name##_item_ref items; \
74 int magic; \
[21580dd]75}; \
76 \
[aadf01e]77int name##_add(name##_ref map, int key, type * value); \
78void name##_clear(name##_ref map); \
79int name##_count(name##_ref map); \
80void name##_destroy(name##_ref map); \
81void name##_exclude(name##_ref map, int key); \
82void name##_exclude_index(name##_ref map, int index); \
83type * name##_find(name##_ref map, int key); \
84int name##_update(name##_ref map, int key, int new_key); \
85type * name##_get_index(name##_ref map, int index); \
86int name##_initialize(name##_ref map); \
87int name##_is_valid(name##_ref map); \
88void name##_item_destroy(name##_item_ref item); \
89int name##_item_is_valid(name##_item_ref item);
[21580dd]90
91/** 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 */
[aadf01e]96#define INT_MAP_IMPLEMENT(name, type) \
[21580dd]97 \
[aadf01e]98int 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; \
[21580dd]102 \
[aadf01e]103 tmp = (name##_item_ref) realloc(map->items, sizeof(name##_item_t) * 2 * map->size); \
104 if(! tmp){ \
105 return ENOMEM; \
106 } \
[21580dd]107 map->size *= 2; \
108 map->items = tmp; \
109 } \
[aadf01e]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; \
[21580dd]113 ++ map->next; \
[aadf01e]114 map->items[map->next].magic = 0; \
[21580dd]115 return map->next - 1; \
116 } \
117 return EINVAL; \
118} \
119 \
[aadf01e]120void name##_clear(name##_ref map){ \
121 if(name##_is_valid(map)){ \
122 int index; \
[21580dd]123 \
124/* map->magic = 0;*/ \
[aadf01e]125 for(index = 0; index < map->next; ++ index){ \
126 if(name##_item_is_valid(&(map->items[index]))){ \
127 name##_item_destroy(&(map->items[index])); \
[21580dd]128 } \
129 } \
130 map->next = 0; \
[aadf01e]131 map->items[map->next].magic = 0; \
[21580dd]132/* map->magic = INT_MAP_MAGIC_VALUE;*/ \
133 } \
134} \
135 \
[aadf01e]136int name##_count(name##_ref map){ \
137 return name##_is_valid(map) ? map->next : -1; \
[21580dd]138} \
139 \
[aadf01e]140void name##_destroy(name##_ref map){ \
141 if(name##_is_valid(map)){ \
142 int index; \
[21580dd]143 \
144 map->magic = 0; \
[aadf01e]145 for(index = 0; index < map->next; ++ index){ \
146 if(name##_item_is_valid(&(map->items[index]))){ \
147 name##_item_destroy(&(map->items[index])); \
[21580dd]148 } \
149 } \
[aadf01e]150 free(map->items); \
[21580dd]151 } \
152} \
153 \
[aadf01e]154void name##_exclude(name##_ref map, int key){ \
155 if(name##_is_valid(map)){ \
156 int index; \
[21580dd]157 \
[aadf01e]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])); \
[21580dd]161 } \
162 } \
163 } \
164} \
165 \
[aadf01e]166void 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])); \
[21580dd]169 } \
170} \
171 \
[aadf01e]172type * name##_find(name##_ref map, int key){ \
173 if(name##_is_valid(map)){ \
174 int index; \
[21580dd]175 \
[aadf01e]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; \
[21580dd]179 } \
180 } \
181 } \
182 return NULL; \
183} \
184 \
[aadf01e]185int name##_update(name##_ref map, int key, int new_key){ \
186 if(name##_is_valid(map)){ \
187 int index; \
[ede63e4]188 \
[aadf01e]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){ \
[ede63e4]192 return EEXIST; \
[aadf01e]193 }else if(map->items[index].key == key){ \
194 map->items[index].key = new_key; \
[ede63e4]195 return EOK; \
196 } \
197 } \
198 } \
199 } \
200 return ENOENT; \
201} \
202 \
[aadf01e]203type * 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; \
[21580dd]206 } \
207 return NULL; \
208} \
209 \
[aadf01e]210int name##_initialize(name##_ref map){ \
211 if(! map){ \
212 return EINVAL; \
213 } \
[21580dd]214 map->size = 2; \
215 map->next = 0; \
[aadf01e]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; \
[21580dd]221 map->magic = INT_MAP_MAGIC_VALUE; \
222 return EOK; \
223} \
224 \
[aadf01e]225int name##_is_valid(name##_ref map){ \
226 return map && (map->magic == INT_MAP_MAGIC_VALUE); \
[21580dd]227} \
228 \
[aadf01e]229void name##_item_destroy(name##_item_ref item){ \
230 if(name##_item_is_valid(item)){ \
[21580dd]231 item->magic = 0; \
[aadf01e]232 if(item->value){ \
233 free(item->value); \
[21580dd]234 item->value = NULL; \
235 } \
236 } \
237} \
238 \
[aadf01e]239int name##_item_is_valid(name##_item_ref item){ \
240 return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE); \
[21580dd]241}
242
243#endif
244
245/** @}
246 */
247
Note: See TracBrowser for help on using the repository browser.