This is an automated email from the ASF dual-hosted git repository.

jonkeane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 007903c2ac GH-49371: [C++] Work around bit_width not being available 
on MacOS's partially compatible C++20 build (#49405)
007903c2ac is described below

commit 007903c2ac783a98c320b91024a8b789c2648236
Author: Jonathan Keane <[email protected]>
AuthorDate: Sat Feb 28 07:32:36 2026 -0600

    GH-49371: [C++] Work around bit_width not being available on MacOS's 
partially compatible C++20 build (#49405)
    
    Fixes #49371
    
    ### Rationale for this change
    Stop main from failing
    
    ### What changes are included in this PR?
    Thanks Kou for the suggestion at 
https://github.com/apache/arrow/pull/49391#issuecomment-3963506183
    
    ### Are these changes tested?
    Yes
    
    ### Are there any user-facing changes?
    No
    
    * GitHub Issue: #49371
    
    Authored-by: Jonathan Keane <[email protected]>
    Signed-off-by: Jonathan Keane <[email protected]>
---
 cpp/src/arrow/util/align_util.h         | 7 +++++++
 cpp/src/arrow/util/bit_util.h           | 7 +++++++
 cpp/src/arrow/util/rle_encoding_test.cc | 6 ++++++
 cpp/src/parquet/chunker_internal.cc     | 6 ++++++
 cpp/src/parquet/encoder.cc              | 7 +++++++
 5 files changed, 33 insertions(+)

diff --git a/cpp/src/arrow/util/align_util.h b/cpp/src/arrow/util/align_util.h
index 64eb1f7ba6..c91b047e88 100644
--- a/cpp/src/arrow/util/align_util.h
+++ b/cpp/src/arrow/util/align_util.h
@@ -44,8 +44,15 @@ struct BitmapWordAlignParams {
 template <uint64_t ALIGN_IN_BYTES>
 inline BitmapWordAlignParams BitmapWordAlign(const uint8_t* data, int64_t 
bit_offset,
                                              int64_t length) {
+  // TODO: We can remove this condition once CRAN upgrades its macOS
+  // SDK from 11.3.
+#if defined(__clang__) && !defined(__cpp_lib_bitops)
+  static_assert((ALIGN_IN_BYTES != 0) && ((ALIGN_IN_BYTES & (ALIGN_IN_BYTES - 
1)) == 0),
+                "ALIGN_IN_BYTES should be a positive power of two");
+#else
   static_assert(std::has_single_bit(ALIGN_IN_BYTES),
                 "ALIGN_IN_BYTES should be a positive power of two");
+#endif
   constexpr uint64_t ALIGN_IN_BITS = ALIGN_IN_BYTES * 8;
 
   BitmapWordAlignParams p;
diff --git a/cpp/src/arrow/util/bit_util.h b/cpp/src/arrow/util/bit_util.h
index 0d2b2655ea..1cbbf2042d 100644
--- a/cpp/src/arrow/util/bit_util.h
+++ b/cpp/src/arrow/util/bit_util.h
@@ -138,7 +138,14 @@ static inline uint64_t TrailingBits(uint64_t v, int 
num_bits) {
 // Returns ceil(log2(x)).
 static inline int Log2(uint64_t x) {
   // DCHECK_GT(x, 0);
+
+  // TODO: We can remove this condition once CRAN upgrades its macOS
+  // SDK from 11.3.
+#if defined(__clang__) && !defined(__cpp_lib_bitops)
+  return std::log2p1(x - 1);
+#else
   return std::bit_width(x - 1);
+#endif
 }
 
 //
diff --git a/cpp/src/arrow/util/rle_encoding_test.cc 
b/cpp/src/arrow/util/rle_encoding_test.cc
index 6826778ae8..93405b5333 100644
--- a/cpp/src/arrow/util/rle_encoding_test.cc
+++ b/cpp/src/arrow/util/rle_encoding_test.cc
@@ -916,7 +916,13 @@ TEST(BitRle, Random) {
       }
       parity = !parity;
     }
+    // TODO: We can remove this condition once CRAN upgrades its macOS
+    // SDK from 11.3.
+#if defined(__clang__) && !defined(__cpp_lib_bitops)
+    if (!CheckRoundTrip(values, std::log2p1(values.size()))) {
+#else
     if (!CheckRoundTrip(values, std::bit_width(values.size()))) {
+#endif
       FAIL() << "failing seed: " << seed;
     }
   }
diff --git a/cpp/src/parquet/chunker_internal.cc 
b/cpp/src/parquet/chunker_internal.cc
index 5cd31f8334..097b20f0f6 100644
--- a/cpp/src/parquet/chunker_internal.cc
+++ b/cpp/src/parquet/chunker_internal.cc
@@ -86,7 +86,13 @@ uint64_t CalculateMask(int64_t min_chunk_size, int64_t 
max_chunk_size, int norm_
 
   // assuming that the gear hash has a uniform distribution, we can calculate 
the mask
   // by taking the floor(log2(target_size))
+  // TODO: We can remove this condition once CRAN upgrades its macOS
+  // SDK from 11.3.
+#if defined(__clang__) && !defined(__cpp_lib_bitops)
+  auto target_bits = std::log2p1(static_cast<uint64_t>(target_size));
+#else
   auto target_bits = std::bit_width(static_cast<uint64_t>(target_size));
+#endif
   int mask_bits = target_bits == 0 ? 0 : static_cast<int>(target_bits - 1);
 
   // a user defined `norm_level` can be used to adjust the mask size, hence 
the matching
diff --git a/cpp/src/parquet/encoder.cc b/cpp/src/parquet/encoder.cc
index edfebad5ab..d4ac6e1e88 100644
--- a/cpp/src/parquet/encoder.cc
+++ b/cpp/src/parquet/encoder.cc
@@ -1167,8 +1167,15 @@ void DeltaBitPackEncoder<DType>::FlushBlock() {
 
     // The minimum number of bits required to write any of values in deltas_ 
vector.
     // See overflow comment above.
+    // TODO: We can remove this condition once CRAN upgrades its macOS
+    // SDK from 11.3.
+#if defined(__clang__) && !defined(__cpp_lib_bitops)
+    const auto bit_width = bit_width_data[i] =
+        std::log2p1(static_cast<UT>(max_delta) - static_cast<UT>(min_delta));
+#else
     const auto bit_width = bit_width_data[i] =
         std::bit_width(static_cast<UT>(max_delta) - 
static_cast<UT>(min_delta));
+#endif
 
     for (uint32_t j = start; j < start + values_current_mini_block; j++) {
       // Convert delta to frame of reference. See overflow comment above.

Reply via email to