1 /* A type-safe hash map.
2 Copyright (C) 2014-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
24 template<typename KeyId
, typename Value
,
26 class GTY((user
)) hash_map
28 typedef typename
Traits::key_type Key
;
34 typedef hash_entry value_type
;
35 typedef Key compare_type
;
37 static hashval_t
hash (const hash_entry
&e
)
39 return Traits::hash (e
.m_key
);
42 static bool equal (const hash_entry
&a
, const Key
&b
)
44 return Traits::equal_keys (a
.m_key
, b
);
47 static void remove (hash_entry
&e
) { Traits::remove (e
); }
49 static void mark_deleted (hash_entry
&e
) { Traits::mark_deleted (e
); }
51 static bool is_deleted (const hash_entry
&e
)
53 return Traits::is_deleted (e
);
56 static void mark_empty (hash_entry
&e
) { Traits::mark_empty (e
); }
57 static bool is_empty (const hash_entry
&e
) { return Traits::is_empty (e
); }
59 static void ggc_mx (hash_entry
&e
)
62 gt_ggc_mx (e
.m_value
);
65 static void pch_nx (hash_entry
&e
)
68 gt_pch_nx (e
.m_value
);
71 static void pch_nx (hash_entry
&e
, gt_pointer_operator op
, void *c
)
73 pch_nx_helper (e
.m_key
, op
, c
);
74 pch_nx_helper (e
.m_value
, op
, c
);
80 pch_nx_helper (T
&x
, gt_pointer_operator op
, void *cookie
)
82 gt_pch_nx (&x
, op
, cookie
);
86 pch_nx_helper (int, gt_pointer_operator
, void *)
91 pch_nx_helper (unsigned int, gt_pointer_operator
, void *)
96 pch_nx_helper (bool, gt_pointer_operator
, void *)
102 pch_nx_helper (T
*&x
, gt_pointer_operator op
, void *cookie
)
109 explicit hash_map (size_t n
= 13, bool ggc
= false,
110 bool gather_mem_stats
= GATHER_STATISTICS
112 : m_table (n
, ggc
, gather_mem_stats
, HASH_MAP_ORIGIN PASS_MEM_STAT
) {}
114 explicit hash_map (const hash_map
&h
, bool ggc
= false,
115 bool gather_mem_stats
= GATHER_STATISTICS
117 : m_table (h
.m_table
, ggc
, gather_mem_stats
,
118 HASH_MAP_ORIGIN PASS_MEM_STAT
) {}
120 /* Create a hash_map in ggc memory. */
121 static hash_map
*create_ggc (size_t size
,
122 bool gather_mem_stats
= GATHER_STATISTICS
125 hash_map
*map
= ggc_alloc
<hash_map
> ();
126 new (map
) hash_map (size
, true, gather_mem_stats PASS_MEM_STAT
);
130 /* If key k isn't already in the map add key k with value v to the map, and
131 return false. Otherwise set the value of the entry for key k to be v and
134 bool put (const Key
&k
, const Value
&v
)
136 hash_entry
*e
= m_table
.find_slot_with_hash (k
, Traits::hash (k
),
138 bool existed
= !hash_entry::is_empty (*e
);
146 /* if the passed in key is in the map return its value otherwise NULL. */
148 Value
*get (const Key
&k
)
150 hash_entry
&e
= m_table
.find_with_hash (k
, Traits::hash (k
));
151 return Traits::is_empty (e
) ? NULL
: &e
.m_value
;
154 /* Return a reference to the value for the passed in key, creating the entry
155 if it doesn't already exist. If existed is not NULL then it is set to false
156 if the key was not previously in the map, and true otherwise. */
158 Value
&get_or_insert (const Key
&k
, bool *existed
= NULL
)
160 hash_entry
*e
= m_table
.find_slot_with_hash (k
, Traits::hash (k
),
162 bool ins
= Traits::is_empty (*e
);
172 void remove (const Key
&k
)
174 m_table
.remove_elt_with_hash (k
, Traits::hash (k
));
177 /* Call the call back on each pair of key and value with the passed in
180 template<typename Arg
, bool (*f
)(const typename
Traits::key_type
&,
182 void traverse (Arg a
) const
184 for (typename hash_table
<hash_entry
>::iterator iter
= m_table
.begin ();
185 iter
!= m_table
.end (); ++iter
)
186 f ((*iter
).m_key
, (*iter
).m_value
, a
);
189 template<typename Arg
, bool (*f
)(const typename
Traits::key_type
&,
191 void traverse (Arg a
) const
193 for (typename hash_table
<hash_entry
>::iterator iter
= m_table
.begin ();
194 iter
!= m_table
.end (); ++iter
)
195 if (!f ((*iter
).m_key
, &(*iter
).m_value
, a
))
199 size_t elements () const { return m_table
.elements (); }
201 void empty () { m_table
.empty(); }
206 explicit iterator (const typename hash_table
<hash_entry
>::iterator
&iter
) :
209 iterator
&operator++ ()
215 std::pair
<Key
, Value
> operator* ()
217 hash_entry
&e
= *m_iter
;
218 return std::pair
<Key
, Value
> (e
.m_key
, e
.m_value
);
222 operator != (const iterator
&other
) const
224 return m_iter
!= other
.m_iter
;
228 typename hash_table
<hash_entry
>::iterator m_iter
;
231 /* Standard iterator retrieval methods. */
233 iterator
begin () const { return iterator (m_table
.begin ()); }
234 iterator
end () const { return iterator (m_table
.end ()); }
238 template<typename T
, typename U
, typename V
> friend void gt_ggc_mx (hash_map
<T
, U
, V
> *);
239 template<typename T
, typename U
, typename V
> friend void gt_pch_nx (hash_map
<T
, U
, V
> *);
240 template<typename T
, typename U
, typename V
> friend void gt_pch_nx (hash_map
<T
, U
, V
> *, gt_pointer_operator
, void *);
242 hash_table
<hash_entry
> m_table
;
245 /* ggc marking routines. */
247 template<typename K
, typename V
, typename H
>
249 gt_ggc_mx (hash_map
<K
, V
, H
> *h
)
251 gt_ggc_mx (&h
->m_table
);
254 template<typename K
, typename V
, typename H
>
256 gt_pch_nx (hash_map
<K
, V
, H
> *h
)
258 gt_pch_nx (&h
->m_table
);
261 template<typename K
, typename V
, typename H
>
263 gt_pch_nx (hash_map
<K
, V
, H
> *h
, gt_pointer_operator op
, void *cookie
)
265 op (&h
->m_table
.m_entries
, cookie
);