7#include <QtCore/qcompilerdetection.h>
8#include <QtCore/qtypes.h>
9#include <QtCore/qcontainerfwd.h>
14#include <initializer_list>
15#include <QtCore/q20iterator.h>
16#include <QtCore/q20memory.h>
20#include <QtCore/q20type_traits.h>
29QT_BEGIN_INCLUDE_NAMESPACE
31#ifdef __cpp_lib_concepts
32namespace std::ranges {
36template <
typename T, std::size_t E>
37constexpr inline bool enable_borrowed_range<QT_PREPEND_NAMESPACE(QSpan)<T, E>> =
true;
38template <
typename T, std::size_t E>
39constexpr inline bool enable_view<QT_PREPEND_NAMESPACE(QSpan)<T, E>> =
true;
43QT_END_INCLUDE_NAMESPACE
47template <
typename From,
typename To>
51template <
typename T,
std::size_t E>
class QSpanBase;
57template <
typename T,
std::size_t E>
73template <
typename T,
std::size_t N>
78template <
typename From,
typename To>
79using is_qualification_conversion =
80 std::is_convertible<From(*)[], To(*)[]>;
81template <
typename From,
typename To>
85#define MAKE_ADL_TEST(what)
87 template <typename T> using what ## _result = decltype( what (std::declval<T&&>()));
97template <
typename Range>
99template <
typename Range>
101template <
typename Range>
106template <
typename Range>
108template <
typename Range>
132 template <
typename Range,
typename =
void>
134 template <
typename Range>
137 template <
typename Range>
156 template <
typename Range>
160template <
typename T,
std::size_t E>
163 static_assert(E < size_t{(std::numeric_limits<qsizetype>::max)()},
164 "QSpan only supports extents that fit into the signed size type (qsizetype).");
166 template <
typename S, std::size_t N>
167 using if_compatible_array = std::enable_if_t<
168 N == E && is_qualification_conversion_v<S, T>
171 template <
typename S>
172 using if_qualification_conversion = std::enable_if_t<
173 is_qualification_conversion_v<S, T>
187 template <std::size_t E2 = E, std::enable_if_t<E2 == 0,
bool> =
true>
188 Q_IMPLICIT
constexpr QSpanBase()
noexcept : m_data{
nullptr} {}
190 template <
typename It,
typename Base::
template if_compatible_iterator<It> =
true>
194 Q_ASSERT(count == m_size);
197 template <
typename It,
typename End,
typename Base::
template if_compatible_iterator_and_sentinel<It, End> =
true>
199 : QSpanBase(first, last - first) {}
201 template <size_t N, std::enable_if_t<N == E,
bool> =
true>
202 Q_IMPLICIT
constexpr QSpanBase(q20::type_identity_t<T> (&arr)[N])
noexcept
203 : QSpanBase(arr, N) {}
205 template <
typename S, size_t N, if_compatible_array<S, N> =
true>
206 Q_IMPLICIT
constexpr QSpanBase(std::array<S, N> &arr)
noexcept
207 : QSpanBase(arr.data(), N) {}
209 template <
typename S, size_t N, if_compatible_array<S, N> =
true>
210 Q_IMPLICIT
constexpr QSpanBase(
const std::array<S, N> &arr)
noexcept
211 : QSpanBase(arr.data(), N) {}
213 template <
typename Range,
typename Base::
template if_compatible_range<Range> =
true>
214 Q_IMPLICIT
constexpr QSpanBase(Range &&r)
215 : QSpanBase(QSpanPrivate::adl_data(QSpanPrivate::const_propagated<T>(r)),
216 qsizetype(QSpanPrivate::adl_size(r)))
219 template <
typename S, if_qualification_conversion<S> =
true>
220 Q_IMPLICIT
constexpr QSpanBase(QSpan<S, E> other)
noexcept
221 : QSpanBase(other.data(), other.size())
224 template <
typename S, if_qualification_conversion<S> =
true>
225 Q_IMPLICIT
constexpr QSpanBase(QSpan<S> other)
226 : QSpanBase(other.data(), other.size())
229 template <
typename U = T, std::enable_if_t<std::is_const_v<U>,
bool> =
true>
230 Q_IMPLICIT
constexpr QSpanBase(std::initializer_list<std::remove_cv_t<T>> il)
231 : QSpanBase(il.begin(), il.size())
235 template <
typename S, if_qualification_conversion<S> =
true>
236 Q_IMPLICIT
constexpr QSpanBase(std::span<S, E> other)
noexcept
237 : QSpanBase(other.data(), other.size())
240 template <
typename S, if_qualification_conversion<S> =
true>
241 Q_IMPLICIT
constexpr QSpanBase(std::span<S> other)
242 : QSpanBase(other.data(), other.size())
250 template <
typename S>
251 using if_qualification_conversion = std::enable_if_t<
252 is_qualification_conversion_v<S, T>
263 Q_IMPLICIT
constexpr QSpanBase()
noexcept : m_data{
nullptr}, m_size{0} {}
265 template <
typename It,
typename Base::
template if_compatible_iterator<It> =
true>
266 Q_IMPLICIT
constexpr QSpanBase(It first, qsizetype count)
267 : m_data{q20::to_address(first)}, m_size{count} {}
269 template <
typename It,
typename End,
typename Base::
template if_compatible_iterator_and_sentinel<It, End> =
true>
270 Q_IMPLICIT
constexpr QSpanBase(It first, End last)
271 : QSpanBase(first, last - first) {}
274 Q_IMPLICIT
constexpr QSpanBase(q20::type_identity_t<T> (&arr)[N])
noexcept
275 : QSpanBase(arr, N) {}
277 template <
typename S, size_t N, if_qualification_conversion<S> =
true>
278 Q_IMPLICIT
constexpr QSpanBase(std::array<S, N> &arr)
noexcept
279 : QSpanBase(arr.data(), N) {}
281 template <
typename S, size_t N, if_qualification_conversion<S> =
true>
282 Q_IMPLICIT
constexpr QSpanBase(
const std::array<S, N> &arr)
noexcept
283 : QSpanBase(arr.data(), N) {}
285 template <
typename Range,
typename Base::
template if_compatible_range<Range> =
true>
286 Q_IMPLICIT
constexpr QSpanBase(Range &&r)
287 : QSpanBase(QSpanPrivate::adl_data(QSpanPrivate::const_propagated<T>(r)),
288 qsizetype(QSpanPrivate::adl_size(r)))
291 template <
typename S, size_t N, if_qualification_conversion<S> =
true>
292 Q_IMPLICIT
constexpr QSpanBase(QSpan<S, N> other)
noexcept
293 : QSpanBase(other.data(), other.size())
296 template <
typename U = T, std::enable_if_t<std::is_const_v<U>,
bool> =
true>
297 Q_IMPLICIT
constexpr QSpanBase(std::initializer_list<std::remove_cv_t<T>> il)
noexcept
298 : QSpanBase(il.begin(), il.size())
302 template <
typename S, size_t N, if_qualification_conversion<S> =
true>
303 Q_IMPLICIT
constexpr QSpanBase(std::span<S, N> other)
noexcept
304 : QSpanBase(other.data(), other.size())
311template <
typename T,
std::size_t E>
318 Q_ALWAYS_INLINE
constexpr void verify([[maybe_unused]] qsizetype pos = 0,
319 [[maybe_unused]] qsizetype n = 1)
const
322 Q_ASSERT(pos <= size());
324 Q_ASSERT(n <= size() - pos);
327 template <std::size_t N>
328 static constexpr bool subspan_always_succeeds_v = N <= E && E != q20::dynamic_extent;
332#ifdef QT_COMPILER_HAS_LWG3346
339 using const_pointer =
const T*;
340 using reference = T&;
341 using const_reference =
const T&;
342 using iterator = pointer;
343 using const_iterator = const_pointer;
344 using reverse_iterator =
std::reverse_iterator<iterator>;
345 using const_reverse_iterator =
std::reverse_iterator<const_iterator>;
372 { verify(idx);
return data()[idx]; }
374 [[
nodiscard]]
constexpr reference
back()
const { verify();
return data()[size() - 1]; }
375 [[
nodiscard]]
constexpr pointer
data()
const noexcept {
return this->m_data; }
379 [[
nodiscard]]
constexpr iterator
end()
const noexcept {
return data() + size(); }
388 template <
std::size_t Count>
392 static_assert(Count <= E,
393 "Count cannot be larger than the span's extent.");
398 template <
std::size_t Count>
402 static_assert(Count <= E,
403 "Count cannot be larger than the span's extent.");
405 return QSpan<T, Count>{data() + (size() - Count), Count};
408 template <
std::size_t Offset>
412 static_assert(Offset <= E,
413 "Offset cannot be larger than the span's extent.");
416 return QSpan<T>{data() + Offset, qsizetype(size() - Offset)};
418 return QSpan<T, E - Offset>{
data() + Offset, qsizetype(E - Offset)};
421 template <
std::size_t Offset,
std::size_t Count>
424 {
return subspan<Offset>().
template first<Count>(); }
427 [[
nodiscard]]
constexpr QSpan<
T>
last(size_type n)
const { verify(0, n);
return {data() + (size() - n), n}; }
439# define QT_ONLY_IF_DYNAMIC_SPAN(DECL)
440 DECL requires(E == q20::dynamic_extent)
442# define QT_ONLY_IF_DYNAMIC_SPAN(DECL)
443 template <size_t M = E, typename = std::enable_if_t<M == q20::dynamic_extent>> DECL
446 constexpr void slice(size_type pos)
448 { *
this = sliced(pos); }
450 constexpr void slice(size_type pos, size_type n)
452 { *
this = sliced(pos, n); }
454 constexpr void chop(size_type n)
456 { *
this = chopped(n); }
457#undef QT_ONLY_IF_DYNAMIC_SPAN
466 return R{
reinterpret_cast<
const std::byte *>(s
.data()), s.size_bytes()};
469 template <
typename U>
473 template <
typename T2 = T, if_mutable<T2> =
true>
480 return R{
reinterpret_cast<
std::byte *>(s
.data()), s.size_bytes()};
485template <
class It,
class EndOrSize>
486QSpan(It, EndOrSize) -> QSpan<std::remove_reference_t<q20::iter_reference_t<It>>>;
487template <
class T,
std::size_t N>
489template <
class T,
std::size_t N>
491template <
class T,
std::size_t N>
494QSpan(R&&) -> QSpan<std::remove_reference_t<QSpanPrivate::range_reference_t<R>>>;
QString convertToQString(QAnyStringView string)
constexpr QSpanBase(It first, qsizetype count)
static constexpr qsizetype m_size
constexpr QSpanBase(It first, End last)
constexpr bool empty() const noexcept
constexpr pointer data() const noexcept
static constexpr std::size_t extent
constexpr reverse_iterator rbegin() const noexcept
constexpr reference front() const
constexpr QSpan< T > sliced(size_type pos, size_type n) const
constexpr QSpan< T > sliced(size_type pos) const
constexpr size_type size() const noexcept
constexpr iterator end() const noexcept
constexpr const_iterator cbegin() const noexcept
constexpr QSpan< T > subspan(size_type pos, size_type n) const
constexpr const_iterator cend() const noexcept
constexpr bool isEmpty() const noexcept
constexpr reverse_iterator rend() const noexcept
constexpr QSpan< T, Count > last() const noexcept(subspan_always_succeeds_v< Count >)
constexpr QSpan< T > last(size_type n) const
constexpr const_reverse_iterator crend() const noexcept
friend QSpan< const std::byte, E==q20::dynamic_extent ? q20::dynamic_extent :E *sizeof(T)> as_bytes(QSpan s) noexcept
constexpr size_type size_bytes() const noexcept
constexpr const_reverse_iterator crbegin() const noexcept
constexpr reference operator[](size_type idx) const
constexpr QSpan< T > first(size_type n) const
constexpr reference back() const
constexpr QSpan< T > subspan(size_type pos) const
constexpr auto subspan() const noexcept(subspan_always_succeeds_v< Offset+Count >)
constexpr QSpan< T, Count > first() const noexcept(subspan_always_succeeds_v< Count >)
constexpr QSpan< T > chopped(size_type n) const
friend QSpan< std::byte, E==q20::dynamic_extent ? q20::dynamic_extent :E *sizeof(T)> as_writable_bytes(QSpan s) noexcept
constexpr iterator begin() const noexcept
constexpr auto subspan() const noexcept(subspan_always_succeeds_v< Offset >)
char32_t next(char32_t invalidAs=QChar::ReplacementCharacter)
QList< uint > convertToUcs4(QStringView string)
QByteArray convertToUtf8(QStringView string)
QByteArray convertToLocal8Bit(QStringView string)
QByteArray convertToLatin1(QStringView string)
AdlTester::size_result< Range > adl_size(Range &&r)
std::conditional_t< std::is_const_v< From >, const To &, To & > const_propagated(To &in)
AdlTester::data_result< Range > adl_data(Range &&r)
AdlTester::begin_result< Range > adl_begin(Range &&r)
constexpr bool is_qualification_conversion_v
Combined button and popup list for selecting options.
@ NormalizationCorrectionsVersionMax
static QString convertCase(T &str, QUnicodeTables::Case which)
static constexpr NormalizationCorrection uc_normalization_corrections[]
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isLower(QStringView s) noexcept
const QString & asString(const QString &s)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isValidUtf16(QStringView s) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QStringView lhs, QStringView rhs) noexcept
qsizetype findString(QStringView str, qsizetype from, QChar needle, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isRightToLeft(QStringView string) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isAscii(QLatin1StringView s) noexcept
constexpr bool isLatin1(QLatin1StringView s) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION const char16_t * qustrcasechr(QStringView str, char16_t ch) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isUpper(QStringView s) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION const char16_t * qustrchr(QStringView str, char16_t ch) noexcept
constexpr auto dynamic_extent
void qt_to_latin1_unchecked(uchar *dst, const char16_t *uc, qsizetype len)
static char16_t foldCase(char16_t ch) noexcept
uint QT_FASTCALL fetch1Pixel< QPixelLayout::BPP1LSB >(const uchar *src, int index)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
#define MAKE_ADL_TEST(what)
QSpan(const std::array< T, N > &) -> QSpan< const T, N >
#define QT_ONLY_IF_DYNAMIC_SPAN(DECL)
QSpan(T(&)[N]) -> QSpan< T, N >
QSpan(std::array< T, N > &) -> QSpan< T, N >
static bool isAscii_helper(const char16_t *&ptr, const char16_t *end)
static Int toIntegral(QStringView string, bool *ok, int base)
void qt_to_latin1(uchar *dst, const char16_t *src, qsizetype length)
Qt::strong_ordering compareThreeWay(const QByteArray &lhs, const QChar &rhs) noexcept
static void append_utf8(QString &qs, const char *cs, qsizetype len)
#define ATTRIBUTE_NO_SANITIZE
bool qt_is_ascii(const char *&ptr, const char *end) noexcept
static void replace_in_place(QString &str, QSpan< size_t > indices, qsizetype blen, QStringView after)
static bool checkCase(QStringView s, QUnicodeTables::Case c) noexcept
static void replace_helper(QString &str, QSpan< size_t > indices, qsizetype blen, QStringView after)
Q_CORE_EXPORT void qt_from_latin1(char16_t *dst, const char *str, size_t size) noexcept
static int ucstrcmp(const char16_t *a, size_t alen, const Char2 *b, size_t blen)
bool comparesEqual(const QByteArray &lhs, char16_t rhs) noexcept
Q_DECLARE_TYPEINFO(Part, Q_PRIMITIVE_TYPE)
static void removeStringImpl(QString &s, const T &needle, Qt::CaseSensitivity cs)
static bool needsReallocate(const QString &str, qsizetype newSize)
static int qArgDigitValue(QChar ch) noexcept
bool comparesEqual(const QByteArray &lhs, const QChar &rhs) noexcept
static void replace_with_copy(QString &str, QSpan< size_t > indices, qsizetype blen, QStringView after)
bool comparesEqual(const QByteArrayView &lhs, char16_t rhs) noexcept
static int ucstrncmp(const char16_t *a, const char16_t *b, size_t l)
static Q_NEVER_INLINE int ucstricmp(qsizetype alen, const char16_t *a, qsizetype blen, const char *b)
static QByteArray qt_convert_to_latin1(QStringView string)
static bool ucstreq(const char16_t *a, size_t alen, const Char2 *b)
static QList< uint > qt_convert_to_ucs4(QStringView string)
qsizetype qFindStringBoyerMoore(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs)
static QByteArray qt_convert_to_local_8bit(QStringView string)
static LengthMod parse_length_modifier(const char *&c) noexcept
static ArgEscapeData findArgEscapes(QStringView s)
static QByteArray qt_convert_to_utf8(QStringView str)
static void qt_to_latin1_internal(uchar *dst, const char16_t *src, qsizetype length)
static void insert_helper(QString &str, qsizetype i, const T &toInsert)
static int latin1nicmp(const char *lhsChar, qsizetype lSize, const char *rhsChar, qsizetype rSize)
Qt::strong_ordering compareThreeWay(const QByteArrayView &lhs, const QChar &rhs) noexcept
static char16_t to_unicode(const char c)
Qt::strong_ordering compareThreeWay(const QByteArray &lhs, char16_t rhs) noexcept
static QString replaceArgEscapes(QStringView s, const ArgEscapeData &d, qsizetype field_width, QStringView arg, QStringView larg, QChar fillChar)
static QVarLengthArray< char16_t > qt_from_latin1_to_qvla(QLatin1StringView str)
static Q_NEVER_INLINE int ucstricmp8(const char *utf8, const char *utf8end, const QChar *utf16, const QChar *utf16end)
void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, qsizetype from)
static uint parse_flag_characters(const char *&c) noexcept
static Q_NEVER_INLINE int ucstricmp(qsizetype alen, const char16_t *a, qsizetype blen, const char16_t *b)
static char16_t to_unicode(const QChar c)
QDataStream & operator>>(QDataStream &in, QString &str)
static int getEscape(const Char *uc, qsizetype *pos, qsizetype len)
static int ucstrncmp(const char16_t *a, const char *b, size_t l)
static bool can_consume(const char *&c, char ch) noexcept
static int parse_field_width(const char *&c, qsizetype size)
Qt::strong_ordering compareThreeWay(const QByteArrayView &lhs, char16_t rhs) noexcept
#define qUtf16Printable(string)
qsizetype locale_occurrences
\inmodule QtCore \reentrant
constexpr char16_t unicode() const noexcept
Converts a Latin-1 character to an 16-bit-encoded Unicode representation of the character.
constexpr QLatin1Char(char c) noexcept
Constructs a Latin-1 character for c.
static auto matcher(char ch)
static int difference(char lhs, char rhs)