(9)给出完整的源代码:
#ifndef QSTRING_H
#define QSTRING_H
//验证了,没有此宏定义的 #if 不成立
#if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
#error QT_NO_CAST_FROM_ASCII and
QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
#endif
#include <QtCore/qchar.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qarraydata.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qstringliteral.h>
#include <QtCore/qstringalgorithms.h>
#include <QtCore/qanystringview.h>
#include <QtCore/qstringtokenizer.h>
#include <string>
#include <iterator>
#include <stdarg.h>
#ifdef truncate //经验证无此定义,不会报错 error
#error qstring.h must be included before any header file that defines truncate
#endif
#if defined(Q_OS_DARWIN) || defined(Q_QDOC) //不会生成 doc 文档的
Q_FORWARD_DECLARE_CF_TYPE(CFString);
Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
#endif
QT_BEGIN_NAMESPACE //说明伟大的 QString 类定义于 QT 全局空间
class QRegularExpression;
class QRegularExpressionMatch;
class QString;
namespace QtPrivate {
template <bool...B> class BoolList;
}
/*
struct QArrayData
{ QBasicAtomicInt ref_ ;
ArrayOptions flags;
qsizetype alloc;
static void * allocate(...) noexcept;
static void deallocate(...) noexcept;
};
template <class T>
struct QTypedArrayData : QArrayData { }; //本类无数据成员
template <class T>
struct QArrayDataPointer //上面的注释给出了学习与阅读本头文件的因缘
{
Data * d ; //Data = QTypedArrayData<T> 包含了申请释放内存的成员方法
T * ptr; //真正的堆区中的数据起点
qsizetype size;
};
class QString
{ typedef QTypedArrayData<char16_t> Data; //一个类型定义
DataPointer d;
//DataPointer = QStringPrivate = QArrayDataPointer<char16_t>;
}; 本注释用于解释本 QByteArray 类的数据结构的组成
*/
//上面的注释,解释了 QString的数据结构。非常类似于 QByteArray
class Q_CORE_EXPORT QString
{
typedef QTypedArrayData<char16_t> Data; //一个类型定义
private: //把私有部分放到前面,是因为其中有重要的数据成员定义
#if defined(QT_NO_CAST_FROM_ASCII) //经测试,无此宏定义
QString &operator+=(const char *s);
QString &operator+=(const QByteArray &s);
QString(const char *ch);
QString(const QByteArray &a);
QString &operator=(const char *ch);
QString &operator=(const QByteArray &a);
#endif
DataPointer d; //typedef QStringPrivate DataPointer;
//using QStringPrivate = QArrayDataPointer<char16_t>;
static const char16_t _empty;
void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
void reallocGrowData(qsizetype n);
static int compare_helper(const QChar *data1, qsizetype length1,
const QChar *data2, qsizetype length2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
static int compare_helper(const QChar *data1, qsizetype length1,
const char *data2, qsizetype length2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
static int localeAwareCompare_helper(const QChar *data1, qsizetype length1,
const QChar *data2, qsizetype length2);
static QString trimmed_helper(const QString & str);
static QString trimmed_helper(QString & str);
static QString simplified_helper(const QString &str);
static QString simplified_helper(QString &str);
static QString toLower_helper(const QString &str);
static QString toLower_helper(QString &str);
static QString toUpper_helper(const QString &str);
static QString toUpper_helper(QString &str);
static QString toCaseFolded_helper(const QString &str);
static QString toCaseFolded_helper(QString &str);
static QByteArray toLatin1_helper(const QString &);
static QByteArray toLatin1_helper_inplace(QString &);
static QByteArray toUtf8_helper(const QString &);
static QByteArray toLocal8Bit_helper(const QChar *data, qsizetype size);
static qsizetype toUcs4_helper(const ushort *uc, qsizetype length, uint *out);
// ### Qt 7 char16_t
static qlonglong toIntegral_helper(QStringView string, bool *ok, int base);
static qulonglong toIntegral_helper(QStringView string, bool *ok, uint base);
void replace_helper(size_t *indices, qsizetype nIndices,
qsizetype blen, const QChar *after, qsizetype alen);
friend class QStringView; //本类的友元类们
friend class QByteArray;
friend class QCollator;
friend struct QAbstractConcatenable;
template <typename T> static //静态成员函数
T toIntegral_helper(QStringView string, bool *ok, int base)
{
using Int64 = typename std::conditional<std::is_unsigned<T>::value,
qulonglong,
qlonglong>::type;
using Int32 = typename std::conditional<std::is_unsigned<T>::value,
uint,
int>::type;
// we select the right overload by casting base to int or uint
Int64 val = toIntegral_helper(string, ok, Int32(base));
if (T(val) != val) {
if (ok)
*ok = false;
val = 0;
}
return T(val);
}
public: //开始重要的公共函数
typedef QStringPrivate DataPointer; //DataPointer d; 本类的数据成员
//using QStringPrivate = QArrayDataPointer<char16_t>;
inline constexpr QString() noexcept { } //默认的构造函数
QString(qsizetype size, Qt::Initialization);
QString(qsizetype size, QChar c);
//Constructs a string of the given size with every character set to c.
//Constructs a string of size 1 containing the character c.
QString( QChar c);
explicit
QString(const QChar * unicode, qsizetype size = -1); //有参构造
//取 unicode 数组的前 size 个字符
//Constructs a string initialized with the first size characters of the
//QChar array unicode. If unicode is 0, a null string is constructed.
//If size is negative, unicode is assumed to point to a \0'-terminated array
//and its length is determined dynamically.
//The terminating null character is not considered part of the string.
//QString makes a deep copy of the string data.
//The unicode data is copied as is and
//the Byte Order Mark is preserved if present.
QT_ASCII_CAST_WARN inline
QString(const char * ch) : QString(fromUtf8(ch)) {}
QT_ASCII_CAST_WARN inline
QString(const QByteArray & a) : QString(fromUtf8(a) ) {}
explicit
QString(DataPointer && dd) : d(std::move(dd)) {}
inline
QString(QLatin1String latin1)
{ *this = QString::fromLatin1(latin1.data(), latin1.size()); }
#if defined(__cpp_char8_t) || defined(Q_CLANG_QDOC)
Q_WEAK_OVERLOAD
inline QString(const char8_t *str)
: QString(fromUtf8(str))
{}
#endif
inline QString(const QString & other) noexcept : d(other.d) { } //copy构造函数
QString & operator=(const QString &) noexcept;
inline QString(QString && other) noexcept //移动构造函数
{ qSwap(d, other.d); }
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QString)
/* 以宏定义的形式得到本类的 移动赋值运算符函数
#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
Class &operator=(Class &&other) noexcept { \
swap(other); \
return *this; \
}
*/
inline ~QString() { } //析构函数
QString & operator=( QChar c); //赋值运算符函数,并构成重载
QT_ASCII_CAST_WARN inline
QString & operator=(const char * ch)
{ return (*this = fromUtf8(ch)); }
QT_ASCII_CAST_WARN inline
QString & operator=(const QByteArray & a)
{ return (*this = fromUtf8(a)); }
QString & operator=(QLatin1String latin1);
void swap(QString &other) noexcept { d.swap(other.d); }
//*********************先介绍 QString 里这个独特的用法*********************
//#define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
// __attribute__((format(gnu_printf, (A), (B))))
static QString vasprintf(const char *format, va_list ap) //不必用 va_list
Q_ATTRIBUTE_FORMAT_PRINTF(1, 0);
static QString asprintf(const char * format, ...) //不要用此函数,过时了
Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
//Safely builds a formatted string from the format string format and an
//arbitrary任意 list of arguments.
//The format string supports the conversion specifiers, length modifiers,
//and flags provided by printf() in the standard C++ library.
//The format string and %s arguments must be UTF-8 encoded.
//安全地从格式字符串 cformat 和任意参数列表构建一个格式化字符串。
//格式字符串支持标准C++库中printf ()提供的转换说明符、长度修饰符和标志。
//cformat字符串和%s参数必须使用UTF-8编码。
//Warning: We do not recommend using QString::asprintf() in new Qt code.
//Instead, consider using QTextStream or arg(),
//both of which support Unicode strings seamlessly无缝 and are type-safe.
//对于翻译,特别是如果字符串包含多个转义序列,您应该考虑使用 arg()函数。
//这允许翻译人员控制替换的顺序。
//For translations, especially if the strings contains more than one
//escape sequence, you should consider using the arg() function instead.
//This allows the order of the replacements to be controlled by the translator.
//fieldWidth specifies the minimum amount of space that a is padded to
//and filled with the character fillChar.
//A positive value produces right-aligned text;
//a negative value produces left-aligned text.
//The base argument specifies the base to use when converting the
//integer a into a string. The base must be between 2 and 36,
//with 8 giving octal, 10 decimal, and 16 hexadecimal numbers.
[[nodiscard]]
QString arg(short a, int fieldWidth = 0, int base = 10,
QChar fillChar = QLatin1Char(' ')) const
{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
[[nodiscard]]
QString arg(ushort a, int fieldWidth = 0, int base = 10,
QChar fillChar = QLatin1Char(' ')) const
{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
[[nodiscard]]
QString arg(int a, int fieldWidth = 0, int base = 10,
QChar fillChar = QLatin1Char(' ')) const
{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
[[nodiscard]]
QString arg(uint a, int fieldWidth = 0, int base = 10,
QChar fillChar = QLatin1Char(' ')) const
{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
[[nodiscard]]
QString arg(long a, int fieldwidth = 0, int base=10,
QChar fillChar = QLatin1Char(' ')) const
{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
[[nodiscard]]
QString arg(ulong a, int fieldwidth = 0, int base=10,
QChar fillChar = QLatin1Char(' ')) const
{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
[[nodiscard]]
QString arg(qlonglong a, int fieldwidth = 0, int base=10,
QChar fillChar = QLatin1Char(' ')) const;
[[nodiscard]]
QString arg(qulonglong a, int fieldwidth = 0, int base=10,
QChar fillChar = QLatin1Char(' ')) const;
[[nodiscard]] //这里开始出现不同,出现了浮点数 %e %E %f %g %G
QString arg(double a, int fieldWidth = 0,
char format = 'g', int precision = -1,
QChar fillChar = QLatin1Char(' ')) const;
[[nodiscard]] //The a argument is interpreted as a Latin-1 character.
QString arg(char a, int fieldWidth = 0,
QChar fillChar = QLatin1Char(' ')) const;
[[nodiscard]]
QString arg(QChar a, int fieldWidth = 0,
QChar fillChar = QLatin1Char(' ')) const;
#if QT_STRINGVIEW_LEVEL < 2
[[nodiscard]]
QString arg(const QString & a, int fieldWidth = 0,
QChar fillChar = QLatin1Char(' ')) const;
//Returns a copy of this string with the lowest numbered place marker
//replaced by string a, i.e., %1, %2, ..., %99.
//返回此字符串的副本,将最低编号的占位符替换为字符串a,即%1,%2,…,%99。
//fieldWidth specifies the minimum amount of space that argument a shall occupy.
//If a requires less space than fieldWidth,
//it is padded to fieldWidth with character fillChar.
//A positive fieldWidth produces right-aligned text.
//A negative fieldWidth produces left-aligned text.
#endif
[[nodiscard]]
QString arg(QStringView a, int fieldWidth = 0,
QChar fillChar = QLatin1Char(' ')) const;
[[nodiscard]] //说明本 QString类的本函数也接受 QLatin1String类字符作为参数
QString arg(QLatin1String a, int fieldWidth = 0,
QChar fillChar = QLatin1Char(' ')) const;
/*
template<typename _Tp, _Tp __v>
struct integral_constant
{
static constexpr _Tp value = __v;
typedef _Tp value_type;
typedef integral_constant<_Tp, __v> type;
constexpr operator value_type() const noexcept
{ return value; }
constexpr value_type operator()() const noexcept
{ return value; }
};
*/
private: //这里突然定义了两个私有的模板类
template <typename T> //本类继承自 std 空间里的 integral_constant类
struct is_convertible_to_view_or_qstring_helper
: std::integral_constant<bool,
std::is_convertible<T, QString> ::value ||
std::is_convertible<T, QStringView> ::value ||
std::is_convertible<T, QLatin1String>::value>
{};
template <typename T> //本类继承自上面的类
struct is_convertible_to_view_or_qstring
: is_convertible_to_view_or_qstring_helper<
typename std::decay<T>::type>
{};
/*
template <bool _Test, class _Ty = void>
struct enable_if {}; // no member "type" when !_Test
template <class _Ty>
struct enable_if<true, _Ty> // type is _Ty for _Test
{
using type = _Ty;
};
*/
public: //接着的本 arg() 函数使用了上面的 private 部分里的模板类定义
template <typename...Args>
[[nodiscard]]
#ifdef Q_CLANG_QDOC //这个不成立,看 else分支
QString
#else
typename std::enable_if<
sizeof...(Args) >= 2 && std::is_same<
QtPrivate::BoolList<is_convertible_to_view_or_qstring<Args>::value..., true>,
QtPrivate::BoolList<true, is_convertible_to_view_or_qstring<Args>::value...>
>::value, QString
>::type
#endif
arg(Args &&...args) const //说明 arg 函数接受可变参
{ return qToStringViewIgnoringNull(*this).arg(std::forward<Args>(args)...); }
//********************以上结束了这个格式化输出的学习注释***********************
//********************以下内容就可以保持与 QByteArray高度的一致性**************
//Returns the maximum number of characters that can be stored in the
//string without forcing a reallocation.
//The sole purpose of this function is to provide a means of fine tuning
//QString's memory usage. In general,
//you will rarely ever need to call this function. 不必调用这个函数
inline qsizetype capacity() const
{ return qsizetype(d->constAllocatedCapacity()); }
inline qsizetype size () const { return d.size; }
inline qsizetype length () const { return d.size; }
inline
qsizetype count( ) const { return d.size; }
//Returns the number of occurrences of character ch in the string.
[[nodiscard]]
qsizetype count( QChar c,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
[[nodiscard]]
qsizetype count(const QString & s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
//Returns the number of (potentially overlapping) occurrences of
//the string s in this string.
[[nodiscard]]
qsizetype count( QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool isEmpty () const { return d.size == 0; }
inline bool isNull () const { return d->isNull(); }
bool isSimpleText () const;
bool isRightToLeft() const;
//Returns true if the string is read right to left.
[[nodiscard]]
bool isValidUtf16 () const noexcept
{ return QStringView(*this).isValidUtf16(); }
//如果字符串包含有效的 UTF-16 编码数据,则返回 true,否则返回 false。
//请注意,此函数不会对数据进行任何特殊的验证;它只是检查是否可以成功从 UTF-16 解码。
//数据假定为主机字节顺序;BOM 的存在毫无意义。
inline bool isDetached() const { return !d->isShared(); }
inline bool isSharedWith(const QString & other) const
{ return d.isSharedWith(other.d); }
//如果字符串是大写字母,则返回true,即它与 toUpper()折叠相同。
//请注意,这并不意味着字符串不包含小写字母(一些小写字母没有大写字母的折叠它们保持不变)。
//有关更多信息,请参见Unicode标准第3.13节。
bool isUpper() const;
bool isLower() const;
//Note that this does not mean that the string does not contain
//uppercase letters (some uppercase letters do not have a lowercase folding;
//they are left unchanged by toLower()).
inline DataPointer & data_ptr() { return d; } //其返回的对象没用
inline const DataPointer & data_ptr() const { return d; }
inline const QChar * data() const
{
#if QT5_NULL_STRINGS == 1
return reinterpret_cast<const QChar *>(d.data() ? d.data() : &_empty);
#else
return reinterpret_cast<const QChar *>(d.data());
#endif
}
inline QChar * data() //返回封装的 QChar数组的起始地址
{
detach();
Q_ASSERT(d.data());
return reinterpret_cast<QChar *>(d.data());
}
inline const QChar * constData() const { return data(); }
inline const QChar * unicode () const { return data(); } //等价于 data()
//Returns a Unicode representation of the string.
//The result remains valid until the string is modified.
//Note: The returned string may not be '\0'-terminated.
// Use size() to determine the length of the array.
//Returns the index position of the first occurrence of the character c
//in the string, searching forward from index position from.
//Returns -1 if ch could not be found.
[[nodiscard]]
qsizetype indexOf(QChar c, qsizetype from = 0,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
[[nodiscard]]
qsizetype indexOf(const QString & s, qsizetype from = 0,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
[[nodiscard]]
qsizetype indexOf(QLatin1String s, qsizetype from = 0,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
[[nodiscard]]
qsizetype indexOf(QStringView s, qsizetype from = 0,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::findString(*this, from, s, cs); }
//Returns the index position of the last occurrence of the character c,
//searching backward from position from.
[[nodiscard]]
qsizetype lastIndexOf( QChar c, qsizetype from = -1,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
//Qt::CaseSensitivity { CaseInsensitive, CaseSensitive };
#if QT_STRINGVIEW_LEVEL < 2
//Returns the index position of the last occurrence of the string s in this string,
//searching backward from index position from.
//If from is -1, the search starts at the last character;
//if from is -2, at the next to last character and so on.
//Returns -1 if str is not found.
//If cs is Qt::CaseSensitive (default), the search is case sensitive;
//otherwise the search is case insensitive.
[[nodiscard]] //对于字符串的匹配,要求所有字符的完全匹配,否则返回 -1
qsizetype lastIndexOf(const QString & s, qsizetype from,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
[[nodiscard]]
qsizetype lastIndexOf(const QString & s, //调用了上面的重载函数
Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return lastIndexOf(s, size(), cs); }
//Returns the index position of the last occurrence of the string s in this
//string. Returns -1 if str is not found.
#endif
[[nodiscard]]
qsizetype lastIndexOf(QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return lastIndexOf(s, size(), cs); }
[[nodiscard]]
qsizetype lastIndexOf(QLatin1String s, qsizetype from,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
[[nodiscard]]
qsizetype lastIndexOf(QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return lastIndexOf(s, size(), cs); }
[[nodiscard]]
qsizetype lastIndexOf(QStringView s, qsizetype from,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::lastIndexOf(*this, from, s, cs); }
#if QT_CONFIG(regularexpression) //经测试是允许正则表达式的
[[nodiscard]]
qsizetype indexOf(const QRegularExpression &re, qsizetype from = 0,
QRegularExpressionMatch *rmatch = nullptr) const;
#ifdef Q_QDOC
[[nodiscard]]
qsizetype lastIndexOf(const QRegularExpression &re,
QRegularExpressionMatch *rmatch = nullptr) const;
#else
// prevent an ambiguity when called like this: lastIndexOf(re, 0)
template <typename T = QRegularExpressionMatch,
std::enable_if_t<
std::is_same_v<T, QRegularExpressionMatch>,
bool> = false>
[[nodiscard]]
qsizetype lastIndexOf(const QRegularExpression &re, T *rmatch = nullptr) const
{ return lastIndexOf(re, size(), rmatch); }
#endif
[[nodiscard]]
qsizetype lastIndexOf(const QRegularExpression &re, qsizetype from,
QRegularExpressionMatch *rmatch = nullptr) const;
[[nodiscard]]
bool contains(const QRegularExpression &re,
QRegularExpressionMatch *rmatch = nullptr) const;
[[nodiscard]]
qsizetype count(const QRegularExpression &re) const;
#endif //#if QT_CONFIG(regularexpression)
[[nodiscard]] inline bool contains( QChar c,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return indexOf(c, 0, cs) != -1; }
#if QT_STRINGVIEW_LEVEL < 2 //对于字符串的匹配,要求所有字符的完全匹配,否则返回 -1
[[nodiscard]] inline bool contains(const QString & s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return indexOf(s, 0, cs) != -1; }
#endif
[[nodiscard]] inline bool contains( QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return indexOf(s, 0, cs) != -1; }
[[nodiscard]] inline bool contains( QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
bool startsWith( QChar c,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2 //Returns true if the string starts with s;
bool startsWith(const QString & s, //otherwise returns false.
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
[[nodiscard]]
bool startsWith( QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::startsWith(*this, s, cs); }
bool startsWith( QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith ( QChar c,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2 //Returns true if the string ends with s;
bool endsWith (const QString & s, //otherwise returns false.
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
[[nodiscard]]
bool endsWith ( QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::endsWith(*this, s, cs); }
bool endsWith ( QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline const QChar at(qsizetype i) const //值返回
{
Q_ASSERT(size_t(i) < size_t(size()));
return QChar(d.data()[i]);
}
const QChar operator[](qsizetype i) const
{
Q_ASSERT(size_t(i) < size_t(size()));
return QChar(d.data()[i]);
}
[[nodiscard]] QChar & operator[](qsizetype i) //有 const 修饰符修饰 this
{ Q_ASSERT(i >= 0 && i < size()); return data()[i]; }
[[nodiscard]] inline QChar front() const { return at(0); }
[[nodiscard]] inline QChar & front() { return operator[](0); }
[[nodiscard]] inline QChar back () const { return at(size() - 1); }
[[nodiscard]] inline QChar & back () { return operator[](size() - 1); }
//Returns a substring that contains the n leftmost characters of the string.
//If you know that n cannot be out of bounds, use first() instead in new code,
[[nodiscard]] //because it is faster.
QString left (qsizetype n) const; //等价于 新代码的 first()
//Returns a substring that contains the n rightmost characters of the string.
[[nodiscard]] //新代码用 last(),更快
QString right (qsizetype n) const;
//Returns a string that contains n characters of this string,
[[nodiscard]] //starting at the specified position index.新代码用 sliced()更快
QString mid (qsizetype position, qsizetype n = -1) const;
[[nodiscard]]
QString first (qsizetype n) const
{ Q_ASSERT(n >= 0);
Q_ASSERT(n <= size());
return QString(data(), n);
}
[[nodiscard]]
QString last (qsizetype n) const
{ Q_ASSERT(n >= 0);
Q_ASSERT(n <= size());
return QString(data() + size() - n, n);
}
[[nodiscard]]
QString sliced(qsizetype pos) const //从字符串的中间位置 pos取一些字符
{ Q_ASSERT(pos >= 0);
Q_ASSERT(pos <= size());
return QString(data() + pos, size() - pos);
}
[[nodiscard]]
QString sliced(qsizetype pos, qsizetype n) const
{ Q_ASSERT(pos >= 0);
Q_ASSERT(n >= 0);
Q_ASSERT(size_t(pos) + size_t(n) <= size_t(size()));
return QString(data() + pos, n);
}
//Returns a string that contains the size() - n leftmost characters of
//this string.
[[nodiscard]] //裁掉右边的 n个字符后返回
QString chopped(qsizetype n) const
{ Q_ASSERT(n >= 0);
Q_ASSERT(n <= size());
return first(size() - n);
}
//void chop (qsizetype n) ; //形参是被裁的数量。此函在前面的间隔 500行
//Removes n characters from the end of the string.
#if !defined(Q_CLANG_QDOC)
[[nodiscard]] QString trimmed() const &
{ return trimmed_helper(*this); }
[[nodiscard]] QString trimmed() &&
{ return trimmed_helper(*this); }
[[nodiscard]] QString simplified() const &
{ return simplified_helper(*this); }
[[nodiscard]] QString simplified() &&
{ return simplified_helper(*this); }
[[nodiscard]] QString toLower() const &
{ return toLower_helper(*this); }
[[nodiscard]] QString toLower() &&
{ return toLower_helper(*this); }
[[nodiscard]] QString toUpper() const &
{ return toUpper_helper(*this); }
[[nodiscard]] QString toUpper() &&
{ return toUpper_helper(*this); }
//Returns the case folded equivalent of the string.
//For most Unicode characters this is the same as toLower().
[[nodiscard]] QString toCaseFolded() const & //返回小写形式
{ return toCaseFolded_helper(*this); }
[[nodiscard]] QString toCaseFolded() &&
{ return toCaseFolded_helper(*this); }
#else
[[nodiscard]] QString toLower() const;
[[nodiscard]] QString toUpper() const;
[[nodiscard]] QString toCaseFolded() const;
[[nodiscard]] QString trimmed() const;
[[nodiscard]] QString simplified() const;
#endif
//将纯文本字符串转换为带有 HTML实体替换的 HTML字符串,HTML实体包括<、>、&和"
//Converts a plain text string to an HTML string with HTML metacharacters <,
//>, &, and " replaced by HTML entities.
[[nodiscard]] QString toHtmlEscaped() const;
//Returns a string of size width that contains this string padded
//by the fill character.
//返回一个指定长度的新 QString,原内容左对齐,右侧填充指定的字符,默认是空格。
//函数可能有参数指定填充字符和是否截断原内容。
//当原数组长度小于width时,右侧填充fill字符;
//如果原长度超过width,是否截取取决于truncate参数是否为true。
[[nodiscard]]
QString leftJustified (qsizetype width, QChar fill = QLatin1Char(' '),
bool trunc = false) const;
[[nodiscard]]
QString rightJustified(qsizetype width, QChar fill = QLatin1Char(' '),
bool trunc = false) const;
enum SectionFlag {
SectionDefault = 0x00,
SectionSkipEmpty = 0x01, //忽略空白符
SectionIncludeLeadingSep = 0x02, //下面函数的官方注释很重要
SectionIncludeTrailingSep = 0x04,
SectionCaseInsensitiveSeps = 0x08
};
Q_DECLARE_FLAGS(SectionFlags, SectionFlag)
//等于定义了 SectionFlags = QFlags<SectionFlag>
//此函数返回字符串的一部分。这个字符串被当作由字符'sep'分隔的字段的序列来处理。
//返回的字符串由从位置`start'到位置`end`(包括)的字段组成。
//如果未指定、end`,则包括从位置start`到字符串结尾的所有字段。
//字段从左到右编号 0、1、2等,从右到左编号 -1、-2等。
//flags 参数可用于影响函数行为的一些方面,例如是否区分大小写,
//是否跳过空字段以及如何处理前导和尾随分隔符;请参阅 SectionFlags。
//If start or end is negative, we count fields from the right of the string,
//the right-most field being -1, the one from right-most field being -2,
//and so on. 总之,这里把 QString里的字符串看成是分段的,分隔符是 sep。
[[nodiscard]] //这里的下标 start不是数组下标,而是分段后的子字符串的序号。
QString section( QChar sep , //注意 sep左边的第一段的序号是 0,即使为空
qsizetype start, qsizetype end = -1,
SectionFlags flags = SectionDefault) const
{ return section(QString(sep), start, end, flags); }
[[nodiscard]]
QString section(const QString & in_sep,
qsizetype start, qsizetype end = -1,
SectionFlags flags = SectionDefault) const;
#if QT_CONFIG(regularexpression)
[[nodiscard]]
QString section(const QRegularExpression &re,
qsizetype start, qsizetype end = -1,
SectionFlags flags = SectionDefault) const;
#endif
public:
//enum SplitBehaviorFlags { KeepEmptyParts = 0, SkipEmptyParts = 0x1, };
[[nodiscard]] //using QStringList = QList<QString>;
QStringList split( QChar sep,
Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
[[nodiscard]]
QStringList split(const QString & sep,
Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
//Splits the string into substrings wherever sep occurs,
//and returns the list of those strings.
//If sep does not match anywhere in the string,
//split() returns a single-element list containing this string.
//cs specifies whether sep should be matched case sensitively or
//case insensitively.
//If behavior is Qt::SkipEmptyParts, empty entries don't appear in the result.
//By default, empty entries are kept.
#ifndef QT_NO_REGULAREXPRESSION
[[nodiscard]]
QStringList split(const QRegularExpression & sep,
Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
#endif
template <typename Needle, typename...Flags> //这些不懂,先留这里
[[nodiscard]] inline
auto tokenize(Needle &&needle, Flags...flags) const &
noexcept(noexcept(qTokenize(std::declval<const QString &>(),
std::forward<Needle>(needle), flags...)))
-> decltype(qTokenize(*this, std::forward<Needle>(needle), flags...))
{ return qTokenize(qToStringViewIgnoringNull(*this),
std::forward<Needle>(needle), flags...);
}
template <typename Needle, typename...Flags>
[[nodiscard]] inline
auto tokenize(Needle &&needle, Flags...flags) const &&
noexcept(noexcept(qTokenize(std::declval<const QString>(),
std::forward<Needle>(needle), flags...)))
-> decltype(qTokenize(std::move(*this),
std::forward<Needle>(needle), flags...))
{ return qTokenize(std::move(*this),
std::forward<Needle>(needle), flags...);
}
template <typename Needle, typename...Flags>
[[nodiscard]] inline
auto tokenize(Needle &&needle, Flags...flags) &&
noexcept(noexcept(qTokenize(std::declval<QString>(),
std::forward<Needle>(needle), flags...)))
-> decltype(qTokenize(std::move(*this),
std::forward<Needle>(needle), flags...))
{ return qTokenize(std::move(*this),
std::forward<Needle>(needle), flags...);
}
enum NormalizationForm {
NormalizationForm_D,
NormalizationForm_C,
NormalizationForm_KD,
NormalizationForm_KC
};
[[nodiscard]] QString normalized(NormalizationForm mode,
QChar::UnicodeVersion version = QChar::Unicode_Unassigned) const;
//Returns the string in the given Unicode normalization mode,
//according to the given version of the Unicode standard.
//Returns a copy of this string repeated the specified number of times.
//If times is less than 1, an empty string is returned.
[[nodiscard]] QString repeated(qsizetype times) const;
//Returns the QString as a '\0'-terminated array of unsigned shorts.
//The result remains valid until the string is modified.
//The returned string is in host byte order.
const ushort * utf16() const; // ### Qt 7 char16_t
//Returns the string converted to an int using base base,
//which is 10 by default and must be between 2 and 36, or 0.
//Returns 0 if the conversion fails.
//If ok is not nullptr, failure is reported by setting *ok to false,
//and success by setting *ok to true.
//If base is 0, the C language convention is used:
//If the string begins with "0x", base 16 is used;
//if the string begins with "0", base 8 is used; otherwise, base 10 is used.
//The string conversion will always happen in the 'C' locale.
//For locale-dependent conversion use QLocale::toInt()
short toShort (bool * ok=nullptr, int base = 10) const
{ return toIntegral_helper<short>(*this, ok, base); }
ushort toUShort (bool * ok=nullptr, int base = 10) const
{ return toIntegral_helper<ushort>(*this, ok, base); }
int toInt (bool * ok=nullptr, int base = 10) const
{ return toIntegral_helper<int>(*this, ok, base); }
uint toUInt (bool * ok=nullptr, int base = 10) const
{ return toIntegral_helper<uint>(*this, ok, base); }
long toLong (bool * ok=nullptr, int base = 10) const
{ return toIntegral_helper<long>(*this, ok, base); }
ulong toULong (bool * ok=nullptr, int base = 10) const
{ return toIntegral_helper<ulong>(*this, ok, base); }
qlonglong toLongLong (bool * ok=nullptr, int base = 10) const;
qulonglong toULongLong(bool * ok=nullptr, int base = 10) const;
float toFloat (bool * ok=nullptr ) const;
double toDouble (bool * ok=nullptr ) const;
#if !defined(Q_CLANG_QDOC)
[[nodiscard]] QByteArray toLatin1() const &
{ return toLatin1_helper(*this); }
[[nodiscard]] QByteArray toLatin1() &&
{ return toLatin1_helper_inplace(*this); }
[[nodiscard]] QByteArray toUtf8() const &
{ return toUtf8_helper(*this); }
[[nodiscard]] QByteArray toUtf8() &&
{ return toUtf8_helper(*this); }
//返回字符串的本地8位表示形式,作为QByteArray。
//如果字符串包含本地8位编码不支持字符,则返回的字节数组是未定义的。
//在Unix系统中,这等同于toUtf8(),在Windows系统中,当前代码页被使用。
//如果该字符串包含任何无法在本地编码的字符,则返回的字节数组是未定义的。
//这些字符可能被抑制或替换为另一个。
[[nodiscard]] QByteArray toLocal8Bit() const &
{ return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
[[nodiscard]] QByteArray toLocal8Bit() &&
{ return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
#else
[[nodiscard]] QByteArray toLatin1() const;
[[nodiscard]] QByteArray toUtf8() const;
[[nodiscard]] QByteArray toLocal8Bit() const;
#endif
[[nodiscard]] QList<uint> toUcs4() const; // ### Qt 7 char32_t
inline std::string toStdString() const
{ return toUtf8().toStdString(); }
inline std::wstring toStdWString() const
{
std::wstring str;
str.resize(length());
#if __cplusplus >= 201703L
str.resize(toWCharArray(str.data()));
#else
if (length())
str.resize(toWCharArray(&str.front()));
#endif
return str;
}
inline std::u16string toStdU16String() const
{ return std::u16string(reinterpret_cast<const char16_t*>(utf16()), length()); }
inline std::u32string toStdU32String() const
{
std::u32string u32str(length(), char32_t(0));
qsizetype len = toUcs4_helper(reinterpret_cast<const ushort *>(constData()),
length(), reinterpret_cast<uint*>(&u32str[0]));
u32str.resize(len);
return u32str;
}
static inline QString fromStdString (const std::string & s)
{ return fromUtf8(s.data(), int(s.size())); }
static inline QString fromStdWString (const std::wstring &s)
{ return fromWCharArray(s.data(), int(s.size())); }
static inline QString fromStdU16String(const std::u16string &s)
{ return fromUtf16(s.data(), int(s.size())); }
static inline QString fromStdU32String(const std::u32string &s)
{ return fromUcs4(s.data(), int(s.size())); }
// note - this are all inline so we can benefit from
//strlen() compile time optimizations 以下全是静态的成员函数
static QString fromLatin1( QByteArrayView ba);
Q_WEAK_OVERLOAD
static inline QString fromLatin1(const QByteArray & ba)
{ return fromLatin1(QByteArrayView(ba)); }
//Returns a QString initialized with the first size characters of the
//Latin-1 string str.
//If size is -1, strlen(str) is used instead.
static inline QString fromLatin1(const char * str, qsizetype size)
{
return fromLatin1(QByteArrayView(str, !str || size < 0
? qstrlen(str) : size));
}
static QString fromUtf8( QByteArrayView utf8);
Q_WEAK_OVERLOAD
static inline QString fromUtf8(const QByteArray & ba )
{ return fromUtf8(QByteArrayView(ba)); }
static inline QString fromUtf8(const char * utf8, qsizetype size)
{
return fromUtf8(QByteArrayView(utf8, !utf8 || size < 0
? qstrlen(utf8) : size));
}
static QString fromLocal8Bit( QByteArrayView ba);
Q_WEAK_OVERLOAD
static inline QString fromLocal8Bit(const QByteArray & ba)
{ return fromLocal8Bit(QByteArrayView(ba)); }
static inline QString fromLocal8Bit(const char * str, qsizetype size)
{
return fromLocal8Bit(QByteArrayView(str, !str || size < 0
? qstrlen(str) : size));
}
static QString fromRawData(const QChar *, qsizetype size );
static QString fromUtf16 (const char16_t *, qsizetype size = -1);
static QString fromUcs4 (const char32_t *, qsizetype size = -1);
#if QT_DEPRECATED_SINCE(6, 0) //函数 fromUtf16()、fromUcs4 的重载版本作废了
QT_DEPRECATED_VERSION_X_6_0("Use char16_t * overload.")
static QString fromUtf16(const ushort *str, qsizetype size = -1)
{ return fromUtf16(reinterpret_cast<const char16_t *>(str), size); }
QT_DEPRECATED_VERSION_X_6_0("Use char32_t * overload.")
static QString fromUcs4(const uint *str, qsizetype size = -1)
{ return fromUcs4(reinterpret_cast<const char32_t *>(str), size); }
#endif
#if defined(__cpp_char8_t) || defined(Q_CLANG_QDOC)
Q_WEAK_OVERLOAD
static inline QString fromUtf8(const char8_t *str)
{ return fromUtf8(reinterpret_cast<const char *>(str)); }
Q_WEAK_OVERLOAD
static inline QString fromUtf8(const char8_t *str, qsizetype size)
{ return fromUtf8(reinterpret_cast<const char *>(str), size); }
#endif
//用本 QString对象中的数据填充形参数组 array。
//The array is encoded in UTF-16 on platforms where wchar_t is 2 bytes wide
//(e.g. windows) and in UCS-4 on platforms where wchar_t is 4 bytes wide
//(most Unix systems).
//数组 array必须由调用者分配,并包含足够的空间来容纳完整的字符串
//(分配与字符串长度相同的数组总是足够的)。
//此函数返回数组中字符串的实际长度。 注意:此函数不会在数组中添加空字符。
inline qsizetype toWCharArray ( wchar_t * array) const
{
return qToStringViewIgnoringNull(*this).toWCharArray(array);
}
[[nodiscard]]
static inline QString fromWCharArray(const wchar_t * string,
qsizetype size = -1)
{
return sizeof(wchar_t) == sizeof(QChar)
? fromUtf16(reinterpret_cast<const char16_t *>(string), size)
: fromUcs4 (reinterpret_cast<const char32_t *>(string), size);
}
//Returns a copy of the string, where the encoding of string depends on the
//size of wchar. If wchar is 4 bytes, the string is interpreted as UCS-4,
//if wchar is 2 bytes it is interpreted as UTF-16.
//If size is -1 (default), the string must be '\0'-terminated.
//Performs a comparison of this with ch, using the case sensitivity setting cs.
int compare( QChar ch,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return compare(QStringView{&ch, 1}, cs); }
//Lexically compares this string with the other string and
//returns an integer less than, equal to,
//or greater than zero if this string is less than, equal to,
//or greater than the other string.
#if QT_STRINGVIEW_LEVEL < 2
int compare(const QString & s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
#endif
int compare( QLatin1String other,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
inline
int compare( QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return -s.compare(*this, cs); }
//Compares s1 with s2 and returns an integer less than, equal to,
//or greater than zero if s1 is less than, equal to, or greater than s2.
//If cs is Qt::CaseSensitive, the comparison is case sensitive;
//otherwise the comparison is case insensitive.
//Case sensitive comparison is based exclusively on the numeric
//Unicode values of the characters and is very fast,
//but is not what a human would expect.
//Consider sorting user-visible strings with localeAwareCompare().
static inline // 其实还是静态函数版本更好用
int compare(const QString & s1, const QString & s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
{ return s1.compare(s2, cs); }
static inline
int compare(const QString & s1, QLatin1String s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
{ return s1.compare(s2, cs); }
static
int compare(const QString & s1, QStringView s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
{ return s1.compare(s2, cs); }
static inline
int compare( QLatin1String s1, const QString & s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
{ return -s2.compare(s1, cs); }
static
int compare( QStringView s1, const QString & s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
{ return -s2.compare(s1, cs); }
int localeAwareCompare(const QString & s) const;
int localeAwareCompare( QStringView s) const
{ return localeAwareCompare_helper(constData(), length(),
s.constData(), s.length());
}
//Compares s1 with s2 and returns an integer less than, equal to,
//or greater than zero if s1 is less than, equal to, or greater than s2.
//The comparison is performed in a locale- and also platform-dependent manner.
//Use this function to present sorted lists of strings to the user.
static
int localeAwareCompare(const QString & s1, const QString & s2)
{ return s1.localeAwareCompare(s2); }
static
int localeAwareCompare( QStringView s1, QStringView s2)
{ return localeAwareCompare_helper(s1.constData(), s1.length(),
s2.constData(), s2.length());
}
QT_ASCII_CAST_WARN inline
bool operator==(const char * s) const
{ return QString::compare_helper(constData(), size(), s, -1) == 0; }
QT_ASCII_CAST_WARN inline
bool operator!=(const char * s) const
{ return QString::compare_helper(constData(), size(), s, -1) != 0; }
QT_ASCII_CAST_WARN inline
bool operator< (const char * s) const
{ return QString::compare_helper(constData(), size(), s, -1) < 0; }
QT_ASCII_CAST_WARN inline
bool operator<=(const char * s) const
{ return QString::compare_helper(constData(), size(), s, -1) <= 0; }
QT_ASCII_CAST_WARN inline
bool operator> (const char * s) const
{ return QString::compare_helper(constData(), size(), s, -1) > 0; }
QT_ASCII_CAST_WARN inline
bool operator>=(const char * s) const
{ return QString::compare_helper(constData(), size(), s, -1) >= 0; }
QT_ASCII_CAST_WARN inline
bool operator==(const QByteArray & s) const
{ return QString::compare_helper(constData(), size(),
s.constData(), s.size()) == 0; }
QT_ASCII_CAST_WARN inline
bool operator!=(const QByteArray & s) const
{ return QString::compare_helper(constData(), size(),
s.constData(), s.size()) != 0; }
QT_ASCII_CAST_WARN inline
bool operator< (const QByteArray & s) const
{ return QString::compare_helper(constData(), size(),
s.constData(), s.size()) < 0; }
QT_ASCII_CAST_WARN inline
bool operator> (const QByteArray & s) const
{ return QString::compare_helper(constData(), size(),
s.constData(), s.size()) > 0; }
QT_ASCII_CAST_WARN inline
bool operator<=(const QByteArray & s) const
{ return QString::compare_helper(constData(), size(),
s.constData(), s.size()) <= 0; }
QT_ASCII_CAST_WARN inline
bool operator>=(const QByteArray & s) const
{ return QString::compare_helper(constData(), size(),
s.constData(), s.size()) >= 0; }
QT_ASCII_CAST_WARN friend //以下开始全局函数
bool operator==(const char * s1, const QString & s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) == 0; }
QT_ASCII_CAST_WARN friend
bool operator!=(const char * s1, const QString & s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) != 0; }
QT_ASCII_CAST_WARN friend
bool operator< (const char * s1, const QString & s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) > 0; }
QT_ASCII_CAST_WARN friend
bool operator> (const char * s1, const QString & s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) < 0; }
QT_ASCII_CAST_WARN friend
bool operator<=(const char * s1, const QString & s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
QT_ASCII_CAST_WARN friend
bool operator>=(const char * s1, const QString & s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
friend //友元函数,这是全局函数,定义的全局比较运算符函数
bool operator==(const QString & s1, const QString & s2) noexcept
{ return (s1.size() == s2.size())
&& QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) == 0;
}
friend
bool operator!=(const QString & s1, const QString & s2) noexcept
{ return !(s1 == s2); }
friend
bool operator< (const QString & s1, const QString & s2) noexcept
{ return QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) < 0; }
friend
bool operator> (const QString & s1, const QString & s2) noexcept
{ return s2 < s1; }
friend
bool operator<=(const QString & s1, const QString & s2) noexcept
{ return !(s1 > s2); }
friend
bool operator>=(const QString & s1, const QString & s2) noexcept
{ return !(s1 < s2); }
friend
bool operator==(const QString &s1, QLatin1String s2) noexcept
{ return (s1.size() == s2.size())
&& QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) == 0;
}
friend
bool operator< (const QString &s1, QLatin1String s2) noexcept
{ return QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) < 0; }
friend
bool operator> (const QString &s1, QLatin1String s2) noexcept
{ return QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) > 0; }
friend
bool operator!=(const QString &s1, QLatin1String s2) noexcept
{ return !(s1 == s2); }
friend
bool operator<=(const QString &s1, QLatin1String s2) noexcept
{ return !(s1 > s2); }
friend
bool operator>=(const QString &s1, QLatin1String s2) noexcept
{ return !(s1 < s2); }
friend
bool operator==(QLatin1String s1, const QString &s2) noexcept
{ return s2 == s1; }
friend
bool operator< (QLatin1String s1, const QString &s2) noexcept
{ return s2 > s1; }
friend
bool operator> (QLatin1String s1, const QString &s2) noexcept
{ return s2 < s1; }
friend
bool operator!=(QLatin1String s1, const QString &s2) noexcept
{ return s2 != s1; }
friend
bool operator<=(QLatin1String s1, const QString &s2) noexcept
{ return s2 >= s1; }
friend
bool operator>=(QLatin1String s1, const QString &s2) noexcept
{ return s2 <= s1; }
// Check isEmpty() instead of isNull() for backwards compatibility.
friend
bool operator==(const QString &s1, std::nullptr_t) noexcept
{ return s1.isEmpty(); }
friend
bool operator!=(const QString &s1, std::nullptr_t) noexcept
{ return !s1.isEmpty(); }
friend
bool operator< (const QString & , std::nullptr_t) noexcept
{ return false; }
friend
bool operator> (const QString &s1, std::nullptr_t) noexcept
{ return !s1.isEmpty(); }
friend
bool operator<=(const QString &s1, std::nullptr_t) noexcept
{ return s1.isEmpty(); }
friend
bool operator>=(const QString & , std::nullptr_t) noexcept
{ return true; }
friend
bool operator==(std::nullptr_t, const QString &s2) noexcept
{ return s2 == nullptr; }
friend
bool operator!=(std::nullptr_t, const QString &s2) noexcept
{ return s2 != nullptr; }
friend
bool operator< (std::nullptr_t, const QString &s2) noexcept
{ return s2 > nullptr; }
friend
bool operator> (std::nullptr_t, const QString &s2) noexcept
{ return s2 < nullptr; }
friend
bool operator<=(std::nullptr_t, const QString &s2) noexcept
{ return s2 >= nullptr; }
friend
bool operator>=(std::nullptr_t, const QString &s2) noexcept
{ return s2 <= nullptr; }
friend
bool operator==(const QString &s1, const char16_t *s2) noexcept
{ return s1 == QStringView(s2); }
friend
bool operator!=(const QString &s1, const char16_t *s2) noexcept
{ return s1 != QStringView(s2); }
friend
bool operator< (const QString &s1, const char16_t *s2) noexcept
{ return s1 < QStringView(s2); }
friend
bool operator> (const QString &s1, const char16_t *s2) noexcept
{ return s1 > QStringView(s2); }
friend
bool operator<=(const QString &s1, const char16_t *s2) noexcept
{ return s1 <= QStringView(s2); }
friend
bool operator>=(const QString &s1, const char16_t *s2) noexcept
{ return s1 >= QStringView(s2); }
friend
bool operator==(const char16_t *s1, const QString &s2) noexcept
{ return s2 == s1; }
friend
bool operator!=(const char16_t *s1, const QString &s2) noexcept
{ return s2 != s1; }
friend
bool operator< (const char16_t *s1, const QString &s2) noexcept
{ return s2 > s1; }
friend
bool operator> (const char16_t *s1, const QString &s2) noexcept
{ return s2 < s1; }
friend
bool operator<=(const char16_t *s1, const QString &s2) noexcept
{ return s2 >= s1; }
friend
bool operator>=(const char16_t *s1, const QString &s2) noexcept
{ return s2 <= s1; }
// QChar <> QString
friend inline
bool operator==(QChar lhs, const QString &rhs) noexcept
{ return rhs.size() == 1 && lhs == rhs.front(); }
friend inline
bool operator!=(QChar lhs, const QString &rhs) noexcept
{ return !(lhs == rhs); }
friend inline
bool operator< (QChar lhs, const QString &rhs) noexcept
{ return compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
friend inline
bool operator> (QChar lhs, const QString &rhs) noexcept
{ return compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
friend inline
bool operator<=(QChar lhs, const QString &rhs) noexcept
{ return !(lhs > rhs); }
friend inline
bool operator>=(QChar lhs, const QString &rhs) noexcept
{ return !(lhs < rhs); }
friend inline
bool operator==(const QString &lhs, QChar rhs) noexcept
{ return rhs == lhs; }
friend inline
bool operator!=(const QString &lhs, QChar rhs) noexcept
{ return !(rhs == lhs); }
friend inline
bool operator< (const QString &lhs, QChar rhs) noexcept
{ return rhs > lhs; }
friend inline
bool operator> (const QString &lhs, QChar rhs) noexcept
{ return rhs < lhs; }
friend inline
bool operator<=(const QString &lhs, QChar rhs) noexcept
{ return !(rhs < lhs); }
friend inline
bool operator>=(const QString &lhs, QChar rhs) noexcept
{ return !(rhs > lhs); }
//-------------以上全是关于 QString 的读函数>>>>>>>>>>>>>>>>>
//-------------接着开始阅读对 QString进行修改的写函数>>>>>>>>>>
inline void detach()
{ if (d->needsDetach()) reallocData(d.size, QArrayData::KeepSize); }
//Resets the QString to use the first size Unicode characters in the
//array unicode. The data in unicode is not copied. //不要修改 unicode数组
//The caller must be able to guarantee that unicode will not be deleted or
//modified as long as the QString (or an unmodified copy of it) exists.
//可以使用此函数代替 fromRawData()来重用现有的 QString 对象,以节省内存重新分配。
QString & setRawData(const QChar * unicode, qsizetype size);
QString & setUnicode(const QChar * unicode, qsizetype size);
//Resizes the string to size characters and
//copies unicode into the string.
//If unicode is nullptr, nothing is copied,
//but the string is still resized to size.
inline
QString & setUtf16 (const ushort * autf16 , qsizetype asize)
{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
// ### Qt 7 char16_t
//Resizes the string to size characters and copies unicode into the string.
//If unicode is nullptr, nothing is copied,
//but the string is still resized to size.
//Note that unlike fromUtf16(),
//this function does not consider BOMs and possibly differing byte ordering.
//Sets the string to the printed value of n in the specified base,
//and returns a reference to the string.
//The base is 10 by default and must be between 2 and 36.
//The formatting always uses QLocale::C, i.e., English/UnitedStates.
//To get a localized string representation of a number,
//use QLocale::toString() with the appropriate locale.
QString & setNum(short n, int base=10)
{ return setNum(qlonglong(n), base); }
QString & setNum(ushort n, int base=10)
{ return setNum(qulonglong(n), base); }
QString & setNum(int n, int base=10)
{ return setNum(qlonglong(n), base); }
QString & setNum(uint n, int base=10)
{ return setNum(qulonglong(n), base); }
QString & setNum(long n, int base=10)
{ return setNum(qlonglong(n), base); }
QString & setNum(ulong n, int base=10)
{ return setNum(qulonglong(n), base); }
QString & setNum(qlonglong , int base=10);
QString & setNum(qulonglong, int base=10);
QString & setNum(float n, char format='g', int precision=6)
{ return setNum(double(n),format,precision); }
QString & setNum(double, char format='g', int precision=6);
//Sets the string to the printed value of n,
//formatted according to the given format and precision,
//and returns a reference to the string.
//Returns a string equivalent of the number n according to the specified base.
//The base is 10 by default and must be between 2 and 36.
//For bases other than 10, n is treated as an unsigned integer.
//The formatting always uses QLocale::C, i.e., English/UnitedStates.
//To get a localized string representation of a number,
//use QLocale::toString() with the appropriate locale.
static QString number(int , int base=10);
static QString number(uint , int base=10);
static QString number(long , int base=10);
static QString number(ulong , int base=10);
static QString number(qlonglong , int base=10);
static QString number(qulonglong , int base=10);
static QString number(double n, char format='g', int precision=6);
//Returns a string representing the floating-point number.
//Returns a string that represents n,
//formatted according to the specified format and precision.
//For formats with an exponent,
//the exponent will show its sign and have at least two digits,
//left-padding the exponent with zero if needed.
void resize(qsizetype size); //不必要调用
void resize(qsizetype size, QChar fillChar);
QString & fill(QChar c, qsizetype size = -1); //本函会修改 本类的大小
//Sets every character in the string to character c.
//If size is different from -1 (default),
//the string is resized to size beforehand.
void truncate(qsizetype pos); //形参是下标
//Truncates the string at the given pos index.
void chop (qsizetype n) ; //形参是被裁的数量
//Removes n characters from the end of the string.
//If n is greater than or equal to size(), the result is an empty string;
//if n is negative, it is equivalent to passing zero.
inline void reserve(qsizetype asize)
{
if (d->needsDetach() || asize >= capacity() - d.freeSpaceAtBegin())
reallocData(qMax(asize, size()), QArrayData::KeepSize);
if (d->constAllocatedCapacity())
d->setFlag(Data::CapacityReserved);
}
inline void squeeze()
{
if (!d.isMutable())
return;
if (d->needsDetach() || size() < capacity())
reallocData(d.size, QArrayData::KeepSize);
if (d->constAllocatedCapacity())
d->clearFlag(Data::CapacityReserved);
}
//Clears the contents of the string and makes it null.
void clear() { if (!isNull()) *this = QString(); }
inline QString & prepend( QChar c)
{ return insert(0, c); }
inline QString & prepend(const QChar * uc, qsizetype len)
{ return insert(0, uc, len); }
#if QT_STRINGVIEW_LEVEL < 2
inline QString & prepend(const QString & s)
{ return insert(0, s); }
#endif
QT_ASCII_CAST_WARN
inline QString & prepend(const char * s)
{ return prepend(QString::fromUtf8(s)); }
QT_ASCII_CAST_WARN
inline QString & prepend(const QByteArray & s)
{ return prepend(QString::fromUtf8(s)); }
inline QString & prepend( QStringView v)
{ return prepend(v.data(), v.length()); }
inline QString & prepend( QLatin1String s)
{ return insert(0, s); }
//Inserts c at the given index i in the string.
QString & insert(qsizetype i, QChar c); //插入 QChar字符
QString & insert(qsizetype i, const QChar * uc, qsizetype len);
//Inserts the first len characters of the QChar array uc at the
//given index i in the string.
#if QT_STRINGVIEW_LEVEL < 2
inline
QString & insert(qsizetype i, const QString & s)
{ return insert(i, s.constData(), s.length()); }
//Inserts the string s at the given index i and
//returns a reference to this string.
//This string grows to accommodate the insertion.
//If i is beyond the end of the string,
//space characters are appended to the string to reach this position,
//followed by s.
#endif
QT_ASCII_CAST_WARN inline
QString & insert(qsizetype i, const char * s)
{ return insert(i, QString::fromUtf8(s)); }
QT_ASCII_CAST_WARN inline
QString & insert(qsizetype i, const QByteArray & s)
{ return insert(i, QString::fromUtf8(s)); }
inline
QString & insert(qsizetype i, QStringView v)
{ return insert(i, v.data(), v.length()); }
QString & insert(qsizetype i, QLatin1String s);
QString & append( QChar c);
QString & append(const QChar * uc, qsizetype len);
#if QT_STRINGVIEW_LEVEL < 2
QString & append(const QString & s);
#endif
QT_ASCII_CAST_WARN inline
QString & append(const char * s)
{ return append(QString::fromUtf8(s)); }
QT_ASCII_CAST_WARN inline
QString & append(const QByteArray & s)
{ return append(QString::fromUtf8(s)); }
inline
QString & append( QStringView v)
{ return append(v.data(), v.length()); }
QString & append( QLatin1String s);
inline QString & operator+=( QChar c)
{ return append(c); }
#if QT_STRINGVIEW_LEVEL < 2
inline QString & operator+=(const QString & s) { return append(s); }
#endif
QT_ASCII_CAST_WARN
inline QString & operator+=(const char * s)
{ return append(QString::fromUtf8(s)); }
QT_ASCII_CAST_WARN
inline QString & operator+=(const QByteArray & s)
{ return append(QString::fromUtf8(s)); }
inline QString & operator+=( QStringView v) { return append(v); }
inline QString & operator+=( QLatin1String s) { return append(s); }
//Replaces len characters beginning at index i with the character after and
//returns a reference to this string.
QString & replace(qsizetype i, qsizetype len, QChar after);
QString & replace(qsizetype i, qsizetype len, const QChar * s, qsizetype slen);
//Replaces len characters beginning at index i with the
//first slen characters of the QChar array s and returns a
//reference to this string.
QString & replace(qsizetype i, qsizetype len, const QString & after);
//Replaces len characters beginning at index i with the string after and
//returns a reference to this string.
//Note: If the specified position i is within the string,
//but i + len goes outside the strings range,
//then len will be adjusted to stop at the end of the string.
//Replaces every occurrence of the character before with the
//character after and returns a reference to this string.
//If cs is Qt::CaseSensitive (default), //替换原字符串里所有的 before字符
//the search is case sensitive; otherwise the search is case insensitive.
QString & replace( QChar before, QChar after,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString & replace( QChar c , const QString & after, //多处替换
Qt::CaseSensitivity cs = Qt::CaseSensitive);
//Replaces every occurrence of the character c in the string with after and
//returns a reference to this string.
QString & replace(const QChar * before, qsizetype blen , //多处替换
const QChar * after , qsizetype alen ,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
//Replaces each occurrence in this string of the first blen characters of
//before with the first alen characters of after and returns a
//reference to this string.
QString & replace(const QString & before, const QString & after,
Qt::CaseSensitivity cs = Qt::CaseSensitive); //多处替换
//Replaces every occurrence of the string before with the
//string after and returns a reference to this string.
QString & replace(const QString & before, QLatin1String after,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString & replace(QLatin1String before, QLatin1String after,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString & replace(QLatin1String before, const QString & after,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString & replace(QChar c , QLatin1String after,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
#if QT_CONFIG(regularexpression)
QString & replace(const QRegularExpression & re, const QString &after);
inline
QString & remove (const QRegularExpression & re)
{ return replace(re, QString()); }
#endif
template <typename Predicate>
QString &removeIf(Predicate pred)
{
QtPrivate::sequential_erase_if(*this, pred);
return *this;
}
//Removes len characters from the string, starting at the given position i,
//and returns a reference to the string.
//If the specified position i is within the string, but i + len is beyond the
//end of the string, the string is truncated at the specified position.
//Element removal will preserve the string's capacity and not reduce the
//amount of allocated memory.
//To shed extra capacity and free as much memory as possible,
//call squeeze() after the last change to the string's size.
QString & remove( qsizetype i, qsizetype len);
//Removes every occurrence of the character c in this string,
//and returns a reference to this string.
//If cs is Qt::CaseSensitive (default), the search is case sensitive;
//otherwise the search is case insensitive.
QString & remove( QChar c,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString & remove(const QString & s,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
//Removes every occurrence of the given s string in this string,
//and returns a reference to this string.
QString & remove( QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
// ASCII compatibility
#if defined(QT_RESTRICTED_CAST_FROM_ASCII) //一般是不会做出限制的
template <qsizetype N>
inline
QString(const char (&ch)[N]) : QString(fromUtf8(ch)) {}
template <qsizetype N>
QString(char (&)[N]) = delete;
template <qsizetype N>
inline
QString & operator=(const char (&ch)[N])
{ return (*this = fromUtf8(ch, N - 1)); }
template <qsizetype N>
QString & operator=(char (&)[N]) = delete;
#endif
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
//一般是不会做出限制的。这个条件编译 #if 里的内容很重要,拆分到归类后的地方了。
//包括构造函数、 =赋值运算符函数、追加删除插入 ascii字符、以及比较运算符 == != < > 等
//全拆走了,详情见官方源代码。
// these are needed, so it compiles with STL support enabled
#endif
//以下是模仿 STL容器的通用成员函数样式
typedef QChar * iterator;
typedef iterator Iterator;
typedef const QChar * const_iterator;
typedef const_iterator ConstIterator;
typedef std::reverse_iterator< iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
inline iterator begin()
{ detach(); return reinterpret_cast<QChar*>(d.data()); }
inline const_iterator begin() const
{ return reinterpret_cast<const QChar*>(d.data()); }
inline const_iterator cbegin() const
{ return reinterpret_cast<const QChar*>(d.data()); }
inline const_iterator constBegin() const
{ return reinterpret_cast<const QChar*>(d.data()); }
inline iterator end()
{ detach(); return reinterpret_cast<QChar*>(d.data() + d.size); }
inline const_iterator end() const
{ return reinterpret_cast<const QChar*>(d.data() + d.size); }
inline const_iterator cend() const
{ return reinterpret_cast<const QChar*>(d.data() + d.size); }
inline const_iterator constEnd() const
{ return reinterpret_cast<const QChar*>(d.data() + d.size); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
// STL compatibility 其实迭代器指向的容器,会因为容器重新分配而失效的。
//using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
typedef qsizetype size_type;
typedef qptrdiff difference_type;
//typedef QIntegerForSizeof<void *>::Signed qptrdiff;
typedef QChar & reference;
typedef const QChar & const_reference;
typedef QChar value_type;
typedef QChar * pointer;
typedef const QChar * const_pointer;
inline void push_back ( QChar c) { append (c); }
inline void push_back (const QString & s) { append (s); }
inline void push_front( QChar c) { prepend(c); }
inline void push_front(const QString & s) { prepend(s); }
void shrink_to_fit() { squeeze(); }
iterator erase(const_iterator first, const_iterator last);
#if defined(Q_OS_DARWIN) || defined(Q_QDOC) //这个没有用
static QString fromCFString(CFStringRef string);
CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
static QString fromNSString(const NSString *string);
NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
#endif
}; //完结 class QString。撒花!!后面还有几个有用的函数,要附带上+++++++
#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
inline const
QString operator+(const QString & s1, const QString & s2)
{ QString t(s1); t += s2; return t; }
inline const
QString operator+(const QString & s1, QChar s2)
{ QString t(s1); t += s2; return t; }
inline const
QString operator+( QChar s1, const QString & s2)
{ QString t(s1); t += s2; return t; }
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
QT_ASCII_CAST_WARN
inline const
QString operator+(const QString & s1, const char * s2)
{ QString t(s1); t += QString::fromUtf8(s2); return t; }
QT_ASCII_CAST_WARN
inline const
QString operator+(const char * s1, const QString & s2)
{ QString t = QString::fromUtf8(s1); t += s2; return t; }
QT_ASCII_CAST_WARN inline const
QString operator+(const QByteArray & ba, const QString & s)
{ QString t = QString::fromUtf8(ba); t += s; return t; }
QT_ASCII_CAST_WARN inline const
QString operator+(const QString & s, const QByteArray & ba)
{ QString t(s); t += QString::fromUtf8(ba); return t; }
# endif // QT_NO_CAST_FROM_ASCII
#endif // QT_USE_QSTRINGBUILDER
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
Q_CORE_EXPORT QDataStream & operator<<(QDataStream &, const QString &);
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &, QString &);
#endif //至此是让 <<、 >> 运算符支持 QString 类型
(10)
谢谢