QT6 源(57):阅读与注释 QLatin1String 这个类的源码,其存储了 c语言形式的字符串。非常类似于 QByteArray 类型。不知道为啥同时存在这两个类

(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)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值