Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
Span.h
Go to the documentation of this file.
1#ifndef ZSERIO_SPAN_H_INC
2#define ZSERIO_SPAN_H_INC
3
4#include <array>
5#include <cstddef>
6#include <iterator>
7#include <limits>
8#include <type_traits>
9#include <vector>
10
11namespace zserio
12{
13
17constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max();
18
19namespace detail
20{
21
22template <typename T, std::size_t Extent>
23struct SpanStorage
24{
25 SpanStorage() = default;
26
27 SpanStorage(T* data, std::size_t) :
28 m_data(data)
29 {}
30
31 T* m_data = nullptr;
32 static constexpr std::size_t m_size = Extent;
33};
34
35template <typename T>
36struct SpanStorage<T, dynamic_extent>
37{
38 SpanStorage() = default;
39
40 SpanStorage(T* data, std::size_t size) :
41 m_data(data),
42 m_size(size)
43 {}
44
45 T* m_data = nullptr;
46 std::size_t m_size = 0;
47};
48
49} // namespace detail
50
57template <typename T, std::size_t Extent = dynamic_extent>
58class Span
59{
60public:
61 using element_type = T;
62 using value_type = typename std::remove_cv_t<T>;
63 using size_type = std::size_t;
64 using difference_type = std::ptrdiff_t;
65 using pointer = T*;
66 using const_pointer = const T*;
67 using reference = T&;
70 using reverse_iterator = std::reverse_iterator<iterator>;
71 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
72
73 static constexpr size_type extent = Extent;
74
78 template <size_type ext = Extent,
79 typename std::enable_if<(ext == 0 || ext == dynamic_extent), int>::type = 0>
80 constexpr Span() noexcept
81 {}
82
91 m_storage(first_, count)
92 {}
93
102 m_storage(first_, static_cast<size_t>(last_ - first_))
103 {}
104
110 template <size_type N, size_type ext = Extent,
111 typename std::enable_if<(ext == dynamic_extent || ext == N), int>::type = 0>
112 constexpr Span(element_type (&arr)[N]) noexcept :
113 m_storage(arr, N)
114 {}
115
121 template <typename U, size_type N, size_type ext = Extent,
122 typename std::enable_if<(ext == dynamic_extent || ext == N) &&
123 std::is_convertible<U (*)[], T (*)[]>::value,
124 int>::type = 0>
125 constexpr Span(std::array<U, N>& arr) noexcept :
126 m_storage(arr.data(), arr.size())
127 {}
128
134 template <typename U, size_type N, size_type ext = Extent,
135 typename std::enable_if<(ext == dynamic_extent || ext == N) &&
136 std::is_convertible<const U (*)[], T (*)[]>::value,
137 int>::type = 0>
138 constexpr Span(const std::array<U, N>& arr) noexcept :
139 m_storage(arr.data(), arr.size())
140 {}
141
147 template <typename U, typename ALLOC, size_type ext = Extent,
148 typename std::enable_if<(ext == dynamic_extent) && std::is_convertible<U (*)[], T (*)[]>::value,
149 int>::type = 0>
150 constexpr Span(std::vector<U, ALLOC>& vec) :
151 m_storage(vec.data(), vec.size())
152 {}
153
159 template <typename U, typename ALLOC, size_type ext = Extent,
160 typename std::enable_if<
161 (ext == dynamic_extent) && std::is_convertible<const U (*)[], T (*)[]>::value, int>::type =
162 0>
163 constexpr Span(const std::vector<U, ALLOC>& vec) :
164 m_storage(vec.data(), vec.size())
165 {}
166
172 template <typename U, size_type N,
173 typename std::enable_if<(Extent == N || Extent == dynamic_extent) &&
174 std::is_convertible<U (*)[], T (*)[]>::value,
175 int>::type = 0>
176 constexpr Span(const Span<U, N>& span) noexcept :
177 m_storage(span.data(), span.size())
178 {}
179
184 ~Span() = default;
185
186 Span(const Span& other) noexcept = default;
187 Span& operator=(const Span& other) noexcept = default;
188
189 Span(Span&& other) noexcept = default;
190 Span& operator=(Span&& other) noexcept = default;
201 {
202 return data();
203 }
204
211 {
212 return data() + size();
213 }
214
221 {
222 return reverse_iterator(end());
223 }
224
231 {
232 return reverse_iterator(begin());
233 }
234
240 constexpr reference front() const
241 {
242 return data()[0];
243 }
244
250 constexpr reference back() const
251 {
252 return data()[size() - 1];
253 }
254
262 {
263 return data()[idx];
264 }
265
272 {
273 return m_storage.m_data;
274 }
275
282 {
283 return m_storage.m_size;
284 }
285
292 {
293 return size() * sizeof(element_type);
294 }
295
301 constexpr bool empty() const noexcept
302 {
303 return size() == 0;
304 }
305
311 template <size_type Count>
313 {
314 static_assert(Count <= Extent, "Requested number of characters out of range.");
316 }
317
328
334 template <size_type Count>
336 {
337 static_assert(Count <= Extent, "Requested number of characters out of range.");
338 return Span<element_type, Count>(data() + (size() - Count), Count);
339 }
340
351
352 template <size_type Offset, size_type Count>
355
363 typename std::enable_if<Count == dynamic_extent, int>::type = 0>
365 {
366 static_assert((Extent == dynamic_extent) || (Offset <= Extent),
367 "Requested number of characters out of range.");
369 }
370
371 template <size_type Offset, size_type Count,
372 typename std::enable_if<Count != dynamic_extent, int>::type = 0>
374 {
375 static_assert((Extent == dynamic_extent) || (Offset <= Extent && Offset + Count <= Extent),
376 "Requested number of characters out of range.");
378 }
394
395private:
396 detail::SpanStorage<T, Extent> m_storage;
397};
398
399} // namespace zserio
400
401#endif // ZSERIO_SPAN_H_INC
constexpr Span< element_type, Count > last() const
Definition Span.h:335
std::size_t size_type
Definition Span.h:63
constexpr Span(pointer first_, size_type count)
Definition Span.h:90
constexpr bool empty() const noexcept
Definition Span.h:301
const T * const_pointer
Definition Span.h:66
pointer iterator
Definition Span.h:68
constexpr reference front() const
Definition Span.h:240
constexpr Span() noexcept
Definition Span.h:80
Span(const Span &other) noexcept=default
constexpr size_type size() const noexcept
Definition Span.h:281
static constexpr size_type extent
Definition Span.h:73
Span & operator=(const Span &other) noexcept=default
constexpr Span(const Span< U, N > &span) noexcept
Definition Span.h:176
constexpr Span(pointer first_, pointer last_)
Definition Span.h:101
constexpr Span< element_type, dynamic_extent > last(size_type Count) const
Definition Span.h:347
constexpr reverse_iterator rbegin() const noexcept
Definition Span.h:220
std::ptrdiff_t difference_type
Definition Span.h:64
T element_type
Definition Span.h:61
constexpr reverse_iterator rend() const noexcept
Definition Span.h:230
const_pointer const_iterator
Definition Span.h:69
~Span()=default
constexpr reference back() const
Definition Span.h:250
constexpr Span< element_type, Count > first() const
Definition Span.h:312
constexpr Span(const std::vector< U, ALLOC > &vec)
Definition Span.h:163
constexpr pointer data() const noexcept
Definition Span.h:271
T * pointer
Definition Span.h:65
std::reverse_iterator< iterator > reverse_iterator
Definition Span.h:70
T & reference
Definition Span.h:67
constexpr SubspanReturnType< Offset, Count > subspan() const
Definition Span.h:364
typename std::remove_cv_t< T > value_type
Definition Span.h:62
Span(Span &&other) noexcept=default
constexpr size_type size_bytes() const noexcept
Definition Span.h:291
Span & operator=(Span &&other) noexcept=default
constexpr Span< element_type, dynamic_extent > first(size_type Count) const
Definition Span.h:324
constexpr Span(const std::array< U, N > &arr) noexcept
Definition Span.h:138
constexpr reference operator[](size_type idx) const
Definition Span.h:261
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition Span.h:71
constexpr Span(std::array< U, N > &arr) noexcept
Definition Span.h:125
constexpr Span(element_type(&arr)[N]) noexcept
Definition Span.h:112
constexpr Span(std::vector< U, ALLOC > &vec)
Definition Span.h:150
constexpr Span< element_type, dynamic_extent > subspan(size_type Offset, size_type Count=dynamic_extent) const
Definition Span.h:388
constexpr iterator end() const noexcept
Definition Span.h:210
constexpr iterator begin() const noexcept
Definition Span.h:200
constexpr std::size_t dynamic_extent
Definition Span.h:17