(1)本类与重要的 QString 类定义于同一个头文件 qstring . h :
/*
//QLatinlString 类为 US-ASCI/Latin-1 编码的字符串字面量提供了一个薄包装。
//定义QT NO_CAST FROM ASCI的应用程序(如QString文档中所解释的)
//无法访问QString的const char *API。
//为了提供一种有效指定拉丁文1字符串的方法,Qt提供了QLatinlstring。
//它只是const char *的一个非常薄的包装。
//总之可见,这个类不重要。更重要的是 QString
QString的许多成员函数都被重载以接受const char *而不是QString。
这包括复制构造函数、赋值运算符比较运算符以及各种其他函数,
如insert()、replace()和indexOf()。
这些函数通常经过优化,以避免为const char *数据构造一个QString对象。
定义 QT_NO_CAST_FROM ASCII(如 QString 文档中所解释)的应用程序无法访问
QString 的const char *API。
为了提供一种高效指定拉丁文1字符串的方法,Qt提供了 QLatin1String,
它只是const char*的一个非常薄的包装。
这段代码稍微长一些,但它提供的功能和第一个版本的代码完全相同,
而且比使用 QString::fromLatin1转换拉丁文1字符串更快。
由于QString(QLatin1String)构造函数,QLatin1String可以在任何需要使用QString的地方使用。
注:如果使用 QLatin1String参数调用的函数实际上没有重载以接受 QLatin1String,
那么隐式转换为 QString将触发内存分配,而这通常是你最初使用 QLatin1String想要避免的。
在这些情况下,使用 QStringLiteral可能是更好的选择。
*/
QT_BEGIN_NAMESPACE //说明伟大的 QString 类定义于 QT 全局空间
class QLatin1String
{
private:
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
static inline int compare_helper(const QLatin1String &s1, const char *s2)
{
return QString::compare(s1, QString::fromUtf8(s2));
}
#endif
Q_ALWAYS_INLINE constexpr void verify(qsizetype pos, qsizetype n = 0) const
{
Q_ASSERT(pos >= 0);
Q_ASSERT(pos <= size());
Q_ASSERT(n >= 0);
Q_ASSERT(n <= size() - pos);
}
Q_CORE_EXPORT static int compare_helper(const QChar *data1, qsizetype length1,
QLatin1String s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
qsizetype m_size; //数据长度
const char * m_data; //数据起点
public:
constexpr inline //介绍本类的构造函数
QLatin1String() noexcept : m_size(0), m_data(nullptr) {}
constexpr inline explicit
QLatin1String(const char * s) noexcept :
m_size(s ? qsizetype(strlen(s)) : 0), m_data(s) {}
//Constructs a QLatin1String object that stores f with length (l - f).
//The range [f ,l ) must remain valid for the lifetime of this
//Latin-1 string object.
//Passing nullptr as f is safe if l is nullptr, too,
//and results in a null Latin-1 string.
//The behavior is undefined if last precedes first,
//first is nullptr and last is not, or if last - first > INT_MAX.
constexpr explicit //包含的字符串的范围是 [f, l)
QLatin1String(const char * f, const char * l)
: QLatin1String(f, qsizetype(l - f)) {}
constexpr inline explicit
QLatin1String(const char *s, qsizetype sz) noexcept
: m_size(sz), m_data(s) {}
explicit
QLatin1String(const QByteArray & s) noexcept // copy构造函数
: m_size(qsizetype(qstrnlen(s.constData(), s.size()))),
m_data(s.constData()) {}
inline QString toString() const { return *this; }
constexpr const char * latin1() const noexcept { return m_data; }
constexpr qsizetype size() const noexcept { return m_size; }
constexpr const char * data() const noexcept { return m_data; }
constexpr bool isNull() const noexcept { return !data(); }
constexpr bool isEmpty() const noexcept { return !size(); }
template <typename...Args>
[[nodiscard]] inline
QString arg(Args &&...args) const
{
return QtPrivate::argToQStringDispatch(*this,
QtPrivate::qStringLikeToArg(args)...);
}
[[nodiscard]] constexpr
QLatin1Char at(qsizetype i) const
{ return Q_ASSERT(i >= 0), Q_ASSERT(i < size()), QLatin1Char(m_data[i]); }
[[nodiscard]] constexpr
QLatin1Char operator[](qsizetype i) const { return at(i); }
[[nodiscard]] constexpr
QLatin1Char front() const { return at(0); }
[[nodiscard]] constexpr
QLatin1Char back() const { return at(size() - 1); }
[[nodiscard]]
int compare(QStringView other,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::compareStrings(*this, other, cs); }
[[nodiscard]]
int compare(QLatin1String other,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::compareStrings(*this, other, cs); }
[[nodiscard]] constexpr
int compare(QChar c) const noexcept
{ return isEmpty()
? -1
: front() == c
? int(size() > 1)
: uchar(m_data[0]) - c.unicode();
}
[[nodiscard]]
int compare(QChar c, Qt::CaseSensitivity cs) const noexcept
{ return QtPrivate::compareStrings(*this, QStringView(&c, 1), cs); }
[[nodiscard]]
bool startsWith(QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::startsWith(*this, s, cs); }
[[nodiscard]]
bool startsWith(QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::startsWith(*this, s, cs); }
[[nodiscard]] constexpr
bool startsWith(QChar c) const noexcept
{ return !isEmpty() && front() == c; }
[[nodiscard]] inline
bool startsWith(QChar c, Qt::CaseSensitivity cs) const noexcept
{ return QtPrivate::startsWith(*this, QStringView(&c, 1), cs); }
[[nodiscard]]
bool endsWith(QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::endsWith(*this, s, cs); }
[[nodiscard]]
bool endsWith(QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::endsWith(*this, s, cs); }
[[nodiscard]] constexpr
bool endsWith(QChar c) const noexcept
{ return !isEmpty() && back() == c; }
[[nodiscard]] inline
bool endsWith(QChar c, Qt::CaseSensitivity cs) const noexcept
{ return QtPrivate::endsWith(*this, QStringView(&c, 1), cs); }
//Returns the index position of the first occurrence of the string-view str,
//Latin-1 string l1, or character ch, respectively,
//in this Latin-1 string, searching forward from index position from.
//Returns -1 if str is not found.
//If cs is Qt::CaseSensitive (default), the search is case sensitive;
//otherwise the search is case insensitive.
//If from is -1, the search starts at the last character;
//if it is -2, at the next to last character and so on.
[[nodiscard]]
qsizetype indexOf(QStringView s, qsizetype from = 0, //参数决定是否区分大小写
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::findString(*this, from, s, cs); }
[[nodiscard]]
qsizetype indexOf(QLatin1String s, qsizetype from = 0,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::findString(*this, from, s, cs); }
[[nodiscard]]
qsizetype indexOf(QChar c, qsizetype from = 0,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::findString(*this, from, QStringView(&c, 1), cs); }
[[nodiscard]]
bool contains(QStringView s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
[[nodiscard]]
bool contains(QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
[[nodiscard]] inline
bool contains(QChar c,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(QStringView(&c, 1), 0, cs) != -1; }
[[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); }
[[nodiscard]]
qsizetype lastIndexOf(QLatin1String s,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return lastIndexOf(s, size(), cs); }
[[nodiscard]]
qsizetype lastIndexOf(QLatin1String s, qsizetype from,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::lastIndexOf(*this, from, s, cs); }
//Returns the index position of the last occurrence of the string-view str,
//Latin-1 string l1, or character ch, respectively, in this Latin-1 string,
//searching backward from index position from. Returns -1 if str is not found.
//If from is -1, the search starts at the last character;
//if from is -2, at the next to last character and so on.
//If cs is Qt::CaseSensitive (default), the search is case sensitive;
//otherwise the search is case insensitive.
[[nodiscard]]
qsizetype lastIndexOf(QChar c, qsizetype from = -1,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs); }
using value_type = const char;
using reference = value_type &;
using const_reference = reference;
using iterator = value_type *;
using const_iterator = iterator;
using difference_type = qsizetype; // violates Container concept requirements
using size_type = qsizetype; // violates Container concept requirements
constexpr const_iterator begin() const noexcept { return data(); }
constexpr const_iterator cbegin() const noexcept { return data(); }
constexpr const_iterator end () const noexcept { return data() + size(); }
constexpr const_iterator cend () const noexcept { return data() + size(); }
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = reverse_iterator;
const_reverse_iterator rbegin() const noexcept
{ return const_reverse_iterator(end()); }
const_reverse_iterator crbegin() const noexcept
{ return const_reverse_iterator(end()); }
const_reverse_iterator rend() const noexcept
{ return const_reverse_iterator(begin()); }
const_reverse_iterator crend() const noexcept
{ return const_reverse_iterator(begin()); }
[[nodiscard]] constexpr
QLatin1String mid(qsizetype pos, qsizetype n = -1) const
{
using namespace QtPrivate;
auto result = QContainerImplHelper::mid(size(), &pos, &n);
return result == QContainerImplHelper::Null
? QLatin1String()
: QLatin1String(m_data + pos, n); //源码显示了
}
[[nodiscard]] constexpr
QLatin1String left(qsizetype n) const
{
if (size_t(n) >= size_t(size())) n = size();
return QLatin1String(m_data, n);
}
[[nodiscard]] constexpr
QLatin1String right(qsizetype n) const
{
if (size_t(n) >= size_t(size())) n = size();
return QLatin1String(m_data + m_size - n, n);
}
[[nodiscard]] constexpr
QLatin1String sliced(qsizetype pos) const
{ verify(pos);
return QLatin1String(m_data + pos, m_size - pos);
}
[[nodiscard]] constexpr //选择从下标 pos 开始的 n 个子杰
QLatin1String sliced(qsizetype pos, qsizetype n) const
{ verify(pos, n);
return QLatin1String(m_data + pos, n);
}
[[nodiscard]] constexpr
QLatin1String first(qsizetype n) const
{ verify(n);
return QLatin1String(m_data, n);
}
[[nodiscard]] constexpr
QLatin1String last(qsizetype n) const
{ verify(n);
return QLatin1String(m_data + size() - n, n);
}
[[nodiscard]] constexpr
QLatin1String chopped(qsizetype n) const //扔掉最后的 n 个字节
{ verify(n);
return QLatin1String(m_data, size() - n);
}
constexpr void chop (qsizetype n) //为本字符串减掉最后的 n 个字节
{ verify(n); m_size -= n; }
constexpr void truncate(qsizetype n) //让本字符串只保留开始的 n 个字节
{ verify(n); m_size = n; }
[[nodiscard]]
QLatin1String trimmed() const noexcept { return QtPrivate::trimmed(*this); }
template <typename Needle, typename...Flags>
[[nodiscard]] inline constexpr
auto tokenize(Needle &&needle, Flags...flags) const
noexcept(noexcept(qTokenize(std::declval<const QLatin1String &>(),
std::forward<Needle>(needle), flags...)))
-> decltype(qTokenize(*this, std::forward<Needle>(needle), flags...))
{ return qTokenize(*this, std::forward<Needle>(needle), flags...); }
//以下函数,不再是本 QLatin1String 的成员函数
friend inline //全局的友元函数
bool operator==(QLatin1String s1, QLatin1String s2) noexcept
{ return s1.size() == s2.size() &&
(!s1.size() || !memcmp(s1.latin1(), s2.latin1(), s1.size()));
}
friend inline
bool operator!=(QLatin1String s1, QLatin1String s2) noexcept
{ return !(s1 == s2); }
friend inline
bool operator<(QLatin1String s1, QLatin1String s2) noexcept
{
const qsizetype len = qMin(s1.size(), s2.size());
const int r = len ? memcmp(s1.latin1(), s2.latin1(), len) : 0;
return r < 0 || (r == 0 && s1.size() < s2.size());
}
friend inline
bool operator>(QLatin1String s1, QLatin1String s2) noexcept
{ return s2 < s1; }
friend inline
bool operator<=(QLatin1String s1, QLatin1String s2) noexcept
{ return !(s1 > s2); }
friend inline
bool operator>=(QLatin1String s1, QLatin1String s2) noexcept
{ return !(s1 < s2); }
// QChar <> QLatin1String
friend inline
bool operator==(QChar lhs, QLatin1String rhs) noexcept
{ return rhs.size() == 1 && lhs == rhs.front(); }
friend inline
bool operator< (QChar lhs, QLatin1String rhs) noexcept
{ return compare_helper(&lhs, 1, rhs) < 0; }
friend inline
bool operator> (QChar lhs, QLatin1String rhs) noexcept
{ return compare_helper(&lhs, 1, rhs) > 0; }
friend inline
bool operator!=(QChar lhs, QLatin1String rhs) noexcept
{ return !(lhs == rhs); }
friend inline
bool operator<=(QChar lhs, QLatin1String rhs) noexcept
{ return !(lhs > rhs); }
friend inline
bool operator>=(QChar lhs, QLatin1String rhs) noexcept
{ return !(lhs < rhs); }
friend inline
bool operator==(QLatin1String lhs, QChar rhs) noexcept
{ return rhs == lhs; }
friend inline
bool operator!=(QLatin1String lhs, QChar rhs) noexcept
{ return !(rhs == lhs); }
friend inline
bool operator< (QLatin1String lhs, QChar rhs) noexcept
{ return rhs > lhs; }
friend inline
bool operator> (QLatin1String lhs, QChar rhs) noexcept
{ return rhs < lhs; }
friend inline
bool operator<=(QLatin1String lhs, QChar rhs) noexcept
{ return !(rhs < lhs); }
friend inline
bool operator>=(QLatin1String lhs, QChar rhs) noexcept
{ return !(rhs > lhs); }
// QStringView <> QLatin1String 全部都是全局的符号比较运算符函数
friend inline bool operator==(QStringView lhs, QLatin1String rhs) noexcept
{ return lhs.size() == rhs.size() && QtPrivate::equalStrings(lhs, rhs); }
friend inline bool operator!=(QStringView lhs, QLatin1String rhs) noexcept
{ return !(lhs == rhs); }
friend inline bool operator< (QStringView lhs, QLatin1String rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) < 0; }
friend inline bool operator<=(QStringView lhs, QLatin1String rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) <= 0; }
friend inline bool operator> (QStringView lhs, QLatin1String rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) > 0; }
friend inline bool operator>=(QStringView lhs, QLatin1String rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) >= 0; }
friend inline bool operator==(QLatin1String lhs, QStringView rhs) noexcept
{ return lhs.size() == rhs.size() && QtPrivate::equalStrings(lhs, rhs); }
friend inline bool operator!=(QLatin1String lhs, QStringView rhs) noexcept
{ return !(lhs == rhs); }
friend inline bool operator< (QLatin1String lhs, QStringView rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) < 0; }
friend inline bool operator<=(QLatin1String lhs, QStringView rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) <= 0; }
friend inline bool operator> (QLatin1String lhs, QStringView rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) > 0; }
friend inline bool operator>=(QLatin1String lhs, QStringView rhs) noexcept
{ return QtPrivate::compareStrings(lhs, rhs) >= 0; }
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
QT_ASCII_CAST_WARN inline bool operator==(const char *s) const;
{ return QString::fromUtf8(s) == *this; }
QT_ASCII_CAST_WARN inline bool operator!=(const char *s) const;
{ return QString::fromUtf8(s) != *this; }
QT_ASCII_CAST_WARN inline bool operator< (const char *s) const;
{ return QString::fromUtf8(s) > *this; }
QT_ASCII_CAST_WARN inline bool operator> (const char *s) const;
{ return QString::fromUtf8(s) < *this; }
QT_ASCII_CAST_WARN inline bool operator<=(const char *s) const;
{ return QString::fromUtf8(s) >= *this; }
QT_ASCII_CAST_WARN inline bool operator>=(const char *s) const;
{ return QString::fromUtf8(s) <= *this; }
QT_ASCII_CAST_WARN inline bool operator==(const QByteArray &s) const;
{ return QString::fromUtf8(s) == *this; }
QT_ASCII_CAST_WARN inline bool operator!=(const QByteArray &s) const;
{ return QString::fromUtf8(s) != *this; }
QT_ASCII_CAST_WARN inline bool operator< (const QByteArray &s) const;
{ return QString::fromUtf8(s) > *this; }
QT_ASCII_CAST_WARN inline bool operator> (const QByteArray &s) const;
{ return QString::fromUtf8(s) < *this; }
QT_ASCII_CAST_WARN inline bool operator<=(const QByteArray &s) const;
{ return QString::fromUtf8(s) >= *this; }
QT_ASCII_CAST_WARN inline bool operator>=(const QByteArray &s) const;
{ return QString::fromUtf8(s) <= *this; }
QT_ASCII_CAST_WARN friend bool operator==(const char *s1, QLatin1String s2)
{ return compare_helper(s2, s1) == 0; }
QT_ASCII_CAST_WARN friend bool operator!=(const char *s1, QLatin1String s2)
{ return compare_helper(s2, s1) != 0; }
QT_ASCII_CAST_WARN friend bool operator< (const char *s1, QLatin1String s2)
{ return compare_helper(s2, s1) > 0; }
QT_ASCII_CAST_WARN friend bool operator> (const char *s1, QLatin1String s2)
{ return compare_helper(s2, s1) < 0; }
QT_ASCII_CAST_WARN friend bool operator<=(const char *s1, QLatin1String s2)
{ return compare_helper(s2, s1) >= 0; }
QT_ASCII_CAST_WARN friend bool operator>=(const char *s1, QLatin1String s2)
{ return compare_helper(s2, s1) <= 0; }
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
}; //完结 class QLatin1String
Q_DECLARE_TYPEINFO(QLatin1String, Q_RELOCATABLE_TYPE);
(2)
谢谢