diff --git a/art_common.hpp b/art_common.hpp index 87858850..a4a662cd 100644 --- a/art_common.hpp +++ b/art_common.hpp @@ -187,7 +187,7 @@ template const T t = v | (v - 1u); // t gets v's least significant 0 bits set to 1 // Next set to 1 the most significant bit to change, set to 0 the // least significant ones, and add the necessary 1 bits. - const T w = (t + 1) | (((~t & -~t) - 1) >> (ctz(v) + 1)); + const T w = (t + 1) | (((~t & -~t) - 1) >> (std::countr_zero(v) + 1)); return w; } diff --git a/art_internal_impl.hpp b/art_internal_impl.hpp index 0f6d2f79..2bd965de 100644 --- a/art_internal_impl.hpp +++ b/art_internal_impl.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -578,7 +579,7 @@ union [[nodiscard]] key_prefix_snapshot { /// Return the number of bytes in common between this key_prefix and a view of /// the next 64-bits (max) of some the shifted_key from which any leading /// bytes already matched by the traversal path have been discarded. - [[nodiscard]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC auto get_shared_length( + [[nodiscard]] constexpr auto get_shared_length( std::uint64_t shifted_key_u64) const noexcept { return shared_len(shifted_key_u64, u64, length()); } @@ -591,14 +592,13 @@ union [[nodiscard]] key_prefix_snapshot { private: // from unodb::detail::key_prefix - [[nodiscard, gnu::const]] static UNODB_DETAIL_CONSTEXPR_NOT_MSVC unsigned - shared_len(std::uint64_t k1, std::uint64_t k2, - unsigned clamp_byte_pos) noexcept { + [[nodiscard, gnu::const]] static constexpr unsigned shared_len( + std::uint64_t k1, std::uint64_t k2, unsigned clamp_byte_pos) noexcept { UNODB_DETAIL_ASSERT(clamp_byte_pos < 8); const auto diff = k1 ^ k2; const auto clamped = diff | (1ULL << (clamp_byte_pos * 8U)); - return static_cast(detail::ctz(clamped) >> 3U); + return static_cast(std::countr_zero(clamped) >> 3U); } }; // class key_prefix_snapshot static_assert(sizeof(key_prefix_snapshot) == sizeof(std::uint64_t)); @@ -733,7 +733,7 @@ union [[nodiscard]] key_prefix { const auto diff = k1 ^ k2; const auto clamped = diff | (1ULL << (clamp_byte_pos * 8U)); - return static_cast(detail::ctz(clamped) >> 3U); + return static_cast(std::countr_zero(clamped) >> 3U); } [[nodiscard, gnu::const]] static constexpr std::uint64_t make_u64( @@ -1480,7 +1480,7 @@ class basic_inode_4 : public basic_inode_4_parent { const auto bit_field = static_cast(_mm_movemask_epi8(matching_key_positions)) & mask; if (bit_field != 0) { - const auto i = detail::ctz(bit_field); + const auto i = static_cast(std::countr_zero(bit_field)); return std::make_pair( i, static_cast *>(&children[i])); } @@ -1502,7 +1502,7 @@ class basic_inode_4 : public basic_inode_4_parent { if (masked_pos == 0) return parent_class::child_not_found; - const auto i = static_cast(detail::ctz(masked_pos) >> 3U); + const auto i = static_cast(std::countr_zero(masked_pos) >> 3U); return std::make_pair( i, static_cast *>(&children[i])); #else // #ifdef UNODB_DETAIL_X86_64 @@ -1902,7 +1902,7 @@ class basic_inode_16 : public basic_inode_16_parent { const auto bit_field = static_cast(_mm_movemask_epi8(matching_key_positions)) & mask; if (bit_field != 0) { - const auto i = detail::ctz(bit_field); + const auto i = static_cast(std::countr_zero(bit_field)); return std::make_pair( i, static_cast *>(&children[i])); } @@ -1924,7 +1924,7 @@ class basic_inode_16 : public basic_inode_16_parent { if (masked_pos == 0) return parent_class::child_not_found; - const auto i = static_cast(detail::ctz(masked_pos) >> 2U); + const auto i = static_cast(std::countr_zero(masked_pos) >> 2U); return std::make_pair( i, static_cast *>(&children[i])); #else @@ -2053,9 +2053,10 @@ class basic_inode_16 : public basic_inode_16_parent { const auto mask = (1U << children_count_) - 1; const auto bit_field = static_cast(_mm_movemask_epi8(lesser_key_positions)) & mask; - const auto result = (bit_field != 0) - ? detail::ctz(bit_field) - : static_cast(children_count_); + const auto result = + (bit_field != 0) + ? static_cast(std::countr_zero(bit_field)) + : static_cast(children_count_); #else // This is also the best current ARM implementation const auto result = static_cast( @@ -2233,7 +2234,8 @@ class basic_inode_48 : public basic_inode_48_parent { const auto cmp_mask = static_cast(_mm_movemask_epi8(vec_cmp)); if (cmp_mask != 0) { - i = (i << 1U) + (((detail::ctz(cmp_mask)) + 1U) >> 1U); + i = (i << 1U) + + ((static_cast(std::countr_zero(cmp_mask)) + 1U) >> 1U); break; } i += 4; @@ -2265,7 +2267,8 @@ class basic_inode_48 : public basic_inode_48_parent { _mm256_permute4x64_epi64(interleaved_vec_cmp, 0b11'01'10'00); const auto cmp_mask = static_cast(_mm256_movemask_epi8(vec_cmp)); - i = (i << 2U) + (detail::ctz(cmp_mask) >> 1U); + i = (i << 2U) + + (static_cast(std::countr_zero(cmp_mask)) >> 1U); break; } i += 4; @@ -2298,7 +2301,8 @@ class basic_inode_48 : public basic_inode_48_parent { // NOLINTNEXTLINE(misc-const-correctness) vget_lane_u64(vreinterpret_u64_u8(narrowed_cmp), 0); if (scalar_pos != 0) { - i = (i << 1U) + static_cast(detail::ctz(scalar_pos) >> 3U); + i = (i << 1U) + + static_cast(std::countr_zero(scalar_pos) >> 3U); break; } i += 4; diff --git a/portability_builtins.hpp b/portability_builtins.hpp index 00034ea2..15e985dc 100644 --- a/portability_builtins.hpp +++ b/portability_builtins.hpp @@ -54,48 +54,6 @@ template #endif // UNODB_DETAIL_MSVC } -/// Return the number of trailing zero bits in \a x. -/// \pre Argument may not be zero -template -[[nodiscard, gnu::const]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC std::uint8_t ctz( - T x) noexcept { - static_assert(std::is_same_v || - // NOLINTNEXTLINE(google-runtime-int) - std::is_same_v || // NOLINT(runtime/int) - // NOLINTNEXTLINE(google-runtime-int) - std::is_same_v); // NOLINT(runtime/int) - - if constexpr (std::is_same_v) { -#ifndef UNODB_DETAIL_MSVC - return static_cast(__builtin_ctz(x)); -#else - unsigned long result; // NOLINT(runtime/int) - _BitScanForward(&result, x); - return static_cast(result); -#endif - } - // NOLINTNEXTLINE(google-runtime-int) - if constexpr (std::is_same_v) { // NOLINT(runtime/int) -#ifndef UNODB_DETAIL_MSVC - return static_cast(__builtin_ctzl(x)); -#else - unsigned long result; // NOLINT(runtime/int) - _BitScanForward(&result, x); - return static_cast(result); -#endif - } - // NOLINTNEXTLINE(google-runtime-int) - if constexpr (std::is_same_v) { // NOLINT(runtime/int) -#ifndef UNODB_DETAIL_MSVC - return static_cast(__builtin_ctzll(x)); -#else - unsigned long result; // NOLINT(runtime/int) - _BitScanForward64(&result, x); - return static_cast(result); -#endif - } // cppcheck-suppress missingReturn -} - /// Return the number of one bits in \a x. [[nodiscard, gnu::const]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC unsigned popcount( unsigned x) noexcept {