Browse Source

MT#55283 introduce typed GHashTable primitives

Simple wrappers around glib's GHashTable functions that add type
information, instead of just using void* for everything.

Change-Id: I3e7c0f095f1f58b943ba80d1e14e763707ee1698
pull/1776/head
Richard Fuchs 2 years ago
parent
commit
c11a05f62d
2 changed files with 134 additions and 0 deletions
  1. +2
    -0
      include/types.h
  2. +132
    -0
      lib/containers.h

+ 2
- 0
include/types.h View File

@ -3,4 +3,6 @@
typedef struct sdp_ng_flags sdp_ng_flags; typedef struct sdp_ng_flags sdp_ng_flags;
#include "containers.h"
#endif #endif

+ 132
- 0
lib/containers.h View File

@ -0,0 +1,132 @@
#ifndef __CONTAINERS_H__
#define __CONTAINERS_H__
#include <stdbool.h>
#include <glib.h>
#include <assert.h>
#define TYPED_GHASHTABLE_PROTO(type_name, key_type, value_type) \
typedef union { \
GHashTable *ht; \
/* unused members to store the contained types */ \
key_type *__key; \
const key_type *__ckey; \
value_type *__value; \
} type_name; \
typedef union { \
GHashTableIter it; \
/* unused members to store the contained types */ \
type_name __ht; \
} type_name##_iter; \
static inline type_name type_name##_null(void) { \
return (type_name) { NULL }; \
} \
static inline void type_name##_destroy_ptr(type_name *h) { \
if (h->ht) \
g_hash_table_destroy(h->ht); \
h->ht = NULL; \
}
#define t_hash_table_is_set(h) ({ \
bool __ret = (h).ht != NULL; \
__ret; \
})
#define t_hash_table_insert(h, k, v) ({ \
__typeof__((h).__key) __k = k; \
__typeof__((h).__value) __v = v; \
g_hash_table_insert((h).ht, __k, __v); \
})
#define t_hash_table_replace(h, k, v) ({ \
__typeof__((h).__key) __k = k; \
__typeof__((h).__value) __v = v; \
g_hash_table_replace((h).ht, __k, __v); \
})
#define t_hash_table_lookup(h, k) ({ \
__typeof__((h).__ckey) __k = k; \
__typeof__((h).__value) __r = g_hash_table_lookup((h).ht, __k); \
__r; \
})
#define t_hash_table_remove(h, k) ({ \
__typeof__((h).__key) __k = k; \
bool __r = g_hash_table_remove((h).ht, __k); \
__r; \
})
#define t_hash_table_steal_extended(h, k, kp, vp) ({ \
__typeof__((h).__key) __k = k; \
__typeof__(&(h).__key) __kp = kp; \
__typeof__(&(h).__value) __vp = vp; \
bool __r = g_hash_table_steal_extended((h).ht, __k, (void **) __kp, (void **) __vp); \
__r; \
})
#define t_hash_table_destroy(h) ({ \
g_hash_table_destroy((h).ht); \
})
#define t_hash_table_destroy_ptr(h) ({ \
if ((h)->ht) \
g_hash_table_destroy((h)->ht); \
(h)->ht = NULL; \
})
#define t_hash_table_size(h) ({ \
unsigned int __ret = g_hash_table_size((h).ht); \
__ret; \
})
#define t_hash_table_foreach_remove(h, f, p) ({ \
gboolean (*__f)(__typeof__((h).__key), __typeof__((h).__value), void *) = f; \
bool __ret = g_hash_table_foreach_remove((h).ht, (GHRFunc) __f, p); \
__ret; \
})
#define t_hash_table_iter_init(i, h) ({ \
__typeof__((i)->__ht) *__h = &(h); \
g_hash_table_iter_init(&(i)->it, __h->ht); \
})
#define t_hash_table_iter_next(i, kp, vp) ({ \
__typeof__(&((i)->__ht).__key) __kp = kp; \
__typeof__(&((i)->__ht).__value) __vp = vp; \
bool __ret = g_hash_table_iter_next(&(i)->it, (void **) __kp, (void **) __vp); \
__ret; \
})
#define TYPED_GHASHTABLE_IMPL(type_name, hash_func, eq_func, key_free_func, value_free_func) \
static inline type_name type_name##_new(void) { \
GHashTable *ht = g_hash_table_new_full(hash_func, eq_func, \
(GDestroyNotify) key_free_func, \
(GDestroyNotify) value_free_func); \
return (type_name) { ht }; \
} \
#define TYPED_GHASHTABLE(type_name, key_type, value_type, hash_func, eq_func, key_free_func, value_free_func) \
TYPED_GHASHTABLE_PROTO(type_name, key_type, value_type) \
TYPED_GHASHTABLE_IMPL(type_name, hash_func, eq_func, key_free_func, value_free_func) \
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(type_name, type_name##_destroy_ptr)
#define TYPED_GHASHTABLE_LOOKUP_INSERT(type_name, key_free_func, value_new_func) \
static inline __typeof__(((type_name *)0)->__value) type_name##_lookup_insert(type_name h, \
__typeof__(((type_name *)0)->__key) k) { \
__typeof__((h).__value) r = t_hash_table_lookup(h, k); \
if (r) { \
void (*free_func)(__typeof__((h).__key)) = key_free_func; \
if (free_func) \
free_func(k); \
return r; \
} \
r = value_new_func(); \
t_hash_table_insert(h, k, r); \
return r; \
}
#endif

Loading…
Cancel
Save