Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-44898: [C++] Fix compilation error on GCC 8 #44899

Merged
merged 1 commit into from
Dec 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 5 additions & 29 deletions cpp/src/arrow/util/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,6 @@ namespace arrow::util {
template <class T>
class span;

// This trait is used to check if a type R can be used to construct a span<T>.
// Specifically, it checks if std::data(R) and std::size(R) are valid expressions
// that may be passed to the span(T*, size_t) constructor. The reason this trait
// is needed rather than expressing this directly in the relevant span constructor
// is that this check requires instantiating span<T>, which would violate the
// C++ standard if written directly in the constructor's enable_if clause
// because span<T> is an incomplete type at that point. By defining this trait
// instead, we add an extra level of indirection that lets us delay the
// evaluation of the template until the first time the associated constructor
// is actually called, at which point span<T> is a complete type.
//
// Note that most compilers do support the noncompliant construct, but nvcc
// does not. See https://github.com/apache/arrow/issues/40252
template <class T, class R, class Enable = void>
struct ConstructibleFromDataAndSize : std::false_type {};

template <class T, class R>
struct ConstructibleFromDataAndSize<
span<T>, R,
std::void_t<decltype(span<T>{std::data(std::declval<R>()),
std::size(std::declval<R>())})>> : std::true_type {};

/// std::span polyfill.
///
/// Does not support static extents.
Expand Down Expand Up @@ -81,14 +59,12 @@ writing code which would break when it is replaced by std::span.)");
constexpr span(T* begin, T* end)
: data_{begin}, size_{static_cast<size_t>(end - begin)} {}

template <
typename R,
std::enable_if_t<ConstructibleFromDataAndSize<span<T>, R>::value, bool> = true,
typename DisableUnlessSimilarTypes = std::enable_if_t<std::is_same_v<
std::decay_t<std::remove_pointer_t<decltype(std::data(std::declval<R>()))>>,
std::decay_t<T>>>>
template <typename R, typename RD = decltype(std::data(std::declval<R>())),
typename RS = decltype(std::size(std::declval<R>())),
typename E = std::enable_if_t<std::is_constructible_v<T*, RD> &&
std::is_constructible_v<size_t, RS>>>
// NOLINTNEXTLINE runtime/explicit, non-const reference
constexpr span(R&& range) : span{std::data(range), std::size(range)} {}
constexpr span(R&& range) : data_{std::data(range)}, size_{std::size(range)} {}

constexpr T* begin() const { return data_; }
constexpr T* end() const { return data_ + size_; }
Expand Down
Loading