aboutsummaryrefslogtreecommitdiffstats
path: root/include/chilbert/detail/operations.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-05-04 06:20:05 -0400
committerDavid Robillard <d@drobilla.net>2023-05-04 06:20:05 -0400
commit54570dc09a0de4c4773e9ca7a6fef80c3bcdfc2e (patch)
tree8ed44deadeb79bb496c31e3b4dcab61df48b3dfa /include/chilbert/detail/operations.hpp
parent8afe1814483ec10f1f425a60d1fc80fe6e3cd8f1 (diff)
downloadchilbert-54570dc09a0de4c4773e9ca7a6fef80c3bcdfc2e.tar.gz
chilbert-54570dc09a0de4c4773e9ca7a6fef80c3bcdfc2e.tar.bz2
chilbert-54570dc09a0de4c4773e9ca7a6fef80c3bcdfc2e.zip
Fix MSVC buildHEADmain
Diffstat (limited to 'include/chilbert/detail/operations.hpp')
-rw-r--r--include/chilbert/detail/operations.hpp47
1 files changed, 44 insertions, 3 deletions
diff --git a/include/chilbert/detail/operations.hpp b/include/chilbert/detail/operations.hpp
index ba9971e..5dd59db 100644
--- a/include/chilbert/detail/operations.hpp
+++ b/include/chilbert/detail/operations.hpp
@@ -8,6 +8,11 @@
#include "chilbert/detail/traits.hpp"
#include "chilbert/operators.hpp"
+#ifdef _MSC_VER
+# include <immintrin.h>
+# include <intrin.h>
+#endif
+
#include <cassert>
#include <climits>
#include <cstddef>
@@ -86,25 +91,59 @@ set_bit(T& field, const size_t index, const bool value)
field.set(index, value);
}
+#ifdef _MSC_VER
+
+inline uint32_t
+pop_count(const uint32_t field)
+{
+ return __popcnt(field);
+}
+
+inline uint64_t
+pop_count(const uint64_t field)
+{
+ return __popcnt64(field);
+}
+
+#else
+
/// Return 1 + the index of the least significant 1-bit of `field`, or zero
template<typename T>
inline int
-pop_count(const T& field);
+pop_count(const T field);
template<>
inline int
-pop_count<unsigned long>(const unsigned long& field)
+pop_count<unsigned long>(const unsigned long field)
{
return __builtin_popcountl(field);
}
template<>
inline int
-pop_count<unsigned long long>(const unsigned long long& field)
+pop_count<unsigned long long>(const unsigned long long field)
{
return __builtin_popcountll(field);
}
+#endif
+
+#ifdef _MSC_VER
+
+inline uint32_t
+find_first(const uint32_t field)
+{
+ return field ? 1U + _tzcnt_u32(field) : 0U;
+}
+
+inline uint64_t
+find_first(const uint64_t field)
+{
+ return field ? 1U + _tzcnt_u64(field) : 0U;
+}
+
+#else
+
/// Return 1 + the index of the least significant 1-bit of `field`, or zero
template<typename T>
inline int
@@ -124,6 +163,8 @@ find_first<unsigned long long>(const unsigned long long field)
return __builtin_ffsll(static_cast<long long>(field));
}
+#endif
+
/// Calculates the Gray Code of `value` in place
template<typename T>
std::enable_if_t<is_bitvec_v<T>>