[clang] Document the return value of __builtin_COLUMN (#118360)
[llvm-project.git] / libc / src / __support / CPP / span.h
blobe9e3dbf169ce0271df011a15c46c5eea622a9754
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
9 #define LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
11 #include <stddef.h> // For size_t
13 #include "array.h" // For array
14 #include "src/__support/macros/config.h"
15 #include "type_traits.h" // For remove_cv_t, enable_if_t, is_same_v, is_const_v
17 #include "src/__support/macros/attributes.h"
19 namespace LIBC_NAMESPACE_DECL {
20 namespace cpp {
22 // 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 overriding
26 // the & operator,
27 // - No implicit type conversion (e.g. Span<B>, initialized with As where A
28 // inherits from B),
29 // - No reverse iterators
30 template <typename T> class span {
31 template <typename U>
32 LIBC_INLINE_VAR static constexpr bool is_const_view_v =
33 !cpp::is_const_v<U> && cpp::is_const_v<T> &&
34 cpp::is_same_v<U, remove_cv_t<T>>;
36 template <typename U>
37 LIBC_INLINE_VAR static constexpr bool is_compatible_v =
38 cpp::is_same_v<U, T> || is_const_view_v<U>;
40 public:
41 using element_type = T;
42 using value_type = remove_cv_t<T>;
43 using size_type = size_t;
44 using difference_type = ptrdiff_t;
45 using pointer = T *;
46 using const_pointer = const T *;
47 using reference = T &;
48 using const_reference = const T &;
49 using iterator = T *;
51 LIBC_INLINE_VAR static constexpr size_type dynamic_extent = -1;
53 LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}
55 LIBC_INLINE constexpr span(pointer first, size_type count)
56 : span_data(first), span_size(count) {}
58 LIBC_INLINE constexpr span(pointer first, pointer end)
59 : span_data(first), span_size(end - first) {}
61 template <typename U, size_t N,
62 cpp::enable_if_t<is_compatible_v<U>, bool> = true>
63 LIBC_INLINE constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}
65 template <typename U, size_t N,
66 cpp::enable_if_t<is_compatible_v<U>, bool> = true>
67 LIBC_INLINE constexpr span(array<U, N> &arr)
68 : span_data(arr.data()), span_size(arr.size()) {}
70 template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
71 LIBC_INLINE constexpr span(span<U> &s)
72 : span_data(s.data()), span_size(s.size()) {}
74 template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
75 LIBC_INLINE constexpr span &operator=(span<U> &s) {
76 span_data = s.data();
77 span_size = s.size();
78 return *this;
81 LIBC_INLINE ~span() = default;
83 LIBC_INLINE constexpr reference operator[](size_type index) const {
84 return data()[index];
87 LIBC_INLINE constexpr iterator begin() const { return data(); }
88 LIBC_INLINE constexpr iterator end() const { return data() + size(); }
89 LIBC_INLINE constexpr reference front() const { return (*this)[0]; }
90 LIBC_INLINE constexpr reference back() const { return (*this)[size() - 1]; }
91 LIBC_INLINE constexpr pointer data() const { return span_data; }
92 LIBC_INLINE constexpr size_type size() const { return span_size; }
93 LIBC_INLINE constexpr size_type size_bytes() const {
94 return sizeof(T) * size();
96 LIBC_INLINE constexpr bool empty() const { return size() == 0; }
98 LIBC_INLINE constexpr span<element_type>
99 subspan(size_type offset, size_type count = dynamic_extent) const {
100 return span<element_type>(data() + offset, count_to_size(offset, count));
103 LIBC_INLINE constexpr span<element_type> first(size_type count) const {
104 return subspan(0, count);
107 LIBC_INLINE constexpr span<element_type> last(size_type count) const {
108 return span<element_type>(data() + (size() - count), count);
111 private:
112 LIBC_INLINE constexpr size_type count_to_size(size_type offset,
113 size_type count) const {
114 if (count == dynamic_extent) {
115 return size() - offset;
117 return count;
120 T *span_data;
121 size_t span_size;
124 } // namespace cpp
125 } // namespace LIBC_NAMESPACE_DECL
127 #endif // LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H