summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2017-03-31 19:52:21 +0200
committerMarc Mutz <marc.mutz@kdab.com>2017-04-04 11:33:08 +0000
commit8b5aa7b6c40d70a7ec15b3ea485f28a142fb247c (patch)
treec61844c946611f71c2953a7b98c0d7728a999389 /src
parentd40dcee642c69784f771aae86531ae65b458f1a5 (diff)
QStringView: add an array ctor
With sufficient enable_if magic, the array ctor can overload the pointer ctor and statically determine the size of the array passed. Consequently, remove the sizeof in QStringViewLiteral again. Change-Id: I486baa3cafefde60ccc5f2b47eb94ee53cefe63c Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qstringview.cpp30
-rw-r--r--src/corelib/tools/qstringview.h53
2 files changed, 74 insertions, 9 deletions
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index ec77e11740..341746e80a 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -260,9 +260,33 @@ QT_BEGIN_NAMESPACE
Passing \c nullptr as \a str is safe and results in a null string view.
- 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.
+ This constructor only participates in overload resolution if \a
+ str is not an array and 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 (&string)[N])
+
+ Constructs a string view on the character string literal \a string.
+ The length is set to \c{N-1}, excluding the trailing \{Char(0)}.
+ If you need the full array, use the constructor from pointer and
+ size instead:
+
+ \code
+ auto sv = QStringView(array, std::size(array)); // using C++17 std::size()
+ \endcode
+
+ \a string must remain valid for the lifetime of this string view
+ object.
+
+ This constructor only participates in overload resolution if \a
+ string is an actual array and \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.
*/
/*!
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 1eb267f78e..acf05a909c 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
# ifndef QT_UNICODE_LITERAL
# error "If you change QStringLiteral, please change QStringViewLiteral, too"
# endif
-# define QStringViewLiteral(str) QStringView(QT_UNICODE_LITERAL(str), sizeof(str) - 1)
+# define QStringViewLiteral(str) QStringView(QT_UNICODE_LITERAL(str))
#endif
namespace QtPrivate {
@@ -69,6 +69,24 @@ template <typename Char>
struct IsCompatibleCharType
: IsCompatibleCharTypeHelper<typename std::remove_cv<typename std::remove_reference<Char>::type>::type> {};
+template <typename Array>
+struct IsCompatibleArrayHelper : std::false_type {};
+template <typename Char, size_t N>
+struct IsCompatibleArrayHelper<Char[N]>
+ : IsCompatibleCharType<Char> {};
+template <typename Array>
+struct IsCompatibleArray
+ : IsCompatibleArrayHelper<typename std::remove_cv<typename std::remove_reference<Array>::type>::type> {};
+
+template <typename Pointer>
+struct IsCompatiblePointerHelper : std::false_type {};
+template <typename Char>
+struct IsCompatiblePointerHelper<Char*>
+ : IsCompatibleCharType<Char> {};
+template <typename Pointer>
+struct IsCompatiblePointer
+ : IsCompatiblePointerHelper<typename std::remove_cv<typename std::remove_reference<Pointer>::type>::type> {};
+
template <typename T>
struct IsCompatibleStdBasicStringHelper : std::false_type {};
template <typename Char, typename...Args>
@@ -108,21 +126,32 @@ private:
template <typename Char>
using if_compatible_char = typename std::enable_if<QtPrivate::IsCompatibleCharType<Char>::value, bool>::type;
+ template <typename Array>
+ using if_compatible_array = typename std::enable_if<QtPrivate::IsCompatibleArray<Array>::value, bool>::type;
+
+ template <typename Pointer>
+ using if_compatible_pointer = typename std::enable_if<QtPrivate::IsCompatiblePointer<Pointer>::value, bool>::type;
+
template <typename T>
using if_compatible_string = typename std::enable_if<QtPrivate::IsCompatibleStdBasicString<T>::value, bool>::type;
template <typename T>
using if_compatible_qstring_like = typename std::enable_if<std::is_same<T, QString>::value || std::is_same<T, QStringRef>::value, bool>::type;
+ template <typename Char, size_t N>
+ static Q_DECL_CONSTEXPR size_type lengthHelperArray(const Char (&)[N]) Q_DECL_NOTHROW
+ {
+ return size_type(N - 1);
+ }
template <typename Char>
- static Q_DECL_RELAXED_CONSTEXPR size_type lengthHelper(const Char *str) Q_DECL_NOTHROW
+ static Q_DECL_RELAXED_CONSTEXPR size_type lengthHelperPointer(const Char *str) Q_DECL_NOTHROW
{
size_type result = 0;
while (*str++)
++result;
return result;
}
- static Q_DECL_RELAXED_CONSTEXPR size_type lengthHelper(const QChar *str) Q_DECL_NOTHROW
+ static Q_DECL_RELAXED_CONSTEXPR size_type lengthHelperPointer(const QChar *str) Q_DECL_NOTHROW
{
size_type result = 0;
while (!str++->isNull())
@@ -151,9 +180,21 @@ 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 *str)
- : QStringView(str, str ? lengthHelper(str) : 0) {}
+#ifdef Q_QDOC
+ template <typename Char, size_t N>
+ Q_DECL_CONSTEXPR QStringView(const Char (&array)[N]) Q_DECL_NOTHROW;
+
+ template <typename Char>
+ Q_DECL_CONSTEXPR QStringView(const Char *str) Q_DECL_NOTHROW;
+#else
+ template <typename Array, if_compatible_array<Array> = true>
+ Q_DECL_CONSTEXPR QStringView(const Array &str) Q_DECL_NOTHROW
+ : QStringView(str, lengthHelperArray(str)) {}
+
+ template <typename Pointer, if_compatible_pointer<Pointer> = true>
+ Q_DECL_CONSTEXPR QStringView(const Pointer &str) Q_DECL_NOTHROW
+ : QStringView(str, str ? lengthHelperPointer(str) : 0) {}
+#endif
#ifdef Q_QDOC
QStringView(const QString &str) Q_DECL_NOTHROW;