1 /* A type-safe hash set.
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/>. */
24 /* implement default behavior for traits when types allow it. */
26 struct default_hashset_traits
28 /* Hashes the passed in key. */
34 return uintptr_t (p
) >> 3;
37 template<typename T
> static hashval_t
hash(const T
&v
) { return v
; }
39 /* Return true if the two keys passed as arguments are equal. */
43 equal (const T
&a
, const T
&b
)
48 /* Called to dispose of the key before marking the entry as deleted. */
50 template<typename T
> static void remove (T
&v
) { v
.~T (); }
52 /* Mark the passed in entry as being deleted. */
58 e
= reinterpret_cast<void *> (1);
61 /* Mark the passed in entry as being empty. */
70 /* Return true if the passed in entry is marked as deleted. */
76 return e
== reinterpret_cast<void *> (1);
79 /* Return true if the passed in entry is marked as empty. */
81 template<typename T
> static bool is_empty (T
*e
) { return e
== NULL
; }
83 /* ggc walking routine, mark all objects refered to by this one. */
89 extern void gt_ggc_mx (T
&);
93 /* pch walking routine, note all objects refered to by this element. */
99 extern void gt_pch_nx (T
&);
104 template<typename Key
, typename Traits
= default_hashset_traits
>
111 typedef hash_entry value_type
;
112 typedef Key compare_type
;
114 static hashval_t
hash (const hash_entry
&e
)
116 return Traits::hash (e
.m_key
);
119 static bool equal (const hash_entry
&a
, const Key
&b
)
121 return Traits::equal (a
.m_key
, b
);
124 static void remove (hash_entry
&e
) { Traits::remove (e
.m_key
); }
127 mark_deleted (hash_entry
&e
)
129 Traits::mark_deleted (e
.m_key
);
132 static bool is_deleted (const hash_entry
&e
)
134 return Traits::is_deleted (e
.m_key
);
138 mark_empty (hash_entry
&e
)
140 Traits::mark_empty (e
.m_key
);
144 is_empty (const hash_entry
&e
)
146 return Traits::is_empty (e
.m_key
);
149 static void ggc_mx (hash_entry
&e
)
151 Traits::ggc_mx (e
.m_key
);
154 static void pch_nx (hash_entry
&e
)
156 Traits::pch_nx (e
.m_key
);
159 static void pch_nx (hash_entry
&e
, gt_pointer_operator op
, void *c
)
161 pch_nx_helper (e
.m_key
, op
, c
);
167 pch_nx_helper (T
&x
, gt_pointer_operator op
, void *cookie
)
169 gt_pch_nx (&x
, op
, cookie
);
174 pch_nx_helper (T
*&x
, gt_pointer_operator op
, void *cookie
)
181 explicit hash_set (size_t n
= 13, bool ggc
= false CXX_MEM_STAT_INFO
)
182 : m_table (n
, ggc
, true, HASH_SET_ORIGIN PASS_MEM_STAT
) {}
184 /* Create a hash_set in gc memory with space for at least n elements. */
187 create_ggc (size_t n
)
189 hash_set
*set
= ggc_alloc
<hash_set
> ();
190 new (set
) hash_set (n
, true);
194 /* If key k isn't already in the map add it to the map, and
195 return false. Otherwise return true. */
197 bool add (const Key
&k
)
199 hash_entry
*e
= m_table
.find_slot_with_hash (k
, Traits::hash (k
),
201 bool existed
= !hash_entry::is_empty (*e
);
208 /* if the passed in key is in the map return its value otherwise NULL. */
210 bool contains (const Key
&k
)
212 hash_entry
&e
= m_table
.find_with_hash (k
, Traits::hash (k
));
213 return !Traits::is_empty (e
.m_key
);
216 /* Call the call back on each pair of key and value with the passed in
219 template<typename Arg
, bool (*f
)(const Key
&, Arg
)>
220 void traverse (Arg a
) const
222 for (typename hash_table
<hash_entry
>::iterator iter
= m_table
.begin ();
223 iter
!= m_table
.end (); ++iter
)
224 f ((*iter
).m_key
, a
);
227 /* Return the number of elements in the set. */
229 size_t elements () const { return m_table
.elements (); }
233 template<typename T
, typename U
> friend void gt_ggc_mx (hash_set
<T
, U
> *);
234 template<typename T
, typename U
> friend void gt_pch_nx (hash_set
<T
, U
> *);
235 template<typename T
, typename U
> friend void gt_pch_nx (hash_set
<T
, U
> *, gt_pointer_operator
, void *);
237 hash_table
<hash_entry
> m_table
;
240 /* ggc marking routines. */
242 template<typename K
, typename H
>
244 gt_ggc_mx (hash_set
<K
, H
> *h
)
246 gt_ggc_mx (&h
->m_table
);
249 template<typename K
, typename H
>
251 gt_pch_nx (hash_set
<K
, H
> *h
)
253 gt_pch_nx (&h
->m_table
);
256 template<typename K
, typename H
>
258 gt_pch_nx (hash_set
<K
, H
> *h
, gt_pointer_operator op
, void *cookie
)
260 op (&h
->m_table
.m_entries
, cookie
);