248template <
typename ElementType, std::
size_t Extent>
class span {
249 static_assert(std::is_object<ElementType>::value,
"A span's ElementType must be an object type (not a "
250 "reference type or void)");
251 static_assert(::nonstd::detail::is_complete<ElementType>::value,
"A span's ElementType must be a complete type (not a forward "
253 static_assert(!std::is_abstract<ElementType>::value,
"A span's ElementType cannot be an abstract class type");
255 using storage_type = ::nonstd::detail::span_storage<ElementType, Extent>;
259 using element_type = ElementType;
260 using value_type =
typename std::remove_cv<ElementType>::type;
261 using size_type = std::size_t;
262 using difference_type = std::ptrdiff_t;
263 using pointer = element_type*;
264 using const_pointer =
const element_type*;
265 using reference = element_type&;
266 using const_reference =
const element_type&;
267 using iterator = pointer;
268 using reverse_iterator = std::reverse_iterator<iterator>;
270 static constexpr size_type extent = Extent;
273 template <std::
size_t E = Extent,
typename std::enable_if<(E == dynamic_extent || E <= 0),
int>::type = 0> constexpr span() noexcept {}
275 TCB_SPAN_CONSTEXPR11 span(po
inter ptr,
size_type count)
276 : storage_(ptr, count) {
277 TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
280 TCB_SPAN_CONSTEXPR11 span(po
inter first_elem, po
inter last_elem)
281 : storage_(first_elem, last_elem - first_elem) {
282 TCB_SPAN_EXPECT(extent == dynamic_extent || last_elem - first_elem == static_cast<std::ptrdiff_t>(extent));
285 template <std::
size_t N, std::
size_t E = Extent,
286 typename std::enable_if<(E == dynamic_extent || N == E) &&
287 ::nonstd::detail::is_container_element_type_compatible<element_type (&)[N], ElementType>::value,
289 constexpr span(element_type (&arr)[N]) noexcept
290 : storage_(arr, N) {}
292 template <
typename T, std::size_t N, std::size_t E = Extent,
293 typename std::enable_if<(E == dynamic_extent || N == E) &&
294 ::nonstd::detail::is_container_element_type_compatible<std::array<T, N>&, ElementType>::value,
296 TCB_SPAN_ARRAY_CONSTEXPR span(std::array<T, N>& arr) noexcept
297 : storage_(arr.data(), N) {}
299 template <
typename T, std::size_t N, std::size_t E = Extent,
300 typename std::enable_if<(E == dynamic_extent || N == E) && ::nonstd::detail::is_container_element_type_compatible<
301 const std::array<T, N>&, ElementType>::value,
303 TCB_SPAN_ARRAY_CONSTEXPR span(
const std::array<T, N>& arr) noexcept
304 : storage_(arr.data(), N) {}
306 template <
typename Container, std::size_t E = Extent,
307 typename std::enable_if<E == dynamic_extent&& ::nonstd::detail::is_container<Container>::value&& ::nonstd::detail::
308 is_container_element_type_compatible<Container&, ElementType>::value,
310 constexpr span(Container& cont)
311 : storage_(::nonstd::detail::data(cont), ::nonstd::detail::size(cont)) {}
313 template <
typename Container, std::size_t E = Extent,
314 typename std::enable_if<E == dynamic_extent&& ::nonstd::detail::is_container<Container>::value&& ::nonstd::detail::
315 is_container_element_type_compatible<const Container&, ElementType>::value,
317 constexpr span(
const Container& cont)
318 : storage_(::nonstd::detail::data(cont), ::nonstd::detail::size(cont)) {}
320 constexpr span(
const span& other)
noexcept =
default;
322 template <
typename OtherElementType, std::size_t OtherExtent,
323 typename std::enable_if<(Extent == dynamic_extent || OtherExtent == dynamic_extent || Extent == OtherExtent) &&
324 std::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value,
326 constexpr span(
const span<OtherElementType, OtherExtent>& other) noexcept
327 : storage_(other.data(), other.size()) {}
329 ~span()
noexcept =
default;
331 TCB_SPAN_CONSTEXPR_ASSIGN span& operator=(
const span& other)
noexcept =
default;
334 template <std::
size_t Count> TCB_SPAN_CONSTEXPR11 span<element_type, Count> first()
const {
335 TCB_SPAN_EXPECT(Count <= size());
336 return {data(), Count};
339 template <std::
size_t Count> TCB_SPAN_CONSTEXPR11 span<element_type, Count> last()
const {
340 TCB_SPAN_EXPECT(Count <= size());
341 return {data() + (size() - Count), Count};
344 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
345 using subspan_return_t =
346 span<ElementType, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)>;
348 template <std::
size_t Offset, std::
size_t Count = dynamic_extent> TCB_SPAN_CONSTEXPR11 subspan_return_t<Offset, Count> subspan()
const {
349 TCB_SPAN_EXPECT(Offset <= size() && (Count == dynamic_extent || Offset + Count <= size()));
350 return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset};
353 TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> first(size_type count)
const {
354 TCB_SPAN_EXPECT(count <= size());
355 return {data(), count};
358 TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> last(size_type count)
const {
359 TCB_SPAN_EXPECT(count <= size());
360 return {data() + (size() - count), count};
363 TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent)
const {
364 TCB_SPAN_EXPECT(offset <= size() && (count == dynamic_extent || offset + count <= size()));
365 return {data() + offset, count == dynamic_extent ? size() - offset : count};
369 constexpr size_type size()
const noexcept {
return storage_.size; }
371 constexpr size_type size_bytes()
const noexcept {
return size() *
sizeof(element_type); }
373 TCB_SPAN_NODISCARD
constexpr bool empty()
const noexcept {
return size() == 0; }
376 TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx)
const {
377 TCB_SPAN_EXPECT(idx < size());
378 return *(data() + idx);
381 TCB_SPAN_CONSTEXPR11 reference front()
const {
382 TCB_SPAN_EXPECT(!empty());
386 TCB_SPAN_CONSTEXPR11 reference back()
const {
387 TCB_SPAN_EXPECT(!empty());
388 return *(data() + (size() - 1));
391 constexpr pointer data()
const noexcept {
return storage_.ptr; }
394 constexpr iterator begin()
const noexcept {
return data(); }
396 constexpr iterator end()
const noexcept {
return data() + size(); }
398 TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin()
const noexcept {
return reverse_iterator(end()); }
400 TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend()
const noexcept {
return reverse_iterator(begin()); }
403 storage_type storage_{};