[vlc-commits] Make C popcount() handle all integer types

Rémi Denis-Courmont git at videolan.org
Sun Feb 11 12:49:25 CET 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Feb 11 13:05:39 2018 +0200| [0979f5a581b11614ea22bccea63dc12da47bbbe6] | committer: Rémi Denis-Courmont

Make C popcount() handle all integer types

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0979f5a581b11614ea22bccea63dc12da47bbbe6
---

 include/vlc_common.h | 93 +++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 63 insertions(+), 30 deletions(-)

diff --git a/include/vlc_common.h b/include/vlc_common.h
index d2648d2667..c7d143bf2d 100644
--- a/include/vlc_common.h
+++ b/include/vlc_common.h
@@ -469,6 +469,20 @@ static inline uint8_t clip_uint8_vlc( int32_t a )
         unsigned: __builtin_ctz(x), \
         unsigned long: __builtin_ctzl(x), \
         unsigned long long: __builtin_ctzll(x))
+
+#  define popcount(x) \
+    _Generic((x), \
+        unsigned char:      __builtin_popcount(x), \
+          signed char:      __builtin_popcount((unsigned char)(x)), \
+        unsigned short:     __builtin_popcount(x), \
+          signed short:     __builtin_popcount((unsigned short)(x)), \
+        unsigned int:       __builtin_popcount(x), \
+          signed int:       __builtin_popcount(x), \
+        unsigned long:      __builtin_popcountl(x), \
+          signed long:      __builtin_popcountl(x), \
+        unsigned long long: __builtin_popcountll(x), \
+          signed long long: __builtin_popcountll(x))
+
 # else
 VLC_USED static inline int ctz(unsigned x)
 {
@@ -484,6 +498,31 @@ VLC_USED static inline int ctz(unsigned long long x)
 {
     return __builtin_ctzll(x);
 }
+
+VLC_USED static inline int popcount(unsigned char x)
+{
+    return __builtin_popcount(x);
+}
+
+VLC_USED static inline int popcount(unsigned short x)
+{
+    return __builtin_popcount(x);
+}
+
+VLC_USED static inline int popcount(unsigned x)
+{
+    return __builtin_popcount(x);
+}
+
+VLC_USED static inline int popcount(unsigned long x)
+{
+    return __builtin_popcountl(x);
+}
+
+VLC_USED static inline int popcount(unsigned long long x)
+{
+    return __builtin_popcountll(x);
+}
 # endif
 #else /* __GNUC__ */
 # ifndef __cplusplus
@@ -541,47 +580,41 @@ VLC_USED static inline int ctz(unsigned long long x)
     }
     return i;
 }
-#endif /* __GNUC__ */
 
-/**
- * Bit weight / population count
- *
- * This function counts the number of non-zero bits in an integer.
- *
- * \return The count of non-zero bits.
- */
-VLC_USED
-static inline unsigned (popcount)(unsigned x)
+VLC_USED static inline int popcount(unsigned long long x)
 {
-#ifdef __GNUC__
-    return __builtin_popcount (x);
-#else
-    unsigned count = 0;
+    int count = 0;
     while (x)
     {
         count += x & 1;
         x = x >> 1;
     }
     return count;
-#endif
 }
 
-/** Bit weight of long long */
-VLC_USED
-static inline int (popcountll)(unsigned long long x)
-{
-#ifdef __GNUC__
-    return __builtin_popcountll(x);
-#else
-    int count = 0;
-    while (x)
-    {
-        count += x & 1;
-        x = x >> 1;
-    }
-    return count;
+# ifndef __cplusplus
+/**
+ * Bit weight / population count
+ *
+ * This function counts the number of non-zero bits in an integer.
+ *
+ * \return The count of non-zero bits.
+ */
+#  define popcount(x) \
+    _Generic((x), \
+        unsigned char:      popcount(x), \
+          signed char:      popcount((unsigned char)(x)), \
+        unsigned short:     popcount(x), \
+          signed short:     popcount((unsigned short)(x)), \
+        unsigned int:       popcount(x), \
+          signed int:       popcount((unsigned int)(x)), \
+        unsigned long:      popcount(x), \
+          signed long:      popcount((unsigned long)(x)), \
+        unsigned long long: popcount(x), \
+          signed long long: popcount(x))
 #endif
-}
+
+#endif /* __GNUC__ */
 
 /**
  * Parity



More information about the vlc-commits mailing list