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 */