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
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype fallbackLocaleIndex() const
@ StringToAlternateQuotation
@ StandaloneMonthNameLong
@ StandaloneDayNameNarrow
@ StandaloneMonthNameNarrow
@ StringToStandardQuotation
@ StandaloneMonthNameShort
virtual QLocale fallbackLocale() const
virtual QVariant query(QueryType type, QVariant &&in=QVariant()) const
Combined button and popup list for selecting options.
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(const QByteArray &input, QByteArray *rvalue, uchar(*lookup)(uchar))
static qsizetype q_fromPercentEncoding(QByteArrayView src, char percent, QSpan< char > buffer)
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 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(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
Descriptor for a digit sequence within a text.
qsizetype size() const
Returns the number of ASCII characters describing the digit sequence.
DigitSequence sliced(qsizetype from, qsizetype count) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
DigitSequence & operator=(const DigitSequence &)=default
QStringView used(const QStringView text) const
Returns the slice of text described by this digit sequence.
Q_DECLARE_FLAGS(Options, Option)
bool hasSign() const
Returns true precisely if the digit sequence parsed includes a leading sign.
bool isEmpty() const
Returns true precisely if this digit sequence represents nothing.
DigitSequence first(qsizetype count) const
Returns a DigitSequence describing a prefix of this.
void transcribeTo(CharBuff *buff) const
Transcribes the ASCII form of this digit sequence to buff.
DigitSequence(DigitSequence &&)=default
DigitSequence & operator=(DigitSequence &&)=default
DigitSequence sliced(qsizetype from) const
Returns a DigitSequence describing a tail of this.
QStringView used(const QStringView text, qsizetype from) const
DigitSequence last(qsizetype count) const
Returns a DigitSequence describing a tail of this.
qsizetype endIndex() const
DigitSequence(const DigitSequence &)=default
void setZero(QStringView zero)
bool fractionalIsGroup() const
qsizetype zeroWidth() 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
Returns a DigitSequence describing some portion of text starting at from.
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
DigitSequence digitSequence(QStringView text, DigitSequence::Options flags=DigitSequence::Option::Default, qsizetype from=0) 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
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()