// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===---------------------------------------------------------------------===// #ifndef _LIBCPP_SPAN #define _LIBCPP_SPAN /* span synopsis namespace std { // constants inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); template<class T> concept integral-constant-like = // exposition only, since C++26 is_integral_v<decltype(T::value)> && !is_same_v<bool, remove_const_t<decltype(T::value)>> && convertible_to<T, decltype(T::value)> && equality_comparable_with<T, decltype(T::value)> && bool_constant<T() == T::value>::value && bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value; template<class T> constexpr size_t maybe-static-ext = dynamic_extent; // exposition only, since C++26 template<integral-constant-like T> constexpr size_t maybe-static-ext<T> = {T::value}; // [views.span], class template span template <class ElementType, size_t Extent = dynamic_extent> class span; template<class ElementType, size_t Extent> inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; template<class ElementType, size_t Extent> inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; // [span.objectrep], views of object representation template <class ElementType, size_t Extent> span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; template <class ElementType, size_t Extent> span< byte, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; template <class ElementType, size_t Extent = dynamic_extent> class span { public: // constants and types using element_type = ElementType; using value_type = remove_cv_t<ElementType>; using size_type = size_t; using difference_type = ptrdiff_t; using pointer = element_type*; using const_pointer = const element_type*; using reference = element_type&; using const_reference = const element_type&; using iterator = implementation-defined; using reverse_iterator = std::reverse_iterator<iterator>; static constexpr size_type extent = Extent; // [span.cons], span constructors, copy, assignment, and destructor constexpr span() noexcept; template <class It> constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); template <class It, class End> constexpr explicit(Extent != dynamic_extent) span(It first, End last); template <size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; template <size_t N> constexpr span(array<value_type, N>& arr) noexcept; template <size_t N> constexpr span(const array<value_type, N>& arr) noexcept; template<class R> constexpr explicit(Extent != dynamic_extent) span(R&& r); constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26 constexpr span(const span& other) noexcept = default; template <class OtherElementType, size_t OtherExtent> constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; constexpr span& operator=(const span& other) noexcept = default; // [span.sub], span subviews template <size_t Count> constexpr span<element_type, Count> first() const; template <size_t Count> constexpr span<element_type, Count> last() const; template <size_t Offset, size_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const; constexpr span<element_type, dynamic_extent> first(size_type count) const; constexpr span<element_type, dynamic_extent> last(size_type count) const; constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; // [span.obs], span observers constexpr size_type size() const noexcept; constexpr size_type size_bytes() const noexcept; [[nodiscard]] constexpr bool empty() const noexcept; // [span.elem], span element access constexpr reference operator[](size_type idx) const; constexpr reference at(size_type idx) const; // since C++26 constexpr reference front() const; constexpr reference back() const; constexpr pointer data() const noexcept; // [span.iterators], span iterator support constexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; constexpr reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() const noexcept; private: pointer data_; // exposition only size_type size_; // exposition only }; template<class It, class EndOrSize> span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; // until C++26 template<class It, class EndOrSize> span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>, maybe-static-ext<EndOrSize>>; // since C++26 template<class T, size_t N> span(T (&)[N]) -> span<T, N>; template<class T, size_t N> span(array<T, N>&) -> span<T, N>; template<class T, size_t N> span(const array<T, N>&) -> span<const T, N>; template<class R> span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; } // namespace std */ #include <__assert> #include <__concepts/convertible_to.h> #include <__concepts/equality_comparable.h> #include <__config> #include <__fwd/array.h> #include <__fwd/span.h> #include <__iterator/bounded_iter.h> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__iterator/reverse_iterator.h> #include <__iterator/wrap_iter.h> #include <__memory/pointer_traits.h> #include <__ranges/concepts.h> #include <__ranges/data.h> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/size.h> #include <__type_traits/integral_constant.h> #include <__type_traits/is_array.h> #include <__type_traits/is_const.h> #include <__type_traits/is_convertible.h> #include <__type_traits/is_integral.h> #include <__type_traits/is_same.h> #include <__type_traits/remove_const.h> #include <__type_traits/remove_cv.h> #include <__type_traits/remove_cvref.h> #include <__type_traits/remove_reference.h> #include <__type_traits/type_identity.h> #include <__utility/forward.h> #include <cstddef> // for byte #include <initializer_list> #include <stdexcept> #include <version> // standard-mandated includes // [iterator.range] #include <__iterator/access.h> #include <__iterator/data.h> #include <__iterator/empty.h> #include <__iterator/reverse_access.h> #include <__iterator/size.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_PUSH_MACROS #include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template <class _Tp> struct __is_std_span : false_type { … }; __is_std_span<span<_Tp, _Sz>>; __span_compatible_range; __span_array_convertible; __span_compatible_iterator; __span_compatible_sentinel_for; template <typename _Tp, size_t _Extent> class _LIBCPP_TEMPLATE_VIS span { … }; span<_Tp, dynamic_extent>; enable_borrowed_range; enable_view; // as_bytes & as_writable_bytes template <class _Tp, size_t _Extent> _LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { … } template <class _Tp, size_t _Extent> requires(!is_const_v<_Tp>) _LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { … } # if _LIBCPP_STD_VER >= 26 template <class _Tp> concept __integral_constant_like = is_integral_v<decltype(_Tp::value)> && !is_same_v<bool, remove_const_t<decltype(_Tp::value)>> && convertible_to<_Tp, decltype(_Tp::value)> && equality_comparable_with<_Tp, decltype(_Tp::value)> && bool_constant<_Tp() == _Tp::value>::value && bool_constant<static_cast<decltype(_Tp::value)>(_Tp()) == _Tp::value>::value; template <class _Tp> inline constexpr size_t __maybe_static_ext = dynamic_extent; template <__integral_constant_like _Tp> inline constexpr size_t __maybe_static_ext<_Tp> = {_Tp::value}; template <contiguous_iterator _It, class _EndOrSize> span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>, __maybe_static_ext<_EndOrSize>>; # else template <contiguous_iterator _It, class _EndOrSize> span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; # endif template <class _Tp, size_t _Sz> span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; template <class _Tp, size_t _Sz> span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; template <class _Tp, size_t _Sz> span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; template <ranges::contiguous_range _Range> span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 # include <array> # include <concepts> # include <functional> # include <iterator> # include <type_traits> #endif #endif // _LIBCPP_SPAN