Path: blob/main/contrib/llvm-project/libc/src/__support/CPP/span.h
213799 views
//===-- Standalone implementation std::span ---------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H8#define LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H910#include <stddef.h> // For size_t1112#include "array.h" // For array13#include "limits.h"14#include "src/__support/macros/config.h"15#include "type_traits.h" // For remove_cv_t, enable_if_t, is_same_v, is_const_v1617#include "src/__support/macros/attributes.h"1819namespace LIBC_NAMESPACE_DECL {20namespace cpp {2122// A trimmed down implementation of std::span.23// Missing features:24// - No constant size spans (e.g. Span<int, 4>),25// - Only handle pointer like types, no fancy interators nor object overriding26// the & operator,27// - No implicit type conversion (e.g. Span<B>, initialized with As where A28// inherits from B),29// - No reverse iterators30template <typename T> class span {31template <typename U>32LIBC_INLINE_VAR static constexpr bool is_const_view_v =33!cpp::is_const_v<U> && cpp::is_const_v<T> &&34cpp::is_same_v<U, remove_cv_t<T>>;3536template <typename U>37LIBC_INLINE_VAR static constexpr bool is_compatible_v =38cpp::is_same_v<U, T> || is_const_view_v<U>;3940public:41using element_type = T;42using value_type = remove_cv_t<T>;43using size_type = size_t;44using difference_type = ptrdiff_t;45using pointer = T *;46using const_pointer = const T *;47using reference = T &;48using const_reference = const T &;49using iterator = T *;5051LIBC_INLINE_VAR static constexpr size_type dynamic_extent =52cpp::numeric_limits<size_type>::max();5354LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}5556LIBC_INLINE constexpr span(const span &) = default;5758LIBC_INLINE constexpr span(pointer first, size_type count)59: span_data(first), span_size(count) {}6061LIBC_INLINE constexpr span(pointer first, pointer end)62: span_data(first), span_size(static_cast<size_t>(end - first)) {}6364template <typename U, size_t N,65cpp::enable_if_t<is_compatible_v<U>, bool> = true>66LIBC_INLINE constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}6768template <typename U, size_t N,69cpp::enable_if_t<is_compatible_v<U>, bool> = true>70LIBC_INLINE constexpr span(array<U, N> &arr)71: span_data(arr.data()), span_size(arr.size()) {}7273template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>74LIBC_INLINE constexpr span(span<U> &s)75: span_data(s.data()), span_size(s.size()) {}7677template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>78LIBC_INLINE constexpr span &operator=(span<U> &s) {79span_data = s.data();80span_size = s.size();81return *this;82}8384LIBC_INLINE ~span() = default;8586LIBC_INLINE constexpr reference operator[](size_type index) const {87return data()[index];88}8990LIBC_INLINE constexpr iterator begin() const { return data(); }91LIBC_INLINE constexpr iterator end() const { return data() + size(); }92LIBC_INLINE constexpr reference front() const { return (*this)[0]; }93LIBC_INLINE constexpr reference back() const { return (*this)[size() - 1]; }94LIBC_INLINE constexpr pointer data() const { return span_data; }95LIBC_INLINE constexpr size_type size() const { return span_size; }96LIBC_INLINE constexpr size_type size_bytes() const {97return sizeof(T) * size();98}99LIBC_INLINE constexpr bool empty() const { return size() == 0; }100101LIBC_INLINE constexpr span<element_type>102subspan(size_type offset, size_type count = dynamic_extent) const {103return span<element_type>(data() + offset, count_to_size(offset, count));104}105106LIBC_INLINE constexpr span<element_type> first(size_type count) const {107return subspan(0, count);108}109110LIBC_INLINE constexpr span<element_type> last(size_type count) const {111return span<element_type>(data() + (size() - count), count);112}113114private:115LIBC_INLINE constexpr size_type count_to_size(size_type offset,116size_type count) const {117if (count == dynamic_extent) {118return size() - offset;119}120return count;121}122123T *span_data;124size_t span_size;125};126127} // namespace cpp128} // namespace LIBC_NAMESPACE_DECL129130#endif // LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H131132133