Revision control
++ // Copyright (C) 2023 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \class QSpan
++ \inmodule QtCore
++ \since 6.7
++ \brief A non-owning container over contiguous data.
++ \ingroup tools
++ \reentrant
++
++ QSpan\<T, E\> is a template class where \a T is the element type and \a E
++ is the extent (number of elements, or \c{std::dynamic_extent} for a
++ variable-sized span).
++
++ A QSpan references a contiguous portion of another contiguous container.
++ It acts as an interface type for all kinds of contiguous containers,
++ without the need to construct an owning container such as QList or
++ std::vector first.
++
++ The data referenced by a QSpan may be represented as an array (or
++ array-compatible data-structure such as QList, std::vector,
++ QVarLengthArray, etc.). QSpan itself merely stores a pointer to the data,
++ so users must ensure that QSpan objects do not outlive the data they
++ reference.
++
++ Unlike views such as QStringView, QLatin1StringView and QUtf8StringView,
++ referenced data can be modified through a QSpan object. To prevent this,
++ construct a QSpan over a \c{const T} (see \l{Const and Mutable Spans}):
++
++ \code
++ int numbers[] = {0, 1, 2};
++ QSpan<int> span = numbers;
++ span[0] = 42;
++ // numbers == {42, 1, 2};
++ QSpan<const int> cspan = numbers;
++ cspan[0] = 0; // ERROR: cspan[0] is read-only
++ \endcode
++
++ \target variable-fixed-spans
++ \section2 Variable-Size and Fixed-Size Spans
++
++ A QSpan can be \e{fixed-size} or \e{variable-sized}.
++
++ A variable-sized span is formed by omitting the second template argument
++ (or setting it to \c{std::dynamic_extent}, which is, however, only
++ available in C++20 builds), as seen in the example above.
++
++ A fixed-size span is formed by passing a number as the second template
++ argument:
++
++ \code
++ int numbers[] = {0, 1, 2};
++ QSpan<int, 3> span = numbers;
++ QSpan<const int, 3> = numbers; // also OK
++ \endcode
++
++ As the name suggests, a fixed-size span's size() is fixed at compile-time
++ whereas the size() of a variable-sized span is determined only at run-time.
++
++ A fixed-size span is not default-constructible (unless its \l extent is zero
++ (0)). A variable-sized span \e{is} default-constructible and will have
++ \c{data() == nullptr} and \c{size() == 0}.
++
++ A fixed-size span can be implicitly converted into a variable-sized one.
++ The opposite direction (variable-length into fixed-length) has the
++ precondition that both span's sizes must match.
++
++ \target const-mutable-spans
++ \section2 Const and Mutable Spans
++
++ Unlike with owning containers, \c{const} is \e{shallow} in QSpan: you can
++ still modify the data through a const QSpan (but not through a
++ \c{QSpan<const T>}), and begin() and end() are not overloaded on
++ \c{const}/non-\c{const}. There are cbegin() and cend(), though, that return
++ const_iterators which prevent modification of the data even though \c{T} is
++ not const:
++ \code
++ int numbers[] = {0, 1, 2};
++ const QSpan<int> span = numbers;
++ span.front() = 42; // OK, numbers[0] == 42 now
++ *span.begin() = 31; // OK, numbers[0] == 31 now
++ *span.cbegin() = -1; // ERROR: cannot assign through a const_iterator
++ \endcode
++
++ \target other-span-properties
++ \section2 Other Properties
++
++ QSpan should be passed by value, not by reference-to-const:
++
++ \code
++ void consume(QSpan<const int> data); // OK
++ void consume(const QSpan<const int> &data); // works, but is non-idiomatic and less efficient
++ \endcode
++
++ \c{QSpan<T,N>} is a \e{Literal Type}, regardless of whether \c{T} is a
++ Literal Type or not.
++
++ \target span-STL
++ \section2 QSpan vs. std::span
++
++ QSpan is closely modelled after
++ \l{https://en.cppreference.com/w/cpp/container/span}{std::span}, but has a
++ few differences which we'll discuss here. Since they both implicitly
++ convert into each other, you're free to choose whichever one you like best
++ in your own code.
++
++ \list
++ \li QSpan is using the signed qsizetype as \c{size_type}
++ whereas \c{std::span} uses \c{size_t}.
++ \li (since Qt 6.9) \c{QSpan<const T>} doesn't detach Qt containers, \c{std::span} does.
++ \li All QSpan constructors are implicit;
++ many \c{std::span} ones are \c{explicit}.
++ \li QSpan can be constructed from rvalue owning containers, \c{std::span} can not.
++ \endlist
++
++ The last two are required for source-compatibility when functions that took
++ owning containers are converted to take QSpan instead, which is a
++ vitally-important use-case in Qt. The use of qsizetype is for consistency
++ with the rest of Qt containers. QSpan template arguments still use size_t
++ to avoid introducing unnecessary error conditions (negative sizes).
++
++ \target span-compatible-iterators
++ \section2 Compatible Iterators
++
++ QSpan can be constructed from an iterator and size or from an
++ iterator pair, provided the iterators are \e{compatible} ones.
++ Eventually, this should mean C++20 \c{std::contiguous_iterator} and
++ \c{std::sentinel_for}, but while Qt still supports C++17, only raw pointers
++ are considered contiguous iterators.
++
++ \target span-compatible-ranges
++ \section2 Compatible Ranges
++
++ QSpan can also be constructed from a \e{compatible} range. A range is
++ compatible if it has \l{span-compatible-iterators}{compatible iterators}.
++
++ \sa QList, QStringView, QLatin1StringView, QUtf8StringView
++ */
++
++ //
++ // Nested types and constants
++ //
++
++ /*!
++ \typedef QSpan::element_type
++
++ An alias for \c{T}. Includes the \c{const}, if any.
++
++ This alias is provided for compatbility with the STL.
++
++ \sa value_type, pointer, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::value_type
++
++ An alias for \c{T}. Excludes the \c{const}, if any.
++
++ This alias is provided for compatbility with the STL.
++
++ \sa element_type, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::size_type
++
++ An alias for qsizetype. This \l{span-STL}{differs from \c{std::span}}.
++
++ This alias is provided for compatbility with the STL.
++ */
++
++ /*!
++ \typedef QSpan::difference_type
++
++ An alias for qptrdiff. This \l{span-STL}{differs from \c{std::span}}.
++
++ This alias is provided for compatbility with the STL.
++ */
++
++ /*!
++ \typedef QSpan::pointer
++
++ An alias for \c{T*} and \c{element_type*}, respectively. Includes the \c{const}, if any.
++
++ This alias is provided for compatbility with the STL.
++
++ \sa element_type, const_pointer, reference, iterator, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::const_pointer
++
++ An alias for \c{const T*} and \c{const element_type*}, respectively.
++
++ This alias is provided for compatbility with the STL.
++
++ \sa element_type, pointer, const_reference, const_iterator, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::reference
++
++ An alias for \c{T&} and \c{element_type&}, respectively. Includes the \c{const}, if any.
++
++ This alias is provided for compatbility with the STL.
++
++ \sa element_type, const_reference, pointer, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::const_reference
++
++ An alias for \c{const T&} and \c{const element_type&}, respectively.
++
++ This alias is provided for compatbility with the STL.
++
++ \sa element_type, reference, const_pointer, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::iterator
++
++ An alias for \c{T*} and \c{pointer}, respectively. Includes the \c{const}, if any.
++
++ \sa pointer, const_iterator, reverse_iterator, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::const_iterator
++
++ An alias for \c{const T*} and \c{const_pointer}, respectively.
++
++ \sa const_pointer, iterator, const_reverse_iterator, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::reverse_iterator
++
++ An alias for \c{std::reverse_iterator<iterator>}. Includes the \c{const}, if any.
++
++ \sa iterator, const_reverse_iterator, {Const and Mutable Spans}
++ */
++
++ /*!
++ \typedef QSpan::const_reverse_iterator
++
++ An alias for \c{std::reverse_iterator<const_iterator>}.
++
++ \sa const_iterator, reverse_iterator, {Const and Mutable Spans}
++ */
++
++ /*!
++ \variable QSpan::extent
++
++ The second template argument of \c{QSpan<T, E>}, that is, \c{E}. This is
++ \c{std::dynamic_extent} for \l{variable-fixed-spans}{variable-sized spans}.
++
++ \note While all other sizes and indexes in QSpan use qsizetype, this
++ variable, like \c{E}, is actually of type \c{size_t}, for compatibility with
++ \c{std::span} and \c{std::dynamic_extent}.
++
++ \sa size()
++ */
++
++ //
++ // Constructors and SMFs
++ //
++
++ /*!
++ \fn template <typename T, size_t E> QSpan<T,E>::QSpan()
++
++ Default constructor.
++
++ This constructor is only present if \c{E} is either zero (0) or
++ \c{std::dynamic_extent}. In other words: only fixed-zero-sized or variable-sized spans
++ are default-constructible.
++
++ \sa extent, {Variable-Size and Fixed-Size Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> QSpan<T,E>::QSpan(const QSpan &other)
++ \fn template <typename T, size_t E> QSpan<T,E>::QSpan(QSpan &&other)
++ \fn template <typename T, size_t E> QSpan<T,E> &QSpan<T,E>::operator=(const QSpan &other)
++ \fn template <typename T, size_t E> QSpan<T,E> &QSpan<T,E>::operator=(QSpan &&other)
++ \fn template <typename T, size_t E> QSpan<T,E>::~QSpan()
++
++ These Special Member Functions are implicitly-defined.
++
++ \note Moves are equivalent to copies. Only data() and size() are copied
++ from span to span, not the referenced data.
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <typename It, QSpan<T, E>::if_compatible_iterator<It>> QSpan<T,E>::QSpan(It first, qsizetype count)
++
++ Constructs a QSpan referencing the data starting at \a first and having length
++ \a count.
++
++ \c{[first, count)} must be a valid range.
++
++ \constraints \c{It} is \l{span-compatible-iterators}{a compatible iterator}.
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <typename It, QSpan<T, E>::if_compatible_iterator<It>> QSpan<T,E>::QSpan(It first, It last)
++
++ Constructs a QSpan referencing the data starting at \a first and having length
++ (\a last - \a first).
++
++ \c{[first, last)} must be a valid range.
++
++ \constraints \c{It} is \l{span-compatible-iterators}{a compatible iterator}.
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <size_t N> QSpan<T,E>::QSpan(q20::type_identity_t<T> (&arr)[N]);
++ \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(std::array<S, N> &arr);
++ \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(const std::array<S, N> &arr);
++
++ Constructs a QSpan referencing the data in the supplied array \a arr.
++
++ \note \c{q20::type_identity_t} is a C++17 backport of C++20's
++ \l{https://en.cppreference.com/w/cpp/types/type_identity}{\c{std::type_identity_t}}.
++
++ \constraints
++ \list
++ \li either \c{N} or \l{extent} are \c{std::dynamic_extent} or otherwise \l{extent} \c{==} \c{N}
++ \li and either \c{S} or \c{const S} are the same as \c{T}.
++ \endlist
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <typename Range, QSpan<T, E>::if_compatible_range<Range> = true> QSpan<T,E>::QSpan(Range &&r)
++
++ Constructs a QSpan referencing the data in the supplied range \a r.
++
++ \constraints \c{Range} is \l{span-compatible-ranges}{a compatible range}.
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(QSpan<S, N> other);
++ \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(std::span<S, N> other);
++
++ Constructs a QSpan referencing the data in the supplied span \a other.
++
++ \constraints
++ \list
++ \li either \c{N} or \l{extent} are \c{std::dynamic_extent} or \l{extent} \c{==} \c{N}
++ \li and either \c{S} or \c{const S} are the same as \c{T}.
++ \endlist
++ */
++
++ /*!
++ \fn template <typename T, size_t E> QSpan<T, E>::QSpan(std::initializer_list<value_type> il);
++
++ Constructs a QSpan referencing the data in the supplied initializer list \a il.
++
++ \note This constructor is \c{noexcept} only if \c{E} is \c{std::dynamic_extent}.
++
++ \note If \c{E} is not \c{std::dynamic_extent} and the size of \a il is not \c{E}, the behavior is undefined.
++
++ \constraints \c{T} is \c{const}-qualified.
++
++ \sa {Const and Mutable Spans}
++ */
++
++ //
++ // Member functions: sizes
++ //
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::size() const
++
++ Returns the size of the span, that is, the number of elements it references.
++
++ \sa size_bytes(), empty(), isEmpty()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::size_bytes() const
++
++ Returns the size of the span in bytes, that is, the number of elements
++ multiplied by \c{sizeof(T)}.
++
++ \sa size(), empty(), isEmpty()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::empty() const
++ \fn template <typename T, size_t E> auto QSpan<T, E>::isEmpty() const
++
++ Returns whether the span is empty, that is, whether \c{size() == 0}.
++
++ These functions do the same thing: empty() is provided for STL
++ compatibility and isEmpty() is provided for Qt compatibility.
++
++ \sa size(), size_bytes()
++ */
++
++ //
++ // element access
++ //
++
++ /*!
++ \fn template <typename T, size_t E> QSpan<T, E>::operator[](size_type idx) const
++
++ Returns a reference to the element at index \a idx in the span.
++
++ The index must be in range, that is, \a idx >= 0 and \a idx < size(),
++ otherwise the behavior is undefined.
++
++ \sa front(), back(), size(), empty(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::front() const
++
++ Returns a reference to the first element in the span.
++
++ The span must not be empty, otherwise the behavior is undefined.
++
++ \sa operator[](), back(), size(), empty(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::back() const
++
++ Returns a reference to the last element in the span.
++
++ The span must not be empty, otherwise the behavior is undefined.
++
++ \sa operator[](), front(), size(), empty(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::data() const
++
++ Returns a pointer to the beginning of the span.
++
++ The same as calling begin().
++
++ \sa begin(), front(), {Const and Mutable Spans}
++ */
++
++ //
++ // iterators
++ //
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::begin() const
++
++ Returns an interator pointing at the beginning of the span.
++
++ Because QSpan iterators are just pointers, this is the same as calling
++ data().
++
++ \sa end(), cbegin(), rbegin(), crbegin(), data(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::end() const
++
++ Returns an iterator pointing to one past the end of the span.
++
++ Because QSpan iterators are just pointers, this it the same as calling
++ \c{data() + size()}.
++
++ \sa begin(), cend(), rend(), crend(), data(), size(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::cbegin() const
++
++ Returns a const_iterator pointing to the beginning of the span.
++
++ This will return a read-only iterator even if \c{T} is not \c{const}:
++ \code
++ QSpan<int> span = ~~~;
++ *span.begin() = 42; // OK
++ *span.cbegin() = 42; // ERROR: cannot assign through a const_iterator
++ \endcode
++
++ \sa cend(), begin(), crbegin(), rbegin(), data(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::cend() const
++
++ Returns a const_iterator pointing to one past the end of the span.
++
++ \sa cbegin(), end(), crend(), rend(), data(), size(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::rbegin() const
++
++ Returns a reverse_iterator pointing to the beginning of the reversed span.
++
++ \sa rend(), crbegin(), begin(), cbegin(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::rend() const
++
++ Returns a reverse_iterator pointing to one past the end of the reversed span.
++
++ \sa rbegin(), crend(), end(), cend(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::crbegin() const
++
++ Returns a const_reverse_iterator pointing to the beginning of the reversed span.
++
++ \sa crend(), rbegin(), cbegin(), begin(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::crend() const
++
++ Returns a const_reverse_iterator pointing to one past the end of the reversed span.
++
++ \sa crbegin(), rend(), cend(), end(), {Const and Mutable Spans}
++ */
++
++ //
++ // compile-time subspans:
++ //
++
++ /*!
++ \fn template <typename T, size_t E> template <std::size_t Count> auto QSpan<T, E>::first() const
++ \keyword first-t
++
++ Returns a \l{variable-fixed-spans}{fixed-sized} span of size \c{Count}
++ referencing the first \c{Count} elements of \c{*this}.
++
++ The span must hold at least \c{Count} elements (\c{E} >= \c{Count} \e{and}
++ size() >= \c{Count}), otherwise the behavior is undefined.
++
++ \sa first(QSpan<T,E>::size_type), last(), subspan()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <std::size_t Count> auto QSpan<T, E>::last() const
++ \keyword last-t
++
++ Returns a \l{variable-fixed-spans}{fixed-sized} span of size \c{Count}
++ referencing the last \c{Count} elements of \c{*this}.
++
++ The span must hold at least \c{Count} elements (\c{E} >= \c{Count} \e{and}
++ size() >= \c{Count}), otherwise the behavior is undefined.
++
++ \sa last(QSpan<T,E>::size_type), first(), subspan()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <std::size_t Offset> auto QSpan<T, E>::subspan() const
++ \keyword subspan-t1
++
++ Returns a span of size \c{E - Offset} referencing the remainder of this span
++ after dropping the first \c{Offset} elements.
++
++ If \c{*this} is a variable-sized span, the return type is a variable-sized
++ span, otherwise it is a fixed-sized span.
++
++ This span must hold at least \c{Offset} elements (\c{E} >= \c{Offset} \e{and}
++ size() >= \c{Offset}), otherwise the behavior is undefined.
++
++ \sa subspan(QSpan<T,E>::size_type), subspan(), first(), last()
++ \sa {Variable-Size and Fixed-Size Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> template <std::size_t Offset, std::size_t Count> auto QSpan<T, E>::subspan() const
++ \keyword subspan-t2
++
++ Returns a span of size \c{Count} referencing the \c{Count} elements of this
++ span starting at \c{Offset}.
++
++ If \c{*this} is a variable-sized span, the return type is a variable-sized
++ span, otherwise it is a fixed-sized span.
++
++ This span must hold at least \c{Offset + Count} elements (\c{E} >=
++ \c{Offset + Count} \e{and} size() >= \c{Offset + Count}), otherwise the
++ behavior is undefined.
++
++ \sa subspan(QSpan<T,E>::size_type, QSpan<T,E>::size_type), first(), last()
++ \sa {Variable-Size and Fixed-Size Spans}
++ */
++
++ //
++ // runtime subspans:
++ //
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::first(qsizetype n) const
++ \keyword first-n
++
++ Returns a \l{variable-fixed-spans}{variable-sized} span of size \a n
++ referencing the first \a n elements of \c{*this}.
++
++ \a n must be non-negative.
++
++ The span must hold at least \a n elements (\c{E} >= \a n \e{and} size() >=
++ \a n), otherwise the behavior is undefined.
++
++ \sa {first-t}{first<N>()}, last(QSpan<T,E>::size_type), subspan(QSpan<T,E>::size_type),
++ subspan(QSpan<T,E>::size_type, QSpan<T,E>::size_type)
++ \sa sliced(), chopped()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::last(qsizetype n) const
++ \keyword last-n
++
++ Returns a \l{variable-fixed-spans}{variable-sized} span of size \a n
++ referencing the last \a n elements of \c{*this}.
++
++ \a n must be non-negative.
++
++ The span must hold at least \a n elements (\c{E} >= \a n \e{and}
++ size() >= \a n), otherwise the behavior is undefined.
++
++ \sa last(), first(QSpan<T,E>::size_type), subspan(QSpan<T,E>::size_type),
++ subspan(QSpan<T,E>::size_type, QSpan<T,E>::size_type), sliced(), chopped()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::subspan(qsizetype pos) const
++ \fn template <typename T, size_t E> auto QSpan<T, E>::sliced(qsizetype pos) const
++ \keyword subspan-n1
++
++ Returns a \l{variable-fixed-spans}{variable-sized} span of size \c{size() -
++ pos} referencing the remainder of this span after dropping the first \a pos
++ elements.
++
++ \a pos must be non-negative.
++
++ This span must hold at least \a pos elements (\c{E} >= \a pos \e{and}
++ size() >= \a pos), otherwise the behavior is undefined.
++
++ These functions do the same thing: subspan() is provided for STL
++ compatibility and sliced() is provided for Qt compatibility.
++
++ \sa subspan(), first(QSpan<T,E>::size_type), last(QSpan<T,E>::size_type), chopped(), slice()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::subspan(qsizetype pos, qsizetype n) const
++ \fn template <typename T, size_t E> auto QSpan<T, E>::sliced(qsizetype pos, qsizetype n) const
++ \keyword subspan-n2
++
++ Returns a \l{variable-fixed-spans}{variable-sized} span of size \a n
++ referencing the \a n elements of this span starting at \a pos.
++
++ Both \a pos and \a n must be non-negative.
++
++ This span must hold at least \c{pos + n} elements (\c{E} >=
++ \c{pos + n} \e{and} size() >= \c{pos + n}), otherwise the
++ behavior is undefined.
++
++ These functions do the same thing: subspan() is provided for STL
++ compatibility and sliced() is provided for Qt compatibility.
++
++ \sa subspan(), first(QSpan<T,E>::size_type), last(QSpan<T,E>::size_type), chopped(), slice()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T,E>::chopped(qsizetype n) const
++ \since 6.9
++
++ Returns a \l{variable-fixed-spans}{variable-sized} span of size size() - \a
++ n referencing the first size() - \a n elements of this span.
++
++ Same as \c{first(size() - n)}.
++
++ \a n must be non-negative.
++
++ This span must hold at least \a n elements (\c{E} >= \a n \e{and} size() >=
++ \a n), otherwise the behavior is undefined.
++
++ \sa subspan(), first(QSpan<T,E>::size_type), last(QSpan<T,E>::size_type), chop()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> void QSpan<T,E>::chop(qsizetype n)
++ \since 6.9
++
++ Same as \c{*this = chopped(}\a{n}\c{)}.
++
++ This function is only available on \l{variable-fixed-spans}{variable-sized spans}.
++
++ \sa chopped()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> void QSpan<T,E>::slice(qsizetype pos)
++ \since 6.9
++
++ Same as \c{*this = sliced(}\a{pos}\c{)}.
++
++ This function is only available on \l{variable-fixed-spans}{variable-sized spans}.
++
++ \sa sliced()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> void QSpan<T,E>::slice(qsizetype pos, qsizetype n)
++ \since 6.9
++
++ Same as \c{*this = sliced(}\a{pos}\c{, }\a{n}\c{)}.
++
++ This function is only available on \l{variable-fixed-spans}{variable-sized spans}.
++
++ \sa sliced()
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::as_bytes(QSpan s)
++ \since 6.8
++
++ Returns \a s as a \c{QSpan<const std::byte, E'>} whose size() is equal to
++ \c{s.size_bytes()}.
++
++ If \c{E} is \c{std::dynamic_extent} then so is \c{E'}.
++ Otherwise, \c{E' = E * sizeof(T)}.
++
++ \note \c{q20::dynamic_extent} is a C++17 backport of C++20's
++ \l{https://en.cppreference.com/w/cpp/container/span/dynamic_extent}{\c{std::dynamic_extent}}.
++
++ \sa as_writable_bytes(), size_bytes(), {Const and Mutable Spans}
++ */
++
++ /*!
++ \fn template <typename T, size_t E> auto QSpan<T, E>::as_writable_bytes(QSpan s)
++ \since 6.8
++
++ Returns \a s as a \c{QSpan<std::byte, E'>} whose size() is equal to
++ \c{s.size_bytes()}.
++
++ If \c{E} is \c{std::dynamic_extent} then so is \c{E'}.
++ Otherwise, \c{E' = E * sizeof(T)}.
++
++ \note \c{q20::dynamic_extent} is a C++17 backport of C++20's
++ \l{https://en.cppreference.com/w/cpp/container/span/dynamic_extent}{\c{std::dynamic_extent}}.
++
++ \constraints \c{!std::is_const_v<T>}.
++
++ \sa as_bytes(), size_bytes(), {Const and Mutable Spans}
++ */