Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qoffsetstringarray_p.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#ifndef QOFFSETSTRINGARRAY_P_H
7#define QOFFSETSTRINGARRAY_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include "private/qglobal_p.h"
21
22#include <QByteArrayView>
23
24#include <QtCore/q20algorithm.h>
25#include <array>
26#include <limits>
27#include <string_view>
28
29class tst_QOffsetStringArray;
30
31QT_BEGIN_NAMESPACE
32
33QT_WARNING_PUSH
34#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1100
35// we usually don't overread, but GCC has a false positive
36QT_WARNING_DISABLE_GCC("-Wstringop-overread")
37#endif
38
39
40template <typename StaticString, typename OffsetList>
41class QOffsetStringArray
42{
43 static auto viewType_helper()
44 {
45 // returning std::type_identity here to avoid having to #include
46 if constexpr (sizeof(Char) == 2) {
47 return q20::type_identity<QStringView>();
48#ifdef __cpp_char8_t
49 } else if constexpr (std::is_same_v<Char, char8_t>) {
50 return q20::type_identity<QUtf8StringView>();
51#endif
52 } else {
53 return q20::type_identity<QByteArrayView>();
54 }
55 }
56
57public:
58 using Char = typename StaticString::value_type;
59 using View = typename decltype(viewType_helper())::type;
60
61 constexpr QOffsetStringArray(const StaticString &string, const OffsetList &offsets)
62 : m_string(string), m_offsets(offsets)
63 {}
64
65 constexpr const Char *operator[](const int index) const noexcept
66 {
67 return m_string.data() + m_offsets[qBound(int(0), index, count())];
68 }
69
70 constexpr const Char *at(const int index) const noexcept
71 {
72 return m_string.data() + m_offsets[index];
73 }
74
75 constexpr View viewAt(qsizetype index) const noexcept
76 {
77 return { m_string.data() + m_offsets[index],
78 qsizetype(m_offsets[index + 1]) - qsizetype(m_offsets[index]) - 1 };
79 }
80
81 constexpr int count() const { return int(m_offsets.size()) - 1; }
82
83 bool contains(View needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
84 {
85 for (qsizetype i = 0; i < count(); ++i) {
86 if (viewAt(i).compare(needle, cs) == 0)
87 return true;
88 }
89 return false;
90 }
91
92private:
93 StaticString m_string;
94 OffsetList m_offsets;
95 friend tst_QOffsetStringArray;
96};
97
98namespace QtPrivate {
99template <size_t Highest> constexpr auto minifyValue()
100{
101 constexpr size_t max8 = (std::numeric_limits<quint8>::max)();
102 constexpr size_t max16 = (std::numeric_limits<quint16>::max)();
103 if constexpr (Highest <= max8) {
104 return quint8(Highest);
105 } else if constexpr (Highest <= max16) {
106 return quint16(Highest);
107 } else {
108 // int is probably enough for everyone
109 return int(Highest);
110 }
111}
112
113template <typename Char, int... Nx>
114constexpr auto makeOffsetStringArray(const Char (&...entries)[Nx])
115{
116 constexpr size_t StringLength = (Nx + ...);
117 using OffsetType = decltype(QtPrivate::minifyValue<StringLength>());
118
119 // prepend the first offset (zero) pointing to the *start* of the first element
120 size_t offset = 0;
121 std::array offsetList = {
122 OffsetType(0),
123 OffsetType(offset += Nx)...
124 };
125
126 // append an extra null terminator
127 std::array<Char, StringLength + 1> staticString = {};
128 const Char *strings[] = { entries... };
129 for (size_t i = 0; i < std::size(strings); ++i) {
130 size_t length = offsetList[i + 1] - offsetList[i];
131 q20::copy_n(strings[i], length, staticString.begin() + offsetList[i]);
132 }
133
134 return QOffsetStringArray(staticString, offsetList);
135}
136} // namespace QtPrivate
137
138template<typename Char, int ... Nx>
139#ifdef __cpp_concepts
140requires std::is_same_v<Char, char> || std::is_same_v<Char, char16_t>
141# ifdef __cpp_char8_t
143# endif
144#endif
145constexpr auto qOffsetStringArray(const Char (&...strings)[Nx]) noexcept
146{
147 return QtPrivate::makeOffsetStringArray<Char>(strings...);
148}
149
152
153#endif // QOFFSETSTRINGARRAY_P_H
\inmodule QtSql
constexpr auto minifyValue()
constexpr auto makeOffsetStringArray(const Char(&...entries)[Nx])
constexpr auto qOffsetStringArray(const Char(&...strings)[Nx]) noexcept