286 static_assert(std::is_object<ElementType>::value,
287 "A span's ElementType must be an object type (not a "
288 "reference type or void)");
290 "A span's ElementType must be a complete type (not a forward "
292 static_assert(!std::is_abstract<ElementType>::value,
293 "A span's ElementType cannot be an abstract class type");
299 using element_type = ElementType;
300 using value_type =
typename std::remove_cv<ElementType>::type;
301 using size_type = std::size_t;
302 using difference_type = std::ptrdiff_t;
303 using pointer = element_type*;
304 using const_pointer =
const element_type*;
305 using reference = element_type&;
306 using const_reference =
const element_type&;
307 using iterator = pointer;
308 using reverse_iterator = std::reverse_iterator<iterator>;
310 static constexpr size_type extent = Extent;
314 std::size_t E = Extent,
315 typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0>
316 constexpr span()
noexcept
319 TCB_SPAN_CONSTEXPR11
span(pointer ptr, size_type count)
320 : storage_(ptr, count)
322 TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
325 TCB_SPAN_CONSTEXPR11
span(pointer first_elem, pointer last_elem)
326 : storage_(first_elem, last_elem - first_elem)
328 TCB_SPAN_EXPECT(extent == dynamic_extent ||
329 last_elem - first_elem ==
330 static_cast<std::ptrdiff_t
>(extent));
333 template <std::size_t N, std::size_t E = Extent,
334 typename std::enable_if<
335 (E == dynamic_extent || N == E) &&
337 element_type (&)[N], ElementType>::value,
339 constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N)
342 template <
typename T, std::size_t N, std::size_t E = Extent,
343 typename std::enable_if<
344 (E == dynamic_extent || N == E) &&
346 std::array<T, N>&, ElementType>::value,
348 TCB_SPAN_ARRAY_CONSTEXPR
span(std::array<T, N>& arr) noexcept
349 : storage_(arr.data(), N)
352 template <
typename T, std::size_t N, std::size_t E = Extent,
353 typename std::enable_if<
354 (E == dynamic_extent || N == E) &&
356 const std::array<T, N>&, ElementType>::value,
358 TCB_SPAN_ARRAY_CONSTEXPR
span(
const std::array<T, N>& arr) noexcept
359 : storage_(arr.data(), N)
363 typename Container, std::size_t E = Extent,
364 typename std::enable_if<
367 Container&, ElementType>::value,
369 constexpr span(Container& cont)
370 : storage_(detail::data(cont), detail::size(cont))
374 typename Container, std::size_t E = Extent,
375 typename std::enable_if<
378 const Container&, ElementType>::value,
380 constexpr span(
const Container& cont)
381 : storage_(detail::data(cont), detail::size(cont))
384 constexpr span(
const span& other)
noexcept =
default;
386 template <
typename OtherElementType, std::size_t OtherExtent,
387 typename std::enable_if<
388 (Extent == dynamic_extent || OtherExtent == dynamic_extent ||
389 Extent == OtherExtent) &&
390 std::is_convertible<OtherElementType (*)[],
391 ElementType (*)[]>::value,
394 : storage_(other.data(), other.size())
397 ~span()
noexcept =
default;
399 TCB_SPAN_CONSTEXPR_ASSIGN
span&
400 operator=(
const span& other)
noexcept =
default;
403 template <std::
size_t Count>
406 TCB_SPAN_EXPECT(Count <= size());
407 return {data(), Count};
410 template <std::
size_t Count>
413 TCB_SPAN_EXPECT(Count <= size());
414 return {data() + (size() - Count), Count};
417 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
419 span<ElementType, Count != dynamic_extent
421 : (Extent != dynamic_extent ? Extent - Offset
424 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
427 TCB_SPAN_EXPECT(Offset <= size() &&
428 (Count == dynamic_extent || Offset + Count <= size()));
429 return {data() + Offset,
430 Count != dynamic_extent ? Count : size() - Offset};
434 first(size_type count)
const
436 TCB_SPAN_EXPECT(count <= size());
437 return {data(), count};
441 last(size_type count)
const
443 TCB_SPAN_EXPECT(count <= size());
444 return {data() + (size() - count), count};
448 subspan(size_type offset, size_type count = dynamic_extent)
const
450 TCB_SPAN_EXPECT(offset <= size() &&
451 (count == dynamic_extent || offset + count <= size()));
452 return {data() + offset,
453 count == dynamic_extent ? size() - offset : count};
457 constexpr size_type size()
const noexcept {
return storage_.size; }
459 constexpr size_type size_bytes()
const noexcept
461 return size() *
sizeof(element_type);
464 TCB_SPAN_NODISCARD
constexpr bool empty()
const noexcept
470 TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx)
const
472 TCB_SPAN_EXPECT(idx < size());
473 return *(data() + idx);
476 TCB_SPAN_CONSTEXPR11 reference front()
const
478 TCB_SPAN_EXPECT(!empty());
482 TCB_SPAN_CONSTEXPR11 reference back()
const
484 TCB_SPAN_EXPECT(!empty());
485 return *(data() + (size() - 1));
488 constexpr pointer data()
const noexcept {
return storage_.ptr; }
491 constexpr iterator begin()
const noexcept {
return data(); }
493 constexpr iterator end()
const noexcept {
return data() + size(); }
495 TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin()
const noexcept
497 return reverse_iterator(end());
500 TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend()
const noexcept
502 return reverse_iterator(begin());