Mercurial > hg > CbC > CbC_gcc
diff gcc/hash-map.h @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/hash-map.h Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/hash-map.h Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* A type-safe hash map. - Copyright (C) 2014-2018 Free Software Foundation, Inc. + Copyright (C) 2014-2020 Free Software Foundation, Inc. This file is part of GCC. @@ -21,8 +21,21 @@ #ifndef hash_map_h #define hash_map_h +/* Class hash_map is a hash-value based container mapping objects of + KeyId type to those of the Value type. + Both KeyId and Value may be non-trivial (non-POD) types provided + a suitabe Traits class. A few default Traits specializations are + provided for basic types such as integers, pointers, and std::pair. + Inserted elements are value-initialized either to zero for POD types + or by invoking their default ctor. Removed elements are destroyed + by invoking their dtor. On hash_map destruction all elements are + removed. Objects of hash_map type are copy-constructible but not + assignable. */ + +const size_t default_hash_map_size = 13; template<typename KeyId, typename Value, - typename Traits> + typename Traits /* = simple_hashmap_traits<default_hash_traits<Key>, + Value> */> class GTY((user)) hash_map { typedef typename Traits::key_type Key; @@ -53,6 +66,7 @@ return Traits::is_deleted (e); } + static const bool empty_zero_p = Traits::empty_zero_p; static void mark_empty (hash_entry &e) { Traits::mark_empty (e); } static bool is_empty (const hash_entry &e) { return Traits::is_empty (e); } @@ -117,24 +131,29 @@ }; public: - explicit hash_map (size_t n = 13, bool ggc = false, + explicit hash_map (size_t n = default_hash_map_size, bool ggc = false, + bool sanitize_eq_and_hash = true, bool gather_mem_stats = GATHER_STATISTICS CXX_MEM_STAT_INFO) - : m_table (n, ggc, gather_mem_stats, HASH_MAP_ORIGIN PASS_MEM_STAT) {} + : m_table (n, ggc, sanitize_eq_and_hash, gather_mem_stats, + HASH_MAP_ORIGIN PASS_MEM_STAT) + { + } explicit hash_map (const hash_map &h, bool ggc = false, + bool sanitize_eq_and_hash = true, bool gather_mem_stats = GATHER_STATISTICS CXX_MEM_STAT_INFO) - : m_table (h.m_table, ggc, gather_mem_stats, + : m_table (h.m_table, ggc, sanitize_eq_and_hash, gather_mem_stats, HASH_MAP_ORIGIN PASS_MEM_STAT) {} /* Create a hash_map in ggc memory. */ - static hash_map *create_ggc (size_t size, + static hash_map *create_ggc (size_t size = default_hash_map_size, bool gather_mem_stats = GATHER_STATISTICS CXX_MEM_STAT_INFO) { hash_map *map = ggc_alloc<hash_map> (); - new (map) hash_map (size, true, gather_mem_stats PASS_MEM_STAT); + new (map) hash_map (size, true, true, gather_mem_stats PASS_MEM_STAT); return map; } @@ -146,12 +165,16 @@ { hash_entry *e = m_table.find_slot_with_hash (k, Traits::hash (k), INSERT); - bool existed = !hash_entry::is_empty (*e); - if (!existed) - e->m_key = k; + bool ins = hash_entry::is_empty (*e); + if (ins) + { + e->m_key = k; + new ((void *) &e->m_value) Value (v); + } + else + e->m_value = v; - e->m_value = v; - return existed; + return !ins; } /* if the passed in key is in the map return its value otherwise NULL. */ @@ -163,8 +186,8 @@ } /* Return a reference to the value for the passed in key, creating the entry - if it doesn't already exist. If existed is not NULL then it is set to false - if the key was not previously in the map, and true otherwise. */ + if it doesn't already exist. If existed is not NULL then it is set to + false if the key was not previously in the map, and true otherwise. */ Value &get_or_insert (const Key &k, bool *existed = NULL) { @@ -172,7 +195,10 @@ INSERT); bool ins = Traits::is_empty (*e); if (ins) - e->m_key = k; + { + e->m_key = k; + new ((void *)&e->m_value) Value (); + } if (existed != NULL) *existed = !ins; @@ -211,6 +237,9 @@ void empty () { m_table.empty(); } + /* Return true when there are no elements in this hash map. */ + bool is_empty () const { return m_table.is_empty (); } + class iterator { public: @@ -223,10 +252,24 @@ return *this; } - std::pair<const Key&, Value&> operator* () + /* Can't use std::pair here, because GCC before 4.3 don't handle + std::pair where template parameters are references well. + See PR86739. */ + class reference_pair { + public: + const Key &first; + Value &second; + + reference_pair (const Key &key, Value &value) : first (key), second (value) {} + + template <typename K, typename V> + operator std::pair<K, V> () const { return std::pair<K, V> (first, second); } + }; + + reference_pair operator* () { hash_entry &e = *m_iter; - return std::pair<const Key&, Value&> (e.m_key, e.m_value); + return reference_pair (e.m_key, e.m_value); } bool @@ -285,4 +328,46 @@ op (&h->m_table.m_entries, cookie); } +enum hm_alloc { hm_heap = false, hm_ggc = true }; +template<bool ggc, typename K, typename V, typename H> +inline hash_map<K,V,H> * +hash_map_maybe_create (hash_map<K,V,H> *&h, + size_t size = default_hash_map_size) +{ + if (!h) + { + if (ggc) + h = hash_map<K,V,H>::create_ggc (size); + else + h = new hash_map<K,V,H> (size); + } + return h; +} + +/* Like h->get, but handles null h. */ +template<typename K, typename V, typename H> +inline V* +hash_map_safe_get (hash_map<K,V,H> *h, const K& k) +{ + return h ? h->get (k) : NULL; +} + +/* Like h->get, but handles null h. */ +template<bool ggc, typename K, typename V, typename H> +inline V& +hash_map_safe_get_or_insert (hash_map<K,V,H> *&h, const K& k, bool *e = NULL, + size_t size = default_hash_map_size) +{ + return hash_map_maybe_create<ggc> (h, size)->get_or_insert (k, e); +} + +/* Like h->put, but handles null h. */ +template<bool ggc, typename K, typename V, typename H> +inline bool +hash_map_safe_put (hash_map<K,V,H> *&h, const K& k, const V& v, + size_t size = default_hash_map_size) +{ + return hash_map_maybe_create<ggc> (h, size)->put (k, v); +} + #endif