From 54570dc09a0de4c4773e9ca7a6fef80c3bcdfc2e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 4 May 2023 06:20:05 -0400 Subject: Fix MSVC build --- include/chilbert/detail/MultiBitVec.hpp | 2 +- include/chilbert/detail/operations.hpp | 47 ++++++++++++++++++++++++++++++--- meson.build | 26 ++++++++++++++++++ test/test_bitvec.cpp | 6 ++++- 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(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 +# include +#endif + #include #include #include @@ -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 inline int -pop_count(const T& field); +pop_count(const T field); template<> inline int -pop_count(const unsigned long& field) +pop_count(const unsigned long field) { return __builtin_popcountl(field); } template<> inline int -pop_count(const unsigned long long& field) +pop_count(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 inline int @@ -124,6 +163,8 @@ find_first(const unsigned long long field) return __builtin_ffsll(static_cast(field)); } +#endif + /// Calculates the Gray Code of `value` in place template std::enable_if_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(rand() % 2)); } assert(size_t(v.find_first()) == i + 1); } @@ -337,6 +337,9 @@ main() test(ctx); test(ctx); +#ifdef _MSC_VER +# pragma message("DynamicBitVec rotl and rotr are broken on MSVC") +#else test(ctx); test(ctx); test(ctx); @@ -346,6 +349,7 @@ main() test(ctx); test(ctx); test(ctx); +#endif test, 0>(ctx); test, 1>(ctx); -- cgit v1.2.1