From 9e1dc1e8a9fda1a7576cc6377c8a36decff631eb Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 12 May 2020 11:00:19 +0200 Subject: QStringView: add converting constructor from array-like containers Centralize, rather than keeping adding constructors from any array-like container. A more robust implementation, likely following the converting constructor for std::span ([span.cons]), is out of scope for C++17 and will require C++20's ranges and concepts. [ChangeLog][QtCore][QStringView] QStringView can now be constructed from any contiguous container, as long as they hold string-like data. For instance, it's now possible to create a QStringView object from a std::vector, a QVarLengthArray and so on. Change-Id: I7043eb194f617e98bd1f8af1237777a93a6c5e75 Reviewed-by: Marc Mutz --- src/corelib/text/qstringview.h | 73 ++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index dc929902fa..0ae1772530 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class QString; class QStringRef; +class QStringView; namespace QtPrivate { template @@ -85,15 +86,6 @@ template struct IsCompatibleCharType : IsCompatibleCharTypeHelper::type>::type> {}; -template -struct IsCompatibleArrayHelper : std::false_type {}; -template -struct IsCompatibleArrayHelper - : IsCompatibleCharType {}; -template -struct IsCompatibleArray - : IsCompatibleArrayHelper::type>::type> {}; - template struct IsCompatiblePointerHelper : std::false_type {}; template @@ -103,17 +95,28 @@ template struct IsCompatiblePointer : IsCompatiblePointerHelper::type>::type> {}; -template -struct IsCompatibleStdBasicStringHelper : std::false_type {}; -template -struct IsCompatibleStdBasicStringHelper > - : IsCompatibleCharType {}; +template +struct IsContainerCompatibleWithQStringView : std::false_type {}; template -struct IsCompatibleStdBasicString - : IsCompatibleStdBasicStringHelper< - typename std::remove_cv::type>::type - > {}; +struct IsContainerCompatibleWithQStringView()) )>, + // ... and that has a suitable size ... + std::is_convertible()) ), qsizetype>, + // ... and it's a range as it defines an iterator-like API + IsCompatibleCharType()) )>::value_type>, + std::is_convertible< + decltype( std::begin(std::declval()) != std::end(std::declval()) ), + bool>, + + // These need to be treated specially due to the empty vs null distinction + std::negation, QString>>, + std::negation, QStringRef>>, + + // Don't make an accidental copy constructor + std::negation, QStringView>> + >>> : std::true_type {}; } // namespace QtPrivate @@ -138,23 +141,14 @@ private: template using if_compatible_char = typename std::enable_if::value, bool>::type; - template - using if_compatible_array = typename std::enable_if::value, bool>::type; - template using if_compatible_pointer = typename std::enable_if::value, bool>::type; - template - using if_compatible_string = typename std::enable_if::value, bool>::type; - template using if_compatible_qstring_like = typename std::enable_if::value || std::is_same::value, bool>::type; - template - static Q_DECL_CONSTEXPR qsizetype lengthHelperArray(const Char (&)[N]) noexcept - { - return qsizetype(N - 1); - } + template + using if_compatible_container = typename std::enable_if::value, bool>::type; template static qsizetype lengthHelperPointer(const Char *str) noexcept @@ -174,6 +168,18 @@ private: return QtPrivate::qustrlen(reinterpret_cast(str)); } + template + static Q_DECL_CONSTEXPR qsizetype lengthHelperContainer(const Container &c) noexcept + { + return qsizetype(std::size(c)); + } + + template + static Q_DECL_CONSTEXPR qsizetype lengthHelperContainer(const Char (&)[N]) noexcept + { + return qsizetype(N - 1); + } + template static const storage_type *castHelper(const Char *str) noexcept { return reinterpret_cast(str); } @@ -202,9 +208,6 @@ public: template Q_DECL_CONSTEXPR QStringView(const Char *str) noexcept; #else - template = true> - Q_DECL_CONSTEXPR QStringView(const Array &str) noexcept - : QStringView(str, lengthHelperArray(str)) {} template = true> Q_DECL_CONSTEXPR QStringView(const Pointer &str) noexcept @@ -220,9 +223,9 @@ public: : QStringView(str.isNull() ? nullptr : str.data(), qsizetype(str.size())) {} #endif - template = true> - Q_DECL_CONSTEXPR QStringView(const StdBasicString &str) noexcept - : QStringView(str.data(), qsizetype(str.size())) {} + template = true> + Q_DECL_CONSTEXPR QStringView(const Container &c) noexcept + : QStringView(std::data(c), lengthHelperContainer(c)) {} Q_REQUIRED_RESULT inline QString toString() const; // defined in qstring.h #if defined(Q_OS_DARWIN) || defined(Q_QDOC) -- cgit v1.2.3