Add an initial tst_QAnyStringView
It's incomplet, but at least something. Task-number: QTBUG-98138 Pick-to: 6.2 Change-Id: I4630a44b62b190dee8a8cc07822dd6ec67dbdc84 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
This commit is contained in:
parent
0fa6e6b0ab
commit
0e245c158f
@ -1,5 +1,6 @@
|
||||
# Generated from text.pro.
|
||||
|
||||
add_subdirectory(qanystringview)
|
||||
add_subdirectory(qbytearray)
|
||||
add_subdirectory(qbytearrayapisymmetry)
|
||||
add_subdirectory(qbytearraylist)
|
||||
|
1
tests/auto/corelib/text/qanystringview/.gitignore
vendored
Normal file
1
tests/auto/corelib/text/qanystringview/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
tst_qanystringview
|
11
tests/auto/corelib/text/qanystringview/CMakeLists.txt
Normal file
11
tests/auto/corelib/text/qanystringview/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
#####################################################################
|
||||
## tst_qstringview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qanystringview
|
||||
SOURCES
|
||||
tst_qanystringview.cpp
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
628
tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp
Normal file
628
tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp
Normal file
@ -0,0 +1,628 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QAnyStringView>
|
||||
#include <QChar>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QVarLengthArray>
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
// for negative testing (can't convert from)
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
# define ONLY_IF_CHAR_8_T(expr) expr
|
||||
#else
|
||||
# define ONLY_IF_CHAR_8_T(expr) \
|
||||
QSKIP("This test requires C++20 char8_t support enabled in the compiler.")
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
# define ONLY_IF_LIB_CHAR_8_T(expr) expr
|
||||
#else
|
||||
# define ONLY_IF_LIB_CHAR_8_T(expr) \
|
||||
QSKIP("This test requires C++20 char8_t support enabled in the standard library.")
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# define ONLY_WIN(expr) expr
|
||||
#else
|
||||
# define ONLY_WIN(expr) QSKIP("This is a Windows-only test")
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool CanConvert = std::is_convertible_v<T, QAnyStringView>;
|
||||
|
||||
static_assert(CanConvert<QLatin1String>);
|
||||
static_assert(CanConvert<const char*>);
|
||||
static_assert(CanConvert<QByteArray>);
|
||||
|
||||
// QAnyStringView qchar_does_not_compile() { return QAnyStringView(QChar('a')); }
|
||||
// QAnyStringView qlatin1string_does_not_compile() { return QAnyStringView(QLatin1String("a")); }
|
||||
// QAnyStringView const_char_star_does_not_compile() { return QAnyStringView("a"); }
|
||||
// QAnyStringView qbytearray_does_not_compile() { return QAnyStringView(QByteArray("a")); }
|
||||
|
||||
//
|
||||
// QChar
|
||||
//
|
||||
|
||||
static_assert(CanConvert<QChar>);
|
||||
|
||||
static_assert(CanConvert<QChar[123]>);
|
||||
|
||||
static_assert(CanConvert< QString >);
|
||||
static_assert(CanConvert<const QString >);
|
||||
static_assert(CanConvert< QString&>);
|
||||
static_assert(CanConvert<const QString&>);
|
||||
|
||||
//
|
||||
// ushort
|
||||
//
|
||||
|
||||
static_assert(CanConvert<ushort>);
|
||||
|
||||
static_assert(CanConvert<ushort[123]>);
|
||||
|
||||
static_assert(CanConvert< ushort*>);
|
||||
static_assert(CanConvert<const ushort*>);
|
||||
|
||||
static_assert(CanConvert<QList<ushort>>);
|
||||
static_assert(CanConvert<QVarLengthArray<ushort>>);
|
||||
static_assert(CanConvert<std::vector<ushort>>);
|
||||
static_assert(CanConvert<std::array<ushort, 123>>);
|
||||
static_assert(!CanConvert<std::deque<ushort>>);
|
||||
static_assert(!CanConvert<std::list<ushort>>);
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
|
||||
//
|
||||
// char8_t
|
||||
//
|
||||
|
||||
static_assert(CanConvert<char8_t>);
|
||||
|
||||
static_assert(CanConvert< char8_t*>);
|
||||
static_assert(CanConvert<const char8_t*>);
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
static_assert(CanConvert< std::u8string >);
|
||||
static_assert(CanConvert<const std::u8string >);
|
||||
static_assert(CanConvert< std::u8string&>);
|
||||
static_assert(CanConvert<const std::u8string&>);
|
||||
|
||||
static_assert(CanConvert< std::u8string_view >);
|
||||
static_assert(CanConvert<const std::u8string_view >);
|
||||
static_assert(CanConvert< std::u8string_view&>);
|
||||
static_assert(CanConvert<const std::u8string_view&>);
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
static_assert(CanConvert<QList<char8_t>>);
|
||||
static_assert(CanConvert<QVarLengthArray<char8_t>>);
|
||||
static_assert(CanConvert<std::vector<char8_t>>);
|
||||
static_assert(CanConvert<std::array<char8_t, 123>>);
|
||||
static_assert(!CanConvert<std::deque<char8_t>>);
|
||||
static_assert(!CanConvert<std::list<char8_t>>);
|
||||
|
||||
#endif // __cpp_char8_t
|
||||
|
||||
//
|
||||
// char16_t
|
||||
//
|
||||
|
||||
static_assert(CanConvert<char16_t>);
|
||||
|
||||
static_assert(CanConvert< char16_t*>);
|
||||
static_assert(CanConvert<const char16_t*>);
|
||||
|
||||
static_assert(CanConvert< std::u16string >);
|
||||
static_assert(CanConvert<const std::u16string >);
|
||||
static_assert(CanConvert< std::u16string&>);
|
||||
static_assert(CanConvert<const std::u16string&>);
|
||||
|
||||
static_assert(CanConvert< std::u16string_view >);
|
||||
static_assert(CanConvert<const std::u16string_view >);
|
||||
static_assert(CanConvert< std::u16string_view&>);
|
||||
static_assert(CanConvert<const std::u16string_view&>);
|
||||
|
||||
static_assert(CanConvert<QList<char16_t>>);
|
||||
static_assert(CanConvert<QVarLengthArray<char16_t>>);
|
||||
static_assert(CanConvert<std::vector<char16_t>>);
|
||||
static_assert(CanConvert<std::array<char16_t, 123>>);
|
||||
static_assert(!CanConvert<std::deque<char16_t>>);
|
||||
static_assert(!CanConvert<std::list<char16_t>>);
|
||||
|
||||
//
|
||||
// char32_t
|
||||
//
|
||||
|
||||
// Qt Policy: char32_t isn't supported
|
||||
|
||||
static_assert(CanConvert<char32_t>); // ... except here
|
||||
|
||||
static_assert(!CanConvert< char32_t*>);
|
||||
static_assert(!CanConvert<const char32_t*>);
|
||||
|
||||
static_assert(!CanConvert< std::u32string >);
|
||||
static_assert(!CanConvert<const std::u32string >);
|
||||
static_assert(!CanConvert< std::u32string&>);
|
||||
static_assert(!CanConvert<const std::u32string&>);
|
||||
|
||||
static_assert(!CanConvert< std::u32string_view >);
|
||||
static_assert(!CanConvert<const std::u32string_view >);
|
||||
static_assert(!CanConvert< std::u32string_view&>);
|
||||
static_assert(!CanConvert<const std::u32string_view&>);
|
||||
|
||||
static_assert(!CanConvert<QList<char32_t>>);
|
||||
static_assert(!CanConvert<QVarLengthArray<char32_t>>);
|
||||
static_assert(!CanConvert<std::vector<char32_t>>);
|
||||
static_assert(!CanConvert<std::array<char32_t, 123>>);
|
||||
static_assert(!CanConvert<std::deque<char32_t>>);
|
||||
static_assert(!CanConvert<std::list<char32_t>>);
|
||||
|
||||
//
|
||||
// wchar_t
|
||||
//
|
||||
|
||||
constexpr bool CanConvertFromWCharT =
|
||||
#ifdef Q_OS_WIN
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
;
|
||||
|
||||
static_assert(CanConvert<wchar_t> == CanConvertFromWCharT); // ### FIXME: should work everywhere
|
||||
|
||||
static_assert(CanConvert< wchar_t*> == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<const wchar_t*> == CanConvertFromWCharT);
|
||||
|
||||
static_assert(CanConvert< std::wstring > == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<const std::wstring > == CanConvertFromWCharT);
|
||||
static_assert(CanConvert< std::wstring&> == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<const std::wstring&> == CanConvertFromWCharT);
|
||||
|
||||
static_assert(CanConvert< std::wstring_view > == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<const std::wstring_view > == CanConvertFromWCharT);
|
||||
static_assert(CanConvert< std::wstring_view&> == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<const std::wstring_view&> == CanConvertFromWCharT);
|
||||
|
||||
static_assert(CanConvert<QList<wchar_t>> == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<QVarLengthArray<wchar_t>> == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<std::vector<wchar_t>> == CanConvertFromWCharT);
|
||||
static_assert(CanConvert<std::array<wchar_t, 123>> == CanConvertFromWCharT);
|
||||
static_assert(!CanConvert<std::deque<wchar_t>>);
|
||||
static_assert(!CanConvert<std::list<wchar_t>>);
|
||||
|
||||
|
||||
class tst_QAnyStringView : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void constExpr() const;
|
||||
void basics() const;
|
||||
|
||||
void fromQString() const { fromQStringOrByteArray<QString>(); }
|
||||
void fromQByteArray() const { fromQStringOrByteArray<QByteArray>(); }
|
||||
|
||||
void fromCharArray() const { fromArray<char>(); }
|
||||
void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray<char8_t>()); }
|
||||
void fromChar16Array() const { fromArray<char16_t>(); }
|
||||
void fromQCharArray() const { fromArray<QChar>(); }
|
||||
void fromWCharTArray() const { ONLY_WIN(fromArray<wchar_t>()); }
|
||||
|
||||
void fromQCharStar() const
|
||||
{
|
||||
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
|
||||
fromLiteral(str);
|
||||
}
|
||||
|
||||
void fromUShortStar() const
|
||||
{
|
||||
const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
|
||||
fromLiteral(str);
|
||||
}
|
||||
|
||||
void fromChar8TStar() const
|
||||
{
|
||||
fromLiteral(u8"Hello, World!"); // char[] in <= C++17, char8_t[] in >= C++20
|
||||
}
|
||||
|
||||
void fromChar16TStar() const { fromLiteral(u"Hello, World!"); }
|
||||
void fromWCharTStar() const { ONLY_WIN(fromLiteral(L"Hello, World!")); }
|
||||
|
||||
void fromQCharRange() const
|
||||
{
|
||||
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
|
||||
fromRange(std::begin(str), std::end(str));
|
||||
}
|
||||
|
||||
void fromUShortRange() const
|
||||
{
|
||||
const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
|
||||
fromRange(std::begin(str), std::end(str));
|
||||
}
|
||||
|
||||
void fromChar16TRange() const
|
||||
{
|
||||
const char16_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
|
||||
fromRange(std::begin(str), std::end(str));
|
||||
}
|
||||
|
||||
void fromWCharTRange() const
|
||||
{
|
||||
[[maybe_unused]] const wchar_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
|
||||
ONLY_WIN(fromRange(std::begin(str), std::end(str)));
|
||||
}
|
||||
|
||||
// std::basic_string
|
||||
void fromStdStringChar() const { fromStdString<char>(); }
|
||||
void fromStdStringChar8T() const { ONLY_IF_LIB_CHAR_8_T(fromStdString<char8_t>()); }
|
||||
void fromStdStringWCharT() const { ONLY_WIN(fromStdString<wchar_t>()); }
|
||||
void fromStdStringChar16T() const { fromStdString<char16_t>(); }
|
||||
|
||||
void fromUShortContainers() const { fromContainers<ushort>(); }
|
||||
void fromQCharContainers() const { fromContainers<QChar>(); }
|
||||
void fromChar16TContainers() const { fromContainers<char16_t>(); }
|
||||
void fromWCharTContainers() const { ONLY_WIN(fromContainers<wchar_t>()); }
|
||||
|
||||
void comparison();
|
||||
|
||||
private:
|
||||
template <typename Char>
|
||||
void fromArray() const;
|
||||
template <typename String>
|
||||
void conversion_tests(String arg) const;
|
||||
template <typename Char>
|
||||
void fromLiteral(const Char *arg) const;
|
||||
template <typename Char>
|
||||
void fromRange(const Char *first, const Char *last) const;
|
||||
template <typename Char, typename Container>
|
||||
void fromContainer() const;
|
||||
template <typename Char>
|
||||
void fromContainers() const;
|
||||
template <typename Char>
|
||||
void fromStdString() const { fromContainer<Char, std::basic_string<Char> >(); }
|
||||
template <typename QStringOrByteArray>
|
||||
void fromQStringOrByteArray() const;
|
||||
};
|
||||
|
||||
void tst_QAnyStringView::constExpr() const
|
||||
{
|
||||
#define IS_NULL(sv) \
|
||||
do { \
|
||||
static_assert(sv.size() == 0); \
|
||||
static_assert(sv.isNull()); \
|
||||
static_assert(sv.empty()); \
|
||||
static_assert(sv.isEmpty()); \
|
||||
static_assert(sv.data() == nullptr); \
|
||||
} while (false) \
|
||||
/*end*/
|
||||
#define IS_EMPTY(sv) \
|
||||
do { \
|
||||
static_assert(sv.size() == 0); \
|
||||
static_assert(!sv.isNull()); \
|
||||
static_assert(sv.empty()); \
|
||||
static_assert(sv.isEmpty()); \
|
||||
static_assert(sv.data() != nullptr); \
|
||||
} while (false) \
|
||||
/*end*/
|
||||
#define IS_OF_SIZE(sv, sz) \
|
||||
do { \
|
||||
static_assert(sv.size() == sz); \
|
||||
static_assert(!sv.isNull()); \
|
||||
static_assert(!sv.empty()); \
|
||||
static_assert(!sv.isEmpty()); \
|
||||
static_assert(sv.data() != nullptr); \
|
||||
} while (false) \
|
||||
/*end*/
|
||||
|
||||
// compile-time checks
|
||||
{
|
||||
constexpr QAnyStringView sv;
|
||||
IS_NULL(sv);
|
||||
}
|
||||
{
|
||||
constexpr const char *nul = nullptr;
|
||||
constexpr QAnyStringView sv(nul, 0);
|
||||
IS_NULL(sv);
|
||||
}
|
||||
{
|
||||
constexpr const char16_t *nul = nullptr;
|
||||
constexpr QAnyStringView sv(nul, 0);
|
||||
IS_NULL(sv);
|
||||
}
|
||||
#ifdef __cpp_char8_t
|
||||
{
|
||||
constexpr const char8_t *nul = nullptr;
|
||||
constexpr QAnyStringView sv(nul, 0);
|
||||
IS_NULL(sv);
|
||||
}
|
||||
#endif // __cpp_char8_t
|
||||
{
|
||||
constexpr QAnyStringView sv = nullptr;
|
||||
IS_NULL(sv);
|
||||
}
|
||||
{
|
||||
constexpr QAnyStringView sv = "";
|
||||
IS_EMPTY(sv);
|
||||
}
|
||||
{
|
||||
constexpr QAnyStringView sv = u8"";
|
||||
IS_EMPTY(sv);
|
||||
}
|
||||
{
|
||||
constexpr QAnyStringView sv = u"";
|
||||
IS_EMPTY(sv);
|
||||
}
|
||||
{
|
||||
constexpr QAnyStringView sv = u"Hello";
|
||||
IS_OF_SIZE(sv, 5);
|
||||
|
||||
constexpr QAnyStringView sv2 = sv;
|
||||
IS_OF_SIZE(sv2, 5);
|
||||
}
|
||||
#undef IS_OF_SIZE
|
||||
#undef IS_EMPTY
|
||||
#undef IS_NULL
|
||||
}
|
||||
|
||||
void tst_QAnyStringView::basics() const
|
||||
{
|
||||
QAnyStringView sv1;
|
||||
|
||||
// a default-constructed QAnyStringView is null:
|
||||
QVERIFY(sv1.isNull());
|
||||
// which implies it's empty();
|
||||
QVERIFY(sv1.isEmpty());
|
||||
|
||||
QAnyStringView sv2;
|
||||
|
||||
QVERIFY(sv2 == sv1);
|
||||
QVERIFY(!(sv2 != sv1));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void tst_QAnyStringView::fromArray() const
|
||||
{
|
||||
constexpr Char hello[] = {'H', 'e', 'l', 'l', 'o', '\0', 'a', 'b', 'c', '\0', '\0', '.', '\0'};
|
||||
|
||||
QAnyStringView sv = QAnyStringView::fromArray(hello);
|
||||
QCOMPARE(sv.size(), 13);
|
||||
QVERIFY(!sv.empty());
|
||||
QVERIFY(!sv.isEmpty());
|
||||
QVERIFY(!sv.isNull());
|
||||
QCOMPARE(sv.front(), 'H');
|
||||
QCOMPARE(sv.back(), '\0');
|
||||
|
||||
const Char bytes[] = {'a', 'b', 'c'};
|
||||
QAnyStringView sv2 = QAnyStringView::fromArray(bytes);
|
||||
QCOMPARE(sv2.data(), static_cast<const void *>(bytes + 0));
|
||||
QCOMPARE(sv2.size(), 3);
|
||||
QCOMPARE(sv2.back(), u'c');
|
||||
}
|
||||
|
||||
template <typename QStringOrByteArray>
|
||||
void tst_QAnyStringView::fromQStringOrByteArray() const
|
||||
{
|
||||
QStringOrByteArray null;
|
||||
QStringOrByteArray empty = "";
|
||||
|
||||
QVERIFY( QAnyStringView(null).isNull());
|
||||
QVERIFY( QAnyStringView(null).isEmpty());
|
||||
QVERIFY( QAnyStringView(empty).isEmpty());
|
||||
QVERIFY(!QAnyStringView(empty).isNull());
|
||||
|
||||
conversion_tests(QStringOrByteArray("Hello World!"));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void tst_QAnyStringView::fromLiteral(const Char *arg) const
|
||||
{
|
||||
const Char *null = nullptr;
|
||||
const Char empty[] = { Char{} };
|
||||
|
||||
QCOMPARE(QAnyStringView(null).size(), qsizetype(0));
|
||||
QCOMPARE(QAnyStringView(null).data(), nullptr);
|
||||
QCOMPARE(QAnyStringView(empty).size(), qsizetype(0));
|
||||
QCOMPARE(static_cast<const void*>(QAnyStringView(empty).data()),
|
||||
static_cast<const void*>(empty));
|
||||
|
||||
QVERIFY( QAnyStringView(null).isNull());
|
||||
QVERIFY( QAnyStringView(null).isEmpty());
|
||||
QVERIFY( QAnyStringView(empty).isEmpty());
|
||||
QVERIFY(!QAnyStringView(empty).isNull());
|
||||
|
||||
conversion_tests(arg);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void tst_QAnyStringView::fromRange(const Char *first, const Char *last) const
|
||||
{
|
||||
const Char *null = nullptr;
|
||||
QCOMPARE(QAnyStringView(null, null).size(), 0);
|
||||
QCOMPARE(QAnyStringView(null, null).data(), nullptr);
|
||||
QCOMPARE(QAnyStringView(first, first).size(), 0);
|
||||
QCOMPARE(static_cast<const void*>(QAnyStringView(first, first).data()),
|
||||
static_cast<const void*>(first));
|
||||
|
||||
const auto sv = QAnyStringView(first, last);
|
||||
QCOMPARE(sv.size(), last - first);
|
||||
QCOMPARE(static_cast<const void*>(sv.data()),
|
||||
static_cast<const void*>(first));
|
||||
|
||||
// can't call conversion_tests() here, as it requires a single object
|
||||
}
|
||||
|
||||
template <typename Char, typename Container>
|
||||
void tst_QAnyStringView::fromContainer() const
|
||||
{
|
||||
const std::string s = "Hello World!";
|
||||
|
||||
Container c;
|
||||
// unspecified whether empty containers make null QAnyStringViews
|
||||
QVERIFY(QAnyStringView(c).isEmpty());
|
||||
|
||||
std::copy(s.begin(), s.end(), std::back_inserter(c));
|
||||
conversion_tests(std::move(c));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void tst_QAnyStringView::fromContainers() const
|
||||
{
|
||||
fromContainer<Char, QList<Char>>();
|
||||
fromContainer<Char, QVarLengthArray<Char>>();
|
||||
fromContainer<Char, std::vector<Char>>();
|
||||
}
|
||||
|
||||
namespace q20 {
|
||||
#ifdef __cpp_lib_ssize
|
||||
using std::ssize;
|
||||
#else
|
||||
template<class C> constexpr auto ssize(const C& c)
|
||||
-> std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(c.size())>>
|
||||
{ return static_cast<std::common_type_t<ptrdiff_t, std::make_signed_t<decltype(c.size())>>>(c.size()); }
|
||||
|
||||
template<class T, ptrdiff_t N> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept
|
||||
{ return N; }
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace help {
|
||||
template <typename T>
|
||||
auto ssize(T &t) { return q20::ssize(t); }
|
||||
|
||||
template <typename T>
|
||||
qsizetype ssize(const T *t)
|
||||
{
|
||||
qsizetype result = 0;
|
||||
if (t) {
|
||||
while (*t++)
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
qsizetype ssize(const QChar *t)
|
||||
{
|
||||
qsizetype result = 0;
|
||||
if (t) {
|
||||
while (!t++->isNull())
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
void tst_QAnyStringView::conversion_tests(String string) const
|
||||
{
|
||||
// copy-construct:
|
||||
{
|
||||
QAnyStringView sv = string;
|
||||
|
||||
QCOMPARE(help::ssize(sv), help::ssize(string));
|
||||
|
||||
QCOMPARE(sv, string);
|
||||
}
|
||||
|
||||
QAnyStringView sv;
|
||||
|
||||
// copy-assign:
|
||||
{
|
||||
sv = string;
|
||||
|
||||
QCOMPARE(help::ssize(sv), help::ssize(string));
|
||||
|
||||
// check relational operators:
|
||||
|
||||
QCOMPARE(sv, string);
|
||||
QCOMPARE(string, sv);
|
||||
|
||||
QVERIFY(!(sv != string));
|
||||
QVERIFY(!(string != sv));
|
||||
|
||||
QVERIFY(!(sv < string));
|
||||
QVERIFY(sv <= string);
|
||||
QVERIFY(!(sv > string));
|
||||
QVERIFY(sv >= string);
|
||||
|
||||
QVERIFY(!(string < sv));
|
||||
QVERIFY(string <= sv);
|
||||
QVERIFY(!(string > sv));
|
||||
QVERIFY(string >= sv);
|
||||
}
|
||||
|
||||
// copy-construct from rvalue (QAnyStringView never assumes ownership):
|
||||
{
|
||||
QAnyStringView sv2 = std::move(string);
|
||||
QCOMPARE(sv2, sv);
|
||||
QCOMPARE(sv2, string);
|
||||
}
|
||||
|
||||
// copy-assign from rvalue (QAnyStringView never assumes ownership):
|
||||
{
|
||||
QAnyStringView sv2;
|
||||
sv2 = std::move(string);
|
||||
QCOMPARE(sv2, sv);
|
||||
QCOMPARE(sv2, string);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QAnyStringView::comparison()
|
||||
{
|
||||
const QAnyStringView aa = u"aa";
|
||||
const QAnyStringView upperAa = u"AA";
|
||||
const QAnyStringView bb = u"bb";
|
||||
|
||||
QVERIFY(aa == aa);
|
||||
QVERIFY(aa != bb);
|
||||
QVERIFY(aa < bb);
|
||||
QVERIFY(bb > aa);
|
||||
|
||||
QCOMPARE(QAnyStringView::compare(aa, aa), 0);
|
||||
QVERIFY(QAnyStringView::compare(aa, upperAa) != 0);
|
||||
QCOMPARE(QAnyStringView::compare(aa, upperAa, Qt::CaseInsensitive), 0);
|
||||
QVERIFY(QAnyStringView::compare(aa, bb) < 0);
|
||||
QVERIFY(QAnyStringView::compare(bb, aa) > 0);
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QAnyStringView)
|
||||
#include "tst_qanystringview.moc"
|
Loading…
x
Reference in New Issue
Block a user