1 /****************************************************************************
2 **
3 ** DQt - D bindings for the Qt Toolkit
4 **
5 ** GNU Lesser General Public License Usage
6 ** This file may be used under the terms of the GNU Lesser
7 ** General Public License version 3 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
9 ** packaging of this file. Please review the following information to
10 ** ensure the GNU Lesser General Public License version 3 requirements
11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
12 **
13 ****************************************************************************/
14 module qt.core.stringview;
15 extern(C++):
16 
17 import core.stdc.config;
18 import qt.config;
19 import qt.core.bytearray;
20 import qt.core.global;
21 import qt.core.list;
22 import qt.core.namespace;
23 import qt.core.qchar;
24 import qt.core.regularexpression;
25 import qt.core.string;
26 import qt.core.typeinfo;
27 import qt.core.vector;
28 import qt.helpers;
29 
30 /+ #ifndef QT_STRINGVIEW_LEVEL
31 #  define QT_STRINGVIEW_LEVEL 1
32 #endif
33 
34 
35 class QString;
36 class QStringRef;
37 class QRegularExpression;
38 
39 namespace QtPrivate {
40 template <typename Char>
41 struct IsCompatibleCharTypeHelper
42     : std::integral_constant<bool,
43                              std::is_same<Char, QChar>::value ||
44                              std::is_same<Char, ushort>::value ||
45                              std::is_same<Char, char16_t>::value ||
46                              (std::is_same<Char, wchar_t>::value && sizeof(wchar_t) == sizeof(QChar))> {};
47 template <typename Char>
48 struct IsCompatibleCharType
49     : IsCompatibleCharTypeHelper<typename std::remove_cv<typename std::remove_reference<Char>::type>::type> {};
50 
51 template <typename Array>
52 struct IsCompatibleArrayHelper : std::false_type {};
53 template <typename Char, size_t N>
54 struct IsCompatibleArrayHelper<Char[N]>
55     : IsCompatibleCharType<Char> {};
56 template <typename Array>
57 struct IsCompatibleArray
58     : IsCompatibleArrayHelper<typename std::remove_cv<typename std::remove_reference<Array>::type>::type> {};
59 
60 template <typename Pointer>
61 struct IsCompatiblePointerHelper : std::false_type {};
62 template <typename Char>
63 struct IsCompatiblePointerHelper<Char*>
64     : IsCompatibleCharType<Char> {};
65 template <typename Pointer>
66 struct IsCompatiblePointer
67     : IsCompatiblePointerHelper<typename std::remove_cv<typename std::remove_reference<Pointer>::type>::type> {};
68 
69 template <typename T>
70 struct IsCompatibleStdBasicStringHelper : std::false_type {};
71 template <typename Char, typename...Args>
72 struct IsCompatibleStdBasicStringHelper<std::basic_string<Char, Args...> >
73     : IsCompatibleCharType<Char> {};
74 
75 template <typename T>
76 struct IsCompatibleStdBasicString
77     : IsCompatibleStdBasicStringHelper<
78         typename std::remove_cv<typename std::remove_reference<T>::type>::type
79       > {};
80 
81 } +/ // namespace QtPrivate
82 
83 @Q_PRIMITIVE_TYPE extern(C++, class) struct QStringView
84 {
85     static import qt.core.stringalgorithms;
86 public:
87     alias storage_type = wchar;
88     alias value_type = const(QChar);
89     alias difference_type = /+ std:: +/ptrdiff_t;
90     alias size_type = qsizetype;
91     /+ typedef value_type &reference; +/
92     /+ typedef value_type &const_reference; +/
93     alias pointer = value_type*;
94     alias const_pointer = value_type*;
95 
96     alias iterator = pointer;
97     alias const_iterator = const_pointer;
98     /+ typedef std::reverse_iterator<iterator> reverse_iterator; +/
99     /+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; +/
100 
101 private:
102     /+ template <typename Char> +/
103     /+ using if_compatible_char = typename std::enable_if<QtPrivate::IsCompatibleCharType<Char>::value, bool>::type; +/
104 
105     /+ template <typename Array> +/
106     /+ using if_compatible_array = typename std::enable_if<QtPrivate::IsCompatibleArray<Array>::value, bool>::type; +/
107 
108     /+ template <typename Pointer> +/
109     /+ using if_compatible_pointer = typename std::enable_if<QtPrivate::IsCompatiblePointer<Pointer>::value, bool>::type; +/
110 
111     /+ template <typename T> +/
112     /+ using if_compatible_string = typename std::enable_if<QtPrivate::IsCompatibleStdBasicString<T>::value, bool>::type; +/
113 
114     /+ template <typename T> +/
115     /+ using if_compatible_qstring_like = typename std::enable_if<std::is_same<T, QString>::value || std::is_same<T, QStringRef>::value, bool>::type; +/
116 
117     /+ template <typename Char, size_t N> +/
118     /+ static qsizetype lengthHelperArray(const Char (&)[N]) noexcept
119     {
120         return qsizetype(N - 1);
121     } +/
122 
123     /+ template <typename Char> +/
124     /+ static qsizetype lengthHelperPointer(const Char *str) noexcept
125     {
126 #if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
127         if (__builtin_constant_p(*str)) {
128             qsizetype result = 0;
129             while (*str++)
130                 ++result;
131             return result;
132         }
133 #endif
134         return QtPrivate::qustrlen(reinterpret_cast<const ushort *>(str));
135     } +/
136     static qsizetype lengthHelperPointer(const(QChar)* str)/+ noexcept+/
137     {
138         import qt.core.stringalgorithms;
139 
140         return /+ QtPrivate:: +/qt.core.stringalgorithms.qustrlen(reinterpret_cast!(const(ushort)*)(str));
141     }
142 
143     static const(storage_type) *castHelper(Char)(const Char *str) /*noexcept*/
144     { return reinterpret_cast!(const storage_type*)(str); }
145     static const(storage_type)* castHelper(const(storage_type)* str)/+ noexcept+/
146     { return str; }
147 
148 public:
149     /+this()/+ noexcept+/
150     {
151         this.m_size = 0;
152         this.m_data = null;
153     }+/
154     this(typeof(null))/+ noexcept+/
155     {
156         //this();
157     }
158 
159     /+ template <typename Char, if_compatible_char<Char> = true> +/
160     this(Char)(const Char *str, qsizetype len) if(is(Char == QChar) || is(Char == ushort) || is(Char == wchar))
161     {
162         assert(len >= 0);
163         assert(str || !len);
164         m_size = len;
165         m_data = castHelper(str);
166     }
167 
168     /+ template <typename Char, if_compatible_char<Char> = true> +/
169     /+ QStringView(const Char *f, const Char *l)
170         : QStringView(f, l - f) {} +/
171 
172 /+ #ifdef Q_CLANG_QDOC
173     template <typename Char, size_t N>
174     QStringView(const Char (&array)[N]) noexcept;
175 
176     template <typename Char>
177     QStringView(const Char *str) noexcept;
178 #else
179 #if QT_DEPRECATED_SINCE(5, 14) +/
180     /+ template <typename Array, if_compatible_array<Array> = true> +/
181     /+ QT_DEPRECATED_VERSION_X_5_14(R"(Use u"~~~" or QStringView(u"~~~") instead of QStringViewLiteral("~~~"))")
182     QStringView(const Array &str, QtPrivate::Deprecated_t) noexcept
183         : QStringView(str, lengthHelperArray(str)) {} +/
184 /+ #endif // QT_DEPRECATED_SINCE
185 
186     template <typename Array, if_compatible_array<Array> = true>
187     QStringView(const Array &str) noexcept
188         : QStringView(str, lengthHelperArray(str)) {}
189 
190     template <typename Pointer, if_compatible_pointer<Pointer> = true>
191     QStringView(const Pointer &str) noexcept
192         : QStringView(str, str ? lengthHelperPointer(str) : 0) {}
193 #endif
194 
195 #ifdef Q_CLANG_QDOC
196     QStringView(const QString &str) noexcept;
197     QStringView(const QStringRef &str) noexcept;
198 #else +/
199     /+ template <typename String, if_compatible_qstring_like<String> = true> +/
200     /+ QStringView(const String &str) noexcept
201         : QStringView(str.isNull() ? nullptr : str.data(), qsizetype(str.size())) {} +/
202     this(String)(ref const String str) /*nothrow*/
203     {
204         this(str.isNull() ? null : str.data(), qsizetype(str.size()));
205     }
206 /+ #endif +/
207 
208     /+ template <typename StdBasicString, if_compatible_string<StdBasicString> = true> +/
209     /+ QStringView(const StdBasicString &str) noexcept
210         : QStringView(str.data(), qsizetype(str.size())) {} +/
211 
212     //
213     // QStringView inline members that require QString:
214     //
215     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) QString toString() const
216     { return (){ (mixin(Q_ASSERT(q{QStringView.size() == QStringView.length()})));
217     return QString(data(), length());
218     }(); } // defined in qstring.h
219 
220     /+ Q_REQUIRED_RESULT +/ qsizetype size() const/+ noexcept+/ { return m_size; }
221     /+ Q_REQUIRED_RESULT +/ const_pointer data() const/+ noexcept+/ { return reinterpret_cast!(const_pointer)(m_data); }
222     /+ Q_REQUIRED_RESULT +/ const(storage_type)* utf16() const/+ noexcept+/ { return m_data; }
223 
224     /+ Q_REQUIRED_RESULT +/ QChar opIndex(qsizetype n) const
225     { return (){(){ (mixin(Q_ASSERT(q{n >= 0})));
226 return /+ Q_ASSERT(n < size()) +/ mixin(Q_ASSERT(q{n < QStringView.size()}));
227 }();
228 return QChar(m_data[n]);
229 }(); }
230 
231     //
232     // QString API
233     //
234 
235     /+ template <typename...Args> +/
236     /+ Q_REQUIRED_RESULT inline QString arg(Args &&...args) const; +/ // defined in qstring.h
237 
238     /+ Q_REQUIRED_RESULT +/ QByteArray toLatin1() const {
239         import qt.core.stringalgorithms;
240         return /+ QtPrivate:: +/qt.core.stringalgorithms.convertToLatin1(this);
241     }
242     /+ Q_REQUIRED_RESULT +/ QByteArray toUtf8() const {
243         import qt.core.stringalgorithms;
244         return /+ QtPrivate:: +/qt.core.stringalgorithms.convertToUtf8(this);
245     }
246     /+ Q_REQUIRED_RESULT +/ QByteArray toLocal8Bit() const {
247         import qt.core.stringalgorithms;
248         return /+ QtPrivate:: +/qt.core.stringalgorithms.convertToLocal8Bit(this);
249     }
250     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) QVector!(uint) toUcs4() const {
251         import qt.core.stringalgorithms;
252         return /+ QtPrivate:: +/qt.core.stringalgorithms.convertToUcs4(this);
253     } // defined in qvector.h
254 
255     /+ Q_REQUIRED_RESULT +/ QChar at(qsizetype n) const { return (this)[n]; }
256 
257     /+ Q_REQUIRED_RESULT +/ QStringView mid(qsizetype pos) const
258     {
259         return QStringView(m_data + qBound(qsizetype(0), pos, m_size), m_size - qBound(qsizetype(0), pos, m_size));
260     }
261     /+ Q_REQUIRED_RESULT +/ QStringView mid(qsizetype pos, qsizetype n) const
262     {
263         return QStringView(m_data + qBound(qsizetype(0), pos, m_size), qBound(qsizetype(0), pos + n, m_size) - qBound(qsizetype(0), pos, m_size));
264     }
265     /+ Q_REQUIRED_RESULT +/ QStringView left(qsizetype n) const
266     {
267         return QStringView(m_data, (size_t(n) > size_t(m_size) ? m_size : n));
268     }
269     /+ Q_REQUIRED_RESULT +/ QStringView right(qsizetype n) const
270     {
271         return QStringView(m_data + m_size - (size_t(n) > size_t(m_size) ? m_size : n), (size_t(n) > size_t(m_size) ? m_size : n));
272     }
273     /+ Q_REQUIRED_RESULT +/ QStringView chopped(qsizetype n) const
274     { return (){(){ (mixin(Q_ASSERT(q{n >= 0})));
275 return /+ Q_ASSERT(n <= size()) +/ mixin(Q_ASSERT(q{n <= QStringView.size()}));
276 }();
277 return QStringView(m_data, m_size - n);
278 }(); }
279 
280     void truncate(qsizetype n)
281     { (mixin(Q_ASSERT(q{n >= 0}))); (mixin(Q_ASSERT(q{n <= QStringView.size()}))); m_size = n; }
282     void chop(qsizetype n)
283     { (mixin(Q_ASSERT(q{n >= 0}))); (mixin(Q_ASSERT(q{n <= QStringView.size()}))); m_size -= n; }
284 
285     /+ Q_REQUIRED_RESULT +/ QStringView trimmed() const/+ noexcept+/ {
286         import qt.core.stringalgorithms;
287         return /+ QtPrivate:: +/qt.core.stringalgorithms.trimmed(this);
288     }
289 
290     /+ Q_REQUIRED_RESULT +/ int compare(QStringView other, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
291     {
292         import qt.core.stringalgorithms;
293         return /+ QtPrivate:: +/qt.core.stringalgorithms.compareStrings(this, other, cs);
294     }
295     //
296     // QStringView members that require QLatin1String:
297     //
298     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) int compare(QLatin1String s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
299     {
300         import qt.core.stringalgorithms;
301         return /+ QtPrivate:: +/qt.core.stringalgorithms.compareStrings(this, s, cs);
302     }
303     /+ Q_REQUIRED_RESULT +/ int compare(QChar c) const/+ noexcept+/
304     { return size() >= 1 ? compare_single_char_helper(*utf16() - c.unicode()) : -1; }
305     /+ Q_REQUIRED_RESULT +/ int compare(QChar c, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs) const/+ noexcept+/
306     {
307         import qt.core.stringalgorithms;
308         return /+ QtPrivate:: +/qt.core.stringalgorithms.compareStrings(this, QStringView(&c, 1), cs);
309     }
310 
311     /+ Q_REQUIRED_RESULT +/ bool startsWith(QStringView s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
312     {
313         import qt.core.stringalgorithms;
314         return /+ QtPrivate:: +/qt.core.stringalgorithms.startsWith(this, s, cs);
315     }
316     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) bool startsWith(QLatin1String s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
317     {
318         import qt.core.stringalgorithms;
319         return /+ QtPrivate:: +/qt.core.stringalgorithms.startsWith(this, s, cs);
320     }
321     /+ Q_REQUIRED_RESULT +/ bool startsWith(QChar c) const/+ noexcept+/
322     { return !empty() && front() == c; }
323     /+ Q_REQUIRED_RESULT +/ bool startsWith(QChar c, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs) const/+ noexcept+/
324     {
325         import qt.core.stringalgorithms;
326         return /+ QtPrivate:: +/qt.core.stringalgorithms.startsWith(this, QStringView(&c, 1), cs);
327     }
328 
329     /+ Q_REQUIRED_RESULT +/ bool endsWith(QStringView s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
330     {
331         import qt.core.stringalgorithms;
332         return /+ QtPrivate:: +/qt.core.stringalgorithms.endsWith(this, s, cs);
333     }
334     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) bool endsWith(QLatin1String s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
335     {
336         import qt.core.stringalgorithms;
337         return /+ QtPrivate:: +/qt.core.stringalgorithms.endsWith(this, s, cs);
338     }
339     /+ Q_REQUIRED_RESULT +/ bool endsWith(QChar c) const/+ noexcept+/
340     { return !empty() && back() == c; }
341     /+ Q_REQUIRED_RESULT +/ bool endsWith(QChar c, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs) const/+ noexcept+/
342     {
343         import qt.core.stringalgorithms;
344         return /+ QtPrivate:: +/qt.core.stringalgorithms.endsWith(this, QStringView(&c, 1), cs);
345     }
346 
347     /+ Q_REQUIRED_RESULT +/ qsizetype indexOf(QChar c, qsizetype from = 0, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
348     {
349         import qt.core.stringalgorithms;
350         return /+ QtPrivate:: +/qt.core.stringalgorithms.findString(this, from, QStringView(&c, 1), cs);
351     }
352     /+ Q_REQUIRED_RESULT +/ qsizetype indexOf(QStringView s, qsizetype from = 0, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
353     {
354         import qt.core.stringalgorithms;
355         return /+ QtPrivate:: +/qt.core.stringalgorithms.findString(this, from, s, cs);
356     }
357     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) qsizetype indexOf(QLatin1String s, qsizetype from = 0, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
358     {
359         import qt.core.stringalgorithms;
360         return /+ QtPrivate:: +/qt.core.stringalgorithms.findString(this, from, s, cs);
361     }
362 
363     /+ Q_REQUIRED_RESULT +/ bool contains(QChar c, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
364     { return indexOf(QStringView(&c, 1), 0, cs) != qsizetype(-1); }
365     /+ Q_REQUIRED_RESULT +/ bool contains(QStringView s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
366     { return indexOf(s, 0, cs) != qsizetype(-1); }
367     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) bool contains(QLatin1String s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
368     { return indexOf(s, 0, cs) != qsizetype(-1); }
369 
370     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) qsizetype count(QChar c, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
371     { return toString().count(c, cs); }
372     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) qsizetype count(QStringView s, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
373     { auto tmp = s.toString(); return toString().count(tmp, cs); }
374 
375     /+ Q_REQUIRED_RESULT +/ qsizetype lastIndexOf(QChar c, qsizetype from = -1, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
376     {
377         import qt.core.stringalgorithms;
378         return /+ QtPrivate:: +/qt.core.stringalgorithms.lastIndexOf(this, from, QStringView(&c, 1), cs);
379     }
380     /+ Q_REQUIRED_RESULT +/ qsizetype lastIndexOf(QStringView s, qsizetype from = -1, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
381     {
382         import qt.core.stringalgorithms;
383         return /+ QtPrivate:: +/qt.core.stringalgorithms.lastIndexOf(this, from, s, cs);
384     }
385     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) qsizetype lastIndexOf(QLatin1String s, qsizetype from = -1, /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const/+ noexcept+/
386     {
387         import qt.core.stringalgorithms;
388         return /+ QtPrivate:: +/qt.core.stringalgorithms.lastIndexOf(this, from, s, cs);
389     }
390 
391     /+ Q_REQUIRED_RESULT +/ bool isRightToLeft() const/+ noexcept+/
392     {
393         import qt.core.stringalgorithms;
394         return /+ QtPrivate:: +/qt.core.stringalgorithms.isRightToLeft(this);
395     }
396     /+ Q_REQUIRED_RESULT +/ bool isValidUtf16() const/+ noexcept+/
397     {
398         import qt.core.stringalgorithms;
399         return /+ QtPrivate:: +/qt.core.stringalgorithms.isValidUtf16(this);
400     }
401 
402     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) short toShort(bool* ok = null, int base = 10) const
403     { return toString().toShort(ok, base); }
404     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) ushort toUShort(bool* ok = null, int base = 10) const
405     { return toString().toUShort(ok, base); }
406     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) int toInt(bool* ok = null, int base = 10) const
407     { return toString().toInt(ok, base); }
408     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) uint toUInt(bool* ok = null, int base = 10) const
409     { return toString().toUInt(ok, base); }
410     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) cpp_long toLong(bool* ok = null, int base = 10) const
411     { return toString().toLong(ok, base); }
412     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) cpp_ulong toULong(bool* ok = null, int base = 10) const
413     { return toString().toULong(ok, base); }
414     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) qlonglong toLongLong(bool* ok = null, int base = 10) const
415     { return toString().toLongLong(ok, base); }
416     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) qulonglong toULongLong(bool* ok = null, int base = 10) const
417     { return toString().toULongLong(ok, base); }
418     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) float toFloat(bool* ok = null) const
419     { return toString().toFloat(ok); }
420     /+ Q_REQUIRED_RESULT +/ pragma(inline, true) double toDouble(bool* ok = null) const
421     { return toString().toDouble(ok); }
422 
423 /+    /+ Q_REQUIRED_RESULT +/ pragma(inline, true) int toWCharArray(wchar_t* array) const
424     {
425         import core.stdc.string;
426 
427         if (wchar_t.sizeof == QChar.sizeof) {
428             if (auto src = data())
429                 memcpy(array, cast(const(void)*)(src), QChar.sizeof * size());
430             return cast(int)(size());     // ### q6sizetype
431         } else {
432             return QString.toUcs4_helper(reinterpret_cast!(const(ushort)*)(data()), int(size()),
433                                           reinterpret_cast!(uint*)(array));
434         }
435     } // defined in qstring.h +/
436 
437     // those methods need to be here, so they can be implemented inline
438     /+ Q_REQUIRED_RESULT +/ 
439 /+        pragma(inline, true) QList!(QStringView) split(QStringView sep,
440                                  /+ Qt:: +/qt.core.namespace.SplitBehavior behavior = /+ Qt:: +/qt.core.namespace.SplitBehaviorFlags.KeepEmptyParts,
441                                  /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const
442     {
443         (mixin(Q_ASSERT(q{cast(int)(QStringView.m_size) == QStringView.m_size})));
444         QString s = QString.fromRawData(data(), cast(int)(m_size));
445         const split = s.splitRef(sep.toString(), behavior, cs);
446         QList!QStringView result;
447         foreach (const ref QStringRef r; split)
448             result.append(QStringView(m_data + r.position(), r.size()));
449         return result;
450     }+/
451     /+ Q_REQUIRED_RESULT +/ 
452 /+        pragma(inline, true) QList!(QStringView) split(QChar sep, /+ Qt:: +/qt.core.namespace.SplitBehavior behavior = /+ Qt:: +/qt.core.namespace.SplitBehaviorFlags.KeepEmptyParts,
453                                  /+ Qt:: +/qt.core.namespace.CaseSensitivity cs = /+ Qt:: +/qt.core.namespace.CaseSensitivity.CaseSensitive) const
454     {
455         (mixin(Q_ASSERT(q{int(QStringView.m_size) == QStringView.m_size})));
456         QString s = QString.fromRawData(data(), int(m_size));
457         const split = s.splitRef(sep, behavior, cs);
458         QList!QStringView result;
459         foreach (const ref QStringRef r; split)
460             result.append(QStringView(m_data + r.position(), r.size()));
461         return result;
462     }+/
463 
464 /+ #if QT_CONFIG(regularexpression) +/
465     // implementation here, so we have all required classes
466     /+ Q_REQUIRED_RESULT +/ 
467 /+        pragma(inline, true) QList!(QStringView) split(ref const(QRegularExpression) sep, /+ Qt:: +/qt.core.namespace.SplitBehavior behavior = /+ Qt:: +/qt.core.namespace.SplitBehaviorFlags.KeepEmptyParts) const
468     {
469         (mixin(Q_ASSERT(q{int(QStringView.m_size) == QStringView.m_size})));
470         QString s = QString.fromRawData(data(), int(m_size));
471         const split = s.splitRef(sep, behavior);
472         QList!QStringView result;
473         result.reserve(split.size());
474         foreach(const ref QStringRef r; split)
475             result.append(r);
476         return result;
477     }+/
478 /+ #endif +/
479 
480     //
481     // STL compatibility API:
482     //
483     /+ Q_REQUIRED_RESULT +/ const_iterator begin()   const/+ noexcept+/ { return data(); }
484     /+ Q_REQUIRED_RESULT +/ const_iterator end()     const/+ noexcept+/ { return data() + size(); }
485     /+ Q_REQUIRED_RESULT +/ const_iterator cbegin()  const/+ noexcept+/ { return begin(); }
486     /+ Q_REQUIRED_RESULT +/ const_iterator cend()    const/+ noexcept+/ { return end(); }
487     /+ Q_REQUIRED_RESULT const_reverse_iterator rbegin()  const noexcept { return const_reverse_iterator(end()); } +/
488     /+ Q_REQUIRED_RESULT const_reverse_iterator rend()    const noexcept { return const_reverse_iterator(begin()); } +/
489     /+ Q_REQUIRED_RESULT const_reverse_iterator crbegin() const noexcept { return rbegin(); } +/
490     /+ Q_REQUIRED_RESULT const_reverse_iterator crend()   const noexcept { return rend(); } +/
491 
492     /+ Q_REQUIRED_RESULT +/ bool empty() const/+ noexcept+/ { return size() == 0; }
493     /+ Q_REQUIRED_RESULT +/ QChar front() const { return (){ (mixin(Q_ASSERT(q{!QStringView.empty()})));
494 return QChar(m_data[0]);
495 }(); }
496     /+ Q_REQUIRED_RESULT +/ QChar back()  const { return (){ (mixin(Q_ASSERT(q{!QStringView.empty()})));
497 return QChar(m_data[m_size - 1]);
498 }(); }
499 
500     //
501     // Qt compatibility API:
502     //
503     /+ Q_REQUIRED_RESULT +/ bool isNull() const/+ noexcept+/ { return !m_data; }
504     /+ Q_REQUIRED_RESULT +/ bool isEmpty() const/+ noexcept+/ { return empty(); }
505     /+ Q_REQUIRED_RESULT +/ int length() const /* not nothrow! */
506     { return (){ (mixin(Q_ASSERT(q{cast(int)(QStringView.size()) == QStringView.size()})));
507 return cast(int)(size());
508 }(); }
509     /+ Q_REQUIRED_RESULT +/ QChar first() const { return front(); }
510     /+ Q_REQUIRED_RESULT +/ QChar last()  const { return back(); }
511 private:
512     qsizetype m_size = 0;
513     const(storage_type)* m_data = null;
514 
515     int compare_single_char_helper(int diff) const/+ noexcept+/
516     { return diff ? diff : size() > 1 ? 1 : 0; }
517 }
518 /+ Q_DECLARE_TYPEINFO(QStringView, Q_PRIMITIVE_TYPE); +/
519 
520 pragma(inline, true) QStringView qToStringViewIgnoringNull(QStringLike, /+ typename std::enable_if<
521     std::is_same<QStringLike, QString>::value || std::is_same<QStringLike, QStringRef>::value,
522     bool>::type +/ /+ = true +/)(ref const(QStringLike) s)/+ noexcept+/
523 { return QStringView(s.data(), s.size()); }
524