[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