]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/hash-traits.h
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / hash-traits.h
CommitLineData
f11c3779 1/* Traits for hashable types.
8d9254fc 2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
f11c3779
RS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#ifndef hash_traits_h
21#define hash_traits_h
22
23/* Helpful type for removing with free. */
24
25template <typename Type>
26struct typed_free_remove
27{
28 static inline void remove (Type *p);
29};
30
31
32/* Remove with free. */
33
34template <typename Type>
35inline void
36typed_free_remove <Type>::remove (Type *p)
37{
38 free (p);
39}
40
74fbae92
ML
41/* Helpful type for removing with delete. */
42
43template <typename Type>
44struct typed_delete_remove
45{
46 static inline void remove (Type *p);
47};
48
49
50/* Remove with delete. */
51
52template <typename Type>
53inline void
54typed_delete_remove <Type>::remove (Type *p)
55{
56 delete p;
57}
f11c3779
RS
58
59/* Helpful type for a no-op remove. */
60
61template <typename Type>
62struct typed_noop_remove
63{
fc17926a 64 static inline void remove (Type &);
f11c3779
RS
65};
66
67
68/* Remove doing nothing. */
69
70template <typename Type>
71inline void
fc17926a 72typed_noop_remove <Type>::remove (Type &)
f11c3779
RS
73{
74}
75
76
e0702244
RS
77/* Hasher for integer type Type in which Empty is a spare value that can be
78 used to mark empty slots. If Deleted != Empty then Deleted is another
79 spare value that can be used for deleted slots; if Deleted == Empty then
80 hash table entries cannot be deleted. */
81
82template <typename Type, Type Empty, Type Deleted = Empty>
83struct int_hash : typed_noop_remove <Type>
84{
85 typedef Type value_type;
86 typedef Type compare_type;
87
88 static inline hashval_t hash (value_type);
89 static inline bool equal (value_type existing, value_type candidate);
90 static inline void mark_deleted (Type &);
7ca50de0 91 static const bool empty_zero_p = Empty == 0;
e0702244
RS
92 static inline void mark_empty (Type &);
93 static inline bool is_deleted (Type);
94 static inline bool is_empty (Type);
95};
96
97template <typename Type, Type Empty, Type Deleted>
98inline hashval_t
99int_hash <Type, Empty, Deleted>::hash (value_type x)
100{
101 return x;
102}
103
104template <typename Type, Type Empty, Type Deleted>
105inline bool
106int_hash <Type, Empty, Deleted>::equal (value_type x, value_type y)
107{
108 return x == y;
109}
110
111template <typename Type, Type Empty, Type Deleted>
112inline void
113int_hash <Type, Empty, Deleted>::mark_deleted (Type &x)
114{
115 gcc_assert (Empty != Deleted);
116 x = Deleted;
117}
118
119template <typename Type, Type Empty, Type Deleted>
120inline void
121int_hash <Type, Empty, Deleted>::mark_empty (Type &x)
122{
123 x = Empty;
124}
125
126template <typename Type, Type Empty, Type Deleted>
127inline bool
128int_hash <Type, Empty, Deleted>::is_deleted (Type x)
129{
130 return Empty != Deleted && x == Deleted;
131}
132
133template <typename Type, Type Empty, Type Deleted>
134inline bool
135int_hash <Type, Empty, Deleted>::is_empty (Type x)
136{
137 return x == Empty;
138}
139
8d67ee55
RS
140/* Pointer hasher based on pointer equality. Other types of pointer hash
141 can inherit this and override the hash and equal functions with some
142 other form of equality (such as string equality). */
f11c3779
RS
143
144template <typename Type>
8d67ee55 145struct pointer_hash
f11c3779
RS
146{
147 typedef Type *value_type;
148 typedef Type *compare_type;
149
150 static inline hashval_t hash (const value_type &);
f11c3779
RS
151 static inline bool equal (const value_type &existing,
152 const compare_type &candidate);
843adf88 153 static inline void mark_deleted (Type *&);
7ca50de0 154 static const bool empty_zero_p = true;
843adf88
RS
155 static inline void mark_empty (Type *&);
156 static inline bool is_deleted (Type *);
157 static inline bool is_empty (Type *);
f11c3779
RS
158};
159
160template <typename Type>
161inline hashval_t
162pointer_hash <Type>::hash (const value_type &candidate)
163{
164 /* This is a really poor hash function, but it is what the current code uses,
165 so I am reusing it to avoid an additional axis in testing. */
166 return (hashval_t) ((intptr_t)candidate >> 3);
167}
168
169template <typename Type>
170inline bool
171pointer_hash <Type>::equal (const value_type &existing,
172 const compare_type &candidate)
173{
174 return existing == candidate;
175}
176
843adf88
RS
177template <typename Type>
178inline void
179pointer_hash <Type>::mark_deleted (Type *&e)
180{
181 e = reinterpret_cast<Type *> (1);
182}
183
184template <typename Type>
185inline void
186pointer_hash <Type>::mark_empty (Type *&e)
187{
188 e = NULL;
189}
190
191template <typename Type>
192inline bool
193pointer_hash <Type>::is_deleted (Type *e)
194{
195 return e == reinterpret_cast<Type *> (1);
196}
197
198template <typename Type>
199inline bool
200pointer_hash <Type>::is_empty (Type *e)
201{
202 return e == NULL;
203}
204
20d2c372
RS
205/* Hasher for "const char *" strings, using string rather than pointer
206 equality. */
207
208struct string_hash : pointer_hash <const char>
209{
210 static inline hashval_t hash (const char *);
211 static inline bool equal (const char *, const char *);
212};
213
214inline hashval_t
215string_hash::hash (const char *id)
216{
217 return htab_hash_string (id);
218}
219
220inline bool
221string_hash::equal (const char *id1, const char *id2)
222{
223 return strcmp (id1, id2) == 0;
224}
225
ca752f39 226/* Remover and marker for entries in gc memory. */
f11c3779
RS
227
228template<typename T>
ca752f39 229struct ggc_remove
f11c3779 230{
5ac6389b 231 static void remove (T &) {}
f11c3779
RS
232
233 static void
5ac6389b 234 ggc_mx (T &p)
f11c3779
RS
235 {
236 extern void gt_ggc_mx (T &);
237 gt_ggc_mx (p);
238 }
239
21faa101
JM
240 /* Overridden in ggc_cache_remove. */
241 static void
242 ggc_maybe_mx (T &p)
243 {
244 ggc_mx (p);
245 }
246
f11c3779
RS
247 static void
248 pch_nx (T &p)
249 {
250 extern void gt_pch_nx (T &);
251 gt_pch_nx (p);
252 }
253
254 static void
255 pch_nx (T &p, gt_pointer_operator op, void *cookie)
256 {
257 op (&p, cookie);
258 }
259};
260
6c907cff
RS
261/* Remover and marker for "cache" entries in gc memory. These entries can
262 be deleted if there are no non-cache references to the data. */
f11c3779
RS
263
264template<typename T>
6c907cff 265struct ggc_cache_remove : ggc_remove<T>
f11c3779 266{
f11c3779 267 /* Entries are weakly held because this is for caches. */
21faa101 268 static void ggc_maybe_mx (T &) {}
f11c3779 269
08ec2754
RS
270 static int
271 keep_cache_entry (T &e)
f11c3779 272 {
08ec2754 273 return ggc_marked_p (e) ? -1 : 0;
f11c3779
RS
274 }
275};
276
8d67ee55
RS
277/* Traits for pointer elements that should not be freed when an element
278 is deleted. */
279
280template <typename T>
fc17926a 281struct nofree_ptr_hash : pointer_hash <T>, typed_noop_remove <T *> {};
8d67ee55 282
95fbe13e
RS
283/* Traits for pointer elements that should be freed via free() when an
284 element is deleted. */
285
286template <typename T>
287struct free_ptr_hash : pointer_hash <T>, typed_free_remove <T> {};
288
74fbae92
ML
289/* Traits for pointer elements that should be freed via delete operand when an
290 element is deleted. */
291
292template <typename T>
293struct delete_ptr_hash : pointer_hash <T>, typed_delete_remove <T> {};
294
ca752f39
RS
295/* Traits for elements that point to gc memory. The pointed-to data
296 must be kept across collections. */
297
298template <typename T>
299struct ggc_ptr_hash : pointer_hash <T>, ggc_remove <T *> {};
300
6c907cff
RS
301/* Traits for elements that point to gc memory. The elements don't
302 in themselves keep the pointed-to data alive and they can be deleted
303 if the pointed-to data is going to be collected. */
304
305template <typename T>
306struct ggc_cache_ptr_hash : pointer_hash <T>, ggc_cache_remove <T *> {};
307
20d2c372
RS
308/* Traits for string elements that should not be freed when an element
309 is deleted. */
310
311struct nofree_string_hash : string_hash, typed_noop_remove <const char *> {};
312
9adee305
RS
313/* Traits for pairs of values, using the first to record empty and
314 deleted slots. */
315
316template <typename T1, typename T2>
317struct pair_hash
318{
319 typedef std::pair <typename T1::value_type,
320 typename T2::value_type> value_type;
321 typedef std::pair <typename T1::compare_type,
322 typename T2::compare_type> compare_type;
323
324 static inline hashval_t hash (const value_type &);
325 static inline bool equal (const value_type &, const compare_type &);
326 static inline void remove (value_type &);
327 static inline void mark_deleted (value_type &);
7ca50de0 328 static const bool empty_zero_p = T1::empty_zero_p;
9adee305
RS
329 static inline void mark_empty (value_type &);
330 static inline bool is_deleted (const value_type &);
331 static inline bool is_empty (const value_type &);
332};
333
334template <typename T1, typename T2>
335inline hashval_t
336pair_hash <T1, T2>::hash (const value_type &x)
337{
338 return iterative_hash_hashval_t (T1::hash (x.first), T2::hash (x.second));
339}
340
341template <typename T1, typename T2>
342inline bool
343pair_hash <T1, T2>::equal (const value_type &x, const compare_type &y)
344{
345 return T1::equal (x.first, y.first) && T2::equal (x.second, y.second);
346}
347
348template <typename T1, typename T2>
349inline void
350pair_hash <T1, T2>::remove (value_type &x)
351{
352 T1::remove (x.first);
353 T2::remove (x.second);
354}
355
356template <typename T1, typename T2>
357inline void
358pair_hash <T1, T2>::mark_deleted (value_type &x)
359{
360 T1::mark_deleted (x.first);
361}
362
363template <typename T1, typename T2>
364inline void
365pair_hash <T1, T2>::mark_empty (value_type &x)
366{
367 T1::mark_empty (x.first);
368}
369
370template <typename T1, typename T2>
371inline bool
372pair_hash <T1, T2>::is_deleted (const value_type &x)
373{
374 return T1::is_deleted (x.first);
375}
376
377template <typename T1, typename T2>
378inline bool
379pair_hash <T1, T2>::is_empty (const value_type &x)
380{
381 return T1::is_empty (x.first);
382}
383
fb5c464a 384template <typename T> struct default_hash_traits : T {};
b32ca1df
RS
385
386template <typename T>
387struct default_hash_traits <T *> : ggc_ptr_hash <T> {};
388
f11c3779 389#endif