1 /* A type-safe hash map.
2 Copyright (C) 2014-2015 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/>. */
26 #include "hash-table.h"
27 #include "hash-map-traits.h"
28 #include "mem-stats.h"
31 template<typename Key
, typename Value
,
33 class GTY((user
)) hash_map
40 typedef hash_entry value_type
;
41 typedef Key compare_type
;
43 static hashval_t
hash (const hash_entry
&e
)
45 return Traits::hash (e
.m_key
);
48 static bool equal (const hash_entry
&a
, const Key
&b
)
50 return Traits::equal_keys (a
.m_key
, b
);
53 static void remove (hash_entry
&e
) { Traits::remove (e
); }
55 static void mark_deleted (hash_entry
&e
) { Traits::mark_deleted (e
); }
57 static bool is_deleted (const hash_entry
&e
)
59 return Traits::is_deleted (e
);
62 static void mark_empty (hash_entry
&e
) { Traits::mark_empty (e
); }
63 static bool is_empty (const hash_entry
&e
) { return Traits::is_empty (e
); }
65 static void ggc_mx (hash_entry
&e
)
68 gt_ggc_mx (e
.m_value
);
71 static void pch_nx (hash_entry
&e
)
74 gt_pch_nx (e
.m_value
);
77 static void pch_nx (hash_entry
&e
, gt_pointer_operator op
, void *c
)
79 pch_nx_helper (e
.m_key
, op
, c
);
80 pch_nx_helper (e
.m_value
, op
, c
);
86 pch_nx_helper (T
&x
, gt_pointer_operator op
, void *cookie
)
88 gt_pch_nx (&x
, op
, cookie
);
92 pch_nx_helper (int, gt_pointer_operator
, void *)
97 pch_nx_helper (unsigned int, gt_pointer_operator
, void *)
102 pch_nx_helper (bool, gt_pointer_operator
, void *)
108 pch_nx_helper (T
*&x
, gt_pointer_operator op
, void *cookie
)
115 explicit hash_map (size_t n
= 13, bool ggc
= false,
116 bool gather_mem_stats
= true CXX_MEM_STAT_INFO
)
117 : m_table (n
, ggc
, gather_mem_stats
, HASH_MAP PASS_MEM_STAT
) {}
119 /* Create a hash_map in ggc memory. */
120 static hash_map
*create_ggc (size_t size
, bool gather_mem_stats
= true
123 hash_map
*map
= ggc_alloc
<hash_map
> ();
124 new (map
) hash_map (size
, true, gather_mem_stats PASS_MEM_STAT
);
128 /* If key k isn't already in the map add key k with value v to the map, and
129 return false. Otherwise set the value of the entry for key k to be v and
132 bool put (const Key
&k
, const Value
&v
)
134 hash_entry
*e
= m_table
.find_slot_with_hash (k
, Traits::hash (k
),
136 bool existed
= !hash_entry::is_empty (*e
);
144 /* if the passed in key is in the map return its value otherwise NULL. */
146 Value
*get (const Key
&k
)
148 hash_entry
&e
= m_table
.find_with_hash (k
, Traits::hash (k
));
149 return Traits::is_empty (e
) ? NULL
: &e
.m_value
;
152 /* Return a reference to the value for the passed in key, creating the entry
153 if it doesn't already exist. If existed is not NULL then it is set to false
154 if the key was not previously in the map, and true otherwise. */
156 Value
&get_or_insert (const Key
&k
, bool *existed
= NULL
)
158 hash_entry
*e
= m_table
.find_slot_with_hash (k
, Traits::hash (k
),
160 bool ins
= Traits::is_empty (*e
);
170 void remove (const Key
&k
)
172 m_table
.remove_elt_with_hash (k
, Traits::hash (k
));
175 /* Call the call back on each pair of key and value with the passed in
178 template<typename Arg
, bool (*f
)(const Key
&, const Value
&, Arg
)>
179 void traverse (Arg a
) const
181 for (typename hash_table
<hash_entry
>::iterator iter
= m_table
.begin ();
182 iter
!= m_table
.end (); ++iter
)
183 f ((*iter
).m_key
, (*iter
).m_value
, a
);
186 template<typename Arg
, bool (*f
)(const Key
&, Value
*, Arg
)>
187 void traverse (Arg a
) const
189 for (typename hash_table
<hash_entry
>::iterator iter
= m_table
.begin ();
190 iter
!= m_table
.end (); ++iter
)
191 if (!f ((*iter
).m_key
, &(*iter
).m_value
, a
))
195 size_t elements () const { return m_table
.elements (); }
200 explicit iterator (const typename hash_table
<hash_entry
>::iterator
&iter
) :
203 iterator
&operator++ ()
209 std::pair
<Key
, Value
> operator* ()
211 hash_entry
&e
= *m_iter
;
212 return std::pair
<Key
, Value
> (e
.m_key
, e
.m_value
);
216 operator != (const iterator
&other
) const
218 return m_iter
!= other
.m_iter
;
222 typename hash_table
<hash_entry
>::iterator m_iter
;
225 /* Standard iterator retrieval methods. */
227 iterator
begin () const { return iterator (m_table
.begin ()); }
228 iterator
end () const { return iterator (m_table
.end ()); }
232 template<typename T
, typename U
, typename V
> friend void gt_ggc_mx (hash_map
<T
, U
, V
> *);
233 template<typename T
, typename U
, typename V
> friend void gt_pch_nx (hash_map
<T
, U
, V
> *);
234 template<typename T
, typename U
, typename V
> friend void gt_pch_nx (hash_map
<T
, U
, V
> *, gt_pointer_operator
, void *);
236 hash_table
<hash_entry
> m_table
;
239 /* ggc marking routines. */
241 template<typename K
, typename V
, typename H
>
243 gt_ggc_mx (hash_map
<K
, V
, H
> *h
)
245 gt_ggc_mx (&h
->m_table
);
248 template<typename K
, typename V
, typename H
>
250 gt_pch_nx (hash_map
<K
, V
, H
> *h
)
252 gt_pch_nx (&h
->m_table
);
255 template<typename K
, typename V
, typename H
>
257 gt_pch_nx (hash_map
<K
, V
, H
> *h
, gt_pointer_operator op
, void *cookie
)
259 op (&h
->m_table
.m_entries
, cookie
);