summaryrefslogtreecommitdiff
path: root/gtk/gtkpopcountprivate.h
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2020-12-09 15:48:09 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2020-12-09 16:06:52 +0000
commitb8a651df4782d790130c73e8c5fe70154ff7e11b (patch)
tree7ff91dbf5b5bba5a901d158a72038a979a2db799 /gtk/gtkpopcountprivate.h
parentc5dd34344f0c660ceffffb3bf9da43c263db16e1 (diff)
downloadgtk+-b8a651df4782d790130c73e8c5fe70154ff7e11b.tar.gz
Share the popcount() fallback for MSVC
We use __builtin_popcount() in a couple of places, so it makes sense to have it in one header.
Diffstat (limited to 'gtk/gtkpopcountprivate.h')
-rw-r--r--gtk/gtkpopcountprivate.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/gtk/gtkpopcountprivate.h b/gtk/gtkpopcountprivate.h
new file mode 100644
index 0000000000..8a99dd2b26
--- /dev/null
+++ b/gtk/gtkpopcountprivate.h
@@ -0,0 +1,42 @@
+/* gtkpopcountprivate.h: Private implementation of popcount
+ *
+ * Copyright 2020 GNOME Foundation
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+
+static inline guint
+gtk_popcount (guint32 value)
+{
+ return __popcnt (value);
+}
+#elif defined(__GNUC__) || defined(__clang__)
+# define gtk_popcount(v) __builtin_popcount(v)
+#else
+static inline guint
+gtk_popcount (guint32 value)
+{
+ /* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */
+ return (((value & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
+ ((((value & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
+ (((value >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f);
+}
+#endif