brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 9234a26 Raw
132 lines · c
1//===-- Standalone implementation std::span ---------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H9#define LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H10 11#include <stddef.h> // For size_t12 13#include "array.h" // For array14#include "limits.h"15#include "src/__support/macros/config.h"16#include "type_traits.h" // For remove_cv_t, enable_if_t, is_same_v, is_const_v17 18#include "src/__support/macros/attributes.h"19 20namespace LIBC_NAMESPACE_DECL {21namespace cpp {22 23// A trimmed down implementation of std::span.24// Missing features:25// - No constant size spans (e.g. Span<int, 4>),26// - Only handle pointer like types, no fancy interators nor object overriding27//   the & operator,28// - No implicit type conversion (e.g. Span<B>, initialized with As where A29//   inherits from B),30// - No reverse iterators31template <typename T> class span {32  template <typename U>33  LIBC_INLINE_VAR static constexpr bool is_const_view_v =34      !cpp::is_const_v<U> && cpp::is_const_v<T> &&35      cpp::is_same_v<U, remove_cv_t<T>>;36 37  template <typename U>38  LIBC_INLINE_VAR static constexpr bool is_compatible_v =39      cpp::is_same_v<U, T> || is_const_view_v<U>;40 41public:42  using element_type = T;43  using value_type = remove_cv_t<T>;44  using size_type = size_t;45  using difference_type = ptrdiff_t;46  using pointer = T *;47  using const_pointer = const T *;48  using reference = T &;49  using const_reference = const T &;50  using iterator = T *;51 52  LIBC_INLINE_VAR static constexpr size_type dynamic_extent =53      cpp::numeric_limits<size_type>::max();54 55  LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}56 57  LIBC_INLINE constexpr span(const span &) = default;58 59  LIBC_INLINE constexpr span(pointer first, size_type count)60      : span_data(first), span_size(count) {}61 62  LIBC_INLINE constexpr span(pointer first, pointer end)63      : span_data(first), span_size(static_cast<size_t>(end - first)) {}64 65  template <typename U, size_t N,66            cpp::enable_if_t<is_compatible_v<U>, bool> = true>67  LIBC_INLINE constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}68 69  template <typename U, size_t N,70            cpp::enable_if_t<is_compatible_v<U>, bool> = true>71  LIBC_INLINE constexpr span(array<U, N> &arr)72      : span_data(arr.data()), span_size(arr.size()) {}73 74  template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>75  LIBC_INLINE constexpr span(span<U> &s)76      : span_data(s.data()), span_size(s.size()) {}77 78  template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>79  LIBC_INLINE constexpr span &operator=(span<U> &s) {80    span_data = s.data();81    span_size = s.size();82    return *this;83  }84 85  LIBC_INLINE ~span() = default;86 87  LIBC_INLINE constexpr reference operator[](size_type index) const {88    return data()[index];89  }90 91  LIBC_INLINE constexpr iterator begin() const { return data(); }92  LIBC_INLINE constexpr iterator end() const { return data() + size(); }93  LIBC_INLINE constexpr reference front() const { return (*this)[0]; }94  LIBC_INLINE constexpr reference back() const { return (*this)[size() - 1]; }95  LIBC_INLINE constexpr pointer data() const { return span_data; }96  LIBC_INLINE constexpr size_type size() const { return span_size; }97  LIBC_INLINE constexpr size_type size_bytes() const {98    return sizeof(T) * size();99  }100  LIBC_INLINE constexpr bool empty() const { return size() == 0; }101 102  LIBC_INLINE constexpr span<element_type>103  subspan(size_type offset, size_type count = dynamic_extent) const {104    return span<element_type>(data() + offset, count_to_size(offset, count));105  }106 107  LIBC_INLINE constexpr span<element_type> first(size_type count) const {108    return subspan(0, count);109  }110 111  LIBC_INLINE constexpr span<element_type> last(size_type count) const {112    return span<element_type>(data() + (size() - count), count);113  }114 115private:116  LIBC_INLINE constexpr size_type count_to_size(size_type offset,117                                                size_type count) const {118    if (count == dynamic_extent) {119      return size() - offset;120    }121    return count;122  }123 124  T *span_data;125  size_t span_size;126};127 128} // namespace cpp129} // namespace LIBC_NAMESPACE_DECL130 131#endif // LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H132