77
88#include < algorithm>
99#include < array>
10+ #include < bit>
1011#include < cstddef>
1112#include < cstdint>
1213#include < iostream>
@@ -578,7 +579,7 @@ union [[nodiscard]] key_prefix_snapshot {
578579 // / Return the number of bytes in common between this key_prefix and a view of
579580 // / the next 64-bits (max) of some the shifted_key from which any leading
580581 // / bytes already matched by the traversal path have been discarded.
581- [[nodiscard]] UNODB_DETAIL_CONSTEXPR_NOT_MSVC auto get_shared_length (
582+ [[nodiscard]] constexpr auto get_shared_length (
582583 std::uint64_t shifted_key_u64) const noexcept {
583584 return shared_len (shifted_key_u64, u64 , length ());
584585 }
@@ -591,14 +592,13 @@ union [[nodiscard]] key_prefix_snapshot {
591592
592593 private:
593594 // from unodb::detail::key_prefix
594- [[nodiscard, gnu::const ]] static UNODB_DETAIL_CONSTEXPR_NOT_MSVC unsigned
595- shared_len (std::uint64_t k1, std::uint64_t k2,
596- unsigned clamp_byte_pos) noexcept {
595+ [[nodiscard, gnu::const ]] static constexpr unsigned shared_len (
596+ std::uint64_t k1, std::uint64_t k2, unsigned clamp_byte_pos) noexcept {
597597 UNODB_DETAIL_ASSERT (clamp_byte_pos < 8 );
598598
599599 const auto diff = k1 ^ k2;
600600 const auto clamped = diff | (1ULL << (clamp_byte_pos * 8U ));
601- return static_cast <unsigned >(detail::ctz (clamped) >> 3U );
601+ return static_cast <unsigned >(std::countr_zero (clamped) >> 3U );
602602 }
603603}; // class key_prefix_snapshot
604604static_assert (sizeof (key_prefix_snapshot) == sizeof (std::uint64_t ));
@@ -733,7 +733,7 @@ union [[nodiscard]] key_prefix {
733733
734734 const auto diff = k1 ^ k2;
735735 const auto clamped = diff | (1ULL << (clamp_byte_pos * 8U ));
736- return static_cast <unsigned >(detail::ctz (clamped) >> 3U );
736+ return static_cast <unsigned >(std::countr_zero (clamped) >> 3U );
737737 }
738738
739739 [[nodiscard, gnu::const ]] static constexpr std::uint64_t make_u64 (
@@ -1480,7 +1480,7 @@ class basic_inode_4 : public basic_inode_4_parent<ArtPolicy> {
14801480 const auto bit_field =
14811481 static_cast <unsigned >(_mm_movemask_epi8 (matching_key_positions)) & mask;
14821482 if (bit_field != 0 ) {
1483- const auto i = detail::ctz ( bit_field);
1483+ const auto i = static_cast <std:: uint8_t >( std::countr_zero ( bit_field) );
14841484 return std::make_pair (
14851485 i, static_cast <critical_section_policy<node_ptr> *>(&children[i]));
14861486 }
@@ -1502,7 +1502,7 @@ class basic_inode_4 : public basic_inode_4_parent<ArtPolicy> {
15021502
15031503 if (masked_pos == 0 ) return parent_class::child_not_found;
15041504
1505- const auto i = static_cast <unsigned >(detail::ctz (masked_pos) >> 3U );
1505+ const auto i = static_cast <unsigned >(std::countr_zero (masked_pos) >> 3U );
15061506 return std::make_pair (
15071507 i, static_cast <critical_section_policy<node_ptr> *>(&children[i]));
15081508#else // #ifdef UNODB_DETAIL_X86_64
@@ -1902,7 +1902,7 @@ class basic_inode_16 : public basic_inode_16_parent<ArtPolicy> {
19021902 const auto bit_field =
19031903 static_cast <unsigned >(_mm_movemask_epi8 (matching_key_positions)) & mask;
19041904 if (bit_field != 0 ) {
1905- const auto i = detail::ctz ( bit_field);
1905+ const auto i = static_cast <std:: uint8_t >( std::countr_zero ( bit_field) );
19061906 return std::make_pair (
19071907 i, static_cast <critical_section_policy<node_ptr> *>(&children[i]));
19081908 }
@@ -1924,7 +1924,7 @@ class basic_inode_16 : public basic_inode_16_parent<ArtPolicy> {
19241924
19251925 if (masked_pos == 0 ) return parent_class::child_not_found;
19261926
1927- const auto i = static_cast <unsigned >(detail::ctz (masked_pos) >> 2U );
1927+ const auto i = static_cast <unsigned >(std::countr_zero (masked_pos) >> 2U );
19281928 return std::make_pair (
19291929 i, static_cast <critical_section_policy<node_ptr> *>(&children[i]));
19301930#else
@@ -2053,9 +2053,10 @@ class basic_inode_16 : public basic_inode_16_parent<ArtPolicy> {
20532053 const auto mask = (1U << children_count_) - 1 ;
20542054 const auto bit_field =
20552055 static_cast <unsigned >(_mm_movemask_epi8 (lesser_key_positions)) & mask;
2056- const auto result = (bit_field != 0 )
2057- ? detail::ctz (bit_field)
2058- : static_cast <std::uint8_t >(children_count_);
2056+ const auto result =
2057+ (bit_field != 0 )
2058+ ? static_cast <std::uint8_t >(std::countr_zero (bit_field))
2059+ : static_cast <std::uint8_t >(children_count_);
20592060#else
20602061 // This is also the best current ARM implementation
20612062 const auto result = static_cast <std::uint8_t >(
@@ -2233,7 +2234,8 @@ class basic_inode_48 : public basic_inode_48_parent<ArtPolicy> {
22332234 const auto cmp_mask =
22342235 static_cast <std::uint64_t >(_mm_movemask_epi8 (vec_cmp));
22352236 if (cmp_mask != 0 ) {
2236- i = (i << 1U ) + (((detail::ctz (cmp_mask)) + 1U ) >> 1U );
2237+ i = (i << 1U ) +
2238+ ((static_cast <unsigned >(std::countr_zero (cmp_mask)) + 1U ) >> 1U );
22372239 break ;
22382240 }
22392241 i += 4 ;
@@ -2265,7 +2267,8 @@ class basic_inode_48 : public basic_inode_48_parent<ArtPolicy> {
22652267 _mm256_permute4x64_epi64 (interleaved_vec_cmp, 0b11'01'10'00 );
22662268 const auto cmp_mask =
22672269 static_cast <std::uint64_t >(_mm256_movemask_epi8 (vec_cmp));
2268- i = (i << 2U ) + (detail::ctz (cmp_mask) >> 1U );
2270+ i = (i << 2U ) +
2271+ (static_cast <unsigned >(std::countr_zero (cmp_mask)) >> 1U );
22692272 break ;
22702273 }
22712274 i += 4 ;
@@ -2298,7 +2301,8 @@ class basic_inode_48 : public basic_inode_48_parent<ArtPolicy> {
22982301 // NOLINTNEXTLINE(misc-const-correctness)
22992302 vget_lane_u64 (vreinterpret_u64_u8 (narrowed_cmp), 0 );
23002303 if (scalar_pos != 0 ) {
2301- i = (i << 1U ) + static_cast <unsigned >(detail::ctz (scalar_pos) >> 3U );
2304+ i = (i << 1U ) +
2305+ static_cast <unsigned >(std::countr_zero (scalar_pos) >> 3U );
23022306 break ;
23032307 }
23042308 i += 4 ;
0 commit comments