5#ifndef QSTRINGALGORITHMS_P_H
6#define QSTRINGALGORITHMS_P_H
19#include <QtCore/qnamespace.h>
26template <
typename StringType>
struct QStringAlgorithms
28 typedef typename StringType::value_type Char;
29 typedef typename StringType::size_type size_type;
30 typedef typename std::remove_cv<StringType>::type NakedStringType;
32 std::conditional_t<std::is_same_v<StringType, QString>, QStringView, QByteArrayView>;
33 using ViewChar =
typename ViewType::storage_type;
34 static const bool isConst = std::is_const<StringType>::value;
36 static NakedStringType aligned(
const StringType &txt, qsizetype width, Char fill,
37 Qt::AlignmentFlag align,
bool truncate)
39 const auto len = txt.size();
46 return txt.left(width);
54 NakedStringType result;
55 result.reserve(width);
59 result.resize(width, fill);
62 result.resize(width - len, fill);
65 case Qt::AlignHCenter:
66 case Qt::AlignJustify:
67 case Qt::AlignAbsolute:
68 case Qt::AlignHorizontal_Mask:
71 case Qt::AlignVCenter:
72 case Qt::AlignBaseline:
73 case Qt::AlignVertical_Mask:
81 static inline bool isSpace(
char ch) {
return ascii_isspace(ch); }
82 static inline bool isSpace(QChar ch) {
return ch.isSpace(); }
88 static inline StringType trimmed_helper_inplace(NakedStringType &str,
const Char *begin,
const Char *end)
91 Char *data =
const_cast<Char *>(str.cbegin());
93 memmove(data, begin, (end - begin) *
sizeof(Char));
94 str.resize(end - begin);
95 return std::move(str);
98 static inline StringType trimmed_helper_inplace(
const NakedStringType &,
const Char *,
const Char *)
101 Q_UNREACHABLE_RETURN(StringType());
104 struct TrimPositions {
113 [[nodiscard]]
static TrimPositions trimmed_helper_positions(
const StringType &str)
115 const Char *begin = str.cbegin();
116 const Char *end = str.cend();
118 while (begin < end && isSpace(end[-1]))
121 while (begin < end && isSpace(*begin))
126 static inline StringType trimmed_helper(StringType &str)
128 const auto [begin, end] = trimmed_helper_positions(str);
129 if (begin == str.cbegin() && end == str.cend())
131 if (!isConst && str.isDetached())
132 return trimmed_helper_inplace(str, begin, end);
133 return StringType(begin, end - begin);
136 static inline StringType simplified_helper(StringType &str)
140 const Char *src = str.cbegin();
141 const Char *end = str.cend();
142 NakedStringType result = isConst || !str.isDetached() ?
143 StringType(str.size(), Qt::Uninitialized) :
146 Char *dst =
const_cast<Char *>(result.cbegin());
148 bool unmodified =
true;
150 while (src != end && isSpace(*src))
152 while (src != end && !isSpace(*src))
156 if (*src != QChar::Space)
158 *ptr++ = QChar::Space;
160 if (ptr != dst && ptr[-1] == QChar::Space)
163 qsizetype newlen = ptr - dst;
164 if (isConst && newlen == str.size() && unmodified) {
168 result.resize(newlen);
172 static inline bool needsReallocate(
const StringType &str, qsizetype newSize)
noexcept
174 const auto capacityAtEnd = str.capacity() - str.data_ptr().freeSpaceAtBegin();
175 return newSize > capacityAtEnd;
178 static inline const ViewChar *asUnicodeChar(ViewType v)
180 if constexpr (
sizeof(ViewChar) ==
sizeof(QChar))
186 static inline qsizetype newSize(StringType &src, qsizetype bsize,
187 ViewType after, QSpan<
const qsizetype> indices)
189 if (bsize == after.size())
191 else if (bsize > after.size())
192 return src.size() - indices.size() * (bsize - after.size());
195 const qsizetype adjust = indices.size() * (after.size() - bsize);
196 return src.size() + adjust;
200 static inline void setSize(StringType &src, qsizetype newSize)
202 Q_ASSERT(src.isDetached());
203 Q_ASSERT(newSize <= src.capacity());
205 auto &d = src.data_ptr();
207 d.data()[newSize] =
'\0';
213 static inline void replace_into_copy(StringType &src, qsizetype bsize,
214 ViewType after, QSpan<
const qsizetype> indices,
217 StringType tmp{newlen, Qt::Uninitialized};
218 auto *to = tmp.data_ptr().data();
219 const auto *a = asUnicodeChar(after);
220 auto *
const begin = src.data_ptr().data();
223 for (
auto i : indices) {
224 to = std::copy(first, begin + i, to);
225 to = std::copy(a, a + after.size(), to);
226 first = begin + i + bsize;
228 std::copy(first, src.data_ptr().end(), to);
232 static inline void replace_equal_len(StringType &src, [[maybe_unused]] qsizetype bsize,
233 ViewType after, QSpan<
const qsizetype> indices)
235 Q_ASSERT(bsize == after.size());
236 Q_ASSERT(!src.data_ptr().needsDetach());
238 const auto *a = asUnicodeChar(after);
239 auto *
const begin = src.data_ptr().data();
241 for (
auto i : indices)
242 std::copy(a, a + after.size(), begin + i);
245 static inline void replace_shrink(StringType &src, qsizetype bsize, ViewType after,
246 QSpan<
const qsizetype> indices)
248 Q_ASSERT(bsize > after.size());
249 Q_ASSERT(!src.data_ptr().needsDetach());
251 const auto *a = asUnicodeChar(after);
252 auto *
const begin = src.data_ptr().data();
253 auto *
const end = begin + src.size();
254 Q_ASSERT(!indices.isEmpty());
255 auto *to = std::copy(a, a + after.size(), begin + indices.front());
256 auto *first = begin + indices.front() + bsize;
257 for (qsizetype i = 1; i < indices.size(); ++i) {
258 auto *last = begin + indices[i];
259 to = std::copy(first, last, to);
260 qsizetype adjust = i * (bsize - after.size());
261 to = std::copy(a, a + after.size(), last - adjust);
262 first = begin + indices[i] + bsize;
264 to = std::copy(first, end, to);
265 setSize(src,to - begin);
268 static inline void replace_grow(StringType &src, qsizetype bsize, ViewType after,
269 QSpan<
const qsizetype> indices, qsizetype newlen)
271 Q_ASSERT(after.size() > bsize);
272 Q_ASSERT(!src.data_ptr().needsDetach());
275 const qsizetype oldlen = src.size();
276 const auto *a = asUnicodeChar(after);
277 setSize(src, newlen);
278 auto *
const begin = src.data_ptr().data();
279 auto *last = begin + oldlen;
280 auto *to = src.data_ptr().end();
281 for (
auto i = indices.size() - 1; i >= 0; --i) {
282 auto *first = begin + indices[i] + bsize;
283 to = std::copy_backward(first, last, to);
284 to = std::copy_backward(a, a + after.size(), to);
285 last = begin + indices[i];
289 static inline void replace_helper(StringType &src, qsizetype bsize, ViewType after,
290 QSpan<
const qsizetype> indices)
292 if (indices.isEmpty())
295 const qsizetype newlen = newSize(src, bsize, after, indices);
296 if (src.data_ptr().needsDetach()
297 || (bsize < after.size() && needsReallocate(src, newlen))) {
301 replace_into_copy(src, bsize, after, indices, newlen);
306 if (bsize == after.size())
307 replace_equal_len(src, bsize, after, indices);
308 else if (bsize > after.size())
309 replace_shrink(src, bsize, after, indices);
311 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 S b64_to_decoded_size(S n)
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)
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.
QList< qsizetype > digitBounds
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()