1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 #ifndef LIBPSPP_STRINGI_MAP_H
18 #define LIBPSPP_STRINGI_MAP_H
20 /* Map from a unique, case-insensitve string key to a string value.
22 This is a convenient wrapper around a "struct hmap" for storing string
26 #include "libpspp/hmap.h"
31 /* A node within a string map. */
32 struct stringi_map_node
34 struct hmap_node hmap_node;
39 /* Returns the string key within NODE. The caller must not modify or free the
41 static inline const char *
42 stringi_map_node_get_key (const struct stringi_map_node *node)
47 /* Returns the string key within NODE. The caller must not free the returned
49 static inline const char *
50 stringi_map_node_get_value (const struct stringi_map_node *node)
55 /* Returns the string key within NODE. The caller must not free the returned
58 stringi_map_node_get_value_rw (struct stringi_map_node *node)
63 char *stringi_map_node_swap_value (struct stringi_map_node *,
64 const char *new_value);
65 char *stringi_map_node_swap_value_nocopy (struct stringi_map_node *,
67 void stringi_map_node_set_value (struct stringi_map_node *, const char *value);
68 void stringi_map_node_set_value_nocopy (struct stringi_map_node *, char *value);
69 void stringi_map_node_destroy (struct stringi_map_node *);
71 /* Unordered map from unique, case-insensitive string keys to string values. */
77 /* Suitable for use as the initializer for a stringi_map named MAP. Typical
79 struct stringi_map map = STRINGI_MAP_INITIALIZER (map);
80 STRINGI_MAP_INITIALIZER is an alternative to calling stringi_map_init. */
81 #define STRINGI_MAP_INITIALIZER(MAP) { HMAP_INITIALIZER ((MAP).hmap) }
83 void stringi_map_init (struct stringi_map *);
84 void stringi_map_clone (struct stringi_map *, const struct stringi_map *);
85 void stringi_map_swap (struct stringi_map *, struct stringi_map *);
86 void stringi_map_destroy (struct stringi_map *);
88 static inline size_t stringi_map_count (const struct stringi_map *);
89 static inline bool stringi_map_is_empty (const struct stringi_map *);
91 bool stringi_map_contains (const struct stringi_map *, const char *);
92 const char *stringi_map_find (const struct stringi_map *, const char *);
93 const char *stringi_map_find__ (const struct stringi_map *, const char *key,
95 struct stringi_map_node *stringi_map_find_node (const struct stringi_map *,
98 char *stringi_map_find_and_delete (struct stringi_map *, const char *key);
100 struct stringi_map_node *stringi_map_insert (struct stringi_map *,
103 struct stringi_map_node *stringi_map_insert_nocopy (struct stringi_map *,
104 char *key, char *value);
105 struct stringi_map_node *stringi_map_replace (struct stringi_map *,
108 struct stringi_map_node *stringi_map_replace_nocopy (struct stringi_map *,
109 char *key, char *value);
110 bool stringi_map_delete (struct stringi_map *, const char *);
111 void stringi_map_delete_node (struct stringi_map *, struct stringi_map_node *);
112 void stringi_map_delete_nofree (struct stringi_map *,
113 struct stringi_map_node *);
115 void stringi_map_clear (struct stringi_map *);
116 void stringi_map_insert_map (struct stringi_map *, const struct stringi_map *);
117 void stringi_map_replace_map (struct stringi_map *,
118 const struct stringi_map *);
120 void stringi_map_get_keys (const struct stringi_map *, struct stringi_set *);
121 void stringi_map_get_values (const struct stringi_map *, struct string_set *);
123 static inline struct stringi_map_node *stringi_map_first (
124 const struct stringi_map *);
125 static inline struct stringi_map_node *stringi_map_next (
126 const struct stringi_map *, const struct stringi_map_node *);
128 /* Macros for conveniently iterating through a stringi_map, e.g. to print all
129 of the key-value pairs in "my_map":
131 struct stringi_map_node *node;
132 const char *key, *value;
134 STRINGI_MAP_FOR_EACH_KEY_VALUE (key, value, node, &my_map)
135 printf ("%s=%s\n", key, value);
137 #define STRINGI_MAP_FOR_EACH_NODE(NODE, MAP) \
138 for ((NODE) = stringi_map_first (MAP); (NODE) != NULL; \
139 (NODE) = stringi_map_next (MAP, NODE))
140 #define STRINGI_MAP_FOR_EACH_NODE_SAFE(NODE, NEXT, MAP) \
141 for ((NODE) = stringi_map_first (MAP); \
143 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
145 #define STRINGI_MAP_FOR_EACH_KEY(KEY, NODE, MAP) \
146 for ((NODE) = stringi_map_first (MAP); \
148 && ((KEY) = stringi_map_node_get_key (NODE), 1)); \
149 (NODE) = stringi_map_next (MAP, NODE))
150 #define STRINGI_MAP_FOR_EACH_KEY_SAFE(KEY, NODE, NEXT, MAP) \
151 for ((NODE) = stringi_map_first (MAP); \
153 && ((KEY) = stringi_map_node_get_key (NODE), 1) \
154 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
156 #define STRINGI_MAP_FOR_EACH_VALUE(VALUE, NODE, MAP) \
157 for ((NODE) = stringi_map_first (MAP); \
159 && ((VALUE) = (NODE)->value, 1)); \
160 (NODE) = stringi_map_next (MAP, NODE))
161 #define STRINGI_MAP_FOR_EACH_VALUE_SAFE(VALUE, NODE, NEXT, MAP) \
162 for ((NODE) = stringi_map_first (MAP); \
164 && ((VALUE) = (NODE)->value, 1) \
165 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
167 #define STRINGI_MAP_FOR_EACH_KEY_VALUE(KEY, VALUE, NODE, MAP) \
168 for ((NODE) = stringi_map_first (MAP); \
170 && ((KEY) = stringi_map_node_get_key (NODE), 1) \
171 && ((VALUE) = (NODE)->value, 1)); \
172 (NODE) = stringi_map_next (MAP, NODE))
173 #define STRINGI_MAP_FOR_EACH_KEY_VALUE_SAFE(KEY, VALUE, NODE, NEXT, MAP) \
174 for ((NODE) = stringi_map_first (MAP); \
176 && ((KEY) = stringi_map_node_get_key (NODE), 1) \
177 && ((VALUE) = (NODE)->value, 1) \
178 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
181 /* Returns the number of key-value pairs currently in MAP. */
183 stringi_map_count (const struct stringi_map *map)
185 return hmap_count (&map->hmap);
188 /* Returns true if MAP currently contains no key-value pairs, false
191 stringi_map_is_empty (const struct stringi_map *map)
193 return hmap_is_empty (&map->hmap);
196 /* Returns the first node in MAP, or a null pointer if MAP is empty. See the
197 hmap_first function for information about complexity (O(1) amortized) and
198 ordering (arbitrary).
200 The STRINGI_MAP_FOR_EACH family of macros provide convenient ways to iterate
201 over all the nodes in a string map. */
202 static inline struct stringi_map_node *
203 stringi_map_first (const struct stringi_map *map)
205 return HMAP_FIRST (struct stringi_map_node, hmap_node, &map->hmap);
208 /* Returns the next node in MAP following NODE, or a null pointer if NODE is
209 the last node in MAP. See the hmap_next function for information about
210 complexity (O(1) amortized) and ordering (arbitrary).
212 The STRINGI_MAP_FOR_EACH family of macros provide convenient ways to iterate
213 over all the nodes in a string map. */
214 static inline struct stringi_map_node *
215 stringi_map_next (const struct stringi_map *map,
216 const struct stringi_map_node *node)
218 return HMAP_NEXT (node, struct stringi_map_node, hmap_node, &map->hmap);
221 #endif /* libpspp/string-map.h */