5#ifndef QSTRINGALGORITHMS_P_H
6#define QSTRINGALGORITHMS_P_H
25template <
typename StringType>
struct QStringAlgorithms
27 typedef typename StringType::value_type Char;
28 typedef typename StringType::size_type size_type;
29 typedef typename std::remove_cv<StringType>::type NakedStringType;
31 std::conditional_t<std::is_same_v<StringType, QString>, QStringView, QByteArrayView>;
32 using ViewChar =
typename ViewType::storage_type;
33 static const bool isConst = std::is_const<StringType>::value;
35 static inline bool isSpace(
char ch) {
return ascii_isspace(ch); }
36 static inline bool isSpace(QChar ch) {
return ch.isSpace(); }
42 static inline StringType trimmed_helper_inplace(NakedStringType &str,
const Char *begin,
const Char *end)
45 Char *data =
const_cast<Char *>(str.cbegin());
47 memmove(data, begin, (end - begin) *
sizeof(Char));
48 str.resize(end - begin);
49 return std::move(str);
52 static inline StringType trimmed_helper_inplace(
const NakedStringType &,
const Char *,
const Char *)
55 Q_UNREACHABLE_RETURN(StringType());
58 struct TrimPositions {
67 [[nodiscard]]
static TrimPositions trimmed_helper_positions(
const StringType &str)
69 const Char *begin = str.cbegin();
70 const Char *end = str.cend();
72 while (begin < end && isSpace(end[-1]))
75 while (begin < end && isSpace(*begin))
80 static inline StringType trimmed_helper(StringType &str)
82 const auto [begin, end] = trimmed_helper_positions(str);
83 if (begin == str.cbegin() && end == str.cend())
85 if (!isConst && str.isDetached())
86 return trimmed_helper_inplace(str, begin, end);
87 return StringType(begin, end - begin);
90 static inline StringType simplified_helper(StringType &str)
94 const Char *src = str.cbegin();
95 const Char *end = str.cend();
96 NakedStringType result = isConst || !str.isDetached() ?
97 StringType(str.size(), Qt::Uninitialized) :
100 Char *dst =
const_cast<Char *>(result.cbegin());
102 bool unmodified =
true;
104 while (src != end && isSpace(*src))
106 while (src != end && !isSpace(*src))
110 if (*src != QChar::Space)
112 *ptr++ = QChar::Space;
114 if (ptr != dst && ptr[-1] == QChar::Space)
117 qsizetype newlen = ptr - dst;
118 if (isConst && newlen == str.size() && unmodified) {
122 result.resize(newlen);
126 static inline bool needsReallocate(
const StringType &str, qsizetype newSize)
noexcept
128 const auto capacityAtEnd = str.capacity() - str.data_ptr().freeSpaceAtBegin();
129 return newSize > capacityAtEnd;
132 static inline const ViewChar *asUnicodeChar(ViewType v)
134 if constexpr (
sizeof(ViewChar) ==
sizeof(QChar))
140 static inline qsizetype newSize(StringType &src, qsizetype bsize,
141 ViewType after, QSpan<
const qsizetype> indices)
143 if (bsize == after.size())
145 else if (bsize > after.size())
146 return src.size() - indices.size() * (bsize - after.size());
149 const qsizetype adjust = indices.size() * (after.size() - bsize);
150 return src.size() + adjust;
154 static inline void setSize(StringType &src, qsizetype newSize)
156 Q_ASSERT(src.isDetached());
157 Q_ASSERT(newSize <= src.capacity());
159 auto &d = src.data_ptr();
161 d.data()[newSize] =
'\0';
167 static inline void replace_into_copy(StringType &src, qsizetype bsize,
168 ViewType after, QSpan<
const qsizetype> indices,
171 StringType tmp{newlen, Qt::Uninitialized};
172 auto *to = tmp.data_ptr().data();
173 const auto *a = asUnicodeChar(after);
174 auto *
const begin = src.data_ptr().data();
177 for (
auto i : indices) {
178 to = std::copy(first, begin + i, to);
179 to = std::copy(a, a + after.size(), to);
180 first = begin + i + bsize;
182 std::copy(first, src.data_ptr().end(), to);
186 static inline void replace_equal_len(StringType &src, [[maybe_unused]] qsizetype bsize,
187 ViewType after, QSpan<
const qsizetype> indices)
189 Q_ASSERT(bsize == after.size());
190 Q_ASSERT(!src.data_ptr().needsDetach());
192 const auto *a = asUnicodeChar(after);
193 auto *
const begin = src.data_ptr().data();
195 for (
auto i : indices)
196 std::copy(a, a + after.size(), begin + i);
199 static inline void replace_shrink(StringType &src, qsizetype bsize, ViewType after,
200 QSpan<
const qsizetype> indices)
202 Q_ASSERT(bsize > after.size());
203 Q_ASSERT(!src.data_ptr().needsDetach());
205 const auto *a = asUnicodeChar(after);
206 auto *
const begin = src.data_ptr().data();
207 auto *
const end = begin + src.size();
208 Q_ASSERT(!indices.isEmpty());
209 auto *to = std::copy(a, a + after.size(), begin + indices.front());
210 auto *first = begin + indices.front() + bsize;
211 for (qsizetype i = 1; i < indices.size(); ++i) {
212 auto *last = begin + indices[i];
213 to = std::copy(first, last, to);
214 qsizetype adjust = i * (bsize - after.size());
215 to = std::copy(a, a + after.size(), last - adjust);
216 first = begin + indices[i] + bsize;
218 to = std::copy(first, end, to);
219 setSize(src,to - begin);
222 static inline void replace_grow(StringType &src, qsizetype bsize, ViewType after,
223 QSpan<
const qsizetype> indices, qsizetype newlen)
225 Q_ASSERT(after.size() > bsize);
226 Q_ASSERT(!src.data_ptr().needsDetach());
229 const qsizetype oldlen = src.size();
230 const auto *a = asUnicodeChar(after);
231 setSize(src, newlen);
232 auto *
const begin = src.data_ptr().data();
233 auto *last = begin + oldlen;
234 auto *to = src.data_ptr().end();
235 for (
auto i = indices.size() - 1; i >= 0; --i) {
236 auto *first = begin + indices[i] + bsize;
237 to = std::copy_backward(first, last, to);
238 to = std::copy_backward(a, a + after.size(), to);
239 last = begin + indices[i];
243 static inline void replace_helper(StringType &src, qsizetype bsize, ViewType after,
244 QSpan<
const qsizetype> indices)
246 if (indices.isEmpty())
249 const qsizetype newlen = newSize(src, bsize, after, indices);
250 if (src.data_ptr().needsDetach()
251 || (bsize < after.size() && needsReallocate(src, newlen))) {
255 replace_into_copy(src, bsize, after, indices, newlen);
260 if (bsize == after.size())
261 replace_equal_len(src, bsize, after, indices);
262 else if (bsize > after.size())
263 replace_shrink(src, bsize, after, indices);
265 replace_grow(src, bsize, after, indices, newlen);
QDataStream & operator>>(QDataStream &in, QByteArray &ba)
Reads a byte array into ba from the stream in and returns a reference to the stream.
quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard)
static QLatin1StringView scriptToCode(QLocale::Script script)
QString toUpper(const QString &str, bool *ok) const
static const QLocalePrivate * get(const QLocale &l)
QString toLower(const QString &str, bool *ok) const
quint16 languageId() const
static QLocale::Language codeToLanguage(QStringView code, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) noexcept
const QLocaleData *const m_data
QLatin1StringView scriptCode() const
QLocale::MeasurementSystem measurementSystem() const
quint16 territoryId() const
static QLatin1StringView territoryToCode(QLocale::Territory territory)
static QLocale::Territory codeToTerritory(QStringView code) noexcept
static std::array< char, 4 > languageToCode(QLocale::Language language, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode)
static QLocale::Script codeToScript(QStringView code) noexcept
QLocale::NumberOptions m_numberOptions
QLatin1StringView territoryCode() const
constexpr QLocalePrivate(const QLocaleData *data, qsizetype index, QLocale::NumberOptions numberOptions=QLocale::DefaultNumberOptions, int refs=0)
std::array< char, 4 > languageCode(QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) const
static QBasicAtomicInt s_generation
QByteArray bcp47Name(char separator='-') const
qsizetype fallbackLocaleIndex() const
@ StringToAlternateQuotation
@ StandaloneMonthNameLong
@ StandaloneDayNameNarrow
@ StandaloneMonthNameNarrow
@ StringToStandardQuotation
@ StandaloneMonthNameShort
virtual QLocale fallbackLocale() const
virtual QVariant query(QueryType type, QVariant &&in=QVariant()) const
constexpr char ascii_space_chars[]
constexpr auto makeCharacterSetMatch() noexcept
static constexpr bool isLowerCaseAscii(char c)
static const quint16 crc_tbl[16]
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
static Q_DECL_COLD_FUNCTION const char * zlibOpAsString(ZLibOp op)
static QByteArray toCase_template(T &input, uchar(*lookup)(uchar))
static void q_fromPercentEncoding(QByteArray *ba, char percent)
int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle, qsizetype ol, qsizetype from)
static constexpr bool isUpperCaseAscii(char c)
static QByteArray xxflate(ZLibOp op, QArrayDataPointer< char > out, QByteArrayView input, qxp::function_ref< int(z_stream *) const > init, qxp::function_ref< int(z_stream *, size_t) const > processChunk, qxp::function_ref< void(z_stream *) const > deinit)
static constexpr uchar asciiLower(uchar c)
static qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
static constexpr uchar asciiUpper(uchar c)
Q_CORE_EXPORT char * qstrncpy(char *dst, const char *src, size_t len)
Q_CORE_EXPORT int qstrnicmp(const char *, const char *, size_t len)
Q_CORE_EXPORT int qstricmp(const char *, const char *)
Q_CORE_EXPORT char * qstrdup(const char *)
Q_CORE_EXPORT char * qstrcpy(char *dst, const char *src)
Q_DECL_PURE_FUNCTION Q_CORE_EXPORT const void * qmemrchr(const void *s, int needle, size_t n) noexcept
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
bool qt_splitLocaleName(QStringView name, QStringView *lang=nullptr, QStringView *script=nullptr, QStringView *cntry=nullptr) noexcept
Q_DECLARE_TYPEINFO(QLocaleData::GroupSizes, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE)
qsizetype qt_repeatCount(QStringView s) noexcept
constexpr bool ascii_isspace(uchar c) noexcept
#define ForEachQLocaleRange(X)
QString qt_readEscapedFormatString(QStringView format, qsizetype *idx)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
qregisteruint mask[Extent]
static constexpr int WordBits
static constexpr int MaxRange
constexpr auto maskLocation(uchar c) const noexcept
constexpr QCharacterSetMatch(std::string_view set) noexcept
constexpr bool matches(uchar c) const noexcept
QStringView viewListEntry(const char16_t *table, qsizetype index) const
char32_t ucsFirst(const char16_t *table) const
QString getData(const char16_t *table) const
QString getListEntry(const char16_t *table, qsizetype index) const
QStringView viewData(const char16_t *table) const
void setZero(QStringView zero)
bool fractionalIsGroup() const
const GroupSizes & groupSizes() const
bool isValid(NumberMode mode) const
const GroupSizes grouping
qint8 digitValue(char32_t digit) const
QString positiveSign() const
static float convertDoubleToFloat(double d, bool *ok)
QString groupSeparator() const
QSimpleParsedNumber< qint64 > stringToLongLong(QStringView str, int base, QLocale::NumberOptions options) const
Q_AUTOTEST_EXPORT char32_t zeroUcs() const
QString zeroDigit() const
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options, NumberMode mode, CharBuff *result) const
QString decimalPoint() const
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
static Q_AUTOTEST_EXPORT bool allLocaleDataRows(bool(*check)(qsizetype, const QLocaleData &))
QString listSeparator() const
static QSimpleParsedNumber< quint64 > bytearrayToUnsLongLong(QByteArrayView num, int base)
QString percentSign() const
double stringToDouble(QStringView str, bool *ok, QLocale::NumberOptions options) const
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
quint8 m_first_day_of_week
quint8 m_currency_rounding
QString exponentSeparator() const
QString negativeSign() const
QSimpleParsedNumber< quint64 > stringToUnsLongLong(QStringView str, int base, QLocale::NumberOptions options) const
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
QLocaleId withLikelySubtagsAdded() const noexcept
Fill in blank fields of a locale ID.
QLocaleId withLikelySubtagsRemoved() const noexcept
bool operator==(QLocaleId other) const noexcept
bool matchesAll() const noexcept
bool isValid() const noexcept
bool operator!=(QLocaleId other) const noexcept
bool acceptScriptTerritory(QLocaleId other) const noexcept
bool acceptLanguage(quint16 lang) const noexcept
CurrencyToStringArgument(const QVariant &v, const QString &s)
CurrencyToStringArgument()