pivot-output: Fix crash when layers axis has no leaves.
[pspp.git] / src / libpspp / string-map.h
blob7f2da1738c2d21ee59d1b332c5ae3e0526dea3c2
1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2009, 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_STRING_MAP_H
18 #define LIBPSPP_STRING_MAP_H
20 /* Map from a unique string key to a string value.
22 This is a convenient wrapper around a "struct hmap" for storing string
23 key-value pairs. */
25 #include <stdbool.h>
26 #include "libpspp/hmap.h"
28 struct string_set;
30 /* A node within a string map. */
31 struct string_map_node
33 struct hmap_node hmap_node;
34 char *key;
35 char *value;
38 /* Returns the string key within NODE. The caller must not modify or free the
39 returned string. */
40 static inline const char *
41 string_map_node_get_key (const struct string_map_node *node)
43 return node->key;
46 /* Returns the string key within NODE. The caller must not free the returned
47 string. */
48 static inline const char *
49 string_map_node_get_value (const struct string_map_node *node)
51 return node->value;
54 /* Returns the string key within NODE. The caller must not free the returned
55 string. */
56 static inline char *
57 string_map_node_get_value_rw (struct string_map_node *node)
59 return node->value;
62 char *string_map_node_swap_value (struct string_map_node *,
63 const char *new_value);
64 char *string_map_node_swap_value_nocopy (struct string_map_node *,
65 char *new_value);
66 void string_map_node_set_value (struct string_map_node *, const char *value);
67 void string_map_node_set_value_nocopy (struct string_map_node *, char *value);
68 void string_map_node_destroy (struct string_map_node *);
70 /* Unordered map from unique string keys to string values. */
71 struct string_map
73 struct hmap hmap;
76 /* Suitable for use as the initializer for a string_map named MAP. Typical
77 usage:
78 struct string_map map = STRING_MAP_INITIALIZER (map);
79 STRING_MAP_INITIALIZER is an alternative to calling string_map_init. */
80 #define STRING_MAP_INITIALIZER(MAP) { HMAP_INITIALIZER ((MAP).hmap) }
82 void string_map_init (struct string_map *);
83 void string_map_clone (struct string_map *, const struct string_map *);
84 void string_map_swap (struct string_map *, struct string_map *);
85 void string_map_destroy (struct string_map *);
87 static inline size_t string_map_count (const struct string_map *);
88 static inline bool string_map_is_empty (const struct string_map *);
90 bool string_map_contains (const struct string_map *, const char *);
91 const char *string_map_find (const struct string_map *, const char *);
92 const char *string_map_find__ (const struct string_map *, const char *,
93 size_t length);
94 struct string_map_node *string_map_find_node (const struct string_map *,
95 const char *);
96 struct string_map_node *string_map_find_node__ (const struct string_map *,
97 const char *, size_t length);
98 char *string_map_find_and_delete (struct string_map *, const char *key);
100 struct string_map_node *string_map_insert (struct string_map *,
101 const char *key, const char *value);
102 struct string_map_node *string_map_insert_nocopy (struct string_map *,
103 char *key, char *value);
104 struct string_map_node *string_map_replace (struct string_map *,
105 const char *key, const char *value);
106 struct string_map_node *string_map_replace_nocopy (struct string_map *,
107 char *key, char *value);
108 bool string_map_delete (struct string_map *, const char *);
109 void string_map_delete_node (struct string_map *, struct string_map_node *);
110 void string_map_delete_nofree (struct string_map *, struct string_map_node *);
112 void string_map_clear (struct string_map *);
113 void string_map_insert_map (struct string_map *, const struct string_map *);
114 void string_map_replace_map (struct string_map *, const struct string_map *);
116 void string_map_get_keys (const struct string_map *, struct string_set *);
117 void string_map_get_values (const struct string_map *, struct string_set *);
119 bool string_map_equals (const struct string_map *, const struct string_map *);
121 static inline struct string_map_node *string_map_first (
122 const struct string_map *);
123 static inline struct string_map_node *string_map_next (
124 const struct string_map *, const struct string_map_node *);
126 /* Macros for conveniently iterating through a string_map, e.g. to print all of
127 the key-value pairs in "my_map":
129 struct string_map_node *node;
130 const char *key, *value;
132 STRING_MAP_FOR_EACH_KEY_VALUE (key, value, node, &my_map)
133 printf ("%s=%s\n", key, value);
135 #define STRING_MAP_FOR_EACH_NODE(NODE, MAP) \
136 for ((NODE) = string_map_first (MAP); (NODE) != NULL; \
137 (NODE) = string_map_next (MAP, NODE))
138 #define STRING_MAP_FOR_EACH_NODE_SAFE(NODE, NEXT, MAP) \
139 for ((NODE) = string_map_first (MAP); \
140 ((NODE) != NULL \
141 && ((NEXT) = string_map_next (MAP, NODE), 1)); \
142 (NODE) = (NEXT))
143 #define STRING_MAP_FOR_EACH_KEY(KEY, NODE, MAP) \
144 for ((NODE) = string_map_first (MAP); \
145 ((NODE) != NULL \
146 && ((KEY) = string_map_node_get_key (NODE), 1)); \
147 (NODE) = string_map_next (MAP, NODE))
148 #define STRING_MAP_FOR_EACH_KEY_SAFE(KEY, NODE, NEXT, MAP) \
149 for ((NODE) = string_map_first (MAP); \
150 ((NODE) != NULL \
151 && ((KEY) = string_map_node_get_key (NODE), 1) \
152 && ((NEXT) = string_map_next (MAP, NODE), 1)); \
153 (NODE) = (NEXT))
154 #define STRING_MAP_FOR_EACH_VALUE(VALUE, NODE, MAP) \
155 for ((NODE) = string_map_first (MAP); \
156 ((NODE) != NULL \
157 && ((VALUE) = (NODE)->value, 1)); \
158 (NODE) = string_map_next (MAP, NODE))
159 #define STRING_MAP_FOR_EACH_VALUE_SAFE(VALUE, NODE, NEXT, MAP) \
160 for ((NODE) = string_map_first (MAP); \
161 ((NODE) != NULL \
162 && ((VALUE) = (NODE)->value, 1) \
163 && ((NEXT) = string_map_next (MAP, NODE), 1)); \
164 (NODE) = (NEXT))
165 #define STRING_MAP_FOR_EACH_KEY_VALUE(KEY, VALUE, NODE, MAP) \
166 for ((NODE) = string_map_first (MAP); \
167 ((NODE) != NULL \
168 && ((KEY) = string_map_node_get_key (NODE), 1) \
169 && ((VALUE) = (NODE)->value, 1)); \
170 (NODE) = string_map_next (MAP, NODE))
171 #define STRING_MAP_FOR_EACH_KEY_VALUE_SAFE(KEY, VALUE, NODE, NEXT, MAP) \
172 for ((NODE) = string_map_first (MAP); \
173 ((NODE) != NULL \
174 && ((KEY) = string_map_node_get_key (NODE), 1) \
175 && ((VALUE) = (NODE)->value, 1) \
176 && ((NEXT) = string_map_next (MAP, NODE), 1)); \
177 (NODE) = (NEXT))
179 /* Returns the number of key-value pairs currently in MAP. */
180 static inline size_t
181 string_map_count (const struct string_map *map)
183 return hmap_count (&map->hmap);
186 /* Returns true if MAP currently contains no key-value pairs, false
187 otherwise. */
188 static inline bool
189 string_map_is_empty (const struct string_map *map)
191 return hmap_is_empty (&map->hmap);
194 /* Returns the first node in MAP, or a null pointer if MAP is empty. See the
195 hmap_first function for information about complexity (O(1) amortized) and
196 ordering (arbitrary).
198 The STRING_MAP_FOR_EACH family of macros provide convenient ways to iterate
199 over all the nodes in a string map. */
200 static inline struct string_map_node *
201 string_map_first (const struct string_map *map)
203 return HMAP_FIRST (struct string_map_node, hmap_node, &map->hmap);
206 /* Returns the next node in MAP following NODE, or a null pointer if NODE is
207 the last node in MAP. See the hmap_next function for information about
208 complexity (O(1) amortized) and ordering (arbitrary).
210 The STRING_MAP_FOR_EACH family of macros provide convenient ways to iterate
211 over all the nodes in a string map. */
212 static inline struct string_map_node *
213 string_map_next (const struct string_map *map,
214 const struct string_map_node *node)
216 return HMAP_NEXT (node, struct string_map_node, hmap_node, &map->hmap);
219 #endif /* libpspp/string-map.h */