f8ffabcffc1250bfdbdc428c511601937bdc6353
[pspp-builds.git] / src / libpspp / string-map.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2009 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
17 #ifndef LIBPSPP_STRING_MAP_H
18 #define LIBPSPP_STRING_MAP_H
19
20 /* Map from a unique string key to a string value.
21
22    This is a convenient wrapper around a "struct hmap" for storing string
23    key-value pairs. */
24
25 #include <stdbool.h>
26 #include <libpspp/hmap.h>
27
28 struct string_set;
29
30 /* A node within a string map. */
31 struct string_map_node
32   {
33     struct hmap_node hmap_node;
34     char *key;
35     char *value;
36   };
37
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)
42 {
43   return node->key;
44 }
45
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)
50 {
51   return node->value;
52 }
53
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)
58 {
59   return node->value;
60 }
61
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 *);
69 \f
70 /* Unordered map from unique string keys to string values. */
71 struct string_map
72   {
73     struct hmap hmap;
74   };
75
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) }
81
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 *);
86
87 static inline size_t string_map_count (const struct string_map *);
88 static inline bool string_map_is_empty (const struct string_map *);
89
90 bool string_map_contains (const struct string_map *, const char *);
91 const char *string_map_find (const struct string_map *, const char *);
92 struct string_map_node *string_map_find_node (const struct string_map *,
93                                               const char *);
94 char *string_map_find_and_delete (struct string_map *, const char *key);
95
96 struct string_map_node *string_map_insert (struct string_map *,
97                                            const char *key, const char *value);
98 struct string_map_node *string_map_insert_nocopy (struct string_map *,
99                                                   char *key, char *value);
100 struct string_map_node *string_map_replace (struct string_map *,
101                                            const char *key, const char *value);
102 struct string_map_node *string_map_replace_nocopy (struct string_map *,
103                                                    char *key, char *value);
104 bool string_map_delete (struct string_map *, const char *);
105 void string_map_delete_node (struct string_map *, struct string_map_node *);
106 void string_map_delete_nofree (struct string_map *, struct string_map_node *);
107
108 void string_map_clear (struct string_map *);
109 void string_map_insert_map (struct string_map *, const struct string_map *);
110 void string_map_replace_map (struct string_map *, const struct string_map *);
111
112 void string_map_get_keys (const struct string_map *, struct string_set *);
113 void string_map_get_values (const struct string_map *, struct string_set *);
114
115 static inline struct string_map_node *string_map_first (
116   const struct string_map *);
117 static inline struct string_map_node *string_map_next (
118   const struct string_map *, const struct string_map_node *);
119
120 /* Macros for conveniently iterating through a string_map, e.g. to print all of
121    the key-value pairs in "my_map":
122
123    struct string_map_node *node;
124    const char *key, *value;
125
126    STRING_MAP_FOR_EACH_KEY_VALUE (key, value, node, &my_map)
127      printf ("%s=%s\n", key, value);
128    */
129 #define STRING_MAP_FOR_EACH_NODE(NODE, MAP)                     \
130         for ((NODE) = string_map_first (MAP); (NODE) != NULL;   \
131              (NODE) = string_map_next (MAP, NODE))
132 #define STRING_MAP_FOR_EACH_NODE_SAFE(NODE, NEXT, MAP)          \
133         for ((NODE) = string_map_first (MAP);                   \
134              ((NODE) != NULL                                    \
135               && ((NEXT) = string_map_next (MAP, NODE), 1));    \
136              (NODE) = (NEXT))
137 #define STRING_MAP_FOR_EACH_KEY(KEY, NODE, MAP)                 \
138         for ((NODE) = string_map_first (MAP);                   \
139              ((NODE) != NULL                                    \
140               && ((KEY) = string_map_node_get_key (NODE), 1));  \
141              (NODE) = string_map_next (MAP, NODE))
142 #define STRING_MAP_FOR_EACH_KEY_SAFE(KEY, NODE, NEXT, MAP)      \
143         for ((NODE) = string_map_first (MAP);                   \
144              ((NODE) != NULL                                    \
145               && ((KEY) = string_map_node_get_key (NODE), 1)    \
146               && ((NEXT) = string_map_next (MAP, NODE), 1));    \
147              (NODE) = (NEXT))
148 #define STRING_MAP_FOR_EACH_VALUE(VALUE, NODE, MAP)     \
149         for ((NODE) = string_map_first (MAP);           \
150              ((NODE) != NULL                            \
151               && ((VALUE) = (NODE)->value, 1));         \
152              (NODE) = string_map_next (MAP, NODE))
153 #define STRING_MAP_FOR_EACH_VALUE_SAFE(VALUE, NODE, NEXT, MAP)  \
154         for ((NODE) = string_map_first (MAP);                   \
155              ((NODE) != NULL                                    \
156               && ((VALUE) = (NODE)->value, 1)                   \
157               && ((NEXT) = string_map_next (MAP, NODE), 1));    \
158              (NODE) = (NEXT))
159 #define STRING_MAP_FOR_EACH_KEY_VALUE(KEY, VALUE, NODE, MAP)    \
160         for ((NODE) = string_map_first (MAP);                   \
161              ((NODE) != NULL                                    \
162               && ((KEY) = string_map_node_get_key (NODE), 1)    \
163               && ((VALUE) = (NODE)->value, 1));                 \
164              (NODE) = string_map_next (MAP, NODE))
165 #define STRING_MAP_FOR_EACH_KEY_VALUE_SAFE(KEY, VALUE, NODE, NEXT, 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               && ((NEXT) = string_map_next (MAP, NODE), 1));            \
171              (NODE) = (NEXT))
172 \f
173 /* Returns the number of key-value pairs currently in MAP. */
174 static inline size_t
175 string_map_count (const struct string_map *map)
176 {
177   return hmap_count (&map->hmap);
178 }
179
180 /* Returns true if MAP currently contains no key-value pairs, false
181    otherwise. */
182 static inline bool
183 string_map_is_empty (const struct string_map *map)
184 {
185   return hmap_is_empty (&map->hmap);
186 }
187
188 /* Returns the first node in MAP, or a null pointer if MAP is empty.  See the
189    hmap_first function for information about complexity (O(1) amortized) and
190    ordering (arbitrary).
191
192    The STRING_MAP_FOR_EACH family of macros provide convenient ways to iterate
193    over all the nodes in a string map. */
194 static inline struct string_map_node *
195 string_map_first (const struct string_map *map)
196 {
197   return HMAP_FIRST (struct string_map_node, hmap_node, &map->hmap);
198 }
199
200 /* Returns the next node in MAP following NODE, or a null pointer if NODE is
201    the last node in MAP.  See the hmap_next function for information about
202    complexity (O(1) amortized) and ordering (arbitrary).
203
204    The STRING_MAP_FOR_EACH family of macros provide convenient ways to iterate
205    over all the nodes in a string map. */
206 static inline struct string_map_node *
207 string_map_next (const struct string_map *map,
208                  const struct string_map_node *node)
209 {
210   return HMAP_NEXT (node, struct string_map_node, hmap_node, &map->hmap);
211 }
212
213 #endif /* libpspp/string-map.h */