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.