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_SET_H
18 #define LIBPSPP_STRINGI_SET_H
20 /* Set of unique, case-insensitive strings.
22 This is a convenient wrapper around a "struct hmap" for storing strings. */
25 #include "libpspp/hmap.h"
27 /* A node in the string set. */
28 struct stringi_set_node
30 struct hmap_node hmap_node;
34 /* Returns the string within NODE. The caller must not modify or free the
36 static inline const char *
37 stringi_set_node_get_string (const struct stringi_set_node *node)
42 /* An unordered set of unique strings. */
48 /* Suitable for use as the initializer for a stringi_set named SET. Typical
50 struct stringi_set set = STRINGI_SET_INITIALIZER (set);
51 STRINGI_SET_INITIALIZER is an alternative to calling stringi_set_init. */
52 #define STRINGI_SET_INITIALIZER(SET) { HMAP_INITIALIZER ((SET).hmap) }
54 void stringi_set_init (struct stringi_set *);
55 void stringi_set_clone (struct stringi_set *, const struct stringi_set *);
56 void stringi_set_swap (struct stringi_set *, struct stringi_set *);
57 void stringi_set_destroy (struct stringi_set *);
59 static inline size_t stringi_set_count (const struct stringi_set *);
60 static inline bool stringi_set_is_empty (const struct stringi_set *);
62 bool stringi_set_contains (const struct stringi_set *, const char *);
63 struct stringi_set_node *stringi_set_find_node (const struct stringi_set *,
66 bool stringi_set_insert (struct stringi_set *, const char *);
67 bool stringi_set_insert_nocopy (struct stringi_set *, char *);
68 bool stringi_set_delete (struct stringi_set *, const char *);
69 void stringi_set_delete_node (struct stringi_set *, struct stringi_set_node *);
70 char *stringi_set_delete_nofree (struct stringi_set *,
71 struct stringi_set_node *);
73 void stringi_set_clear (struct stringi_set *);
74 void stringi_set_union (struct stringi_set *, const struct stringi_set *);
75 void stringi_set_union_and_intersection (struct stringi_set *,
76 struct stringi_set *);
77 void stringi_set_intersect (struct stringi_set *, const struct stringi_set *);
78 void stringi_set_subtract (struct stringi_set *, const struct stringi_set *);
80 char **stringi_set_get_array (const struct stringi_set *);
81 char **stringi_set_get_sorted_array (const struct stringi_set *);
83 static inline const struct stringi_set_node *stringi_set_first (
84 const struct stringi_set *);
85 static inline const struct stringi_set_node *stringi_set_next (
86 const struct stringi_set *, const struct stringi_set_node *);
88 /* Macros for conveniently iterating through a stringi_set, e.g. to print all
89 of the strings in "my_set":
91 struct stringi_set_node *node;
94 STRINGI_SET_FOR_EACH (string, node, &my_set)
97 #define STRINGI_SET_FOR_EACH(STRING, NODE, SET) \
98 for ((NODE) = stringi_set_first (SET); \
100 ? ((STRING) = stringi_set_node_get_string (NODE), \
103 (NODE) = stringi_set_next (SET, NODE))
104 #define STRINGI_SET_FOR_EACH_SAFE(STRING, NODE, NEXT, SET) \
105 for ((NODE) = stringi_set_first (SET); \
107 ? ((STRING) = stringi_set_node_get_string (NODE), \
108 (NEXT) = stringi_set_next (SET, NODE), \
113 /* Returns the number of strings currently in SET. */
115 stringi_set_count (const struct stringi_set *set)
117 return hmap_count (&set->hmap);
120 /* Returns true if SET currently contains no strings, false otherwise. */
122 stringi_set_is_empty (const struct stringi_set *set)
124 return hmap_is_empty (&set->hmap);
127 /* Returns the first node in SET, or a null pointer if SET is empty. See the
128 hmap_first function for information about complexity (O(1) amortized) and
129 ordering (arbitrary).
131 The STRINGI_SET_FOR_EACH and STRINGI_SET_FOR_EACH_SAFE macros provide
132 convenient ways to iterate over all the nodes in a string set. */
133 static inline const struct stringi_set_node *
134 stringi_set_first (const struct stringi_set *set)
136 return HMAP_FIRST (struct stringi_set_node, hmap_node, &set->hmap);
139 /* Returns the next node in SET following NODE, or a null pointer if NODE is
140 the last node in SET. See the hmap_next function for information about
141 complexity (O(1) amortized) and ordering (arbitrary).
143 The STRINGI_SET_FOR_EACH and STRINGI_SET_FOR_EACH_SAFE macros provide
144 convenient ways to iterate over all the nodes in a string set. */
145 static inline const struct stringi_set_node *
146 stringi_set_next (const struct stringi_set *set,
147 const struct stringi_set_node *node)
149 return HMAP_NEXT (node, struct stringi_set_node, hmap_node, &set->hmap);
152 #endif /* libpspp/string-set.h */