diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 1d1773981d8..e024f18c644 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -304,6 +304,7 @@ qt_internal_add_module(Core tools/qsharedpointer.cpp tools/qsharedpointer.h tools/qsharedpointer_impl.h tools/qsize.cpp tools/qsize.h + tools/qsmallbytearray_p.h tools/qspan.h tools/qspan_p.h tools/qstack.h diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index f6b7aee4553..59201941f9a 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -124,75 +125,6 @@ static inline int SHA384_512AddLength(SHA512Context *context, unsigned int lengt QT_BEGIN_NAMESPACE -template -class QSmallByteArray -{ - std::array m_data; - static_assert(N <= (std::numeric_limits::max)()); - quint8 m_size = 0; -public: - QSmallByteArray() = default; - // all compiler-generated SMFs are ok! - template = true> // M == N is for copy ctor! - constexpr QSmallByteArray(const QSmallByteArray &other) noexcept - { - assign(other); - } - template = true> // M == N is for copy-assignment op! - constexpr QSmallByteArray &operator=(const QSmallByteArray &other) noexcept - { - assign(other); - return *this; - } - - template // ### underconstrained - constexpr void assign(const Container &c) - { - const size_t otherSize = size_t(std::size(c)); - Q_ASSERT(otherSize < N); - memcpy(data(), std::data(c), otherSize); - m_size = quint8(otherSize); - } - - constexpr quint8 *data() noexcept { return m_data.data(); } - constexpr const quint8 *data() const noexcept { return m_data.data(); } - constexpr qsizetype size() const noexcept { return qsizetype{m_size}; } - constexpr quint8 &operator[](qsizetype n) - { - Q_ASSERT(n < size()); - return data()[n]; - } - constexpr const quint8 &operator[](qsizetype n) const - { - Q_ASSERT(n < size()); - return data()[n]; - } - constexpr bool isEmpty() const noexcept { return size() == 0; } - constexpr void clear() noexcept { m_size = 0; } - constexpr void resizeForOverwrite(qsizetype s) - { - Q_ASSERT(s >= 0); - Q_ASSERT(size_t(s) <= N); - m_size = std::uint8_t(s); - } - constexpr void resize(qsizetype s, quint8 v) - { - const auto oldSize = size(); - resizeForOverwrite(s); - if (s > oldSize) - memset(data() + oldSize, v, size() - oldSize); - } - constexpr QByteArrayView toByteArrayView() const noexcept - { return *this; } - - constexpr auto begin() noexcept { return data(); } - constexpr auto begin() const noexcept { return data(); } - constexpr auto cbegin() const noexcept { return begin(); } - constexpr auto end() noexcept { return data() + size(); } - constexpr auto end() const noexcept { return data() + size(); } - constexpr auto cend() const noexcept { return end(); } -}; - static constexpr int hashLengthInternal(QCryptographicHash::Algorithm method) noexcept { switch (method) { diff --git a/src/corelib/tools/qsmallbytearray_p.h b/src/corelib/tools/qsmallbytearray_p.h new file mode 100644 index 00000000000..3b45237bc8d --- /dev/null +++ b/src/corelib/tools/qsmallbytearray_p.h @@ -0,0 +1,104 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QTCORE_QSMALLBYTEARRAY_P_H +#define QTCORE_QSMALLBYTEARRAY_P_H + +#include +#include +#include + +#include +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +// +// A fixed-max-size version of QByteArray. Since it's fixed-max-size, it's +// never going to the heap. Can contain a maximum of 256 octets. Never +// NUL-terminates on its own. +// + +template +class QSmallByteArray +{ + std::array m_data; + static_assert(N <= (std::numeric_limits::max)()); + quint8 m_size = 0; +public: + QSmallByteArray() = default; + // all compiler-generated SMFs are ok! + template = true> // M == N is for copy ctor! + constexpr QSmallByteArray(const QSmallByteArray &other) noexcept + { + assign(other); + } + template = true> // M == N is for copy-assignment op! + constexpr QSmallByteArray &operator=(const QSmallByteArray &other) noexcept + { + assign(other); + return *this; + } + + template // ### underconstrained + constexpr void assign(const Container &c) + { + const size_t otherSize = size_t(std::size(c)); + Q_ASSERT(otherSize < N); + memcpy(data(), std::data(c), otherSize); + m_size = quint8(otherSize); + } + + constexpr quint8 *data() noexcept { return m_data.data(); } + constexpr const quint8 *data() const noexcept { return m_data.data(); } + constexpr qsizetype size() const noexcept { return qsizetype{m_size}; } + constexpr quint8 &operator[](qsizetype n) + { + Q_ASSERT(n < size()); + return data()[n]; + } + constexpr const quint8 &operator[](qsizetype n) const + { + Q_ASSERT(n < size()); + return data()[n]; + } + constexpr bool isEmpty() const noexcept { return size() == 0; } + constexpr void clear() noexcept { m_size = 0; } + constexpr void resizeForOverwrite(qsizetype s) + { + Q_ASSERT(s >= 0); + Q_ASSERT(size_t(s) <= N); + m_size = std::uint8_t(s); + } + constexpr void resize(qsizetype s, quint8 v) + { + const auto oldSize = size(); + resizeForOverwrite(s); + if (s > oldSize) + memset(data() + oldSize, v, size() - oldSize); + } + constexpr QByteArrayView toByteArrayView() const noexcept + { return *this; } + + constexpr auto begin() noexcept { return data(); } + constexpr auto begin() const noexcept { return data(); } + constexpr auto cbegin() const noexcept { return begin(); } + constexpr auto end() noexcept { return data() + size(); } + constexpr auto end() const noexcept { return data() + size(); } + constexpr auto cend() const noexcept { return end(); } +}; + +QT_END_NAMESPACE + +#endif // QTCORE_QSMALLBYTEARRAY_P_H