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 struct stringi_map_node *stringi_map_find_node (const struct stringi_map *,
95 char *stringi_map_find_and_delete (struct stringi_map *, const char *key);
97 struct stringi_map_node *stringi_map_insert (struct stringi_map *,
100 struct stringi_map_node *stringi_map_insert_nocopy (struct stringi_map *,
101 char *key, char *value);
102 struct stringi_map_node *stringi_map_replace (struct stringi_map *,
105 struct stringi_map_node *stringi_map_replace_nocopy (struct stringi_map *,
106 char *key, char *value);
107 bool stringi_map_delete (struct stringi_map *, const char *);
108 void stringi_map_delete_node (struct stringi_map *, struct stringi_map_node *);
109 void stringi_map_delete_nofree (struct stringi_map *,
110 struct stringi_map_node *);
112 void stringi_map_clear (struct stringi_map *);
113 void stringi_map_insert_map (struct stringi_map *, const struct stringi_map *);
114 void stringi_map_replace_map (struct stringi_map *,
115 const struct stringi_map *);
117 void stringi_map_get_keys (const struct stringi_map *, struct stringi_set *);
118 void stringi_map_get_values (const struct stringi_map *, struct string_set *);
120 static inline struct stringi_map_node *stringi_map_first (
121 const struct stringi_map *);
122 static inline struct stringi_map_node *stringi_map_next (
123 const struct stringi_map *, const struct stringi_map_node *);
125 /* Macros for conveniently iterating through a stringi_map, e.g. to print all
126 of the key-value pairs in "my_map":
128 struct stringi_map_node *node;
129 const char *key, *value;
131 STRINGI_MAP_FOR_EACH_KEY_VALUE (key, value, node, &my_map)
132 printf ("%s=%s\n", key, value);
134 #define STRINGI_MAP_FOR_EACH_NODE(NODE, MAP) \
135 for ((NODE) = stringi_map_first (MAP); (NODE) != NULL; \
136 (NODE) = stringi_map_next (MAP, NODE))
137 #define STRINGI_MAP_FOR_EACH_NODE_SAFE(NODE, NEXT, MAP) \
138 for ((NODE) = stringi_map_first (MAP); \
140 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
142 #define STRINGI_MAP_FOR_EACH_KEY(KEY, NODE, MAP) \
143 for ((NODE) = stringi_map_first (MAP); \
145 && ((KEY) = stringi_map_node_get_key (NODE), 1)); \
146 (NODE) = stringi_map_next (MAP, NODE))
147 #define STRINGI_MAP_FOR_EACH_KEY_SAFE(KEY, NODE, NEXT, MAP) \
148 for ((NODE) = stringi_map_first (MAP); \
150 && ((KEY) = stringi_map_node_get_key (NODE), 1) \
151 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
153 #define STRINGI_MAP_FOR_EACH_VALUE(VALUE, NODE, MAP) \
154 for ((NODE) = stringi_map_first (MAP); \
156 && ((VALUE) = (NODE)->value, 1)); \
157 (NODE) = stringi_map_next (MAP, NODE))
158 #define STRINGI_MAP_FOR_EACH_VALUE_SAFE(VALUE, NODE, NEXT, MAP) \
159 for ((NODE) = stringi_map_first (MAP); \
161 && ((VALUE) = (NODE)->value, 1) \
162 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
164 #define STRINGI_MAP_FOR_EACH_KEY_VALUE(KEY, VALUE, NODE, MAP) \
165 for ((NODE) = stringi_map_first (MAP); \
167 && ((KEY) = stringi_map_node_get_key (NODE), 1) \
168 && ((VALUE) = (NODE)->value, 1)); \
169 (NODE) = stringi_map_next (MAP, NODE))
170 #define STRINGI_MAP_FOR_EACH_KEY_VALUE_SAFE(KEY, VALUE, NODE, NEXT, MAP) \
171 for ((NODE) = stringi_map_first (MAP); \
173 && ((KEY) = stringi_map_node_get_key (NODE), 1) \
174 && ((VALUE) = (NODE)->value, 1) \
175 && ((NEXT) = stringi_map_next (MAP, NODE), 1)); \
178 /* Returns the number of key-value pairs currently in MAP. */
180 stringi_map_count (const struct stringi_map *map)
182 return hmap_count (&map->hmap);
185 /* Returns true if MAP currently contains no key-value pairs, false
188 stringi_map_is_empty (const struct stringi_map *map)
190 return hmap_is_empty (&map->hmap);
193 /* Returns the first node in MAP, or a null pointer if MAP is empty. See the
194 hmap_first function for information about complexity (O(1) amortized) and
195 ordering (arbitrary).
197 The STRINGI_MAP_FOR_EACH family of macros provide convenient ways to iterate
198 over all the nodes in a string map. */
199 static inline struct stringi_map_node *
200 stringi_map_first (const struct stringi_map *map)
202 return HMAP_FIRST (struct stringi_map_node, hmap_node, &map->hmap);
205 /* Returns the next node in MAP following NODE, or a null pointer if NODE is
206 the last node in MAP. See the hmap_next function for information about
207 complexity (O(1) amortized) and ordering (arbitrary).
209 The STRINGI_MAP_FOR_EACH family of macros provide convenient ways to iterate
210 over all the nodes in a string map. */
211 static inline struct stringi_map_node *
212 stringi_map_next (const struct stringi_map *map,
213 const struct stringi_map_node *node)
215 return HMAP_NEXT (node, struct stringi_map_node, hmap_node, &map->hmap);
218 #endif /* libpspp/string-map.h */