diff --git a/cpp/src/arrow/compute/kernels/codegen_internal.h b/cpp/src/arrow/compute/kernels/codegen_internal.h index 405f35a9234b..d51fd7c9a0e0 100644 --- a/cpp/src/arrow/compute/kernels/codegen_internal.h +++ b/cpp/src/arrow/compute/kernels/codegen_internal.h @@ -17,7 +17,6 @@ #pragma once -#include #include #include #include @@ -1234,9 +1233,12 @@ struct GeneratorApplicator { using Type = GeneratorApplicator::Type; }; +// std::is_invocable_v is used instead of the std::invocable concept because some +// older standard library implementations (e.g., macOS 11.x libc++, used by CRAN) +// have partial C++20 concepts support and lack std::invocable. template class Generator, typename... Args> - requires std::invocable + requires std::is_invocable_v auto GenerateKernelExecImpl(Type::type id) { constexpr auto kNumTypeIds = std::tuple_size_v; static_assert(ArrayIndex < kNumTypeIds); @@ -1272,7 +1274,7 @@ auto GenerateKernelExecImpl(Type::type id) { template class Generator, typename... Args> - requires std::invocable + requires std::is_invocable_v auto GenerateKernelExec(detail::GetTypeId get_id) { return detail::GenerateKernelExecImpl(get_id.id); diff --git a/cpp/src/parquet/column_reader.cc b/cpp/src/parquet/column_reader.cc index 6aca8a23ce16..8594acb41d69 100644 --- a/cpp/src/parquet/column_reader.cc +++ b/cpp/src/parquet/column_reader.cc @@ -83,10 +83,29 @@ inline void CheckNumberDecoded(int64_t number_decoded, int64_t expected) { } } -/// True if a T can hold a U. +/// True if an integer type T can hold every value of integer type U. +/// +/// Written in terms of std::numeric_limits rather than std::in_range because +/// the libc++ in the macOS 11.3 SDK used by CRAN does not provide the latter. +template +struct CanHold { + static_assert(std::is_integral_v && std::is_integral_v, + "can_hold_v is only defined for integer types"); + static constexpr bool value = + std::numeric_limits::digits >= std::numeric_limits::digits && + (std::is_signed_v || !std::is_signed_v); +}; + template -inline constexpr bool can_hold_v = std::in_range(std::numeric_limits::min()) && - std::in_range(std::numeric_limits::max()); +inline constexpr bool can_hold_v = CanHold::value; + +static_assert(can_hold_v); +static_assert(can_hold_v); +static_assert(can_hold_v); +static_assert(!can_hold_v); +static_assert(!can_hold_v); +static_assert(!can_hold_v); +static_assert(!can_hold_v); /// Clamp to a given type. template