/**************************************************************************** ** ** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** 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 Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** 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-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QSTRING_H # include #endif #ifndef QSTRINGVIEW_H #define QSTRINGVIEW_H #include QT_BEGIN_NAMESPACE #ifndef QT_NO_UNICODE_LITERAL # ifndef QT_UNICODE_LITERAL # error "If you change QStringLiteral, please change QStringViewLiteral, too" # endif # define QStringViewLiteral(str) QStringView(QT_UNICODE_LITERAL(str)) #endif namespace QtPrivate { template struct IsCompatibleCharTypeHelper : std::integral_constant::value || std::is_same::value || #if !defined(Q_OS_WIN) || defined(Q_COMPILER_UNICODE_STRINGS) std::is_same::value || #endif (std::is_same::value && sizeof(wchar_t) == sizeof(QChar))> {}; 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 struct IsCompatiblePointerHelper : IsCompatibleCharType {}; template struct IsCompatiblePointer : IsCompatiblePointerHelper::type>::type> {}; template struct IsCompatibleStdBasicStringHelper : std::false_type {}; template struct IsCompatibleStdBasicStringHelper > : IsCompatibleCharType {}; template struct IsCompatibleStdBasicString : IsCompatibleStdBasicStringHelper< typename std::remove_cv::type>::type > {}; } // namespace QtPrivate class QStringView { #if defined(Q_OS_WIN) && !defined(Q_COMPILER_UNICODE_STRINGS) typedef wchar_t storage_type; #else typedef char16_t storage_type; #endif public: typedef const QChar value_type; typedef std::ptrdiff_t difference_type; typedef QIntegerForSizeof::Signed size_type; typedef value_type &reference; typedef value_type &const_reference; typedef value_type *pointer; typedef value_type *const_pointer; typedef pointer iterator; typedef const_pointer const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; 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 size_type lengthHelperArray(const Char (&)[N]) Q_DECL_NOTHROW { return size_type(N - 1); } template 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 lengthHelperPointer(const QChar *str) Q_DECL_NOTHROW { size_type result = 0; while (!str++->isNull()) ++result; return result; } template static const storage_type *castHelper(const Char *str) Q_DECL_NOTHROW { return reinterpret_cast(str); } static Q_DECL_CONSTEXPR const storage_type *castHelper(const storage_type *str) Q_DECL_NOTHROW { return str; } public: Q_DECL_CONSTEXPR QStringView() Q_DECL_NOTHROW : m_size(0), m_data(nullptr) {} Q_DECL_CONSTEXPR QStringView(std::nullptr_t) Q_DECL_NOTHROW : QStringView() {} #if QT_DEPRECATED_SINCE(5, 9) Q_DECL_CONSTEXPR QStringView(QString::Null) Q_DECL_NOTHROW : QStringView() {} #endif template = true> Q_DECL_CONSTEXPR QStringView(const Char *str, size_type len) : m_size((Q_ASSERT(len >= 0), Q_ASSERT(str || !len), len)), m_data(castHelper(str)) {} #ifdef Q_QDOC template Q_DECL_CONSTEXPR QStringView(const Char (&array)[N]) Q_DECL_NOTHROW; template Q_DECL_CONSTEXPR QStringView(const Char *str) Q_DECL_NOTHROW; #else template = true> Q_DECL_CONSTEXPR QStringView(const Array &str) Q_DECL_NOTHROW : QStringView(str, lengthHelperArray(str)) {} template = 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; QStringView(const QStringRef &str) Q_DECL_NOTHROW; #else template = true> QStringView(const String &str) Q_DECL_NOTHROW : QStringView(str.isNull() ? nullptr : str.data(), size_type(str.size())) {} #endif template = true> QStringView(const StdBasicString &str) Q_DECL_NOTHROW : QStringView(str.data(), size_type(str.size())) {} QString toString() const { return Q_ASSERT(size() == length()), QString(data(), length()); } Q_DECL_CONSTEXPR size_type size() const Q_DECL_NOTHROW { return m_size; } const_pointer data() const Q_DECL_NOTHROW { return reinterpret_cast(m_data); } Q_DECL_CONSTEXPR const storage_type *utf16() const Q_DECL_NOTHROW { return m_data; } Q_DECL_CONSTEXPR QChar operator[](size_type n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n < size()), QChar(m_data[n]); } // // QString API // Q_DECL_CONSTEXPR QChar at(size_type n) const { return (*this)[n]; } Q_DECL_CONSTEXPR QStringView mid(size_type pos) const { return Q_ASSERT(pos >= 0), Q_ASSERT(pos <= size()), QStringView(m_data + pos, m_size - pos); } Q_DECL_CONSTEXPR QStringView mid(size_type pos, size_type n) const { return Q_ASSERT(pos >= 0), Q_ASSERT(n >= 0), Q_ASSERT(pos + n <= size()), QStringView(m_data + pos, n); } Q_DECL_CONSTEXPR QStringView left(size_type n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data, n); } Q_DECL_CONSTEXPR QStringView right(size_type n) const { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data + m_size - n, n); } // // STL compatibility API: // const_iterator begin() const Q_DECL_NOTHROW { return data(); } const_iterator end() const Q_DECL_NOTHROW { return data() + size(); } const_iterator cbegin() const Q_DECL_NOTHROW { return begin(); } const_iterator cend() const Q_DECL_NOTHROW { return end(); } const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return rbegin(); } const_reverse_iterator crend() const Q_DECL_NOTHROW { return rend(); } Q_DECL_CONSTEXPR bool empty() const Q_DECL_NOTHROW { return size() == 0; } Q_DECL_CONSTEXPR QChar front() const { return Q_ASSERT(!empty()), QChar(m_data[0]); } Q_DECL_CONSTEXPR QChar back() const { return Q_ASSERT(!empty()), QChar(m_data[m_size - 1]); } // // Qt compatibility API: // Q_DECL_CONSTEXPR bool isNull() const Q_DECL_NOTHROW { return !m_data; } Q_DECL_CONSTEXPR bool isEmpty() const Q_DECL_NOTHROW { return empty(); } Q_DECL_CONSTEXPR int length() const /* not nothrow! */ { return Q_ASSERT(int(size()) == size()), int(size()); } Q_DECL_CONSTEXPR QChar first() const { return front(); } Q_DECL_CONSTEXPR QChar last() const { return back(); } private: size_type m_size; const storage_type *m_data; }; Q_DECLARE_TYPEINFO(QStringView, Q_MOVABLE_TYPE); QT_END_NAMESPACE #endif /* QSTRINGVIEW_H */