diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-05-03 20:11:34 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2017-05-16 09:34:50 +0000 |
commit | 3c592a17f1b54c88a0d868b7251f5134dac421b6 (patch) | |
tree | 6719d9efc907a0edffe7df4ba102e72acf45c32f | |
parent | 221653cbeabea604db3644442b0134c718b6c2b6 (diff) |
QStringView: add constructor from pointer pair
This is often more natural than (ptr, len), and I need it in the
implementation of QStringView::trimmed().
Change-Id: I1d99b5ddaf76eee0582150b0233ef6ce9c37d25d
Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r-- | src/corelib/tools/qstringview.cpp | 20 | ||||
-rw-r--r-- | src/corelib/tools/qstringview.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qstringview/tst_qstringview.cpp | 75 |
3 files changed, 99 insertions, 0 deletions
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp index 0b1dac2f98..8d2fc996e9 100644 --- a/src/corelib/tools/qstringview.cpp +++ b/src/corelib/tools/qstringview.cpp @@ -240,6 +240,26 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QStringView::QStringView(const Char *first, const Char *last) + + Constructs a string view on \a first with length (\a last - \a first). + + The range \c{[first,last)} must remain valid for the lifetime of + this string view object. + + Passing \c nullptr as \a first is safe if \a last is nullptr, too, + and results in a null string view. + + The behavior is undefined if \a last precedes \a first, or \a first + is \c nullptr and \a last is not. + + This constructor only participates in overload resolution if \c Char + is a compatible character type. The compatible character types + are: \c QChar, \c ushort, \c char16_t and (on platforms, such as + Windows, where it is a 16-bit type) \c wchar_t. +*/ + +/*! \fn QStringView::QStringView(const Char *str) Constructs a string view on \a str. The length is determined diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h index 62173f9765..fdbf644518 100644 --- a/src/corelib/tools/qstringview.h +++ b/src/corelib/tools/qstringview.h @@ -176,6 +176,10 @@ public: : m_size((Q_ASSERT(len >= 0), Q_ASSERT(str || !len), len)), m_data(castHelper(str)) {} + template <typename Char, if_compatible_char<Char> = true> + Q_DECL_CONSTEXPR QStringView(const Char *f, const Char *l) + : QStringView(f, l - f) {} + #ifdef Q_QDOC template <typename Char, size_t N> Q_DECL_CONSTEXPR QStringView(const Char (&array)[N]) Q_DECL_NOTHROW; diff --git a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp index 28f81e50e7..9617afb651 100644 --- a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp @@ -171,6 +171,38 @@ private Q_SLOTS: #endif } + 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 + { +#if defined(Q_COMPILER_UNICODE_STRINGS) + const char16_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' }; + fromRange(std::begin(str), std::end(str)); +#else + QSKIP("This test requires C++11 char16_t support enabled in the compiler"); +#endif + } + + void fromWCharTRange() const + { +#ifdef Q_OS_WIN + const wchar_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' }; + fromRange(std::begin(str), std::end(str)); +#else + QSKIP("This is a Windows-only test"); +#endif + } + // std::basic_string void fromStdStringWCharT() const { @@ -194,6 +226,8 @@ private: 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> @@ -211,6 +245,10 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv.empty()); Q_STATIC_ASSERT(sv.isEmpty()); Q_STATIC_ASSERT(sv.utf16() == nullptr); + + constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size()); + Q_STATIC_ASSERT(sv2.isNull()); + Q_STATIC_ASSERT(sv2.empty()); } { constexpr QStringView sv = QStringViewLiteral(""); @@ -219,6 +257,10 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv.empty()); Q_STATIC_ASSERT(sv.isEmpty()); Q_STATIC_ASSERT(sv.utf16() != nullptr); + + constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size()); + Q_STATIC_ASSERT(!sv2.isNull()); + Q_STATIC_ASSERT(sv2.empty()); } { constexpr QStringView sv = QStringViewLiteral("Hello"); @@ -235,6 +277,11 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv.at(4) == QLatin1Char('o')); Q_STATIC_ASSERT(sv.back() == QLatin1Char('o')); Q_STATIC_ASSERT(sv.last() == QLatin1Char('o')); + + constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size()); + Q_STATIC_ASSERT(!sv2.isNull()); + Q_STATIC_ASSERT(!sv2.empty()); + Q_STATIC_ASSERT(sv2.size() == 5); } #if !defined(Q_OS_WIN) || defined(Q_COMPILER_UNICODE_STRINGS) { @@ -253,6 +300,11 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv.at(4) == QLatin1Char('o')); Q_STATIC_ASSERT(sv.back() == QLatin1Char('o')); Q_STATIC_ASSERT(sv.last() == QLatin1Char('o')); + + constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size()); + Q_STATIC_ASSERT(!sv2.isNull()); + Q_STATIC_ASSERT(!sv2.empty()); + Q_STATIC_ASSERT(sv2.size() == 5); } #else // storage_type is wchar_t { @@ -271,6 +323,11 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv.at(4) == QLatin1Char('o')); Q_STATIC_ASSERT(sv.back() == QLatin1Char('o')); Q_STATIC_ASSERT(sv.last() == QLatin1Char('o')); + + constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size()); + Q_STATIC_ASSERT(!sv2.isNull()); + Q_STATIC_ASSERT(!sv2.empty()); + Q_STATIC_ASSERT(sv2.size() == 5); } #endif #endif @@ -349,6 +406,24 @@ void tst_QStringView::fromLiteral(const Char *arg) const conversion_tests(arg); } +template <typename Char> +void tst_QStringView::fromRange(const Char *first, const Char *last) const +{ + const Char *null = nullptr; + QCOMPARE(QStringView(null, null).size(), 0); + QCOMPARE(QStringView(null, null).data(), nullptr); + QCOMPARE(QStringView(first, first).size(), 0); + QCOMPARE(static_cast<const void*>(QStringView(first, first).data()), + static_cast<const void*>(first)); + + const auto sv = QStringView(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_QStringView::fromContainer() const { |