Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 08:27:10

0001 // Licensed to the Apache Software Foundation (ASF) under one
0002 // or more contributor license agreements.  See the NOTICE file
0003 // distributed with this work for additional information
0004 // regarding copyright ownership.  The ASF licenses this file
0005 // to you under the Apache License, Version 2.0 (the
0006 // "License"); you may not use this file except in compliance
0007 // with the License.  You may obtain a copy of the License at
0008 //
0009 //   http://www.apache.org/licenses/LICENSE-2.0
0010 //
0011 // Unless required by applicable law or agreed to in writing,
0012 // software distributed under the License is distributed on an
0013 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0014 // KIND, either express or implied.  See the License for the
0015 // specific language governing permissions and limitations
0016 // under the License.
0017 
0018 #pragma once
0019 
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <cstring>
0023 #include <iterator>
0024 #include <type_traits>
0025 
0026 namespace arrow::util {
0027 
0028 template <class T>
0029 class span;
0030 
0031 /// std::span polyfill.
0032 ///
0033 /// Does not support static extents.
0034 template <typename T>
0035 class span {
0036   static_assert(sizeof(T),
0037                 R"(
0038 std::span allows contiguous_iterators instead of just pointers, the enforcement
0039 of which requires T to be a complete type. arrow::util::span does not support
0040 contiguous_iterators, but T is still required to be a complete type to prevent
0041 writing code which would break when it is replaced by std::span.)");
0042 
0043  public:
0044   using element_type = T;
0045   using value_type = std::remove_cv_t<T>;
0046   using iterator = T*;
0047   using const_iterator = T const*;
0048 
0049   span() = default;
0050   span(const span&) = default;
0051   span& operator=(const span&) = default;
0052 
0053   template <typename M, typename = std::enable_if_t<std::is_same_v<T, M const>>>
0054   // NOLINTNEXTLINE runtime/explicit
0055   constexpr span(span<M> mut) : span{mut.data(), mut.size()} {}
0056 
0057   constexpr span(T* data, size_t count) : data_{data}, size_{count} {}
0058 
0059   constexpr span(T* begin, T* end)
0060       : data_{begin}, size_{static_cast<size_t>(end - begin)} {}
0061 
0062   template <typename R, typename RD = decltype(std::data(std::declval<R>())),
0063             typename RS = decltype(std::size(std::declval<R>())),
0064             typename E = std::enable_if_t<std::is_constructible_v<T*, RD> &&
0065                                           std::is_constructible_v<size_t, RS>>>
0066   // NOLINTNEXTLINE runtime/explicit, non-const reference
0067   constexpr span(R&& range) : data_{std::data(range)}, size_{std::size(range)} {}
0068 
0069   constexpr T* begin() const { return data_; }
0070   constexpr T* end() const { return data_ + size_; }
0071   constexpr T* data() const { return data_; }
0072 
0073   constexpr size_t size() const { return size_; }
0074   constexpr size_t size_bytes() const { return size_ * sizeof(T); }
0075   constexpr bool empty() const { return size_ == 0; }
0076 
0077   constexpr T& operator[](size_t i) { return data_[i]; }
0078   constexpr const T& operator[](size_t i) const { return data_[i]; }
0079 
0080   constexpr span subspan(size_t offset) const {
0081     if (offset > size_) return {data_, data_};
0082     return {data_ + offset, size_ - offset};
0083   }
0084 
0085   constexpr span subspan(size_t offset, size_t count) const {
0086     auto out = subspan(offset);
0087     if (count < out.size_) {
0088       out.size_ = count;
0089     }
0090     return out;
0091   }
0092 
0093   constexpr bool operator==(span const& other) const {
0094     if (size_ != other.size_) return false;
0095 
0096     if constexpr (std::is_integral_v<T>) {
0097       if (size_ == 0) {
0098         return true;  // memcmp does not handle null pointers, even if size_ == 0
0099       }
0100       return std::memcmp(data_, other.data_, size_bytes()) == 0;
0101     } else {
0102       T* ptr = data_;
0103       for (T const& e : other) {
0104         if (*ptr++ != e) return false;
0105       }
0106       return true;
0107     }
0108   }
0109   constexpr bool operator!=(span const& other) const { return !(*this == other); }
0110 
0111  private:
0112   T* data_{};
0113   size_t size_{};
0114 };
0115 
0116 template <typename R>
0117 span(R& range) -> span<std::remove_pointer_t<decltype(std::data(range))>>;
0118 
0119 template <typename T>
0120 span(T*, size_t) -> span<T>;
0121 
0122 template <typename T>
0123 constexpr span<std::byte const> as_bytes(span<T> s) {
0124   return {reinterpret_cast<std::byte const*>(s.data()), s.size_bytes()};
0125 }
0126 
0127 template <typename T>
0128 constexpr span<std::byte> as_writable_bytes(span<T> s) {
0129   return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
0130 }
0131 
0132 }  // namespace arrow::util