xref: /llvm-project-15.0.7/libcxx/include/span (revision d761fe6e)
18a0794b7SMarshall Clow// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
38a0794b7SMarshall Clow//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
78a0794b7SMarshall Clow//
88a0794b7SMarshall Clow//===---------------------------------------------------------------------===//
98a0794b7SMarshall Clow
108a0794b7SMarshall Clow#ifndef _LIBCPP_SPAN
118a0794b7SMarshall Clow#define _LIBCPP_SPAN
128a0794b7SMarshall Clow
138a0794b7SMarshall Clow/*
148a0794b7SMarshall Clow    span synopsis
158a0794b7SMarshall Clow
168a0794b7SMarshall Clownamespace std {
178a0794b7SMarshall Clow
188a0794b7SMarshall Clow// constants
197ad06a93SMarshall Clowinline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
208a0794b7SMarshall Clow
218a0794b7SMarshall Clow// [views.span], class template span
227ad06a93SMarshall Clowtemplate <class ElementType, size_t Extent = dynamic_extent>
238a0794b7SMarshall Clow    class span;
248a0794b7SMarshall Clow
2501ace074SMark de Wevertemplate<class ElementType, size_t Extent>
26462f8f06SChristopher Di Bella  inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
27462f8f06SChristopher Di Bella
28462f8f06SChristopher Di Bellatemplate<class ElementType, size_t Extent>
2901ace074SMark de Wever    inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
3001ace074SMark de Wever
318a0794b7SMarshall Clow// [span.objectrep], views of object representation
327ad06a93SMarshall Clowtemplate <class ElementType, size_t Extent>
338a0794b7SMarshall Clow    span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
348eda3ad2SMarshall Clow        (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
358a0794b7SMarshall Clow
367ad06a93SMarshall Clowtemplate <class ElementType, size_t Extent>
378a0794b7SMarshall Clow    span<      byte, ((Extent == dynamic_extent) ? dynamic_extent :
388eda3ad2SMarshall Clow        (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
398a0794b7SMarshall Clow
408a0794b7SMarshall Clow
417ad06a93SMarshall Clowtemplate <class ElementType, size_t Extent = dynamic_extent>
428a0794b7SMarshall Clowclass span {
438a0794b7SMarshall Clowpublic:
448a0794b7SMarshall Clow    // constants and types
458a0794b7SMarshall Clow    using element_type = ElementType;
468a0794b7SMarshall Clow    using value_type = remove_cv_t<ElementType>;
471466335cSLouis Dionne    using size_type = size_t;
488a0794b7SMarshall Clow    using difference_type = ptrdiff_t;
498a0794b7SMarshall Clow    using pointer = element_type*;
504fd03954SMarshall Clow    using const_pointer = const element_type*;
518a0794b7SMarshall Clow    using reference = element_type&;
524fd03954SMarshall Clow    using const_reference = const element_type&;
537ad06a93SMarshall Clow    using iterator = implementation-defined;
548a0794b7SMarshall Clow    using reverse_iterator = std::reverse_iterator<iterator>;
551466335cSLouis Dionne    static constexpr size_type extent = Extent;
568a0794b7SMarshall Clow
578a0794b7SMarshall Clow    // [span.cons], span constructors, copy, assignment, and destructor
588a0794b7SMarshall Clow    constexpr span() noexcept;
593a208c68SJoe Loser    template <class It>
603a208c68SJoe Loser    constexpr explicit(Extent != dynamic_extent) span(It first, size_type count);
613a208c68SJoe Loser    template <class It, class End>
623a208c68SJoe Loser    constexpr explicit(Extent != dynamic_extent) span(It first, End last);
638a0794b7SMarshall Clow    template <size_t N>
640412c007SArthur O'Dwyer        constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
658a0794b7SMarshall Clow    template <size_t N>
668a0794b7SMarshall Clow        constexpr span(array<value_type, N>& arr) noexcept;
678a0794b7SMarshall Clow    template <size_t N>
688a0794b7SMarshall Clow        constexpr span(const array<value_type, N>& arr) noexcept;
693a208c68SJoe Loser    template<class R>
703a208c68SJoe Loser      constexpr explicit(Extent != dynamic_extent) span(R&& r);
718a0794b7SMarshall Clow    constexpr span(const span& other) noexcept = default;
727ad06a93SMarshall Clow    template <class OtherElementType, size_t OtherExtent>
736d2599e4SMichael Schellenberger Costa        constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;
748a0794b7SMarshall Clow    ~span() noexcept = default;
758a0794b7SMarshall Clow    constexpr span& operator=(const span& other) noexcept = default;
768a0794b7SMarshall Clow
778a0794b7SMarshall Clow    // [span.sub], span subviews
787ad06a93SMarshall Clow    template <size_t Count>
798a0794b7SMarshall Clow        constexpr span<element_type, Count> first() const;
807ad06a93SMarshall Clow    template <size_t Count>
818a0794b7SMarshall Clow        constexpr span<element_type, Count> last() const;
827ad06a93SMarshall Clow    template <size_t Offset, size_t Count = dynamic_extent>
838a0794b7SMarshall Clow        constexpr span<element_type, see below> subspan() const;
848a0794b7SMarshall Clow
851466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> first(size_type count) const;
861466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> last(size_type count) const;
871466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const;
888a0794b7SMarshall Clow
898a0794b7SMarshall Clow    // [span.obs], span observers
901466335cSLouis Dionne    constexpr size_type size() const noexcept;
911466335cSLouis Dionne    constexpr size_type size_bytes() const noexcept;
928e92410eSJoe Loser    [[nodiscard]] constexpr bool empty() const noexcept;
938a0794b7SMarshall Clow
948a0794b7SMarshall Clow    // [span.elem], span element access
951466335cSLouis Dionne    constexpr reference operator[](size_type idx) const;
969ab85a69SMarshall Clow    constexpr reference front() const;
979ab85a69SMarshall Clow    constexpr reference back() const;
988a0794b7SMarshall Clow    constexpr pointer data() const noexcept;
998a0794b7SMarshall Clow
1008a0794b7SMarshall Clow    // [span.iterators], span iterator support
1018a0794b7SMarshall Clow    constexpr iterator begin() const noexcept;
1028a0794b7SMarshall Clow    constexpr iterator end() const noexcept;
1038a0794b7SMarshall Clow    constexpr reverse_iterator rbegin() const noexcept;
1048a0794b7SMarshall Clow    constexpr reverse_iterator rend() const noexcept;
1058a0794b7SMarshall Clow
1068a0794b7SMarshall Clowprivate:
1078a0794b7SMarshall Clow    pointer data_;    // exposition only
1081466335cSLouis Dionne    size_type size_;  // exposition only
1098a0794b7SMarshall Clow};
1108a0794b7SMarshall Clow
1113a208c68SJoe Losertemplate<class It, class EndOrSize>
1123a208c68SJoe Loser    span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;
1133a208c68SJoe Loser
1148a0794b7SMarshall Clowtemplate<class T, size_t N>
1158a0794b7SMarshall Clow    span(T (&)[N]) -> span<T, N>;
1168a0794b7SMarshall Clow
1178a0794b7SMarshall Clowtemplate<class T, size_t N>
1188a0794b7SMarshall Clow    span(array<T, N>&) -> span<T, N>;
1198a0794b7SMarshall Clow
1208a0794b7SMarshall Clowtemplate<class T, size_t N>
1218a0794b7SMarshall Clow    span(const array<T, N>&) -> span<const T, N>;
1228a0794b7SMarshall Clow
1233a208c68SJoe Losertemplate<class R>
1243a208c68SJoe Loser    span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
1258a0794b7SMarshall Clow
1268a0794b7SMarshall Clow} // namespace std
1278a0794b7SMarshall Clow
1288a0794b7SMarshall Clow*/
1298a0794b7SMarshall Clow
130385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
13135773f55SMarshall Clow#include <__config>
13206b40e80SArthur O'Dwyer#include <__debug>
1339924d8d6SKonstantin Varlamov#include <__fwd/span.h>
134633d1d0dSLouis Dionne#include <__iterator/bounded_iter.h>
1353a208c68SJoe Loser#include <__iterator/concepts.h>
1363cd4531bSNikolas Klauser#include <__iterator/iterator_traits.h>
137f32f3db9SLouis Dionne#include <__iterator/wrap_iter.h>
1383cd4531bSNikolas Klauser#include <__memory/pointer_traits.h>
1393a208c68SJoe Loser#include <__ranges/concepts.h>
1403a208c68SJoe Loser#include <__ranges/data.h>
14101ace074SMark de Wever#include <__ranges/enable_borrowed_range.h>
142462f8f06SChristopher Di Bella#include <__ranges/enable_view.h>
1433a208c68SJoe Loser#include <__ranges/size.h>
144643df8faSLouis Dionne#include <__utility/forward.h>
1458a0794b7SMarshall Clow#include <array>        // for array
1468a0794b7SMarshall Clow#include <cstddef>      // for byte
14769d5a666SChristopher Di Bella#include <limits>
148edbaa7fcSLouis Dionne#include <type_traits>  // for remove_cv, etc
149e37bbfe5SChristopher Di Bella#include <version>
1508a0794b7SMarshall Clow
151de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
152de4a57cbSLouis Dionne#  include <functional>
153de4a57cbSLouis Dionne#  include <iterator>
154de4a57cbSLouis Dionne#endif
155de4a57cbSLouis Dionne
156db1978b6SNikolas Klauser// standard-mandated includes
157db1978b6SNikolas Klauser
158db1978b6SNikolas Klauser// [iterator.range]
159db1978b6SNikolas Klauser#include <__iterator/access.h>
160db1978b6SNikolas Klauser#include <__iterator/data.h>
161db1978b6SNikolas Klauser#include <__iterator/empty.h>
162db1978b6SNikolas Klauser#include <__iterator/reverse_access.h>
163db1978b6SNikolas Klauser#include <__iterator/size.h>
164db1978b6SNikolas Klauser
1658a0794b7SMarshall Clow#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1668a0794b7SMarshall Clow#  pragma GCC system_header
1678a0794b7SMarshall Clow#endif
1688a0794b7SMarshall Clow
16903ee4612SArthur O'Dwyer_LIBCPP_PUSH_MACROS
17003ee4612SArthur O'Dwyer#include <__undef_macros>
17103ee4612SArthur O'Dwyer
1728a0794b7SMarshall Clow_LIBCPP_BEGIN_NAMESPACE_STD
1738a0794b7SMarshall Clow
1748a0794b7SMarshall Clow#if _LIBCPP_STD_VER > 17
1758a0794b7SMarshall Clow
1768a0794b7SMarshall Clowtemplate <class _Tp>
1773a208c68SJoe Loserstruct __is_std_array : false_type {};
1788a0794b7SMarshall Clow
1798a0794b7SMarshall Clowtemplate <class _Tp, size_t _Sz>
1803a208c68SJoe Loserstruct __is_std_array<array<_Tp, _Sz>> : true_type {};
1818a0794b7SMarshall Clow
1828a0794b7SMarshall Clowtemplate <class _Tp>
1833a208c68SJoe Loserstruct __is_std_span : false_type {};
1848a0794b7SMarshall Clow
1853a208c68SJoe Losertemplate <class _Tp, size_t _Sz>
1863a208c68SJoe Loserstruct __is_std_span<span<_Tp, _Sz>> : true_type {};
1878a0794b7SMarshall Clow
188d4c39f1aSLouis Dionne#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
189d4c39f1aSLouis Dionne// This is a temporary workaround until we ship <ranges> -- we've unfortunately been
190d4c39f1aSLouis Dionne// shipping <span> before its API was finalized, and we used to provide a constructor
191d4c39f1aSLouis Dionne// from container types that had the requirements below. To avoid breaking code that
192d4c39f1aSLouis Dionne// has started relying on the range-based constructor until we ship all of <ranges>,
193d4c39f1aSLouis Dionne// we emulate the constructor requirements like this.
194d4c39f1aSLouis Dionnetemplate <class _Range, class _ElementType>
195d4c39f1aSLouis Dionneconcept __span_compatible_range =
196d4c39f1aSLouis Dionne  !__is_std_span<remove_cvref_t<_Range>>::value  &&
197d4c39f1aSLouis Dionne  !__is_std_array<remove_cvref_t<_Range>>::value &&
198d4c39f1aSLouis Dionne  !is_array_v<remove_cvref_t<_Range>> &&
199d4c39f1aSLouis Dionne  requires (_Range&& __r) {
200d4c39f1aSLouis Dionne      data(std::forward<_Range>(__r));
201d4c39f1aSLouis Dionne      size(std::forward<_Range>(__r));
202d4c39f1aSLouis Dionne  } &&
203d4c39f1aSLouis Dionne  is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>;
204d4c39f1aSLouis Dionne#else
2053a208c68SJoe Losertemplate <class _Range, class _ElementType>
2063a208c68SJoe Loserconcept __span_compatible_range =
2073a208c68SJoe Loser  ranges::contiguous_range<_Range> &&
2083a208c68SJoe Loser  ranges::sized_range<_Range> &&
2093a208c68SJoe Loser  (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) &&
2103a208c68SJoe Loser  !__is_std_span<remove_cvref_t<_Range>>::value  &&
2113a208c68SJoe Loser  !__is_std_array<remove_cvref_t<_Range>>::value &&
2123a208c68SJoe Loser  !is_array_v<remove_cvref_t<_Range>> &&
2133a208c68SJoe Loser  is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>;
214849e749dSLouis Dionne#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
2158a0794b7SMarshall Clow
216cb48ed38SJoe Losertemplate <class _From, class _To>
217cb48ed38SJoe Loserconcept __span_array_convertible = is_convertible_v<_From(*)[], _To(*)[]>;
218cb48ed38SJoe Loser
219cb48ed38SJoe Losertemplate <class _It, class _Tp>
220cb48ed38SJoe Loserconcept __span_compatible_iterator = contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>;
221cb48ed38SJoe Loser
222cb48ed38SJoe Losertemplate <class _Sentinel, class _It>
223cb48ed38SJoe Loserconcept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>;
224cb48ed38SJoe Loser
2257ad06a93SMarshall Clowtemplate <typename _Tp, size_t _Extent>
2268a0794b7SMarshall Clowclass _LIBCPP_TEMPLATE_VIS span {
2278a0794b7SMarshall Clowpublic:
2288a0794b7SMarshall Clow//  constants and types
2298a0794b7SMarshall Clow    using element_type           = _Tp;
2308a0794b7SMarshall Clow    using value_type             = remove_cv_t<_Tp>;
2311466335cSLouis Dionne    using size_type              = size_t;
2328a0794b7SMarshall Clow    using difference_type        = ptrdiff_t;
2338a0794b7SMarshall Clow    using pointer                = _Tp *;
2344fd03954SMarshall Clow    using const_pointer          = const _Tp *;
2358a0794b7SMarshall Clow    using reference              = _Tp &;
2364fd03954SMarshall Clow    using const_reference        = const _Tp &;
237633d1d0dSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
238633d1d0dSLouis Dionne    using iterator               = __bounded_iter<pointer>;
2396946f0ecSArthur O'Dwyer#else
2408a0794b7SMarshall Clow    using iterator               = __wrap_iter<pointer>;
2416946f0ecSArthur O'Dwyer#endif
2428a0794b7SMarshall Clow    using reverse_iterator       = _VSTD::reverse_iterator<iterator>;
2438a0794b7SMarshall Clow
2441466335cSLouis Dionne    static constexpr size_type extent = _Extent;
2458a0794b7SMarshall Clow
2468a0794b7SMarshall Clow// [span.cons], span constructors, copy, assignment, and destructor
247cb48ed38SJoe Loser    template <size_t _Sz = _Extent> requires(_Sz == 0)
24879941086SMichael Schellenberger Costa    _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {}
2498a0794b7SMarshall Clow
2508a0794b7SMarshall Clow    constexpr span           (const span&) noexcept = default;
2518a0794b7SMarshall Clow    constexpr span& operator=(const span&) noexcept = default;
2528a0794b7SMarshall Clow
253cb48ed38SJoe Loser    template <__span_compatible_iterator<element_type> _It>
2543a208c68SJoe Loser    _LIBCPP_INLINE_VISIBILITY
2553a208c68SJoe Loser    constexpr explicit span(_It __first, size_type __count)
2563a208c68SJoe Loser        : __data{_VSTD::to_address(__first)} {
2573a208c68SJoe Loser      (void)__count;
2583a208c68SJoe Loser      _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
2593a208c68SJoe Loser    }
2603a208c68SJoe Loser
261cb48ed38SJoe Loser    template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
2623a208c68SJoe Loser    _LIBCPP_INLINE_VISIBILITY
2633a208c68SJoe Loser    constexpr explicit span(_It __first, _End __last) : __data{_VSTD::to_address(__first)} {
2643a208c68SJoe Loser      (void)__last;
2653a208c68SJoe Loser      _LIBCPP_ASSERT((__last - __first >= 0), "invalid range in span's constructor (iterator, sentinel)");
2663a208c68SJoe Loser      _LIBCPP_ASSERT(__last - __first == _Extent,
2673a208c68SJoe Loser                     "invalid range in span's constructor (iterator, sentinel): last - first != extent");
2683a208c68SJoe Loser    }
2698a0794b7SMarshall Clow
2700412c007SArthur O'Dwyer    _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data{__arr} {}
271ab9f1116SMichael Schellenberger Costa
272cb48ed38SJoe Loser    template <__span_array_convertible<element_type> _OtherElementType>
273ab9f1116SMichael Schellenberger Costa    _LIBCPP_INLINE_VISIBILITY
274ab9f1116SMichael Schellenberger Costa    constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
275ab9f1116SMichael Schellenberger Costa
276cb48ed38SJoe Loser    template <class _OtherElementType>
277cb48ed38SJoe Loser        requires __span_array_convertible<const _OtherElementType, element_type>
278ab9f1116SMichael Schellenberger Costa    _LIBCPP_INLINE_VISIBILITY
279ab9f1116SMichael Schellenberger Costa    constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
2808a0794b7SMarshall Clow
281d4c39f1aSLouis Dionne#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
282d4c39f1aSLouis Dionne    template <class _Container>
283d4c39f1aSLouis Dionne        requires __span_compatible_range<_Container, element_type>
284d4c39f1aSLouis Dionne    _LIBCPP_INLINE_VISIBILITY
285d4c39f1aSLouis Dionne    constexpr explicit span(_Container& __c) : __data{std::data(__c)} {
286d4c39f1aSLouis Dionne      _LIBCPP_ASSERT(std::size(__c) == _Extent, "size mismatch in span's constructor (range)");
287d4c39f1aSLouis Dionne    }
288d4c39f1aSLouis Dionne    template <class _Container>
289d4c39f1aSLouis Dionne        requires __span_compatible_range<const _Container, element_type>
290d4c39f1aSLouis Dionne    _LIBCPP_INLINE_VISIBILITY
291d4c39f1aSLouis Dionne    constexpr explicit span(const _Container& __c) : __data{std::data(__c)} {
292d4c39f1aSLouis Dionne      _LIBCPP_ASSERT(std::size(__c) == _Extent, "size mismatch in span's constructor (range)");
293d4c39f1aSLouis Dionne    }
294d4c39f1aSLouis Dionne#else
2953a208c68SJoe Loser    template <__span_compatible_range<element_type> _Range>
2966d2599e4SMichael Schellenberger Costa    _LIBCPP_INLINE_VISIBILITY
2973a208c68SJoe Loser    constexpr explicit span(_Range&& __r) : __data{ranges::data(__r)} {
2983a208c68SJoe Loser      _LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
2996d2599e4SMichael Schellenberger Costa    }
300849e749dSLouis Dionne#endif
3016d2599e4SMichael Schellenberger Costa
302cb48ed38SJoe Loser    template <__span_array_convertible<element_type> _OtherElementType>
3038eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
304cb48ed38SJoe Loser        constexpr span(const span<_OtherElementType, _Extent>& __other)
3058a0794b7SMarshall Clow        : __data{__other.data()} {}
3068a0794b7SMarshall Clow
307cb48ed38SJoe Loser    template <__span_array_convertible<element_type> _OtherElementType>
3088eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
309cb48ed38SJoe Loser        constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept
3108a0794b7SMarshall Clow        : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
3118a0794b7SMarshall Clow
3128a0794b7SMarshall Clow
3138a0794b7SMarshall Clow//  ~span() noexcept = default;
3148a0794b7SMarshall Clow
3157ad06a93SMarshall Clow    template <size_t _Count>
3168eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
3178a0794b7SMarshall Clow    constexpr span<element_type, _Count> first() const noexcept
3188a0794b7SMarshall Clow    {
319633d1d0dSLouis Dionne        static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range");
3206d2599e4SMichael Schellenberger Costa        return span<element_type, _Count>{data(), _Count};
3218a0794b7SMarshall Clow    }
3228a0794b7SMarshall Clow
3237ad06a93SMarshall Clow    template <size_t _Count>
3248eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
3258a0794b7SMarshall Clow    constexpr span<element_type, _Count> last() const noexcept
3268a0794b7SMarshall Clow    {
327633d1d0dSLouis Dionne        static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range");
3286d2599e4SMichael Schellenberger Costa        return span<element_type, _Count>{data() + size() - _Count, _Count};
3298a0794b7SMarshall Clow    }
3308a0794b7SMarshall Clow
3318a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
3321466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
3338a0794b7SMarshall Clow    {
334633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size(), "span<T, N>::first(count): count out of range");
3358a0794b7SMarshall Clow        return {data(), __count};
3368a0794b7SMarshall Clow    }
3378a0794b7SMarshall Clow
3388a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
3391466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept
3408a0794b7SMarshall Clow    {
341633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size(), "span<T, N>::last(count): count out of range");
3428a0794b7SMarshall Clow        return {data() + size() - __count, __count};
3438a0794b7SMarshall Clow    }
3448a0794b7SMarshall Clow
3457ad06a93SMarshall Clow    template <size_t _Offset, size_t _Count = dynamic_extent>
3468eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
3478a0794b7SMarshall Clow    constexpr auto subspan() const noexcept
3488a0794b7SMarshall Clow        -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
3498a0794b7SMarshall Clow    {
350633d1d0dSLouis Dionne        static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range");
351633d1d0dSLouis Dionne        static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range");
3526d2599e4SMichael Schellenberger Costa
3536d2599e4SMichael Schellenberger Costa        using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>;
3546d2599e4SMichael Schellenberger Costa        return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
3558a0794b7SMarshall Clow    }
3568a0794b7SMarshall Clow
3578a0794b7SMarshall Clow
3588eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
3598a0794b7SMarshall Clow    constexpr span<element_type, dynamic_extent>
3601466335cSLouis Dionne       subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
3618a0794b7SMarshall Clow    {
362633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");
363633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count  <= size() || __count == dynamic_extent, "span<T, N>::subspan(offset, count): count out of range");
3648a0794b7SMarshall Clow        if (__count == dynamic_extent)
3658a0794b7SMarshall Clow            return {data() + __offset, size() - __offset};
366633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");
3678a0794b7SMarshall Clow        return {data() + __offset, __count};
3688a0794b7SMarshall Clow    }
3698a0794b7SMarshall Clow
3701466335cSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr size_type size()           const noexcept { return _Extent; }
3711466335cSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes()     const noexcept { return _Extent * sizeof(element_type); }
3728e92410eSJoe Loser    [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; }
3738a0794b7SMarshall Clow
3741466335cSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
3758a0794b7SMarshall Clow    {
376633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__idx < size(), "span<T, N>::operator[](index): index out of range");
3778a0794b7SMarshall Clow        return __data[__idx];
3788a0794b7SMarshall Clow    }
3798a0794b7SMarshall Clow
3809ab85a69SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
3818a0794b7SMarshall Clow    {
3820a0e0afaSLouis Dionne        _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");
3839ab85a69SMarshall Clow        return __data[0];
3849ab85a69SMarshall Clow    }
3859ab85a69SMarshall Clow
3869ab85a69SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
3879ab85a69SMarshall Clow    {
3880a0e0afaSLouis Dionne        _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");
3899ab85a69SMarshall Clow        return __data[size()-1];
3908a0794b7SMarshall Clow    }
3918a0794b7SMarshall Clow
3928a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr pointer data()                         const noexcept { return __data; }
3938a0794b7SMarshall Clow
3948a0794b7SMarshall Clow// [span.iter], span iterator support
3954eab04f8SLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
396633d1d0dSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
397633d1d0dSLouis Dionne        return std::__make_bounded_iter(data(), data(), data() + size());
3984eab04f8SLouis Dionne#else
3994eab04f8SLouis Dionne        return iterator(this, data());
4004eab04f8SLouis Dionne#endif
4014eab04f8SLouis Dionne    }
4024eab04f8SLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
403633d1d0dSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
404633d1d0dSLouis Dionne        return std::__make_bounded_iter(data() + size(), data(), data() + size());
4054eab04f8SLouis Dionne#else
4064eab04f8SLouis Dionne        return iterator(this, data() + size());
4074eab04f8SLouis Dionne#endif
4084eab04f8SLouis Dionne    }
4098a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator        rbegin() const noexcept { return reverse_iterator(end()); }
4108a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator          rend() const noexcept { return reverse_iterator(begin()); }
4118a0794b7SMarshall Clow
4128a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept
4136d2599e4SMichael Schellenberger Costa    { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; }
4148a0794b7SMarshall Clow
4157cd0dad8SLouis Dionne    _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept
4166d2599e4SMichael Schellenberger Costa    { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; }
4178a0794b7SMarshall Clow
4188a0794b7SMarshall Clowprivate:
4198a0794b7SMarshall Clow    pointer    __data;
4208a0794b7SMarshall Clow};
4218a0794b7SMarshall Clow
4228a0794b7SMarshall Clow
4238a0794b7SMarshall Clowtemplate <typename _Tp>
4248a0794b7SMarshall Clowclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> {
4258a0794b7SMarshall Clowpublic:
4268a0794b7SMarshall Clow//  constants and types
4278a0794b7SMarshall Clow    using element_type           = _Tp;
4288a0794b7SMarshall Clow    using value_type             = remove_cv_t<_Tp>;
4291466335cSLouis Dionne    using size_type              = size_t;
4308a0794b7SMarshall Clow    using difference_type        = ptrdiff_t;
4318a0794b7SMarshall Clow    using pointer                = _Tp *;
4324fd03954SMarshall Clow    using const_pointer          = const _Tp *;
4338a0794b7SMarshall Clow    using reference              = _Tp &;
4344fd03954SMarshall Clow    using const_reference        = const _Tp &;
435633d1d0dSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
436633d1d0dSLouis Dionne    using iterator               = __bounded_iter<pointer>;
4376946f0ecSArthur O'Dwyer#else
4388a0794b7SMarshall Clow    using iterator               = __wrap_iter<pointer>;
4396946f0ecSArthur O'Dwyer#endif
4408a0794b7SMarshall Clow    using reverse_iterator       = _VSTD::reverse_iterator<iterator>;
4418a0794b7SMarshall Clow
4421466335cSLouis Dionne    static constexpr size_type extent = dynamic_extent;
4438a0794b7SMarshall Clow
4448a0794b7SMarshall Clow// [span.cons], span constructors, copy, assignment, and destructor
4458a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {}
4468a0794b7SMarshall Clow
4478a0794b7SMarshall Clow    constexpr span           (const span&) noexcept = default;
4488a0794b7SMarshall Clow    constexpr span& operator=(const span&) noexcept = default;
4498a0794b7SMarshall Clow
450cb48ed38SJoe Loser    template <__span_compatible_iterator<element_type> _It>
4513a208c68SJoe Loser    _LIBCPP_INLINE_VISIBILITY
4523a208c68SJoe Loser    constexpr span(_It __first, size_type __count)
4533a208c68SJoe Loser        : __data{_VSTD::to_address(__first)}, __size{__count} {}
4543a208c68SJoe Loser
455cb48ed38SJoe Loser    template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
456*d761fe6eSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last)
457*d761fe6eSLouis Dionne        : __data(_VSTD::to_address(__first)), __size(__last - __first) {
458*d761fe6eSLouis Dionne      _LIBCPP_ASSERT(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)");
459*d761fe6eSLouis Dionne    }
4608a0794b7SMarshall Clow
4618a0794b7SMarshall Clow    template <size_t _Sz>
4628eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4630412c007SArthur O'Dwyer    constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
4648a0794b7SMarshall Clow
465cb48ed38SJoe Loser    template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz>
4668eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
467ab9f1116SMichael Schellenberger Costa    constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
4688a0794b7SMarshall Clow
469cb48ed38SJoe Loser    template <class _OtherElementType, size_t _Sz>
470cb48ed38SJoe Loser        requires __span_array_convertible<const _OtherElementType, element_type>
4718eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
472ab9f1116SMichael Schellenberger Costa    constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
4738a0794b7SMarshall Clow
474d4c39f1aSLouis Dionne#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
475d4c39f1aSLouis Dionne    template <class _Container>
476d4c39f1aSLouis Dionne        requires __span_compatible_range<_Container, element_type>
477d4c39f1aSLouis Dionne    _LIBCPP_INLINE_VISIBILITY
478d4c39f1aSLouis Dionne    constexpr span(_Container& __c) : __data(std::data(__c)), __size{std::size(__c)} {}
479d4c39f1aSLouis Dionne    template <class _Container>
480d4c39f1aSLouis Dionne        requires __span_compatible_range<const _Container, element_type>
481d4c39f1aSLouis Dionne    _LIBCPP_INLINE_VISIBILITY
482d4c39f1aSLouis Dionne    constexpr span(const _Container& __c) : __data(std::data(__c)), __size{std::size(__c)} {}
483d4c39f1aSLouis Dionne#else
4843a208c68SJoe Loser    template <__span_compatible_range<element_type> _Range>
4858eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4863a208c68SJoe Loser    constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {}
487849e749dSLouis Dionne#endif
4888a0794b7SMarshall Clow
489cb48ed38SJoe Loser    template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent>
4908eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
491cb48ed38SJoe Loser        constexpr span(const span<_OtherElementType, _OtherExtent>& __other)  noexcept
4928a0794b7SMarshall Clow        : __data{__other.data()}, __size{__other.size()} {}
4938a0794b7SMarshall Clow
4948a0794b7SMarshall Clow//    ~span() noexcept = default;
4958a0794b7SMarshall Clow
4967ad06a93SMarshall Clow    template <size_t _Count>
4978eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4988a0794b7SMarshall Clow    constexpr span<element_type, _Count> first() const noexcept
4998a0794b7SMarshall Clow    {
500633d1d0dSLouis Dionne        _LIBCPP_ASSERT(_Count <= size(), "span<T>::first<Count>(): Count out of range");
5016d2599e4SMichael Schellenberger Costa        return span<element_type, _Count>{data(), _Count};
5028a0794b7SMarshall Clow    }
5038a0794b7SMarshall Clow
5047ad06a93SMarshall Clow    template <size_t _Count>
5058eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
5068a0794b7SMarshall Clow    constexpr span<element_type, _Count> last() const noexcept
5078a0794b7SMarshall Clow    {
508633d1d0dSLouis Dionne        _LIBCPP_ASSERT(_Count <= size(), "span<T>::last<Count>(): Count out of range");
5096d2599e4SMichael Schellenberger Costa        return span<element_type, _Count>{data() + size() - _Count, _Count};
5108a0794b7SMarshall Clow    }
5118a0794b7SMarshall Clow
5128a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
5131466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept
5148a0794b7SMarshall Clow    {
515633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size(), "span<T>::first(count): count out of range");
5168a0794b7SMarshall Clow        return {data(), __count};
5178a0794b7SMarshall Clow    }
5188a0794b7SMarshall Clow
5198a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
5201466335cSLouis Dionne    constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept
5218a0794b7SMarshall Clow    {
522633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size(), "span<T>::last(count): count out of range");
5238a0794b7SMarshall Clow        return {data() + size() - __count, __count};
5248a0794b7SMarshall Clow    }
5258a0794b7SMarshall Clow
5267ad06a93SMarshall Clow    template <size_t _Offset, size_t _Count = dynamic_extent>
5278eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
52892a1f65fSLouis Dionne    constexpr span<element_type, _Count> subspan() const noexcept
5298a0794b7SMarshall Clow    {
530633d1d0dSLouis Dionne        _LIBCPP_ASSERT(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");
531633d1d0dSLouis Dionne        _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
5326d2599e4SMichael Schellenberger Costa        return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
5338a0794b7SMarshall Clow    }
5348a0794b7SMarshall Clow
5358a0794b7SMarshall Clow    constexpr span<element_type, dynamic_extent>
5368eda3ad2SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
5371466335cSLouis Dionne    subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept
5388a0794b7SMarshall Clow    {
539633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");
540633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T>::subspan(offset, count): count out of range");
5418a0794b7SMarshall Clow        if (__count == dynamic_extent)
5428a0794b7SMarshall Clow            return {data() + __offset, size() - __offset};
543633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");
5448a0794b7SMarshall Clow        return {data() + __offset, __count};
5458a0794b7SMarshall Clow    }
5468a0794b7SMarshall Clow
5471466335cSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr size_type size()           const noexcept { return __size; }
5481466335cSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes()     const noexcept { return __size * sizeof(element_type); }
5498e92410eSJoe Loser    [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; }
5508a0794b7SMarshall Clow
5511466335cSLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
5528a0794b7SMarshall Clow    {
553633d1d0dSLouis Dionne        _LIBCPP_ASSERT(__idx < size(), "span<T>::operator[](index): index out of range");
5548a0794b7SMarshall Clow        return __data[__idx];
5558a0794b7SMarshall Clow    }
5568a0794b7SMarshall Clow
5579ab85a69SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
5588a0794b7SMarshall Clow    {
559633d1d0dSLouis Dionne        _LIBCPP_ASSERT(!empty(), "span<T>::front() on empty span");
5609ab85a69SMarshall Clow        return __data[0];
5618a0794b7SMarshall Clow    }
5628a0794b7SMarshall Clow
5639ab85a69SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
5649ab85a69SMarshall Clow    {
565633d1d0dSLouis Dionne        _LIBCPP_ASSERT(!empty(), "span<T>::back() on empty span");
5669ab85a69SMarshall Clow        return __data[size()-1];
5679ab85a69SMarshall Clow    }
5689ab85a69SMarshall Clow
5699ab85a69SMarshall Clow
5708a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr pointer data()                         const noexcept { return __data; }
5718a0794b7SMarshall Clow
5728a0794b7SMarshall Clow// [span.iter], span iterator support
5734eab04f8SLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
574633d1d0dSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
575633d1d0dSLouis Dionne        return std::__make_bounded_iter(data(), data(), data() + size());
5764eab04f8SLouis Dionne#else
5774eab04f8SLouis Dionne        return iterator(this, data());
5784eab04f8SLouis Dionne#endif
5794eab04f8SLouis Dionne    }
5804eab04f8SLouis Dionne    _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept {
581633d1d0dSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
582633d1d0dSLouis Dionne        return std::__make_bounded_iter(data() + size(), data(), data() + size());
5834eab04f8SLouis Dionne#else
5844eab04f8SLouis Dionne        return iterator(this, data() + size());
5854eab04f8SLouis Dionne#endif
5864eab04f8SLouis Dionne    }
5878a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator        rbegin() const noexcept { return reverse_iterator(end()); }
5888a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator          rend() const noexcept { return reverse_iterator(begin()); }
5898a0794b7SMarshall Clow
5908a0794b7SMarshall Clow    _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept
5918a0794b7SMarshall Clow    { return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
5928a0794b7SMarshall Clow
5937cd0dad8SLouis Dionne    _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept
5948a0794b7SMarshall Clow    { return {reinterpret_cast<byte *>(data()), size_bytes()}; }
5958a0794b7SMarshall Clow
5968a0794b7SMarshall Clowprivate:
5978a0794b7SMarshall Clow    pointer   __data;
5981466335cSLouis Dionne    size_type __size;
5998a0794b7SMarshall Clow};
6008a0794b7SMarshall Clow
60101ace074SMark de Wevertemplate <class _Tp, size_t _Extent>
60201ace074SMark de Weverinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
603462f8f06SChristopher Di Bella
604462f8f06SChristopher Di Bellatemplate <class _ElementType, size_t _Extent>
605462f8f06SChristopher Di Bellainline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
60601ace074SMark de Wever
6077cd0dad8SLouis Dionne//  as_bytes & as_writable_bytes
6087ad06a93SMarshall Clowtemplate <class _Tp, size_t _Extent>
60902e1651cSMarshall Clow_LIBCPP_INLINE_VISIBILITY
6108a0794b7SMarshall Clowauto as_bytes(span<_Tp, _Extent> __s) noexcept
6118a0794b7SMarshall Clow{ return __s.__as_bytes(); }
6128a0794b7SMarshall Clow
613cb48ed38SJoe Losertemplate <class _Tp, size_t _Extent> requires(!is_const_v<_Tp>)
61402e1651cSMarshall Clow_LIBCPP_INLINE_VISIBILITY
6157cd0dad8SLouis Dionneauto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
6167cd0dad8SLouis Dionne{ return __s.__as_writable_bytes(); }
6178a0794b7SMarshall Clow
618d2baefaeSJoe Loser#if _LIBCPP_STD_VER > 17
6193a208c68SJoe Losertemplate<contiguous_iterator _It, class _EndOrSize>
6203a208c68SJoe Loser    span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;
621d2baefaeSJoe Loser#endif // _LIBCPP_STD_VER > 17
6223a208c68SJoe Loser
6238a0794b7SMarshall Clowtemplate<class _Tp, size_t _Sz>
6248a0794b7SMarshall Clow    span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
6258a0794b7SMarshall Clow
6268a0794b7SMarshall Clowtemplate<class _Tp, size_t _Sz>
6278a0794b7SMarshall Clow    span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>;
6288a0794b7SMarshall Clow
6298a0794b7SMarshall Clowtemplate<class _Tp, size_t _Sz>
6308a0794b7SMarshall Clow    span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
6318a0794b7SMarshall Clow
6326a7f0551SLouis Dionne#if defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
6336a7f0551SLouis Dionnetemplate<class _Container>
6346a7f0551SLouis Dionne    span(_Container&) -> span<typename _Container::value_type>;
6356a7f0551SLouis Dionne
6366a7f0551SLouis Dionnetemplate<class _Container>
6376a7f0551SLouis Dionne    span(const _Container&) -> span<const typename _Container::value_type>;
6386a7f0551SLouis Dionne#else
6393a208c68SJoe Losertemplate<ranges::contiguous_range _Range>
6403a208c68SJoe Loser    span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>;
6413a208c68SJoe Loser#endif
6428a0794b7SMarshall Clow
64335773f55SMarshall Clow#endif // _LIBCPP_STD_VER > 17
64435773f55SMarshall Clow
6458a0794b7SMarshall Clow_LIBCPP_END_NAMESPACE_STD
6468a0794b7SMarshall Clow
64703ee4612SArthur O'Dwyer_LIBCPP_POP_MACROS
64803ee4612SArthur O'Dwyer
6498a0794b7SMarshall Clow#endif // _LIBCPP_SPAN
650