From 2c2c6de85ae41d09063f3c68a42522e3d74ad8fa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 29 Sep 2021 19:08:15 -0700 Subject: [PATCH] qlibraryinfo.cpp: use qOffsetStringArray for qtConfEntries Beats a manual array with too wide strings. I thought even to simply replace this with a switch (loc)... it's not like this is performance-critical code, given it uses QString. Change-Id: I2bbf422288924c198645fffd16a977778ff8d52d Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- src/corelib/global/qlibraryinfo.cpp | 76 +++++++++---------- src/corelib/tools/qoffsetstringarray_p.h | 20 +++-- .../tst_qoffsetstringarray.cpp | 10 +-- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index a2bf7599fed..b77df87f912 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -304,35 +304,6 @@ QVersionNumber QLibraryInfo::version() noexcept return QVersionNumber(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH); } -/* - * To add a new entry in QLibraryInfo::LibraryPath, add it to the enum - * in qtbase/src/corelib/global/qlibraryinfo.h and: - * - add its relative path in the qtConfEntries[] array below - * (the key is what appears in a qt.conf file) - */ - -static const struct { - char key[19], value[13]; -} qtConfEntries[] = { - { "Prefix", "." }, - { "Documentation", "doc" }, // should be ${Data}/doc - { "Headers", "include" }, - { "Libraries", "lib" }, -#ifdef Q_OS_WIN - { "LibraryExecutables", "bin" }, -#else - { "LibraryExecutables", "libexec" }, // should be ${ArchData}/libexec -#endif - { "Binaries", "bin" }, - { "Plugins", "plugins" }, // should be ${ArchData}/plugins - { "Qml2Imports", "qml" }, // should be ${ArchData}/qml - { "ArchData", "." }, - { "Data", "." }, - { "Translations", "translations" }, // should be ${Data}/translations - { "Examples", "examples" }, - { "Tests", "tests" }, -}; - static QString prefixFromAppDirHelper() { QString appDir; @@ -515,17 +486,44 @@ static QString getPrefix() void QLibraryInfoPrivate::keyAndDefault(QLibraryInfo::LibraryPath loc, QString *key, QString *value) { - if (unsigned(loc) < sizeof(qtConfEntries)/sizeof(qtConfEntries[0])) { - *key = QLatin1String(qtConfEntries[loc].key); - *value = QLatin1String(qtConfEntries[loc].value); - } -#ifndef Q_OS_WIN // On Windows we use the registry - else if (loc == QLibraryInfo::SettingsPath) { - *key = QLatin1String("Settings"); - *value = QLatin1String("."); - } + /* + * To add a new entry in QLibraryInfo::LibraryPath, add it to the enum + * in qtbase/src/corelib/global/qlibraryinfo.h and: + * - add its relative path in the qtConfEntries[] array below + * (the key is what appears in a qt.conf file) + */ + static constexpr auto qtConfEntries = qOffsetStringArray( + "Prefix", ".", + "Documentation", "doc", // should be ${Data}/doc + "Headers", "include", + "Libraries", "lib", +#ifdef Q_OS_WIN + "LibraryExecutables", "bin", +#else + "LibraryExecutables", "libexec", // should be ${ArchData}/libexec #endif - else { + "Binaries", "bin", + "Plugins", "plugins", // should be ${ArchData}/plugins + "Qml2Imports", "qml", // should be ${ArchData}/qml + "ArchData", ".", + "Data", ".", + "Translations", "translations", // should be ${Data}/translations + "Examples", "examples", + "Tests", "tests" + ); + static constexpr QByteArrayView dot = qtConfEntries.viewAt(1); + static_assert(dot.size() == 1); + static_assert(dot[0] == '.'); + + if (int(loc) < qtConfEntries.count()) { + *key = QLatin1String(qtConfEntries.viewAt(loc * 2)); + *value = QLatin1String(qtConfEntries.viewAt(loc * 2 + 1)); +#ifndef Q_OS_WIN // On Windows we use the registry + } else if (loc == QLibraryInfo::SettingsPath) { + *key = QLatin1String("Settings"); + *value = QLatin1String(dot); +#endif + } else { key->clear(); value->clear(); } diff --git a/src/corelib/tools/qoffsetstringarray_p.h b/src/corelib/tools/qoffsetstringarray_p.h index 607f13d6623..8bd7d79afbd 100644 --- a/src/corelib/tools/qoffsetstringarray_p.h +++ b/src/corelib/tools/qoffsetstringarray_p.h @@ -54,9 +54,11 @@ #include "private/qglobal_p.h" +#include + #include #include -#include +#include #include class tst_QOffsetStringArray; @@ -80,7 +82,7 @@ public: constexpr const char *operator[](const int index) const noexcept { - return m_string.data() + m_offsets[qBound(int(0), index, count() - 1)]; + return m_string.data() + m_offsets[qBound(int(0), index, count())]; } constexpr const char *at(const int index) const noexcept @@ -88,7 +90,13 @@ public: return m_string.data() + m_offsets[index]; } - constexpr int count() const { return int(m_offsets.size()); } + constexpr QByteArrayView viewAt(qsizetype index) const noexcept + { + return { m_string.data() + m_offsets[index], + qsizetype(m_offsets[index + 1]) - qsizetype(m_offsets[index]) - 1 }; + } + + constexpr int count() const { return int(m_offsets.size()) - 1; } private: StaticString m_string; @@ -162,9 +170,9 @@ constexpr auto qOffsetStringArray(StringExtractor extractString, const T &... en size_t offset = 0; std::array fullOffsetList = { offset += sizeof(extractString(T{}))... }; - // prepend zero, drop last element - std::array minifiedOffsetList = {}; - QtPrivate::copyData(fullOffsetList.begin(), Count - 1, minifiedOffsetList.begin() + 1); + // prepend zero + std::array minifiedOffsetList = {}; + QtPrivate::copyData(fullOffsetList.begin(), Count, minifiedOffsetList.begin() + 1); std::array staticString = QtPrivate::makeStaticString(extractString, entries...); return QOffsetStringArray(staticString, minifiedOffsetList); diff --git a/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp index 0130939b4ef..aecbe0b6167 100644 --- a/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp +++ b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp @@ -46,8 +46,7 @@ constexpr const auto messages = qOffsetStringArray( "level - 1", "level - 2", "level - 3", - "level - 4", - "" + "level - 4" ); constexpr const auto messages257 = qOffsetStringArray( @@ -90,15 +89,15 @@ constexpr const auto messagesBigOffsets = qOffsetStringArray( void tst_QOffsetStringArray::init() { - static_assert(messages.m_string.size() == 51); + static_assert(messages.m_string.size() == 50); static_assert(messages.m_offsets.size() == 6); static_assert(std::is_same_v); - static_assert(messages257.m_offsets.size() == 257); + static_assert(messages257.m_offsets.size() == 258); static_assert(messages257.m_string.size() == 260); static_assert(std::is_same_v); - static_assert(messagesBigOffsets.m_offsets.size() == 4); + static_assert(messagesBigOffsets.m_offsets.size() == 5); static_assert(messagesBigOffsets.m_string.size() == 364); static_assert(std::is_same_v); } @@ -110,6 +109,7 @@ void tst_QOffsetStringArray::access() QCOMPARE(messages[2], "level - 2"); QCOMPARE(messages[3], "level - 3"); QCOMPARE(messages[4], "level - 4"); + // out of bounds returns empty strings: QCOMPARE(messages[5], ""); QCOMPARE(messages[6], ""); }