2 * Copyright (C) 2001-2010, Parrot Foundation.
6 * Hashtable implementation
9 #ifndef PARROT_HASH_H_GUARD
10 #define PARROT_HASH_H_GUARD
14 enum_hash_int
= enum_type_INTVAL
,
15 enum_hash_num
= enum_type_FLOATVAL
,
16 enum_hash_string
= enum_type_STRING
,
17 enum_hash_pmc
= enum_type_PMC
,
18 enum_hash_ptr
= enum_type_ptr
22 /* A BucketIndex is an index into the pool of available buckets. */
23 typedef UINTVAL BucketIndex
;
24 #define INITBucketIndex ((BucketIndex)-2)
26 #define N_BUCKETS(n) ((n))
27 #define HASH_ALLOC_SIZE(n) (N_BUCKETS(n) * sizeof (HashBucket) + \
28 (n) * sizeof (HashBucket *))
30 typedef int (*hash_comp_fn
)(PARROT_INTERP
, ARGIN(const void *), ARGIN(const void *));
31 typedef size_t (*hash_hash_key_fn
)(PARROT_INTERP
, ARGIN(const void *), size_t seed
);
33 /* &gen_from_enum(hash_key_type.pasm) */
36 Hash_key_type_cstring
,
43 typedef struct _hashbucket
{
44 struct _hashbucket
*next
;
50 /* Large slab store of buckets */
53 /* List of Bucket pointers */
56 /* Store for empty buckets */
57 HashBucket
*free_list
;
59 /* Number of values stored in hashtable */
65 /* The type of key object this hash uses */
66 Hash_key_type key_type
;
69 PARROT_DATA_TYPE entry_type
;
71 /* Random seed value for seeding hash algorithms */
74 /* Comparison function pointer. Returns 0 if elements are equal */
77 /* Function pointer to generate a hash value for the object */
78 hash_hash_key_fn hash_val
;
81 /* Utility macros - use them, do not reinvent the wheel */
82 #define parrot_hash_iterate parrot_hash_iterate_linear
84 #define parrot_hash_iterate_linear(_hash, _code) \
86 HashBucket *_bucket = (_hash)->buckets; \
88 while (_found < (_hash)->entries){ \
99 #define parrot_hash_iterate_indexed(_hash, _code) \
102 for (_loc = (_hash)->mask; _loc >= 0; --_loc) { \
103 HashBucket *_bucket = (_hash)->index[_loc]; \
106 _bucket = _bucket->next; \
112 #define parrot_hash_iterator_advance(_hash, _bucket, _loc) \
114 /* Try to advance current bucket */ \
116 (_bucket) = (_bucket)->next; \
117 while (!(_bucket)) { \
118 /* If there is no more buckets */ \
119 if ((_loc) == (INTVAL)(_hash)->mask+1) \
121 (_bucket) = (_hash)->index[(_loc)++]; \
126 typedef void (*value_free
)(ARGFREE(void *));
128 /* To avoid creating OrderedHashItem PMC we reuse FixedPMCArray PMC */
129 /* So, there is indexes to avoid using of "magick constants" */
130 enum ORDERED_HASH_ITEM_PART
{
131 ORDERED_HASH_ITEM_KEY
= 0,
132 ORDERED_HASH_ITEM_VALUE
= 1,
133 ORDERED_HASH_ITEM_PREV
= 2,
134 ORDERED_HASH_ITEM_NEXT
= 3,
135 ORDERED_HASH_ITEM_MAX
= 4
138 /* HEADERIZER BEGIN: src/hash.c */
139 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
142 void parrot_dump_hash(SHIM_INTERP
, SHIM(const Hash
*hash
));
145 void parrot_hash_clone(PARROT_INTERP
,
146 ARGIN(const Hash
*hash
),
148 __attribute__nonnull__(1)
149 __attribute__nonnull__(2)
150 __attribute__nonnull__(3)
151 FUNC_MODIFIES(*dest
);
154 void parrot_hash_delete(PARROT_INTERP
, ARGMOD(Hash
*hash
), ARGIN(void *key
))
155 __attribute__nonnull__(1)
156 __attribute__nonnull__(2)
157 __attribute__nonnull__(3)
158 FUNC_MODIFIES(*hash
);
161 void parrot_hash_destroy(PARROT_INTERP
, ARGFREE_NOTNULL(Hash
*hash
))
162 __attribute__nonnull__(1)
163 __attribute__nonnull__(2);
166 PARROT_WARN_UNUSED_RESULT
167 INTVAL
parrot_hash_exists(PARROT_INTERP
,
168 ARGIN(const Hash
*hash
),
170 __attribute__nonnull__(1)
171 __attribute__nonnull__(2)
172 __attribute__nonnull__(3);
175 PARROT_WARN_UNUSED_RESULT
176 PARROT_CAN_RETURN_NULL
177 void * parrot_hash_get(PARROT_INTERP
,
178 ARGIN(const Hash
*hash
),
179 ARGIN(const void *key
))
180 __attribute__nonnull__(1)
181 __attribute__nonnull__(2)
182 __attribute__nonnull__(3);
185 PARROT_WARN_UNUSED_RESULT
186 PARROT_CAN_RETURN_NULL
187 HashBucket
* parrot_hash_get_bucket(PARROT_INTERP
,
188 ARGIN(const Hash
*hash
),
189 ARGIN_NULLOK(const void *key
))
190 __attribute__nonnull__(1)
191 __attribute__nonnull__(2);
194 PARROT_WARN_UNUSED_RESULT
195 PARROT_CAN_RETURN_NULL
196 void * parrot_hash_get_idx(PARROT_INTERP
,
197 ARGIN(const Hash
*hash
),
199 __attribute__nonnull__(1)
200 __attribute__nonnull__(2)
201 __attribute__nonnull__(3)
205 PARROT_IGNORABLE_RESULT
206 PARROT_CANNOT_RETURN_NULL
207 HashBucket
* parrot_hash_put(PARROT_INTERP
,
209 ARGIN_NULLOK(void *key
),
210 ARGIN_NULLOK(void *value
))
211 __attribute__nonnull__(1)
212 __attribute__nonnull__(2)
213 FUNC_MODIFIES(*hash
);
216 PARROT_WARN_UNUSED_RESULT
218 INTVAL
parrot_hash_size(SHIM_INTERP
, ARGIN(const Hash
*hash
))
219 __attribute__nonnull__(2);
222 void parrot_hash_visit(PARROT_INTERP
,
225 __attribute__nonnull__(1)
226 __attribute__nonnull__(2)
227 __attribute__nonnull__(3)
229 FUNC_MODIFIES(*pinfo
);
232 void parrot_mark_hash(PARROT_INTERP
, ARGMOD(Hash
*hash
))
233 __attribute__nonnull__(1)
234 __attribute__nonnull__(2)
235 FUNC_MODIFIES(*hash
);
238 PARROT_CANNOT_RETURN_NULL
239 Hash
* parrot_new_cstring_hash(PARROT_INTERP
)
240 __attribute__nonnull__(1);
243 PARROT_CANNOT_RETURN_NULL
244 Hash
* parrot_new_hash(PARROT_INTERP
)
245 __attribute__nonnull__(1);
248 PARROT_WARN_UNUSED_RESULT
249 PARROT_CANNOT_RETURN_NULL
250 Hash
* parrot_new_intval_hash(PARROT_INTERP
)
251 __attribute__nonnull__(1);
254 PARROT_CANNOT_RETURN_NULL
255 Hash
* parrot_new_pointer_hash(PARROT_INTERP
)
256 __attribute__nonnull__(1);
258 PARROT_CANNOT_RETURN_NULL
259 PMC
* get_integer_pmc(PARROT_INTERP
, INTVAL value
)
260 __attribute__nonnull__(1);
262 PARROT_CANNOT_RETURN_NULL
263 PMC
* get_number_pmc(PARROT_INTERP
, FLOATVAL value
)
264 __attribute__nonnull__(1);
266 PARROT_CANNOT_RETURN_NULL
267 PMC
* get_string_pmc(PARROT_INTERP
, ARGIN(STRING
*value
))
268 __attribute__nonnull__(1)
269 __attribute__nonnull__(2);
271 PARROT_CAN_RETURN_NULL
272 void* hash_key_from_int(PARROT_INTERP
, ARGIN(const Hash
*hash
), INTVAL key
)
273 __attribute__nonnull__(1)
274 __attribute__nonnull__(2);
276 PARROT_CAN_RETURN_NULL
277 void* hash_key_from_pmc(PARROT_INTERP
,
278 ARGIN(const Hash
*hash
),
280 __attribute__nonnull__(1)
281 __attribute__nonnull__(2)
282 __attribute__nonnull__(3);
284 PARROT_CAN_RETURN_NULL
285 void* hash_key_from_string(PARROT_INTERP
,
286 ARGIN(const Hash
*hash
),
288 __attribute__nonnull__(1)
289 __attribute__nonnull__(2)
290 __attribute__nonnull__(3);
292 INTVAL
hash_key_to_int(PARROT_INTERP
,
293 ARGIN(const Hash
*hash
),
294 ARGIN_NULLOK(void *key
))
295 __attribute__nonnull__(1)
296 __attribute__nonnull__(2);
298 PARROT_CANNOT_RETURN_NULL
299 PMC
* hash_key_to_pmc(PARROT_INTERP
,
300 ARGIN(const Hash
* const hash
),
302 __attribute__nonnull__(1)
303 __attribute__nonnull__(2)
304 __attribute__nonnull__(3);
306 PARROT_CANNOT_RETURN_NULL
307 STRING
* hash_key_to_string(PARROT_INTERP
,
308 ARGIN(const Hash
*hash
),
309 ARGIN_NULLOK(void *key
))
310 __attribute__nonnull__(1)
311 __attribute__nonnull__(2);
313 PARROT_CAN_RETURN_NULL
314 void* hash_value_from_int(PARROT_INTERP
,
315 ARGIN(const Hash
*hash
),
317 __attribute__nonnull__(1)
318 __attribute__nonnull__(2);
320 PARROT_CAN_RETURN_NULL
321 void* hash_value_from_number(PARROT_INTERP
,
322 ARGIN(const Hash
*hash
),
324 __attribute__nonnull__(1)
325 __attribute__nonnull__(2);
327 PARROT_CAN_RETURN_NULL
328 void* hash_value_from_pmc(PARROT_INTERP
,
329 ARGIN(const Hash
*hash
),
330 ARGIN_NULLOK(PMC
*value
))
331 __attribute__nonnull__(1)
332 __attribute__nonnull__(2);
334 PARROT_CAN_RETURN_NULL
335 void* hash_value_from_string(PARROT_INTERP
,
336 ARGIN(const Hash
*hash
),
337 ARGIN_NULLOK(STRING
*value
))
338 __attribute__nonnull__(1)
339 __attribute__nonnull__(2);
341 INTVAL
hash_value_to_int(PARROT_INTERP
,
342 ARGIN(const Hash
*hash
),
343 ARGIN_NULLOK(void *value
))
344 __attribute__nonnull__(1)
345 __attribute__nonnull__(2);
347 FLOATVAL
hash_value_to_number(PARROT_INTERP
,
348 ARGIN(const Hash
*hash
),
349 ARGIN_NULLOK(void *value
))
350 __attribute__nonnull__(1)
351 __attribute__nonnull__(2);
353 PARROT_CANNOT_RETURN_NULL
354 PMC
* hash_value_to_pmc(PARROT_INTERP
,
355 ARGIN(const Hash
*hash
),
356 ARGIN_NULLOK(void *value
))
357 __attribute__nonnull__(1)
358 __attribute__nonnull__(2);
360 PARROT_CANNOT_RETURN_NULL
361 STRING
* hash_value_to_string(PARROT_INTERP
,
362 ARGIN(const Hash
*hash
),
363 ARGIN_NULLOK(void *value
))
364 __attribute__nonnull__(1)
365 __attribute__nonnull__(2);
367 PARROT_WARN_UNUSED_RESULT
368 PARROT_CONST_FUNCTION
369 int int_compare(SHIM_INTERP
,
370 ARGIN_NULLOK(const void *a
),
371 ARGIN_NULLOK(const void *b
));
373 PARROT_WARN_UNUSED_RESULT
374 PARROT_CONST_FUNCTION
375 size_t key_hash_int(SHIM_INTERP
,
376 ARGIN_NULLOK(const void *value
),
379 PARROT_WARN_UNUSED_RESULT
381 size_t key_hash_PMC(PARROT_INTERP
, ARGIN(PMC
*value
), NULLOK(size_t seed
))
382 __attribute__nonnull__(1)
383 __attribute__nonnull__(2);
385 PARROT_WARN_UNUSED_RESULT
386 size_t key_hash_STRING(PARROT_INTERP
,
389 __attribute__nonnull__(1)
390 __attribute__nonnull__(2)
393 void parrot_chash_destroy(PARROT_INTERP
, ARGMOD(Hash
*hash
))
394 __attribute__nonnull__(1)
395 __attribute__nonnull__(2)
396 FUNC_MODIFIES(*hash
);
398 void parrot_chash_destroy_values(PARROT_INTERP
,
400 NOTNULL(value_free func
))
401 __attribute__nonnull__(1)
402 __attribute__nonnull__(2)
403 __attribute__nonnull__(3)
404 FUNC_MODIFIES(*hash
);
406 PARROT_CANNOT_RETURN_NULL
407 PARROT_WARN_UNUSED_RESULT
409 Hash
* parrot_create_hash(PARROT_INTERP
,
410 PARROT_DATA_TYPE val_type
,
411 Hash_key_type hkey_type
,
412 NOTNULL(hash_comp_fn compare
),
413 NOTNULL(hash_hash_key_fn keyhash
))
414 __attribute__nonnull__(1)
415 __attribute__nonnull__(4)
416 __attribute__nonnull__(5);
418 void parrot_hash_clone_prunable(PARROT_INTERP
,
419 ARGIN(const Hash
*hash
),
422 __attribute__nonnull__(1)
423 __attribute__nonnull__(2)
424 __attribute__nonnull__(3)
425 FUNC_MODIFIES(*dest
);
427 PARROT_WARN_UNUSED_RESULT
429 int PMC_compare(PARROT_INTERP
, ARGIN(PMC
*a
), ARGIN(PMC
*b
))
430 __attribute__nonnull__(1)
431 __attribute__nonnull__(2)
432 __attribute__nonnull__(3);
434 PARROT_WARN_UNUSED_RESULT
435 int STRING_compare(PARROT_INTERP
,
436 ARGIN(const void *search_key
),
437 ARGIN_NULLOK(const void *bucket_key
))
438 __attribute__nonnull__(1)
439 __attribute__nonnull__(2);
441 PARROT_WARN_UNUSED_RESULT
442 int STRING_compare_distinct_cs_enc(PARROT_INTERP
,
443 ARGIN(const void *search_key
),
444 ARGIN(const void *bucket_key
))
445 __attribute__nonnull__(1)
446 __attribute__nonnull__(2)
447 __attribute__nonnull__(3);
449 #define ASSERT_ARGS_parrot_dump_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
450 #define ASSERT_ARGS_parrot_hash_clone __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
451 PARROT_ASSERT_ARG(interp) \
452 , PARROT_ASSERT_ARG(hash) \
453 , PARROT_ASSERT_ARG(dest))
454 #define ASSERT_ARGS_parrot_hash_delete __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
455 PARROT_ASSERT_ARG(interp) \
456 , PARROT_ASSERT_ARG(hash) \
457 , PARROT_ASSERT_ARG(key))
458 #define ASSERT_ARGS_parrot_hash_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
459 PARROT_ASSERT_ARG(interp) \
460 , PARROT_ASSERT_ARG(hash))
461 #define ASSERT_ARGS_parrot_hash_exists __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
462 PARROT_ASSERT_ARG(interp) \
463 , PARROT_ASSERT_ARG(hash) \
464 , PARROT_ASSERT_ARG(key))
465 #define ASSERT_ARGS_parrot_hash_get __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
466 PARROT_ASSERT_ARG(interp) \
467 , PARROT_ASSERT_ARG(hash) \
468 , PARROT_ASSERT_ARG(key))
469 #define ASSERT_ARGS_parrot_hash_get_bucket __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
470 PARROT_ASSERT_ARG(interp) \
471 , PARROT_ASSERT_ARG(hash))
472 #define ASSERT_ARGS_parrot_hash_get_idx __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
473 PARROT_ASSERT_ARG(interp) \
474 , PARROT_ASSERT_ARG(hash) \
475 , PARROT_ASSERT_ARG(key))
476 #define ASSERT_ARGS_parrot_hash_put __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
477 PARROT_ASSERT_ARG(interp) \
478 , PARROT_ASSERT_ARG(hash))
479 #define ASSERT_ARGS_parrot_hash_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
480 PARROT_ASSERT_ARG(hash))
481 #define ASSERT_ARGS_parrot_hash_visit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
482 PARROT_ASSERT_ARG(interp) \
483 , PARROT_ASSERT_ARG(hash) \
484 , PARROT_ASSERT_ARG(pinfo))
485 #define ASSERT_ARGS_parrot_mark_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
486 PARROT_ASSERT_ARG(interp) \
487 , PARROT_ASSERT_ARG(hash))
488 #define ASSERT_ARGS_parrot_new_cstring_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
489 PARROT_ASSERT_ARG(interp))
490 #define ASSERT_ARGS_parrot_new_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
491 PARROT_ASSERT_ARG(interp))
492 #define ASSERT_ARGS_parrot_new_intval_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
493 PARROT_ASSERT_ARG(interp))
494 #define ASSERT_ARGS_parrot_new_pointer_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
495 PARROT_ASSERT_ARG(interp))
496 #define ASSERT_ARGS_get_integer_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
497 PARROT_ASSERT_ARG(interp))
498 #define ASSERT_ARGS_get_number_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
499 PARROT_ASSERT_ARG(interp))
500 #define ASSERT_ARGS_get_string_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
501 PARROT_ASSERT_ARG(interp) \
502 , PARROT_ASSERT_ARG(value))
503 #define ASSERT_ARGS_hash_key_from_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
504 PARROT_ASSERT_ARG(interp) \
505 , PARROT_ASSERT_ARG(hash))
506 #define ASSERT_ARGS_hash_key_from_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
507 PARROT_ASSERT_ARG(interp) \
508 , PARROT_ASSERT_ARG(hash) \
509 , PARROT_ASSERT_ARG(key))
510 #define ASSERT_ARGS_hash_key_from_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
511 PARROT_ASSERT_ARG(interp) \
512 , PARROT_ASSERT_ARG(hash) \
513 , PARROT_ASSERT_ARG(key))
514 #define ASSERT_ARGS_hash_key_to_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
515 PARROT_ASSERT_ARG(interp) \
516 , PARROT_ASSERT_ARG(hash))
517 #define ASSERT_ARGS_hash_key_to_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
518 PARROT_ASSERT_ARG(interp) \
519 , PARROT_ASSERT_ARG(hash) \
520 , PARROT_ASSERT_ARG(key))
521 #define ASSERT_ARGS_hash_key_to_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
522 PARROT_ASSERT_ARG(interp) \
523 , PARROT_ASSERT_ARG(hash))
524 #define ASSERT_ARGS_hash_value_from_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
525 PARROT_ASSERT_ARG(interp) \
526 , PARROT_ASSERT_ARG(hash))
527 #define ASSERT_ARGS_hash_value_from_number __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
528 PARROT_ASSERT_ARG(interp) \
529 , PARROT_ASSERT_ARG(hash))
530 #define ASSERT_ARGS_hash_value_from_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
531 PARROT_ASSERT_ARG(interp) \
532 , PARROT_ASSERT_ARG(hash))
533 #define ASSERT_ARGS_hash_value_from_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
534 PARROT_ASSERT_ARG(interp) \
535 , PARROT_ASSERT_ARG(hash))
536 #define ASSERT_ARGS_hash_value_to_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
537 PARROT_ASSERT_ARG(interp) \
538 , PARROT_ASSERT_ARG(hash))
539 #define ASSERT_ARGS_hash_value_to_number __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
540 PARROT_ASSERT_ARG(interp) \
541 , PARROT_ASSERT_ARG(hash))
542 #define ASSERT_ARGS_hash_value_to_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
543 PARROT_ASSERT_ARG(interp) \
544 , PARROT_ASSERT_ARG(hash))
545 #define ASSERT_ARGS_hash_value_to_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
546 PARROT_ASSERT_ARG(interp) \
547 , PARROT_ASSERT_ARG(hash))
548 #define ASSERT_ARGS_int_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
549 #define ASSERT_ARGS_key_hash_int __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
550 #define ASSERT_ARGS_key_hash_PMC __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
551 PARROT_ASSERT_ARG(interp) \
552 , PARROT_ASSERT_ARG(value))
553 #define ASSERT_ARGS_key_hash_STRING __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
554 PARROT_ASSERT_ARG(interp) \
555 , PARROT_ASSERT_ARG(s))
556 #define ASSERT_ARGS_parrot_chash_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
557 PARROT_ASSERT_ARG(interp) \
558 , PARROT_ASSERT_ARG(hash))
559 #define ASSERT_ARGS_parrot_chash_destroy_values __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
560 PARROT_ASSERT_ARG(interp) \
561 , PARROT_ASSERT_ARG(hash) \
562 , PARROT_ASSERT_ARG(func))
563 #define ASSERT_ARGS_parrot_create_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
564 PARROT_ASSERT_ARG(interp) \
565 , PARROT_ASSERT_ARG(compare) \
566 , PARROT_ASSERT_ARG(keyhash))
567 #define ASSERT_ARGS_parrot_hash_clone_prunable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
568 PARROT_ASSERT_ARG(interp) \
569 , PARROT_ASSERT_ARG(hash) \
570 , PARROT_ASSERT_ARG(dest))
571 #define ASSERT_ARGS_PMC_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
572 PARROT_ASSERT_ARG(interp) \
573 , PARROT_ASSERT_ARG(a) \
574 , PARROT_ASSERT_ARG(b))
575 #define ASSERT_ARGS_STRING_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
576 PARROT_ASSERT_ARG(interp) \
577 , PARROT_ASSERT_ARG(search_key))
578 #define ASSERT_ARGS_STRING_compare_distinct_cs_enc \
579 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
580 PARROT_ASSERT_ARG(interp) \
581 , PARROT_ASSERT_ARG(search_key) \
582 , PARROT_ASSERT_ARG(bucket_key))
583 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
584 /* HEADERIZER END: src/hash.c */
586 #endif /* PARROT_HASH_H_GUARD */
590 * c-file-style: "parrot"
592 * vim: expandtab shiftwidth=4: