Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libc/src/__support/CPP/span.h
213799 views
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
10
11
#include <stddef.h> // For size_t
12
13
#include "array.h" // For array
14
#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_v
17
18
#include "src/__support/macros/attributes.h"
19
20
namespace LIBC_NAMESPACE_DECL {
21
namespace 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 overriding
27
// the & operator,
28
// - No implicit type conversion (e.g. Span<B>, initialized with As where A
29
// inherits from B),
30
// - No reverse iterators
31
template <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
41
public:
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
115
private:
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 cpp
129
} // namespace LIBC_NAMESPACE_DECL
130
131
#endif // LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
132
133