glib-aux: add nm_hash_vals() and adjust implementation of nm_hash_update_val(),nm_hash_val()

nm_hash_update_vals() has variadic arguments and accepts (in principle) any
number of arguments. It works by copying the value to a packed struct on
the stack.

nm_hash_update_val() is essentially the same, but accepts only one
argument. Implement nm_hash_update_val() in terms of
nm_hash_update_vals().

Also, add nm_hash_vals(), and adjust nm_hash_val() to be implemented that way.

Maybe we should drop combine the val/vals variants into one, and not
have two variants. We only keep them because both are currently in use.
Also, we have nm_hash_update_valp(), which is useful but can only take one
argument. For naming consistency of nm_hash_update_val(), nm_hash_update_valp()
and nm_hash_update_vals() they are all kept.
This commit is contained in:
Thomas Haller 2022-09-23 12:44:27 +02:00
parent 5a87683b14
commit 43c3e2b683
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728

View file

@ -105,33 +105,6 @@ nm_hash_update(NMHashState *state, const void *ptr, gsize n)
c_siphash_append(&state->_state, ptr, n);
}
#define nm_hash_update_val(state, val) \
G_STMT_START \
{ \
typeof(val) _val = (val); \
\
nm_hash_update((state), &_val, sizeof(_val)); \
} \
G_STMT_END
#define nm_hash_update_valp(state, val) nm_hash_update((state), (val), sizeof(*(val)))
static inline void
nm_hash_update_bool(NMHashState *state, bool val)
{
nm_hash_update(state, &val, sizeof(val));
}
#define _NM_HASH_COMBINE_BOOLS_OP(x, n, op_arg) ((x) ? NM_BIT((n)) : 0ull)
#define NM_HASH_COMBINE_BOOLS(type, ...) \
((type) (NM_STATIC_ASSERT_EXPR_1(NM_NARG(__VA_ARGS__) <= 8 * sizeof(type)) \
? (NM_VA_ARGS_FOREACH(, , |, _NM_HASH_COMBINE_BOOLS_OP, , __VA_ARGS__)) \
: 0ull))
#define nm_hash_update_bools(state, ...) \
nm_hash_update_val(state, NM_HASH_COMBINE_BOOLS(guint8, __VA_ARGS__))
#define _NM_HASH_COMBINE_VALS_TYPE_OP(x, idx, op_arg) typeof(x) _v##idx;
#define _NM_HASH_COMBINE_VALS_INIT_OP(x, idx, op_arg) ._v##idx = (x),
@ -154,6 +127,26 @@ nm_hash_update_bool(NMHashState *state, bool val)
} \
G_STMT_END
#define nm_hash_update_val(state, val) nm_hash_update_vals((state), (val))
#define nm_hash_update_valp(state, val) nm_hash_update((state), (val), sizeof(*(val)))
static inline void
nm_hash_update_bool(NMHashState *state, bool val)
{
nm_hash_update(state, &val, sizeof(val));
}
#define _NM_HASH_COMBINE_BOOLS_OP(x, n, op_arg) ((x) ? NM_BIT((n)) : 0ull)
#define NM_HASH_COMBINE_BOOLS(type, ...) \
((type) (NM_STATIC_ASSERT_EXPR_1(NM_NARG(__VA_ARGS__) <= 8 * sizeof(type)) \
? (NM_VA_ARGS_FOREACH(, , |, _NM_HASH_COMBINE_BOOLS_OP, , __VA_ARGS__)) \
: 0ull))
#define nm_hash_update_bools(state, ...) \
nm_hash_update_val(state, NM_HASH_COMBINE_BOOLS(guint8, __VA_ARGS__))
static inline void
nm_hash_update_mem(NMHashState *state, const void *ptr, gsize n)
{
@ -206,15 +199,17 @@ guint nm_hash_ptr(gconstpointer ptr);
guint nm_hash_str(const char *str);
#define nm_str_hash ((guint(*)(gconstpointer str)) nm_hash_str)
#define nm_hash_val(static_seed, val) \
({ \
NMHashState _h; \
\
nm_hash_init(&_h, (static_seed)); \
nm_hash_update_val(&_h, (val)); \
nm_hash_complete(&_h); \
#define nm_hash_vals(static_seed, ...) \
({ \
NMHashState _h; \
\
nm_hash_init(&_h, (static_seed)); \
nm_hash_update_vals(&_h, __VA_ARGS__); \
nm_hash_complete(&_h); \
})
#define nm_hash_val(static_seed, val) nm_hash_vals((static_seed), (val))
static inline guint
nm_hash_mem(guint static_seed, const void *ptr, gsize n)
{