util: introduce typesafe_bsearch() and typesafe_bsearch_r()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 18 Sep 2018 02:05:20 +0000 (11:05 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 18 Sep 2018 23:06:57 +0000 (08:06 +0900)
src/basic/util.c
src/basic/util.h

index f951d64..081c63c 100644 (file)
@@ -133,7 +133,7 @@ void in_initrd_force(bool value) {
 
 /* hey glibc, APIs with callbacks without a user pointer are so useless */
 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
-                 int (*compar) (const void *, const void *, void *), void *arg) {
+                 __compar_d_fn_t compar, void *arg) {
         size_t l, u, idx;
         const void *p;
         int comparison;
index a6e7798..5f3f982 100644 (file)
@@ -68,15 +68,21 @@ bool in_initrd(void);
 void in_initrd_force(bool value);
 
 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
-                 int (*compar) (const void *, const void *, void *),
-                 void *arg);
+                 __compar_d_fn_t compar, void *arg);
+
+#define typesafe_bsearch_r(k, b, n, func, userdata)                     \
+        ({                                                              \
+                const typeof(b[0]) *_k = k;                             \
+                int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \
+                xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_d_fn_t) _func_, userdata); \
+        })
 
 /**
  * Normal bsearch requires base to be nonnull. Here were require
  * that only if nmemb > 0.
  */
 static inline void* bsearch_safe(const void *key, const void *base,
-                                 size_t nmemb, size_t size, comparison_fn_t compar) {
+                                 size_t nmemb, size_t size, __compar_fn_t compar) {
         if (nmemb <= 0)
                 return NULL;
 
@@ -84,6 +90,13 @@ static inline void* bsearch_safe(const void *key, const void *base,
         return bsearch(key, base, nmemb, size, compar);
 }
 
+#define typesafe_bsearch(k, b, n, func)                                 \
+        ({                                                              \
+                const typeof(b[0]) *_k = k;                             \
+                int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \
+                bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_fn_t) _func_); \
+        })
+
 /**
  * Normal qsort requires base to be nonnull. Here were require
  * that only if nmemb > 0.