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#include <tuple>
29
30#ifdef __cpp_concepts
31# include <concepts>
32#endif
33
34class tst_QOffsetStringArray;
35
36QT_BEGIN_NAMESPACE
37
38QT_WARNING_PUSH
39#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1100
40// we usually don't overread, but GCC has a false positive
41QT_WARNING_DISABLE_GCC("-Wstringop-overread")
42#endif
43
44
45template <typename StaticString, typename OffsetList>
46class QOffsetStringArray
47{
48 static auto viewType_helper()
49 {
50 // returning std::type_identity here to avoid having to #include
51 if constexpr (sizeof(Char) == 2) {
52 return q20::type_identity<QStringView>();
53#ifdef __cpp_char8_t
54 } else if constexpr (std::is_same_v<Char, char8_t>) {
55 return q20::type_identity<QUtf8StringView>();
56#endif
57 } else {
58 return q20::type_identity<QByteArrayView>();
59 }
60 }
61
62public:
63 using Char = typename StaticString::value_type;
64 using View = typename decltype(viewType_helper())::type;
65
66 constexpr QOffsetStringArray(const StaticString &string, const OffsetList &offsets)
67 : m_string(string), m_offsets(offsets)
68 {}
69
70 constexpr const Char *operator[](const int index) const noexcept
71 {
72 return m_string.data() + m_offsets[qBound(int(0), index, count())];
73 }
74
75 constexpr const Char *at(const int index) const noexcept
76 {
77 return m_string.data() + m_offsets[index];
78 }
79
80 constexpr View viewAt(qsizetype index) const noexcept
81 {
82 return { m_string.data() + m_offsets[index],
83 qsizetype(m_offsets[index + 1]) - qsizetype(m_offsets[index]) - 1 };
84 }
85
86 constexpr int count() const { return int(m_offsets.size()) - 1; }
87
88 bool contains(View needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
89 {
90 for (qsizetype i = 0; i < count(); ++i) {
91 if (viewAt(i).compare(needle, cs) == 0)
92 return true;
93 }
94 return false;
95 }
96
97private:
98 StaticString m_string;
99 OffsetList m_offsets;
100 friend tst_QOffsetStringArray;
101};
102
103namespace QtPrivate {
104template <size_t Highest> constexpr auto minifyValue()
105{
106 constexpr size_t max8 = (std::numeric_limits<quint8>::max)();
107 constexpr size_t max16 = (std::numeric_limits<quint16>::max)();
108 if constexpr (Highest <= max8) {
109 return quint8(Highest);
110 } else if constexpr (Highest <= max16) {
111 return quint16(Highest);
112 } else {
113 // int is probably enough for everyone
114 return int(Highest);
115 }
116}
117
118template <typename Char, int... Nx>
119constexpr auto makeOffsetStringArray(const Char (&...entries)[Nx])
120{
121 constexpr size_t StringLength = (Nx + ...);
122 using OffsetType = decltype(QtPrivate::minifyValue<StringLength>());
123
124 // prepend the first offset (zero) pointing to the *start* of the first element
125 size_t offset = 0;
126 std::array offsetList = {
127 OffsetType(0),
128 OffsetType(offset += Nx)...
129 };
130
131 // append an extra null terminator
132 std::array<Char, StringLength + 1> staticString = {};
133 const Char *strings[] = { entries... };
134 for (size_t i = 0; i < std::size(strings); ++i) {
135 size_t length = offsetList[i + 1] - offsetList[i];
136 q20::copy_n(strings[i], length, staticString.begin() + offsetList[i]);
137 }
138
139 return QOffsetStringArray(staticString, offsetList);
140}
141} // namespace QtPrivate
142
143template<typename Char, int ... Nx>
144#ifdef __cpp_concepts
145requires std::is_same_v<Char, char> || std::is_same_v<Char, char16_t>
146# ifdef __cpp_char8_t
148# endif
149#endif
150constexpr auto qOffsetStringArray(const Char (&...strings)[Nx]) noexcept
151{
152 return QtPrivate::makeOffsetStringArray<Char>(strings...);
153}
154
157
158#endif // QOFFSETSTRINGARRAY_P_H
\inmodule QtSql
constexpr auto minifyValue()
constexpr auto makeOffsetStringArray(const Char(&...entries)[Nx])
constexpr auto qOffsetStringArray(const Char(&...strings)[Nx]) noexcept