Branch data Line data Source code
1 : : /* Unit tests for ordered-hash-map.h.
2 : : Copyright (C) 2015-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "tm.h"
24 : : #include "opts.h"
25 : : #include "hash-set.h"
26 : : #include "fixed-value.h"
27 : : #include "alias.h"
28 : : #include "flags.h"
29 : : #include "symtab.h"
30 : : #include "tree-core.h"
31 : : #include "stor-layout.h"
32 : : #include "tree.h"
33 : : #include "stringpool.h"
34 : : #include "ordered-hash-map.h"
35 : : #include "selftest.h"
36 : :
37 : : #if CHECKING_P
38 : :
39 : : namespace selftest {
40 : :
41 : : /* Populate *OUT_KVS with the key/value pairs of M. */
42 : :
43 : : template <typename HashMap, typename Key, typename Value>
44 : : static void
45 : 20 : get_kv_pairs (const HashMap &m,
46 : : auto_vec<std::pair<Key, Value> > *out_kvs)
47 : : {
48 : 20 : for (typename HashMap::iterator iter = m.begin ();
49 : 152 : iter != m.end ();
50 : 56 : ++iter)
51 : 56 : out_kvs->safe_push (std::make_pair ((*iter).first, (*iter).second));
52 : 20 : }
53 : :
54 : : /* Construct an ordered_hash_map <const char *, int> and verify that
55 : : various operations work correctly. */
56 : :
57 : : static void
58 : 4 : test_map_of_strings_to_int ()
59 : : {
60 : 4 : ordered_hash_map <const char *, int> m;
61 : 4 : bool existed;
62 : :
63 : 4 : const char *ostrich = "ostrich";
64 : 4 : const char *elephant = "elephant";
65 : 4 : const char *ant = "ant";
66 : 4 : const char *spider = "spider";
67 : 4 : const char *millipede = "Illacme plenipes";
68 : 4 : const char *eric = "half a bee";
69 : :
70 : : /* A fresh hash_map should be empty. */
71 : 4 : ASSERT_EQ (0, m.elements ());
72 : 4 : ASSERT_EQ (NULL, m.get (ostrich));
73 : :
74 : : /* Populate the hash_map. */
75 : 4 : ASSERT_EQ (false, m.put (ostrich, 2));
76 : 4 : ASSERT_EQ (false, m.put (elephant, 4));
77 : 4 : ASSERT_EQ (false, m.put (ant, 6));
78 : 4 : existed = true;
79 : 4 : int &value = m.get_or_insert (spider, &existed);
80 : 4 : value = 8;
81 : 4 : ASSERT_EQ (false, existed);
82 : 4 : ASSERT_EQ (false, m.put (millipede, 750));
83 : 4 : ASSERT_EQ (false, m.put (eric, 3));
84 : :
85 : :
86 : : /* Verify that we can recover the stored values. */
87 : 4 : ASSERT_EQ (6, m.elements ());
88 : 4 : ASSERT_EQ (2, *m.get (ostrich));
89 : 4 : ASSERT_EQ (4, *m.get (elephant));
90 : 4 : ASSERT_EQ (6, *m.get (ant));
91 : 4 : ASSERT_EQ (8, *m.get (spider));
92 : 4 : existed = false;
93 : 4 : ASSERT_EQ (750, m.get_or_insert (millipede, &existed));
94 : 4 : ASSERT_EQ (true, existed);
95 : 4 : ASSERT_EQ (3, *m.get (eric));
96 : :
97 : : /* Verify that the order of insertion is preserved. */
98 : 4 : auto_vec<std::pair<const char *, int> > kvs;
99 : 4 : get_kv_pairs (m, &kvs);
100 : 4 : ASSERT_EQ (kvs.length (), 6);
101 : 4 : ASSERT_EQ (kvs[0].first, ostrich);
102 : 4 : ASSERT_EQ (kvs[0].second, 2);
103 : 4 : ASSERT_EQ (kvs[1].first, elephant);
104 : 4 : ASSERT_EQ (kvs[1].second, 4);
105 : 4 : ASSERT_EQ (kvs[2].first, ant);
106 : 4 : ASSERT_EQ (kvs[2].second, 6);
107 : 4 : ASSERT_EQ (kvs[3].first, spider);
108 : 4 : ASSERT_EQ (kvs[3].second, 8);
109 : 4 : ASSERT_EQ (kvs[4].first, millipede);
110 : 4 : ASSERT_EQ (kvs[4].second, 750);
111 : 4 : ASSERT_EQ (kvs[5].first, eric);
112 : 4 : ASSERT_EQ (kvs[5].second, 3);
113 : 4 : }
114 : :
115 : : /* Construct an ordered_hash_map using int_hash and verify that various
116 : : operations work correctly. */
117 : :
118 : : static void
119 : 4 : test_map_of_int_to_strings ()
120 : : {
121 : 4 : const int EMPTY = -1;
122 : 4 : const int DELETED = -2;
123 : 4 : bool existed;
124 : 4 : typedef int_hash <int, EMPTY, DELETED> int_hash_t;
125 : 4 : ordered_hash_map <int_hash_t, const char *> m;
126 : :
127 : 4 : const char *ostrich = "ostrich";
128 : 4 : const char *elephant = "elephant";
129 : 4 : const char *ant = "ant";
130 : 4 : const char *spider = "spider";
131 : 4 : const char *millipede = "Illacme plenipes";
132 : 4 : const char *eric = "half a bee";
133 : :
134 : : /* A fresh hash_map should be empty. */
135 : 4 : ASSERT_EQ (0, m.elements ());
136 : 4 : ASSERT_EQ (NULL, m.get (2));
137 : :
138 : : /* Populate the hash_map. */
139 : 4 : ASSERT_EQ (false, m.put (2, ostrich));
140 : 4 : ASSERT_EQ (false, m.put (4, elephant));
141 : 4 : ASSERT_EQ (false, m.put (6, ant));
142 : 4 : const char* &value = m.get_or_insert (8, &existed);
143 : 4 : value = spider;
144 : 4 : ASSERT_EQ (false, existed);
145 : 4 : ASSERT_EQ (false, m.put (750, millipede));
146 : 4 : ASSERT_EQ (false, m.put (3, eric));
147 : :
148 : : /* Verify that we can recover the stored values. */
149 : 4 : ASSERT_EQ (6, m.elements ());
150 : 4 : ASSERT_EQ (*m.get (2), ostrich);
151 : 4 : ASSERT_EQ (*m.get (4), elephant);
152 : 4 : ASSERT_EQ (*m.get (6), ant);
153 : 4 : ASSERT_EQ (*m.get (8), spider);
154 : 4 : ASSERT_EQ (m.get_or_insert (750, &existed), millipede);
155 : 4 : ASSERT_EQ (existed, true);
156 : 4 : ASSERT_EQ (*m.get (3), eric);
157 : :
158 : : /* Verify that the order of insertion is preserved. */
159 : 4 : auto_vec<std::pair<int, const char *> > kvs;
160 : 4 : get_kv_pairs (m, &kvs);
161 : 4 : ASSERT_EQ (kvs.length (), 6);
162 : 4 : ASSERT_EQ (kvs[0].first, 2);
163 : 4 : ASSERT_EQ (kvs[0].second, ostrich);
164 : 4 : ASSERT_EQ (kvs[1].first, 4);
165 : 4 : ASSERT_EQ (kvs[1].second, elephant);
166 : 4 : ASSERT_EQ (kvs[2].first, 6);
167 : 4 : ASSERT_EQ (kvs[2].second, ant);
168 : 4 : ASSERT_EQ (kvs[3].first, 8);
169 : 4 : ASSERT_EQ (kvs[3].second, spider);
170 : 4 : ASSERT_EQ (kvs[4].first, 750);
171 : 4 : ASSERT_EQ (kvs[4].second, millipede);
172 : 4 : ASSERT_EQ (kvs[5].first, 3);
173 : 4 : ASSERT_EQ (kvs[5].second, eric);
174 : 4 : }
175 : :
176 : : /* Verify that we can remove items from an ordered_hash_map. */
177 : :
178 : : static void
179 : 4 : test_removal ()
180 : : {
181 : 4 : ordered_hash_map <const char *, int> m;
182 : :
183 : 4 : const char *ostrich = "ostrich";
184 : 4 : ASSERT_EQ (false, m.put (ostrich, 2));
185 : :
186 : 4 : ASSERT_EQ (1, m.elements ());
187 : 4 : ASSERT_EQ (2, *m.get (ostrich));
188 : :
189 : 4 : {
190 : 4 : auto_vec<std::pair<const char *, int> > kvs;
191 : 4 : get_kv_pairs (m, &kvs);
192 : 4 : ASSERT_EQ (kvs.length (), 1);
193 : 4 : ASSERT_EQ (kvs[0].first, ostrich);
194 : 4 : ASSERT_EQ (kvs[0].second, 2);
195 : 4 : }
196 : :
197 : 4 : m.remove (ostrich);
198 : :
199 : 4 : ASSERT_EQ (0, m.elements ());
200 : 4 : {
201 : 4 : auto_vec<std::pair<const char *, int> > kvs;
202 : 4 : get_kv_pairs (m, &kvs);
203 : 4 : ASSERT_EQ (kvs.length (), 0);
204 : 4 : }
205 : :
206 : : /* Reinsertion (with a different value). */
207 : 4 : ASSERT_EQ (false, m.put (ostrich, 42));
208 : 4 : ASSERT_EQ (1, m.elements ());
209 : 4 : ASSERT_EQ (42, *m.get (ostrich));
210 : 4 : {
211 : 4 : auto_vec<std::pair<const char *, int> > kvs;
212 : 4 : get_kv_pairs (m, &kvs);
213 : 4 : ASSERT_EQ (kvs.length (), 1);
214 : 4 : ASSERT_EQ (kvs[0].first, ostrich);
215 : 4 : ASSERT_EQ (kvs[0].second, 42);
216 : 4 : }
217 : 4 : }
218 : :
219 : : /* Verify that ordered_hash_map's copy-ctor works. */
220 : :
221 : : static void
222 : 4 : test_copy_ctor ()
223 : : {
224 : 4 : ordered_hash_map <const char *, int> m;
225 : :
226 : 4 : const char *ostrich = "ostrich";
227 : 4 : ASSERT_EQ (false, m.put (ostrich, 2));
228 : :
229 : 4 : ASSERT_EQ (1, m.elements ());
230 : 4 : ASSERT_EQ (2, *m.get (ostrich));
231 : :
232 : 4 : ordered_hash_map <const char *, int> copy (m);
233 : 4 : ASSERT_EQ (1, copy.elements ());
234 : 4 : ASSERT_EQ (2, *copy.get (ostrich));
235 : :
236 : : /* Remove from source. */
237 : 4 : m.remove (ostrich);
238 : 4 : ASSERT_EQ (0, m.elements ());
239 : :
240 : : /* Copy should be unaffected. */
241 : 4 : ASSERT_EQ (1, copy.elements ());
242 : 4 : ASSERT_EQ (2, *copy.get (ostrich));
243 : 4 : }
244 : :
245 : : /* Run all of the selftests within this file. */
246 : :
247 : : void
248 : 4 : ordered_hash_map_tests_cc_tests ()
249 : : {
250 : 4 : test_map_of_strings_to_int ();
251 : 4 : test_map_of_int_to_strings ();
252 : 4 : test_removal ();
253 : 4 : test_copy_ctor ();
254 : 4 : }
255 : :
256 : : } // namespace selftest
257 : :
258 : : #endif /* CHECKING_P */
|