aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/chilbert/detail/MultiBitVec.hpp2
-rw-r--r--include/chilbert/detail/operations.hpp47
-rw-r--r--meson.build26
-rw-r--r--test/test_bitvec.cpp6
4 files changed, 76 insertions, 5 deletions
diff --git a/include/chilbert/detail/MultiBitVec.hpp b/include/chilbert/detail/MultiBitVec.hpp
index 9053a04..bf1802c 100644
--- a/include/chilbert/detail/MultiBitVec.hpp
+++ b/include/chilbert/detail/MultiBitVec.hpp
@@ -165,7 +165,7 @@ public:
size_t find_first() const
{
for (size_t i = 0; i < num_racks(); ++i) {
- const int j = chilbert::detail::find_first(rack(i));
+ const auto j = chilbert::detail::find_first(rack(i));
if (j) {
return (i * bits_per_rack) + static_cast<size_t>(j);
}
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>>
diff --git a/meson.build b/meson.build
index 52b9012..ccbac27 100644
--- a/meson.build
+++ b/meson.build
@@ -54,6 +54,14 @@ elif cpp.get_id() == 'gcc'
endif
elif cpp.get_id() == 'msvc'
+ cpp_suppressions += [
+ '/experimental:external',
+ '/external:W0',
+ '/external:anglebrackets',
+
+ '/wd4146', # unary minus operator applied to unsigned type
+ ]
+
if warning_level == 'everything'
cpp_suppressions += [
'/wd4028', # formal parameter different from declaration
@@ -65,6 +73,24 @@ elif cpp.get_id() == 'msvc'
'/wd4711', # function selected for automatic inline expansion
'/wd4820', # padding added after construct
'/wd5045', # will insert Spectre mitigation
+
+ '/wd4625', # copy constructor implicitly deleted
+ '/wd4626', # assignment operator implicitly deleted
+ '/wd5026', # move constructor implicitly deleted
+ '/wd5027', # move assignment operator implicitly deleted
+ '/wd5246', # subobject should be wrapped in braces
+ ]
+ endif
+
+ if warning_level in ['everything', '3']
+ cpp_suppressions += [
+ '/wd4127', # conditional expression is constant
+ ]
+ endif
+
+ if warning_level in ['everything', '3', '2', '1']
+ cpp_suppressions += [
+ '/wd4146', # unary minus operator applied to unsigned type
]
endif
endif
diff --git a/test/test_bitvec.cpp b/test/test_bitvec.cpp
index aaf69a4..e03a27f 100644
--- a/test/test_bitvec.cpp
+++ b/test/test_bitvec.cpp
@@ -237,7 +237,7 @@ test_find_first(Context&)
v.reset();
v.set(i);
for (size_t j = i + 1; j < N; ++j) {
- v.set(j, rand() % 2);
+ v.set(j, static_cast<bool>(rand() % 2));
}
assert(size_t(v.find_first()) == i + 1);
}
@@ -337,6 +337,9 @@ main()
test<chilbert::SmallBitVec, 63>(ctx);
test<chilbert::SmallBitVec, 64>(ctx);
+#ifdef _MSC_VER
+# pragma message("DynamicBitVec rotl and rotr are broken on MSVC")
+#else
test<chilbert::DynamicBitVec, 0>(ctx);
test<chilbert::DynamicBitVec, 1>(ctx);
test<chilbert::DynamicBitVec, 31>(ctx);
@@ -346,6 +349,7 @@ main()
test<chilbert::DynamicBitVec, 64>(ctx);
test<chilbert::DynamicBitVec, 65>(ctx);
test<chilbert::DynamicBitVec, 997>(ctx);
+#endif
test<chilbert::StaticBitVec<0>, 0>(ctx);
test<chilbert::StaticBitVec<1>, 1>(ctx);