Mercurial > hg > CbC > CbC_gcc
diff gcc/hash-map-tests.c @ 146:351920fa3827
merge
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 01 Mar 2020 16:13:28 +0900 |
parents | 1830386684a0 |
children |
line wrap: on
line diff
--- a/gcc/hash-map-tests.c Sun Dec 23 21:23:56 2018 +0900 +++ b/gcc/hash-map-tests.c Sun Mar 01 16:13:28 2020 +0900 @@ -1,5 +1,5 @@ /* Unit tests for hash-map.h. - Copyright (C) 2015-2018 Free Software Foundation, Inc. + Copyright (C) 2015-2020 Free Software Foundation, Inc. This file is part of GCC. @@ -53,7 +53,7 @@ const char *eric = "half a bee"; /* A fresh hash_map should be empty. */ - ASSERT_EQ (0, m.elements ()); + ASSERT_TRUE (m.is_empty ()); ASSERT_EQ (NULL, m.get (ostrich)); /* Populate the hash_map. */ @@ -77,6 +77,228 @@ m.remove (eric); ASSERT_EQ (5, m.elements ()); ASSERT_EQ (NULL, m.get (eric)); + + m.remove (eric); + ASSERT_EQ (5, m.elements ()); + ASSERT_EQ (NULL, m.get (eric)); + + /* A plain char * key is hashed based on its value (address), rather + than the string it points to. */ + char *another_ant = static_cast <char *> (xcalloc (4, 1)); + another_ant[0] = 'a'; + another_ant[1] = 'n'; + another_ant[2] = 't'; + another_ant[3] = 0; + ASSERT_NE (ant, another_ant); + unsigned prev_size = m.elements (); + ASSERT_EQ (false, m.put (another_ant, 7)); + ASSERT_EQ (prev_size + 1, m.elements ()); + + /* Need to use string_hash or nofree_string_hash key types to hash + based on the string contents. */ + hash_map <nofree_string_hash, int> string_map; + ASSERT_EQ (false, string_map.put (ant, 1)); + ASSERT_EQ (1, string_map.elements ()); + ASSERT_EQ (true, string_map.put (another_ant, 5)); + ASSERT_EQ (1, string_map.elements ()); + + free (another_ant); +} + +/* Construct a hash_map using int_hash and verify that + various operations work correctly. */ + +static void +test_map_of_int_to_strings () +{ + const int EMPTY = -1; + const int DELETED = -2; + typedef int_hash <int, EMPTY, DELETED> int_hash_t; + hash_map <int_hash_t, const char *> m; + + const char *ostrich = "ostrich"; + const char *elephant = "elephant"; + const char *ant = "ant"; + const char *spider = "spider"; + const char *millipede = "Illacme plenipes"; + const char *eric = "half a bee"; + + /* A fresh hash_map should be empty. */ + ASSERT_EQ (0, m.elements ()); + ASSERT_EQ (NULL, m.get (2)); + + /* Populate the hash_map. */ + ASSERT_EQ (false, m.put (2, ostrich)); + ASSERT_EQ (false, m.put (4, elephant)); + ASSERT_EQ (false, m.put (6, ant)); + ASSERT_EQ (false, m.put (8, spider)); + ASSERT_EQ (false, m.put (750, millipede)); + ASSERT_EQ (false, m.put (3, eric)); + + /* Verify that we can recover the stored values. */ + ASSERT_EQ (6, m.elements ()); + ASSERT_EQ (*m.get (2), ostrich); + ASSERT_EQ (*m.get (4), elephant); + ASSERT_EQ (*m.get (6), ant); + ASSERT_EQ (*m.get (8), spider); + ASSERT_EQ (*m.get (750), millipede); + ASSERT_EQ (*m.get (3), eric); +} + +typedef class hash_map_test_val_t +{ +public: + static int ndefault; + static int ncopy; + static int nassign; + static int ndtor; + + hash_map_test_val_t () + : ptr (&ptr) + { + ++ndefault; + } + + hash_map_test_val_t (const hash_map_test_val_t &rhs) + : ptr (&ptr) + { + ++ncopy; + gcc_assert (rhs.ptr == &rhs.ptr); + } + + hash_map_test_val_t& operator= (const hash_map_test_val_t &rhs) + { + ++nassign; + gcc_assert (ptr == &ptr); + gcc_assert (rhs.ptr == &rhs.ptr); + return *this; + } + + ~hash_map_test_val_t () + { + gcc_assert (ptr == &ptr); + ++ndtor; + } + + void *ptr; +} val_t; + +int val_t::ndefault; +int val_t::ncopy; +int val_t::nassign; +int val_t::ndtor; + +static void +test_map_of_type_with_ctor_and_dtor () +{ + typedef hash_map <void *, val_t> Map; + + { + /* Test default ctor. */ + Map m; + (void)&m; + } + + ASSERT_TRUE (val_t::ndefault == 0); + ASSERT_TRUE (val_t::ncopy == 0); + ASSERT_TRUE (val_t::nassign == 0); + ASSERT_TRUE (val_t::ndtor == 0); + + { + /* Test single insertion. */ + Map m; + void *p = &p; + m.get_or_insert (p); + } + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + + { + /* Test copy ctor. */ + Map m1; + void *p = &p; + val_t &rv1 = m1.get_or_insert (p); + + int ncopy = val_t::ncopy; + int nassign = val_t::nassign; + + Map m2 (m1); + val_t *pv2 = m2.get (p); + + ASSERT_TRUE (ncopy + 1 == val_t::ncopy); + ASSERT_TRUE (nassign == val_t::nassign); + + ASSERT_TRUE (&rv1 != pv2); + } + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + +#if 0 /* Avoid testing until bug 90959 is fixed. */ + { + /* Test copy assignment into an empty map. */ + Map m1; + void *p = &p; + val_t &rv1 = m1.get_or_insert (p); + + int ncopy = val_t::ncopy; + int nassign = val_t::nassign; + + Map m2; + m2 = m1; + val_t *pv2 = m2.get (p); + + ASSERT_TRUE (ncopy == val_t::ncopy); + ASSERT_TRUE (nassign + 1 == val_t::nassign); + + ASSERT_TRUE (&rv1 != pv2); + } + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + +#endif + + { + Map m; + void *p = &p, *q = &q; + val_t &v1 = m.get_or_insert (p); + val_t &v2 = m.get_or_insert (q); + + ASSERT_TRUE (v1.ptr == &v1.ptr && &v2.ptr == v2.ptr); + } + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + + { + Map m; + void *p = &p, *q = &q; + m.get_or_insert (p); + m.remove (p); + m.get_or_insert (q); + m.remove (q); + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + } +} + +/* Test calling empty on a hash_map that has a key type with non-zero + "empty" value. */ + +static void +test_nonzero_empty_key () +{ + typedef int_hash<int, INT_MIN, INT_MAX> IntHash; + hash_map<int, int, simple_hashmap_traits<IntHash, int> > x; + + for (int i = 1; i != 32; ++i) + x.put (i, i); + + ASSERT_EQ (x.get (0), NULL); + ASSERT_EQ (*x.get (1), 1); + + x.empty (); + + ASSERT_EQ (x.get (0), NULL); + ASSERT_EQ (x.get (1), NULL); } /* Run all of the selftests within this file. */ @@ -85,6 +307,9 @@ hash_map_tests_c_tests () { test_map_of_strings_to_int (); + test_map_of_int_to_strings (); + test_map_of_type_with_ctor_and_dtor (); + test_nonzero_empty_key (); } } // namespace selftest