hash-map-tests.cc revision 1.1.1.1 1 1.1 mrg /* Unit tests for hash-map.h.
2 1.1 mrg Copyright (C) 2015-2022 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg This file is part of GCC.
5 1.1 mrg
6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
7 1.1 mrg the terms of the GNU General Public License as published by the Free
8 1.1 mrg Software Foundation; either version 3, or (at your option) any later
9 1.1 mrg version.
10 1.1 mrg
11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 1.1 mrg for more details.
15 1.1 mrg
16 1.1 mrg You should have received a copy of the GNU General Public License
17 1.1 mrg along with GCC; see the file COPYING3. If not see
18 1.1 mrg <http://www.gnu.org/licenses/>. */
19 1.1 mrg
20 1.1 mrg #include "config.h"
21 1.1 mrg #include "system.h"
22 1.1 mrg #include "coretypes.h"
23 1.1 mrg #include "tm.h"
24 1.1 mrg #include "opts.h"
25 1.1 mrg #include "hash-set.h"
26 1.1 mrg #include "fixed-value.h"
27 1.1 mrg #include "alias.h"
28 1.1 mrg #include "flags.h"
29 1.1 mrg #include "symtab.h"
30 1.1 mrg #include "tree-core.h"
31 1.1 mrg #include "stor-layout.h"
32 1.1 mrg #include "tree.h"
33 1.1 mrg #include "stringpool.h"
34 1.1 mrg #include "selftest.h"
35 1.1 mrg
36 1.1 mrg #if CHECKING_P
37 1.1 mrg
38 1.1 mrg namespace selftest {
39 1.1 mrg
40 1.1 mrg /* Construct a hash_map <const char *, int> and verify that
41 1.1 mrg various operations work correctly. */
42 1.1 mrg
43 1.1 mrg static void
44 1.1 mrg test_map_of_strings_to_int ()
45 1.1 mrg {
46 1.1 mrg hash_map <const char *, int> m;
47 1.1 mrg
48 1.1 mrg const char *ostrich = "ostrich";
49 1.1 mrg const char *elephant = "elephant";
50 1.1 mrg const char *ant = "ant";
51 1.1 mrg const char *spider = "spider";
52 1.1 mrg const char *millipede = "Illacme plenipes";
53 1.1 mrg const char *eric = "half a bee";
54 1.1 mrg
55 1.1 mrg /* A fresh hash_map should be empty. */
56 1.1 mrg ASSERT_TRUE (m.is_empty ());
57 1.1 mrg ASSERT_EQ (NULL, m.get (ostrich));
58 1.1 mrg
59 1.1 mrg /* Populate the hash_map. */
60 1.1 mrg ASSERT_EQ (false, m.put (ostrich, 2));
61 1.1 mrg ASSERT_EQ (false, m.put (elephant, 4));
62 1.1 mrg ASSERT_EQ (false, m.put (ant, 6));
63 1.1 mrg ASSERT_EQ (false, m.put (spider, 8));
64 1.1 mrg ASSERT_EQ (false, m.put (millipede, 750));
65 1.1 mrg ASSERT_EQ (false, m.put (eric, 3));
66 1.1 mrg
67 1.1 mrg /* Verify that we can recover the stored values. */
68 1.1 mrg ASSERT_EQ (6, m.elements ());
69 1.1 mrg ASSERT_EQ (2, *m.get (ostrich));
70 1.1 mrg ASSERT_EQ (4, *m.get (elephant));
71 1.1 mrg ASSERT_EQ (6, *m.get (ant));
72 1.1 mrg ASSERT_EQ (8, *m.get (spider));
73 1.1 mrg ASSERT_EQ (750, *m.get (millipede));
74 1.1 mrg ASSERT_EQ (3, *m.get (eric));
75 1.1 mrg
76 1.1 mrg /* Verify removing an item. */
77 1.1 mrg m.remove (eric);
78 1.1 mrg ASSERT_EQ (5, m.elements ());
79 1.1 mrg ASSERT_EQ (NULL, m.get (eric));
80 1.1 mrg
81 1.1 mrg m.remove (eric);
82 1.1 mrg ASSERT_EQ (5, m.elements ());
83 1.1 mrg ASSERT_EQ (NULL, m.get (eric));
84 1.1 mrg
85 1.1 mrg /* A plain char * key is hashed based on its value (address), rather
86 1.1 mrg than the string it points to. */
87 1.1 mrg char *another_ant = static_cast <char *> (xcalloc (4, 1));
88 1.1 mrg another_ant[0] = 'a';
89 1.1 mrg another_ant[1] = 'n';
90 1.1 mrg another_ant[2] = 't';
91 1.1 mrg another_ant[3] = 0;
92 1.1 mrg ASSERT_NE (ant, another_ant);
93 1.1 mrg unsigned prev_size = m.elements ();
94 1.1 mrg ASSERT_EQ (false, m.put (another_ant, 7));
95 1.1 mrg ASSERT_EQ (prev_size + 1, m.elements ());
96 1.1 mrg
97 1.1 mrg /* Need to use string_hash or nofree_string_hash key types to hash
98 1.1 mrg based on the string contents. */
99 1.1 mrg hash_map <nofree_string_hash, int> string_map;
100 1.1 mrg ASSERT_EQ (false, string_map.put (ant, 1));
101 1.1 mrg ASSERT_EQ (1, string_map.elements ());
102 1.1 mrg ASSERT_EQ (true, string_map.put (another_ant, 5));
103 1.1 mrg ASSERT_EQ (1, string_map.elements ());
104 1.1 mrg
105 1.1 mrg free (another_ant);
106 1.1 mrg }
107 1.1 mrg
108 1.1 mrg /* Construct a hash_map using int_hash and verify that
109 1.1 mrg various operations work correctly. */
110 1.1 mrg
111 1.1 mrg static void
112 1.1 mrg test_map_of_int_to_strings ()
113 1.1 mrg {
114 1.1 mrg const int EMPTY = -1;
115 1.1 mrg const int DELETED = -2;
116 1.1 mrg typedef int_hash <int, EMPTY, DELETED> int_hash_t;
117 1.1 mrg hash_map <int_hash_t, const char *> m;
118 1.1 mrg
119 1.1 mrg const char *ostrich = "ostrich";
120 1.1 mrg const char *elephant = "elephant";
121 1.1 mrg const char *ant = "ant";
122 1.1 mrg const char *spider = "spider";
123 1.1 mrg const char *millipede = "Illacme plenipes";
124 1.1 mrg const char *eric = "half a bee";
125 1.1 mrg
126 1.1 mrg /* A fresh hash_map should be empty. */
127 1.1 mrg ASSERT_EQ (0, m.elements ());
128 1.1 mrg ASSERT_EQ (NULL, m.get (2));
129 1.1 mrg
130 1.1 mrg /* Populate the hash_map. */
131 1.1 mrg ASSERT_EQ (false, m.put (2, ostrich));
132 1.1 mrg ASSERT_EQ (false, m.put (4, elephant));
133 1.1 mrg ASSERT_EQ (false, m.put (6, ant));
134 1.1 mrg ASSERT_EQ (false, m.put (8, spider));
135 1.1 mrg ASSERT_EQ (false, m.put (750, millipede));
136 1.1 mrg ASSERT_EQ (false, m.put (3, eric));
137 1.1 mrg
138 1.1 mrg /* Verify that we can recover the stored values. */
139 1.1 mrg ASSERT_EQ (6, m.elements ());
140 1.1 mrg ASSERT_EQ (*m.get (2), ostrich);
141 1.1 mrg ASSERT_EQ (*m.get (4), elephant);
142 1.1 mrg ASSERT_EQ (*m.get (6), ant);
143 1.1 mrg ASSERT_EQ (*m.get (8), spider);
144 1.1 mrg ASSERT_EQ (*m.get (750), millipede);
145 1.1 mrg ASSERT_EQ (*m.get (3), eric);
146 1.1 mrg }
147 1.1 mrg
148 1.1 mrg typedef class hash_map_test_val_t
149 1.1 mrg {
150 1.1 mrg public:
151 1.1 mrg static int ndefault;
152 1.1 mrg static int ncopy;
153 1.1 mrg static int nassign;
154 1.1 mrg static int ndtor;
155 1.1 mrg
156 1.1 mrg hash_map_test_val_t ()
157 1.1 mrg : ptr (&ptr)
158 1.1 mrg {
159 1.1 mrg ++ndefault;
160 1.1 mrg }
161 1.1 mrg
162 1.1 mrg hash_map_test_val_t (const hash_map_test_val_t &rhs)
163 1.1 mrg : ptr (&ptr)
164 1.1 mrg {
165 1.1 mrg ++ncopy;
166 1.1 mrg gcc_assert (rhs.ptr == &rhs.ptr);
167 1.1 mrg }
168 1.1 mrg
169 1.1 mrg hash_map_test_val_t& operator= (const hash_map_test_val_t &rhs)
170 1.1 mrg {
171 1.1 mrg ++nassign;
172 1.1 mrg gcc_assert (ptr == &ptr);
173 1.1 mrg gcc_assert (rhs.ptr == &rhs.ptr);
174 1.1 mrg return *this;
175 1.1 mrg }
176 1.1 mrg
177 1.1 mrg ~hash_map_test_val_t ()
178 1.1 mrg {
179 1.1 mrg gcc_assert (ptr == &ptr);
180 1.1 mrg ++ndtor;
181 1.1 mrg }
182 1.1 mrg
183 1.1 mrg void *ptr;
184 1.1 mrg } val_t;
185 1.1 mrg
186 1.1 mrg int val_t::ndefault;
187 1.1 mrg int val_t::ncopy;
188 1.1 mrg int val_t::nassign;
189 1.1 mrg int val_t::ndtor;
190 1.1 mrg
191 1.1 mrg static void
192 1.1 mrg test_map_of_type_with_ctor_and_dtor ()
193 1.1 mrg {
194 1.1 mrg typedef hash_map <void *, val_t> Map;
195 1.1 mrg
196 1.1 mrg {
197 1.1 mrg /* Test default ctor. */
198 1.1 mrg Map m;
199 1.1 mrg (void)&m;
200 1.1 mrg }
201 1.1 mrg
202 1.1 mrg ASSERT_TRUE (val_t::ndefault == 0);
203 1.1 mrg ASSERT_TRUE (val_t::ncopy == 0);
204 1.1 mrg ASSERT_TRUE (val_t::nassign == 0);
205 1.1 mrg ASSERT_TRUE (val_t::ndtor == 0);
206 1.1 mrg
207 1.1 mrg {
208 1.1 mrg /* Test single insertion. */
209 1.1 mrg Map m;
210 1.1 mrg void *p = &p;
211 1.1 mrg m.get_or_insert (p);
212 1.1 mrg }
213 1.1 mrg
214 1.1 mrg ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
215 1.1 mrg
216 1.1 mrg {
217 1.1 mrg /* Test copy ctor. */
218 1.1 mrg Map m1;
219 1.1 mrg void *p = &p;
220 1.1 mrg val_t &rv1 = m1.get_or_insert (p);
221 1.1 mrg
222 1.1 mrg int ncopy = val_t::ncopy;
223 1.1 mrg int nassign = val_t::nassign;
224 1.1 mrg
225 1.1 mrg Map m2 (m1);
226 1.1 mrg val_t *pv2 = m2.get (p);
227 1.1 mrg
228 1.1 mrg ASSERT_TRUE (ncopy + 1 == val_t::ncopy);
229 1.1 mrg ASSERT_TRUE (nassign == val_t::nassign);
230 1.1 mrg
231 1.1 mrg ASSERT_TRUE (&rv1 != pv2);
232 1.1 mrg }
233 1.1 mrg
234 1.1 mrg ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
235 1.1 mrg
236 1.1 mrg #if 0 /* Avoid testing until bug 90959 is fixed. */
237 1.1 mrg {
238 1.1 mrg /* Test copy assignment into an empty map. */
239 1.1 mrg Map m1;
240 1.1 mrg void *p = &p;
241 1.1 mrg val_t &rv1 = m1.get_or_insert (p);
242 1.1 mrg
243 1.1 mrg int ncopy = val_t::ncopy;
244 1.1 mrg int nassign = val_t::nassign;
245 1.1 mrg
246 1.1 mrg Map m2;
247 1.1 mrg m2 = m1;
248 1.1 mrg val_t *pv2 = m2.get (p);
249 1.1 mrg
250 1.1 mrg ASSERT_TRUE (ncopy == val_t::ncopy);
251 1.1 mrg ASSERT_TRUE (nassign + 1 == val_t::nassign);
252 1.1 mrg
253 1.1 mrg ASSERT_TRUE (&rv1 != pv2);
254 1.1 mrg }
255 1.1 mrg
256 1.1 mrg ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
257 1.1 mrg
258 1.1 mrg #endif
259 1.1 mrg
260 1.1 mrg {
261 1.1 mrg Map m;
262 1.1 mrg void *p = &p, *q = &q;
263 1.1 mrg val_t &v1 = m.get_or_insert (p);
264 1.1 mrg val_t &v2 = m.get_or_insert (q);
265 1.1 mrg
266 1.1 mrg ASSERT_TRUE (v1.ptr == &v1.ptr && &v2.ptr == v2.ptr);
267 1.1 mrg }
268 1.1 mrg
269 1.1 mrg ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
270 1.1 mrg
271 1.1 mrg {
272 1.1 mrg Map m;
273 1.1 mrg void *p = &p, *q = &q;
274 1.1 mrg m.get_or_insert (p);
275 1.1 mrg m.remove (p);
276 1.1 mrg m.get_or_insert (q);
277 1.1 mrg m.remove (q);
278 1.1 mrg
279 1.1 mrg ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
280 1.1 mrg }
281 1.1 mrg
282 1.1 mrg
283 1.1 mrg /* Verify basic construction and destruction of Value objects. */
284 1.1 mrg {
285 1.1 mrg /* Configure, arbitrary. */
286 1.1 mrg const size_t N_init = 0;
287 1.1 mrg const int N_elem = 28;
288 1.1 mrg
289 1.1 mrg void *a[N_elem];
290 1.1 mrg for (size_t i = 0; i < N_elem; ++i)
291 1.1 mrg a[i] = &a[i];
292 1.1 mrg
293 1.1 mrg val_t::ndefault = 0;
294 1.1 mrg val_t::ncopy = 0;
295 1.1 mrg val_t::nassign = 0;
296 1.1 mrg val_t::ndtor = 0;
297 1.1 mrg Map m (N_init);
298 1.1 mrg ASSERT_EQ (val_t::ndefault
299 1.1 mrg + val_t::ncopy
300 1.1 mrg + val_t::nassign
301 1.1 mrg + val_t::ndtor, 0);
302 1.1 mrg
303 1.1 mrg for (int i = 0; i < N_elem; ++i)
304 1.1 mrg {
305 1.1 mrg m.get_or_insert (a[i]);
306 1.1 mrg ASSERT_EQ (val_t::ndefault, 1 + i);
307 1.1 mrg ASSERT_EQ (val_t::ncopy, 0);
308 1.1 mrg ASSERT_EQ (val_t::nassign, 0);
309 1.1 mrg ASSERT_EQ (val_t::ndtor, i);
310 1.1 mrg
311 1.1 mrg m.remove (a[i]);
312 1.1 mrg ASSERT_EQ (val_t::ndefault, 1 + i);
313 1.1 mrg ASSERT_EQ (val_t::ncopy, 0);
314 1.1 mrg ASSERT_EQ (val_t::nassign, 0);
315 1.1 mrg ASSERT_EQ (val_t::ndtor, 1 + i);
316 1.1 mrg }
317 1.1 mrg }
318 1.1 mrg }
319 1.1 mrg
320 1.1 mrg /* Verify aspects of 'hash_table::expand', in particular that it doesn't leak
321 1.1 mrg Value objects. */
322 1.1 mrg
323 1.1 mrg static void
324 1.1 mrg test_map_of_type_with_ctor_and_dtor_expand (bool remove_some_inline)
325 1.1 mrg {
326 1.1 mrg /* Configure, so that hash table expansion triggers a few times. */
327 1.1 mrg const size_t N_init = 0;
328 1.1 mrg const int N_elem = 70;
329 1.1 mrg size_t expand_c_expected = 4;
330 1.1 mrg size_t expand_c = 0;
331 1.1 mrg
332 1.1 mrg /* For stability of this testing, we need all Key values 'k' to produce
333 1.1 mrg unique hash values 'Traits::hash (k)', as otherwise the dynamic
334 1.1 mrg insert/remove behavior may diverge across different architectures. This
335 1.1 mrg is, for example, a problem when using the standard 'pointer_hash::hash',
336 1.1 mrg which is simply doing a 'k >> 3' operation, which is fine on 64-bit
337 1.1 mrg architectures, but on 32-bit architectures produces the same hash value
338 1.1 mrg for subsequent 'a[i] = &a[i]' array elements. Therefore, use an
339 1.1 mrg 'int_hash'. */
340 1.1 mrg
341 1.1 mrg int a[N_elem];
342 1.1 mrg for (size_t i = 0; i < N_elem; ++i)
343 1.1 mrg a[i] = i;
344 1.1 mrg
345 1.1 mrg const int EMPTY = -1;
346 1.1 mrg const int DELETED = -2;
347 1.1 mrg typedef hash_map<int_hash<int, EMPTY, DELETED>, val_t> Map;
348 1.1 mrg
349 1.1 mrg /* Note that we are starting with a fresh 'Map'. Even if an existing one has
350 1.1 mrg been cleared out completely, there remain 'deleted' elements, and these
351 1.1 mrg would disturb the following logic, where we don't have access to the
352 1.1 mrg actual 'm_n_deleted' value. */
353 1.1 mrg size_t m_n_deleted = 0;
354 1.1 mrg
355 1.1 mrg val_t::ndefault = 0;
356 1.1 mrg val_t::ncopy = 0;
357 1.1 mrg val_t::nassign = 0;
358 1.1 mrg val_t::ndtor = 0;
359 1.1 mrg Map m (N_init);
360 1.1 mrg
361 1.1 mrg /* In the following, in particular related to 'expand', we're adapting from
362 1.1 mrg the internal logic of 'hash_table', glossing over "some details" not
363 1.1 mrg relevant for this testing here. */
364 1.1 mrg
365 1.1 mrg /* Per 'hash_table::hash_table'. */
366 1.1 mrg size_t m_size;
367 1.1 mrg {
368 1.1 mrg unsigned int size_prime_index_ = hash_table_higher_prime_index (N_init);
369 1.1 mrg m_size = prime_tab[size_prime_index_].prime;
370 1.1 mrg }
371 1.1 mrg
372 1.1 mrg int n_expand_moved = 0;
373 1.1 mrg
374 1.1 mrg for (int i = 0; i < N_elem; ++i)
375 1.1 mrg {
376 1.1 mrg size_t elts = m.elements ();
377 1.1 mrg
378 1.1 mrg /* Per 'hash_table::find_slot_with_hash'. */
379 1.1 mrg size_t m_n_elements = elts + m_n_deleted;
380 1.1 mrg bool expand = m_size * 3 <= m_n_elements * 4;
381 1.1 mrg
382 1.1 mrg m.get_or_insert (a[i]);
383 1.1 mrg if (expand)
384 1.1 mrg {
385 1.1 mrg ++expand_c;
386 1.1 mrg
387 1.1 mrg /* Per 'hash_table::expand'. */
388 1.1 mrg {
389 1.1 mrg unsigned int nindex = hash_table_higher_prime_index (elts * 2);
390 1.1 mrg m_size = prime_tab[nindex].prime;
391 1.1 mrg }
392 1.1 mrg m_n_deleted = 0;
393 1.1 mrg
394 1.1 mrg /* All non-deleted elements have been moved. */
395 1.1 mrg n_expand_moved += i;
396 1.1 mrg if (remove_some_inline)
397 1.1 mrg n_expand_moved -= (i + 2) / 3;
398 1.1 mrg }
399 1.1 mrg
400 1.1 mrg ASSERT_EQ (val_t::ndefault, 1 + i);
401 1.1 mrg ASSERT_EQ (val_t::ncopy, n_expand_moved);
402 1.1 mrg ASSERT_EQ (val_t::nassign, 0);
403 1.1 mrg if (remove_some_inline)
404 1.1 mrg ASSERT_EQ (val_t::ndtor, n_expand_moved + (i + 2) / 3);
405 1.1 mrg else
406 1.1 mrg ASSERT_EQ (val_t::ndtor, n_expand_moved);
407 1.1 mrg
408 1.1 mrg /* Remove some inline. This never triggers an 'expand' here, but via
409 1.1 mrg 'm_n_deleted' does influence any following one. */
410 1.1 mrg if (remove_some_inline
411 1.1 mrg && !(i % 3))
412 1.1 mrg {
413 1.1 mrg m.remove (a[i]);
414 1.1 mrg /* Per 'hash_table::remove_elt_with_hash'. */
415 1.1 mrg m_n_deleted++;
416 1.1 mrg
417 1.1 mrg ASSERT_EQ (val_t::ndefault, 1 + i);
418 1.1 mrg ASSERT_EQ (val_t::ncopy, n_expand_moved);
419 1.1 mrg ASSERT_EQ (val_t::nassign, 0);
420 1.1 mrg ASSERT_EQ (val_t::ndtor, n_expand_moved + 1 + (i + 2) / 3);
421 1.1 mrg }
422 1.1 mrg }
423 1.1 mrg ASSERT_EQ (expand_c, expand_c_expected);
424 1.1 mrg
425 1.1 mrg int ndefault = val_t::ndefault;
426 1.1 mrg int ncopy = val_t::ncopy;
427 1.1 mrg int nassign = val_t::nassign;
428 1.1 mrg int ndtor = val_t::ndtor;
429 1.1 mrg
430 1.1 mrg for (int i = 0; i < N_elem; ++i)
431 1.1 mrg {
432 1.1 mrg if (remove_some_inline
433 1.1 mrg && !(i % 3))
434 1.1 mrg continue;
435 1.1 mrg
436 1.1 mrg m.remove (a[i]);
437 1.1 mrg ++ndtor;
438 1.1 mrg ASSERT_EQ (val_t::ndefault, ndefault);
439 1.1 mrg ASSERT_EQ (val_t::ncopy, ncopy);
440 1.1 mrg ASSERT_EQ (val_t::nassign, nassign);
441 1.1 mrg ASSERT_EQ (val_t::ndtor, ndtor);
442 1.1 mrg }
443 1.1 mrg ASSERT_EQ (val_t::ndefault + val_t::ncopy, val_t::ndtor);
444 1.1 mrg }
445 1.1 mrg
446 1.1 mrg /* Test calling empty on a hash_map that has a key type with non-zero
447 1.1 mrg "empty" value. */
448 1.1 mrg
449 1.1 mrg static void
450 1.1 mrg test_nonzero_empty_key ()
451 1.1 mrg {
452 1.1 mrg typedef int_hash<int, INT_MIN, INT_MAX> IntHash;
453 1.1 mrg hash_map<int, int, simple_hashmap_traits<IntHash, int> > x;
454 1.1 mrg
455 1.1 mrg for (int i = 1; i != 32; ++i)
456 1.1 mrg x.put (i, i);
457 1.1 mrg
458 1.1 mrg ASSERT_EQ (x.get (0), NULL);
459 1.1 mrg ASSERT_EQ (*x.get (1), 1);
460 1.1 mrg
461 1.1 mrg x.empty ();
462 1.1 mrg
463 1.1 mrg ASSERT_EQ (x.get (0), NULL);
464 1.1 mrg ASSERT_EQ (x.get (1), NULL);
465 1.1 mrg }
466 1.1 mrg
467 1.1 mrg /* Run all of the selftests within this file. */
468 1.1 mrg
469 1.1 mrg void
470 1.1 mrg hash_map_tests_cc_tests ()
471 1.1 mrg {
472 1.1 mrg test_map_of_strings_to_int ();
473 1.1 mrg test_map_of_int_to_strings ();
474 1.1 mrg test_map_of_type_with_ctor_and_dtor ();
475 1.1 mrg test_map_of_type_with_ctor_and_dtor_expand (false);
476 1.1 mrg test_map_of_type_with_ctor_and_dtor_expand (true);
477 1.1 mrg test_nonzero_empty_key ();
478 1.1 mrg }
479 1.1 mrg
480 1.1 mrg } // namespace selftest
481 1.1 mrg
482 1.1 mrg #endif /* CHECKING_P */
483