1// Copyright (C) 2016 Intel Corporation.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QSTRINGALGORITHMS_P_H
5#define QSTRINGALGORITHMS_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of internal files. This header file may change from version to version
13// without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qstring.h"
19#include "qlocale_p.h" // for ascii_isspace
20
21QT_BEGIN_NAMESPACE
22
23template <typename StringType> struct QStringAlgorithms
24{
25 typedef typename StringType::value_type Char;
26 typedef typename StringType::size_type size_type;
27 typedef typename std::remove_cv<StringType>::type NakedStringType;
28 static const bool isConst = std::is_const<StringType>::value;
29
30 static inline bool isSpace(char ch) { return ascii_isspace(c: ch); }
31 static inline bool isSpace(QChar ch) { return ch.isSpace(); }
32
33 // Surrogate pairs are not handled in either of the functions below. That is
34 // not a problem because there are no space characters (Zs, Zl, Zp) outside the
35 // Basic Multilingual Plane.
36
37 static inline StringType trimmed_helper_inplace(NakedStringType &str, const Char *begin, const Char *end)
38 {
39 // in-place trimming:
40 Char *data = const_cast<Char *>(str.cbegin());
41 if (begin != data)
42 memmove(data, begin, (end - begin) * sizeof(Char));
43 str.resize(end - begin);
44 return std::move(str);
45 }
46
47 static inline StringType trimmed_helper_inplace(const NakedStringType &, const Char *, const Char *)
48 {
49 // can't happen
50 Q_UNREACHABLE_RETURN(StringType());
51 }
52
53 static inline void trimmed_helper_positions(const Char *&begin, const Char *&end)
54 {
55 // skip white space from end
56 while (begin < end && isSpace(end[-1]))
57 --end;
58 // skip white space from start
59 while (begin < end && isSpace(*begin))
60 begin++;
61 }
62
63 static inline StringType trimmed_helper(StringType &str)
64 {
65 const Char *begin = str.cbegin();
66 const Char *end = str.cend();
67 trimmed_helper_positions(begin, end);
68
69 if (begin == str.cbegin() && end == str.cend())
70 return str;
71 if (!isConst && str.isDetached())
72 return trimmed_helper_inplace(str, begin, end);
73 return StringType(begin, end - begin);
74 }
75
76 static inline StringType simplified_helper(StringType &str)
77 {
78 if (str.isEmpty())
79 return str;
80 const Char *src = str.cbegin();
81 const Char *end = str.cend();
82 NakedStringType result = isConst || !str.isDetached() ?
83 StringType(str.size(), Qt::Uninitialized) :
84 std::move(str);
85
86 Char *dst = const_cast<Char *>(result.cbegin());
87 Char *ptr = dst;
88 bool unmodified = true;
89 forever {
90 while (src != end && isSpace(*src))
91 ++src;
92 while (src != end && !isSpace(*src))
93 *ptr++ = *src++;
94 if (src == end)
95 break;
96 if (*src != QChar::Space)
97 unmodified = false;
98 *ptr++ = QChar::Space;
99 }
100 if (ptr != dst && ptr[-1] == QChar::Space)
101 --ptr;
102
103 qsizetype newlen = ptr - dst;
104 if (isConst && newlen == str.size() && unmodified) {
105 // nothing happened, return the original
106 return str;
107 }
108 result.resize(newlen);
109 return result;
110 }
111};
112
113QT_END_NAMESPACE
114
115#endif // QSTRINGALGORITHMS_P_H
116

source code of qtbase/src/corelib/text/qstringalgorithms_p.h