27#define SHT_MAX_ESIZE 16384
34#define SHT_FNATTR(...) __attribute__((__VA_ARGS__))
36#define SHT_FNATTR(...)
61extern void (*sht_abort_print)(
const char *msg);
111 void *restrict context);
145 const void *restrict entry,
146 void *restrict context);
170 void *restrict context);
214_Static_assert(
sizeof(
enum sht_err) == 1,
"sht_err size");
232SHT_FNATTR(nonnull(1, 2))
234 size_t ealign, enum
sht_err *err);
237SHT_FNATTR(nonnull(1))
241SHT_FNATTR(nonnull(1))
245SHT_FNATTR(nonnull(1))
258_Bool
sht_init(struct sht_ht *ht, uint32_t capacity);
271int sht_add(struct sht_ht *ht, const
void *key, const
void *entry);
275int sht_set(struct sht_ht *ht, const
void *key, const
void *entry);
279const
void *
sht_get(struct sht_ht *ht, const
void *restrict key);
283uint32_t
sht_size(const struct sht_ht *ht);
291_Bool
sht_delete(struct sht_ht *ht, const
void *restrict key);
295_Bool
sht_pop(struct sht_ht *ht, const
void *restrict key,
void *restrict out);
299_Bool
sht_replace(struct sht_ht *ht, const
void *key,
304_Bool
sht_swap(struct sht_ht *ht, const
void *key,
305 const
void *entry,
void *out);
314struct sht_ro_iter *sht_ro_iter(struct sht_ht *ht);
318struct sht_rw_iter *sht_rw_iter(struct sht_ht *ht);
348 const
void *restrict entry);
353 const
void *restrict entry);
412#define SHT_ARG2(_, a2, ...) (a2)
455#define SHT_NEW(hashfn, eqfn, etype, ...) \
457 _Static_assert(sizeof(etype) <= SHT_MAX_ESIZE, \
458 "Entry type (" #etype ") too large"); \
459 sht_new_(hashfn, eqfn, sizeof(etype), _Alignof(etype), \
460 SHT_ARG2(_, ##__VA_ARGS__, NULL)); \
483#define SHT_ITER_GENERIC(op, iter, ...) \
485 struct sht_ro_iter *: sht_ro_iter_##op##_, \
486 struct sht_rw_iter *: sht_rw_iter_##op##_ \
487 )(iter, ##__VA_ARGS__)
497#define SHT_ITER_FREE(iter) SHT_ITER_GENERIC(free, iter)
510#define SHT_ITER_NEXT(iter) SHT_ITER_GENERIC(next, iter)
531#define SHT_ITER_REPLACE(iter, entry) SHT_ITER_GENERIC(replace, iter, entry)
546#define SHT_ITER_ERR(iter) SHT_ITER_GENERIC(err, iter)
561#define SHT_ITER_MSG(iter) SHT_ITER_GENERIC(msg, iter)
void * sht_rw_iter_next_(struct sht_rw_iter *iter)
(Get the next entry from a read/write iterator.)
const void * sht_get(struct sht_ht *ht, const void *restrict key)
Lookup an entry in a table.
_Bool sht_empty(const struct sht_ht *ht)
Determine whether a table is empty.
void sht_rw_iter_free_(struct sht_rw_iter *iter)
(Free a read/write iterator.)
int sht_set(struct sht_ht *ht, const void *key, const void *entry)
Unconditionally set the value associated with a key.
void sht_set_hash_ctx(struct sht_ht *ht, void *context)
Set the "context" for a table's hash function.
int sht_add(struct sht_ht *ht, const void *key, const void *entry)
Add an entry to the table, if its key is not already present.
const void * sht_ro_iter_next_(struct sht_ro_iter *iter)
(Get the next entry from a read-only iterator.)
const char * sht_rw_iter_msg_(const struct sht_rw_iter *iter)
(Get a description of a read/write iterator's last error.)
_Bool sht_ro_iter_replace_(struct sht_ro_iter *iter, const void *restrict entry)
(Replace the last entry returned by a read-only iterator.)
_Bool sht_delete(struct sht_ht *ht, const void *restrict key)
Remove an entry from the table.
_Bool sht_replace(struct sht_ht *ht, const void *key, const void *entry)
Replace the entry associated with an existing key.
_Bool sht_pop(struct sht_ht *ht, const void *restrict key, void *restrict out)
Remove and return an entry from the table.
uint32_t sht_size(const struct sht_ht *ht)
Get the number of entries in a table.
enum sht_err sht_get_err(const struct sht_ht *ht)
Get the error code of a table's last error.
enum sht_err sht_ro_iter_err_(const struct sht_ro_iter *iter)
(Get the error code of a read-only iterator's last error.)
_Bool sht_iter_delete(struct sht_rw_iter *iter)
Remove the last entry returned by a read/write iterator.
enum sht_err sht_rw_iter_err_(const struct sht_rw_iter *iter)
(Get the error code of a read/write iterator's last error.)
void sht_set_lft(struct sht_ht *ht, uint8_t lft)
Set the load factor threshold for a table.
void sht_set_eq_ctx(struct sht_ht *ht, void *context)
Set the "context" for a table's equality function.
void sht_set_psl_limit(struct sht_ht *ht, uint8_t limit)
Set the PSL limit of a table.
const char * sht_msg(enum sht_err err)
Get the description for an error code.
struct sht_ht * sht_new_(sht_hashfn_t hashfn, sht_eqfn_t eqfn, size_t esize, size_t ealign, enum sht_err *err)
(Create a new hash table.)
void sht_ro_iter_free_(struct sht_ro_iter *iter)
(Free a read-only iterator.)
const char * sht_get_msg(const struct sht_ht *ht)
Get a description of a table's last error.
_Bool sht_init(struct sht_ht *ht, uint32_t capacity)
Initialize a hash table.
void sht_set_freefn(struct sht_ht *ht, sht_freefn_t freefn, void *context)
Set the optional entry resource free function for a table.
_Bool sht_rw_iter_replace_(struct sht_rw_iter *iter, const void *restrict entry)
(Replace the last entry returned by a read/write iterator.)
void sht_free(struct sht_ht *ht)
Free the resources used by a hash table.
_Bool sht_swap(struct sht_ht *ht, const void *key, const void *entry, void *out)
Exchange an existing entry and a new entry.
const char * sht_ro_iter_msg_(const struct sht_ro_iter *iter)
(Get a description of a read-only iterator's last error.)
@ SHT_ERR_TOOBIG
Requested table size too large.
@ SHT_ERR_ITER_COUNT
Table has too many iterators.
@ SHT_ERR_BAD_ESIZE
Entry size too large (> 16KiB).
@ SHT_ERR_ALLOC
Memory allocation failed.
@ SHT_ERR_BAD_HASH
Too many hash collisions.
@ SHT_ERR_ITER_NO_LAST
Iterator at beginning or end.
@ SHT_ERR_COUNT
(Not an error; used for bounds checks.)
@ SHT_ERR_ITER_LOCK
Can't acquire iterator lock.
void(* sht_freefn_t)(const void *restrict entry, void *restrict context)
Free function type.
_Bool(* sht_eqfn_t)(const void *restrict key, const void *restrict entry, void *restrict context)
Equality comparison function type.
uint32_t(* sht_hashfn_t)(const void *restrict key, void *restrict context)
Hash function type.