shared: add nm_g_slice_free_fcn() util

Useful, when you need a GDestroyNotify function for g_slice_free() of
a certain type.
This commit is contained in:
Thomas Haller 2017-08-15 12:32:37 +02:00
parent 3faff5b457
commit d100ce28e0
2 changed files with 68 additions and 0 deletions

View file

@ -78,6 +78,26 @@ G_STATIC_ASSERT (sizeof (bool) <= sizeof (int));
/*****************************************************************************/
static void
test_nm_g_slice_free_fcn (void)
{
gpointer p;
p = g_slice_new (gint64);
(nm_g_slice_free_fcn (gint64)) (p);
p = g_slice_new (gint32);
(nm_g_slice_free_fcn (gint32)) (p);
p = g_slice_new (gint);
(nm_g_slice_free_fcn (gint)) (p);
p = g_slice_new (gint64);
nm_g_slice_free_fcn_gint64 (p);
}
/*****************************************************************************/
typedef struct {
int val;
int idx;
@ -6177,6 +6197,7 @@ int main (int argc, char **argv)
{
nmtst_init (&argc, &argv, TRUE);
g_test_add_func ("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn);
g_test_add_func ("/core/general/test_c_list_sort", test_c_list_sort);
g_test_add_func ("/core/general/test_dedup_multi", test_dedup_multi);
g_test_add_func ("/core/general/test_utils_str_utf8safe", test_utils_str_utf8safe);

View file

@ -150,6 +150,53 @@ gint _nm_utils_ascii_str_to_bool (const char *str,
/*****************************************************************************/
#define _nm_g_slice_free_fcn_define(mem_size) \
static inline void \
_nm_g_slice_free_fcn_##mem_size (gpointer mem_block) \
{ \
g_slice_free1 (mem_size, mem_block); \
}
_nm_g_slice_free_fcn_define (1)
_nm_g_slice_free_fcn_define (2)
_nm_g_slice_free_fcn_define (4)
_nm_g_slice_free_fcn_define (8)
_nm_g_slice_free_fcn_define (16)
#define _nm_g_slice_free_fcn1(mem_size) \
({ \
void (*_fcn) (gpointer); \
\
/* If mem_size is a compile time constant, the compiler
* will be able to optimize this. Hence, you don't want
* to call this with a non-constant size argument. */ \
switch (mem_size) { \
case 1: _fcn = _nm_g_slice_free_fcn_1; break; \
case 2: _fcn = _nm_g_slice_free_fcn_2; break; \
case 4: _fcn = _nm_g_slice_free_fcn_4; break; \
case 8: _fcn = _nm_g_slice_free_fcn_8; break; \
case 16: _fcn = _nm_g_slice_free_fcn_16; break; \
default: g_assert_not_reached (); _fcn = NULL; break; \
} \
_fcn; \
})
/**
* nm_g_slice_free_fcn:
* @type: type argument for sizeof() operator that you would
* pass to g_slice_new().
*
* Returns: a function pointer with GDestroyNotify signature
* for g_slice_free(type,*).
*
* Only certain types are implemented. You'll get an assertion
* using the wrong type. */
#define nm_g_slice_free_fcn(type) (_nm_g_slice_free_fcn1 (sizeof (type)))
#define nm_g_slice_free_fcn_gint64 (nm_g_slice_free_fcn (gint64))
/*****************************************************************************/
/**
* NMUtilsError:
* @NM_UTILS_ERROR_UNKNOWN: unknown or unclassified error