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