libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
span.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <cstddef>
14#include <span>
15#include <type_traits>
16#include <promeki/namespace.h>
17
18PROMEKI_NAMESPACE_BEGIN
19
20// Forward declarations
21template <typename T> class List;
22template <typename T, size_t N> class Array;
23
41template <typename T> class Span {
42 public:
44 using Iterator = typename std::span<T>::iterator;
45
47 using ConstIterator = typename std::span<const T>::iterator;
48
50 using RevIterator = typename std::span<T>::reverse_iterator;
51
53 using ConstRevIterator = typename std::span<const T>::reverse_iterator;
54
56 Span() = default;
57
63 Span(T *ptr, size_t count) : d(ptr, count) {}
64
69 Span(List<T> &list) : d(list.data(), list.size()) {}
70
76 template <size_t N> Span(T (&arr)[N]) : d(arr, N) {}
77
83 template <size_t N> Span(Array<T, N> &arr) : d(arr.data(), N) {}
84
86 Span(const Span &other) = default;
87
89 Span &operator=(const Span &other) = default;
90
99 template <typename U, typename = std::enable_if_t<std::is_convertible_v<U (*)[], T (*)[]>>>
100 Span(const Span<U> &other) : d(other.data(), other.size()) {}
101
102 // -- Iterators --
103
105 Iterator begin() noexcept { return d.begin(); }
106
108 ConstIterator begin() const noexcept { return std::span<const T>(d.data(), d.size()).begin(); }
109
111 Iterator end() noexcept { return d.end(); }
112
114 ConstIterator end() const noexcept { return std::span<const T>(d.data(), d.size()).end(); }
115
117 ConstIterator constBegin() const noexcept { return begin(); }
118
120 ConstIterator constEnd() const noexcept { return end(); }
121
123 RevIterator rbegin() noexcept { return d.rbegin(); }
124
126 RevIterator revBegin() noexcept { return d.rbegin(); }
127
129 RevIterator rend() noexcept { return d.rend(); }
130
132 RevIterator revEnd() noexcept { return d.rend(); }
133
135 ConstRevIterator crbegin() const noexcept { return std::span<const T>(d.data(), d.size()).rbegin(); }
136
138 ConstRevIterator constRevBegin() const noexcept { return crbegin(); }
139
141 ConstRevIterator crend() const noexcept { return std::span<const T>(d.data(), d.size()).rend(); }
142
144 ConstRevIterator constRevEnd() const noexcept { return crend(); }
145
146 // -- Access --
147
153 T &operator[](size_t index) { return d[index]; }
154
156 const T &operator[](size_t index) const { return d[index]; }
157
159 T &front() { return d.front(); }
160
162 const T &front() const { return d.front(); }
163
165 T &back() { return d.back(); }
166
168 const T &back() const { return d.back(); }
169
171 T *data() noexcept { return d.data(); }
172
174 const T *data() const noexcept { return d.data(); }
175
176 // -- Capacity --
177
179 bool isEmpty() const noexcept { return d.empty(); }
180
182 size_t size() const noexcept { return d.size(); }
183
185 size_t sizeBytes() const noexcept { return d.size_bytes(); }
186
187 // -- Sub-views --
188
195 Span subspan(size_t offset, size_t count) const { return Span(d.data() + offset, count); }
196
202 Span first(size_t count) const { return Span(d.data(), count); }
203
209 Span last(size_t count) const { return Span(d.data() + d.size() - count, count); }
210
211 // -- Convenience --
212
218 template <typename Func> void forEach(Func &&func) const {
219 for (size_t i = 0; i < d.size(); ++i) func(d[i]);
220 return;
221 }
222
223 private:
224 std::span<T> d;
225};
226
227PROMEKI_NAMESPACE_END
228
229#endif // PROMEKI_ENABLE_CORE