QT6 源(18):Qt 里的容器类 QList<T> 的 源码阅读。以及宏定义 Q_QDOC,其关系到源码的条件编译,实验证明,有用版本里是没有定义此宏的; 宏 Q_CLANG_QDOC 也未被定义

(1) 宏定义 Q_QDOC

在这里插入图片描述

++同样 宏 Q_CLANG_QDOC 似乎也没有被定义

在这里插入图片描述

(2) 阅读 QLsit 的源码,并补充了一些注释

template <typename T>
class QList
#ifndef Q_QDOC // 是有继承的,下略去这样的宏定义
    : public QListSpecialMethods<T>
#endif
{
    using Data = QTypedArrayData<T>;
    using DataOps = QArrayDataOps<T>;
    using DataPointer = QArrayDataPointer<T>;
    class DisableRValueRefs {};

    DataPointer d; //貌似定义了指向链表中元素的指针

    template <typename V, typename U> // 声明了两个友元函数
    friend qsizetype QtPrivate::indexOf(const QList<V> &list,
            const U &u, qsizetype from) noexcept;

    template <typename V, typename U>
    friend qsizetype QtPrivate::lastIndexOf(const QList<V> &list,
                    const U &u, qsizetype from) noexcept;

public:
    using Type = T;
    using value_type = T;
    using pointer = T *;
    using const_pointer = const T *;
    using reference = T &;
    using const_reference = const T &;

    //using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
    using size_type = qsizetype; //总之是有符号类型的整数

    using difference_type = qptrdiff;
    //typedef QIntegerForSizeof<void *>::Signed qptrdiff;
    //typedef qptrdiff qintptr;

    using parameter_type = typename DataPointer::parameter_type;
    //std::conditional<bool, A, B>::type
    //若 bool 为真,则 type = 类型A,否则 type = 类型B
    using rvalue_ref = typename std::conditional<
                 DataPointer::pass_parameter_by_value,
                                    DisableRValueRefs,
                                                T &&
                                                 >::type;


    class iterator //内部类
    {
        T * i = nullptr; //裸指针,作为本类中的数据成员
    public:
        using difference_type = qsizetype;
        using value_type = T;
//libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
    //gcc<11 附带的 libstdc++ 没有修复缺陷 LWG 3346
#if __cplusplus >= 202002L && //肯定是高版本 c++,选择 if 分支
            (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
        using iterator_category = std::contiguous_iterator_tag;
        using element_type = value_type;
#else
        using iterator_category = std::random_access_iterator_tag;
#endif

        using pointer = T *;
        using reference = T &;

        inline constexpr iterator() = default;
        inline iterator(T * n) : i(n) {} //迭代器的有参构造函数
        inline T & operator* () const { return *i; } //运算符重载
        inline T * operator->() const { return  i; } // *p 与 p->

        inline T &operator[](qsizetype j) const
        { return *(i + j); } // i 是本迭代器类的数据成员 T * i = nullptr;

        inline constexpr bool operator==(iterator o) const
        { return i == o.i; } //这里出现了 == 的成员函数重载

        inline constexpr bool operator==(pointer p) const
        { return i == p; }   //说明形参可以是迭代器类型或裸指针类型,均可

        inline constexpr bool operator!=(iterator o) const
        { return i != o.i; }

        inline constexpr bool operator!=(pointer p) const
        { return i != p; } //只对 ==   != 做了重载定义
                           //下面的运算符函数只接受迭代器类型的形参
        inline constexpr bool operator<(iterator other) const
        { return i < other.i; }

        inline constexpr bool operator<=(iterator other) const
        { return i <= other.i; }

        inline constexpr bool operator>(iterator other) const
        { return i > other.i; }

        inline constexpr bool operator>=(iterator other) const
        { return i >= other.i; }

        inline iterator & operator++() { ++i; return *this; }
        inline iterator   operator++(int)  // a++ 与  ++a
        { T *n = i; ++i; return n; }

        inline iterator & operator--() { i--; return *this; }
        inline iterator   operator--(int)  // a-- 与  --a
        { T *n = i; i--; return n; }

        inline qsizetype operator-(iterator j) const
        { return i - j.i; }     //俩迭代器相减

        inline operator T*() const //类型转换运算符
        { return i; }              // 可以隐式转换为裸指针 T* 类型

        //c++14,std::enable_if_t<bool, T>
        //当 bool为 true时返回 T类型,否则什么也不返回而导致编译错误
        template <typename Int> //太长而换行,下面的是函数返回值
        std::enable_if_t<std::is_integral_v<Int>, iterator> &
        operator+=(Int j)  //意思是要求模板参数 Int 是某个整数类型
        { i+=j; return *this; }

        template <typename Int>
        std::enable_if_t<std::is_integral_v<Int>, iterator> &
        operator-=(Int j)  //复合运算符 += -=
        { i-=j; return *this; }

        template <typename Int>  // iter + 3
        std::enable_if_t<std::is_integral_v<Int>, iterator>
        operator+(Int j) const
        { return iterator(i+j); }

        template <typename Int>  // iter - 3
        std::enable_if_t<std::is_integral_v<Int>, iterator>
        operator-(Int j) const
        { return iterator(i-j); }

        template <typename Int> //定义了全局友元函数 3 + iter
        friend std::enable_if_t<std::is_integral_v<Int>, iterator>
        operator+(Int j, iterator k)
        { return k + j; }
    };

    class const_iterator //配套于本 Qt 容器的常量迭代器
    {
        const T * i = nullptr;
    public:
        using difference_type = qsizetype;
        using value_type = T;

        using iterator_category = std::contiguous_iterator_tag;
        using element_type = const value_type;

        using pointer   = const T *;
        using reference = const T &;

        inline constexpr const_iterator() = default;//默认无参构造函数
        inline const_iterator(const T * n) : i(n) {}//有参构造函数
        inline constexpr const_iterator(iterator o): i(o) {}//有参构造
        inline const T &operator*() const { return *i; } // *iter
        inline const T *operator->() const { return i; } // iter->

        inline const T & operator[](qsizetype j) const   // iter[3]
        { return *(i + j); }

        inline constexpr bool operator==(const_iterator o) const
        { return i == o.i; }

        inline constexpr bool operator==(      iterator o) const
        { return i == const_iterator(o).i; } // ==运算符函数的重载

        inline constexpr bool operator==(       pointer p) const
        { return i == p; }

        inline constexpr bool operator!=(const_iterator o) const
        { return i != o.i; }

        inline constexpr bool operator!=(      iterator o) const
        { return i != const_iterator(o).i; }

        inline constexpr bool operator!=(       pointer p) const
        { return i != p; }

        inline constexpr bool operator<(const_iterator other) const
        { return i < other.i; }

        inline constexpr bool operator<=(const_iterator other) const
        { return i <= other.i; }

        inline constexpr bool operator>(const_iterator other) const
        { return i > other.i; }

        inline constexpr bool operator>=(const_iterator other) const
        { return i >= other.i; }

        inline const_iterator & operator++() // a++ 与  ++a
        { ++i; return *this; }

        inline const_iterator   operator++(int)
        { const T *n = i; ++i; return n; }

        inline const_iterator & operator--() // a-- 与 --a
        { i--; return *this; }

        inline const_iterator   operator--(int)
        { const T *n = i; i--; return n; }

        inline qsizetype operator-(const_iterator j) const
        { return i - j.i; }               // iterA - iterB

        inline operator const T*() const  //类型转换运算符
        { return i; }                     //转换为 const T*

        template <typename Int>           // iter += 3
        std::enable_if_t<std::is_integral_v<Int>, const_iterator> &
        operator+=(Int j) { i+=j; return *this; }

        template <typename Int>           // iter  = 3
        std::enable_if_t<std::is_integral_v<Int>, const_iterator>
        operator+(Int j) const { return const_iterator(i+j); }

        template <typename Int>           // iter -= 3
        std::enable_if_t<std::is_integral_v<Int>, const_iterator> &
        operator-=(Int j) { i-=j; return *this; }

        template <typename Int>           // iter  - 3
        std::enable_if_t<std::is_integral_v<Int>, const_iterator>
        operator-(Int j) const { return const_iterator(i-j); }

        template <typename Int>   //全局友元函数,响应 3 + iter 运算
        friend std::enable_if_t<std::is_integral_v<Int>, const_iterator>
        operator+(Int j, const_iterator k)
        { return k + j; }
    };

    using Iterator      =       iterator;
    using ConstIterator = const_iterator;  //说明支持反向迭代
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

private:  //本 QList<T> 的私有成员函数
    void resize_internal(qsizetype i);

    bool isValidIterator(const_iterator i) const
    {   const std::less<const T*> less = {};
        return !less(d->end(), i) && !less(i, d->begin());
    } //本函验证形参迭代器 i 的有效性,合法返回 true,非法返回 F
    //比 end() 大,比 begin() 小的迭代器都是非法迭代器

public: //有参初始化函数
    QList(DataPointer dd) noexcept : d(dd) {  }

public:
    QList() = default; //默认的无参构造函数

    //构造一个初始大小为 size 元素的列表。
    //这些元素使用默认构造的值进行初始化。
    explicit QList(qsizetype size) : d(Data::allocate(size))
    {   if (size)  d->appendInitialize(size);    }

    //构造一个初始大小为 size 元素的列表。每个元素都初始化为 value。
    QList(qsizetype size, parameter_type t)
        : d(Data::allocate(size))
    { if (size)  d->copyAppend(size, t); }

    //初始化列表形式的构造初始化
    //QList<int> myList{1,2,3,4}
    inline QList(std::initializer_list<T> args)
        : d(Data::allocate(   args.size() )   )
    {   //从args提供的 std::initializer list构造列表。
        if (args.size())
            d->copyAppend(args.begin(), args.end());
    }

    //赋值运算符函数 myList = {1,2,3,4}
    QList<T> & operator=(std::initializer_list<T> args)
    {
        d = DataPointer(Data::allocate(args.size()));
        if (args.size())
            d->copyAppend(args.begin(), args.end());
        return *this;
    }

    template <typename InputIterator,
             QtPrivate::IfIsInputIterator<InputIterator> = true>
    QList(InputIterator i1, InputIterator i2)
    {   //意思是接受形参俩迭代器之间的范围赋值形式的构造初始化
        if constexpr (!std::is_convertible_v<
         typename std::iterator_traits<InputIterator>::iterator_category,
                          std::forward_iterator_tag>)
        {      std::copy(i1, i2, std::back_inserter(*this));   }
        else {  // else 系列更简单
            const auto distance = std::distance(i1, i2);
            if (distance) {
                d = DataPointer(Data::allocate(distance));
                if constexpr (
                 std::is_same_v<std::decay_t<InputIterator>, iterator> ||
                 std::is_same_v<std::decay_t<InputIterator>, const_iterator>)
                {
                    d->copyAppend(i1, i2);
                }
                else {
                    d->appendIteratorRange(i1, i2);
               }
            }
        }
    }

    // This constructor is here for compatibility with QStringList in Qt 5,
    //that has a QStringList(const QString &) constructor
    template<typename String, //特应用于  String 或 QString 类型
             typename = std::enable_if_t<
                 std::is_same_v<T, QString> &&
                 std::is_convertible_v<String, QString>>>
    inline explicit QList(const String &str)
    { append(str); }

    // compiler-generated special member functions are fine!

    void swap(QList &other) noexcept { d.swap(other.d); }

    template <typename U = T> // == 运算符函数,比较俩链表
    QTypeTraits::compare_eq_result_container<QList, U>
    operator==(const QList & other) const
    {
        if (size() != other.size())   return false;

        //只要链表的首地址相同就返回 true
        if (begin() == other.begin()) return  true;

        // do element-by-element comparison 全链表范围的元素比较
        return d->compare(begin(), other.begin(), size());
    }

    template <typename U = T>  // != 运算符函数,比较俩链表
    QTypeTraits::compare_eq_result_container<QList, U>
    operator!=(const QList &other) const
    {   return !(*this == other);  } //基于 == 运算符完成本函

    //如果此列表在词法上小于其他列表,则返回 true;否则返回 false。
    //此函数要求值类型具有运算符<()的实现。lexically less than
    template <typename U = T>  //  < 运算符函数,比较俩链表
    QTypeTraits::compare_lt_result_container<QList, U>
    operator<(const QList &other) const //不用在意下面的 noexcept()判断
    noexcept(noexcept(std::lexicographical_compare<typename QList<U>::const_iterator,
        typename QList::const_iterator>(  std::declval<QList<U>>().begin(),
        std::declval<QList<U>>().end(),  other.begin(), other.end())))
    {   return std::lexicographical_compare(
            begin(), end(), other.begin(), other.end());
    }

    template <typename U = T>  //  > 运算符函数,比较俩链表
    QTypeTraits::compare_lt_result_container<QList, U>
    operator>(const QList &other) const
        noexcept(noexcept(other < std::declval<QList<U>>()))
    {
        return other < *this;  // 基于 < 运算符函数的实现完成 > 的函数实现
    }

    template <typename U = T>  //  <= 运算符函数,比较俩链表
    QTypeTraits::compare_lt_result_container<QList, U>
    operator<=(const QList &other) const
        noexcept(noexcept(other < std::declval<QList<U>>()))
    {
        return !(other < *this); //就是不大于
    }

    template <typename U = T>  //  >= 运算符函数,比较俩链表
    QTypeTraits::compare_lt_result_container<QList, U>
    operator>=(const QList &other) const
        noexcept(noexcept(std::declval<QList<U>>() < other))
    {
        return !(*this < other); //就是不小于
    }

    qsizetype size() const noexcept   //返回链表中的元素数量
    { return d->size; }

    qsizetype count() const noexcept  //可见本函数等价于 size()
    { return size(); }

    qsizetype length() const noexcept //可见本函数等价于 size()
    { return size(); }

    inline bool isEmpty() const noexcept
    { return d->size == 0; }

    //将列表的大小设置为size。如果size大于当前大小,则将元素添加到末尾;
    //新元素初始化为默认构造的值。如果size小于当前大小,则从末尾删除元素。
    //自Ot5.6以来,resize()不再缩小容量。要释放多余容量,请使用squeeze()。
    void resize(qsizetype size)  // squeeze 挤压
    {   resize_internal(size);
        if (size > this->size())   d->appendInitialize(size);
    }

    void resize(qsizetype size, parameter_type c)
    {   resize_internal(size);  // 为找到此函数的官方注释
        if (size > this->size())
            d->copyAppend(size - this->size(), c);
    }

    //返回在不强制重新分配的情况下可以存储在列表中的最大项数。
    //此函数的唯一目的是提供微调OList内存使用的方法。
    //通常,您很少需要调用此函数。如果您想知道列表中有多少项,请调用size()
    inline qsizetype capacity() const
    { return qsizetype(d->constAllocatedCapacity()); }

    //尝试为至少 size 个元素分配内存。
    //如果你提前知道列表的大小,你应该调用这个函数来防止重新分配和内存碎片化。
    //如果你经常调整列表的大小,你可能会得到更好的性能。
    //如果不确定需要多少空间,通常最好用一个上界作为大小,
    //或者对最可能的大小作一个高估计,如果严格的上界比这个大得多的话。
    //如果规模被低估,一旦超出预留的规模,列表将根据需要增长,
    //这可能导致分配比最佳高估的规模更大,并减缓触发该分配的操作。
    //警告:reserve:()保留内存但不改变列表的大小。
    //访问当前列表末尾以外的数据是不定义的行为。
    //如果您需要访问当前列表末尾以外的内存,请使用resize()
    void reserve(qsizetype size);

    //Releases any memory not required to store the items.
    //此函数的唯一目的是提供微调OList内存使用的方法。
    //通常,您很少需要调用此函数。
    inline void squeeze();

    void detach() //停止共享,为写链表做准备。本函会被自动调用
    { d.detach(); } //判断是否停止了链表共享,是则返回 true
    bool isDetached() const noexcept { return !d->isShared(); }

    inline bool isSharedWith(const QList<T> &other) const
    { return d == other.d; } //判断这俩链表是否在共享元素

    //返回存储在列表中的数据的指针。该指针可用于访问和修改列表中的项。
    //警告:在分离或修改 QList 时,指针会被无效化。
    //这个函数主要用来将一个列表传递给一个接受纯 C++数组的函数。
    pointer data() { detach(); return d->data(); }
    // QList<int> list(10);   int *data = list.data();
    // for (qsizetype i = 0; i < 10; ++i)  data[i] = 2 * i;
    //本函数可见, QT6 里的Qlist 已经弱化为 vector
    //只有数组才可以直接使用地址的加减法运算    了

    const_pointer data() const noexcept
    { return d->data(); }  //一模一样,只是为了方便常量对象
    const_pointer constData() const noexcept
    { return d->data(); }

    //从列表中删除所有元素。
    //注意:在Qt5.6之前,这也会释放列表使用的内存。
    //从Qt5.7开始,容量被保留。
    //要清除所有容量,请使用默认构造的列表进行交换: 举例在此处略了
    void clear() //清除链表中的所有元素
    {   if (!size())   return;
        if (d->needsDetach()) {
            // must allocate memory
 DataPointer detached(Data::allocate(d.allocatedCapacity()));
            d.swap(detached);
        } else {
            d->truncate(0);
        }
    }

    const_reference at(qsizetype i) const noexcept
    {   Q_ASSERT_X(size_t(i) < size_t(d->size),
                   "QList::at", "index out of range");
        return data()[i];
    }
    //QList<T>.at(3) 与 QList<T>.[3] 返回的都是左值引用
    reference operator[](qsizetype i)
    {
        Q_ASSERT_X(size_t(i) < size_t(d->size), "QList::operator[]", "index out of range");
        detach();
        return data()[i];
    }

    const_reference operator[](qsizetype i) const noexcept
    { return at(i); }

    void append(parameter_type t) //在链表末尾添加数据
    { emplaceBack(t); }

    //把迭代器 i1 到 i2 之间的数据都添加进来
    void append(const_iterator i1, const_iterator i2);

    void append(rvalue_ref t) //形参是右值引用
    {   if constexpr (DataPointer::pass_parameter_by_value) {
            Q_UNUSED(t);
        } else {
            emplaceBack(std::move(t));
        }
    }

    void append(const QList<T> &l) //把形参链表中的数据都复制过来
    {   append(l.constBegin(), l.constEnd()); }

    void append(QList<T> &&l); //把形参链表中的数据都移动过来

    void prepend(parameter_type t) { emplaceFront(t); }

    //通常情况下,这种操作相对较快(摊销常数时间)。
    //(QList能够在列表数据开始时分配额外的内存,并在每次操作时按该方向增长,
    //而无需重新分配或移动数据。但是,如果您想要一个具有常数时间前缀保证的容器类,
    //请使用std::ist,否则请使用QList。
    void prepend(rvalue_ref t) //移动版本
    {
        if constexpr (DataPointer::pass_parameter_by_value) {
            Q_UNUSED(t);
        } else {
            emplaceFront(std::move(t)); //move 右值引用
        }
    }

    template<typename... Args> //万能引用版本,尾部插入
    inline reference emplaceBack(Args &&... args);
    //返回值应该是左值引用。一般也不会关心返回值
    //using reference = T &;
    template <typename ...Args> //万能引用版本,头部插入
    inline reference emplaceFront(Args&&... args);

    //对于大型列表,此操作可能很慢(线性时间),
    //因为它需要将索引为 i及之后的所有项在内存中移动一位。
    //如果您想要一个提供快速插入功能的容器类,请使用std::list。
    //此注释实锤了 QList<T> 就是适量数组 vector,而非指针链表 std::list

    //Inserts value at index position i in the list.
    iterator insert(qsizetype i, parameter_type t)
    { return emplace(i, t); }  //任意位置插入

    //Inserts n copies of t at index position i in the list.
    iterator insert(qsizetype i, qsizetype n, parameter_type t);

    //将值插入迭代器  before指向的项前面。返回指向插入项的迭代器。
    iterator insert(const_iterator before, parameter_type t)
    {
        Q_ASSERT_X(isValidIterator(before),
            "QList::insert",
            "The specified iterator argument 'before' is invalid");
        return insert(before, 1, t);
    }
    //留意此函数的返回值,即返回的迭代器指向哪里
    //Inserts n copies of t in front of the item
    //pointed to by the iterator before.
    //Returns an iterator pointing at the first of the inserted items.
    //在迭代器 before 之前插入 n个元素。返回指向插入项的第一个的迭代器。
    iterator insert(const_iterator before, qsizetype n, parameter_type t)
    {
        Q_ASSERT_X(isValidIterator(before),
            "QList::insert",
            "The specified iterator argument 'before' is invalid");
        return insert(std::distance(constBegin(), before), n, t);
    }

    iterator insert(const_iterator before, rvalue_ref t)
    {
        Q_ASSERT_X(isValidIterator(before), //移动插入
            "QList::insert",
            "The specified iterator argument 'before' is invalid");
        return insert(std::distance(constBegin(), before), std::move(t));
    }

    iterator insert(qsizetype i, rvalue_ref t)
    {
        if constexpr (DataPointer::pass_parameter_by_value) {
            Q_UNUSED(i);
            Q_UNUSED(t);
            return end();
        } else {
            return emplace(i, std::move(t));
        }
    }

    //通过在位置 before插入一个新元素来扩展容器。
    //这个新元素使用 args 作为其构造的参数,直接在原地构造。
    template <typename ...Args>  //万能引用,args 用于定点 new新元素
    iterator emplace(const_iterator before, Args&&... args)
    {
        Q_ASSERT_X(isValidIterator(before),
            "QList::emplace",
            "The specified iterator argument 'before' is invalid");
        return emplace(
            std::distance(constBegin(), before),
            std::forward<Args>(args)...);
    }

    template <typename ...Args> // 贡献于插入操作
    iterator emplace(qsizetype i, Args&&... args);

    void replace(qsizetype i, parameter_type t)
    {   //容器中元素的替换操作 arr[i] = t
        Q_ASSERT_X(i >= 0 && i < d->size,
            "QList<T>::replace", "index out of range");
        DataPointer oldData;
        d.detach(&oldData);
        d.data()[i] = t;
    }

    void replace(qsizetype i, rvalue_ref t) //右值引用
    {
        if constexpr (DataPointer::pass_parameter_by_value) {
            Q_UNUSED(i);
            Q_UNUSED(t);
        } else {
            Q_ASSERT_X(i >= 0 && i < d->size,
                "QList<T>::replace", "index out of range");
            DataPointer oldData;
            d.detach(&oldData);
            d.data()[i] = std::move(t); //移动 move版本
        }
    }

    //从列表中删除 n个元素,从索引位置 i开始。
    //元素移除将保留列表的容量,不会减少分配的内存量。
    //为了释放额外的容量并尽可能多地释放内存,请调用squeeze()。
    //注:当 QList不是隐式共享时,此函数仅使在指定位置或之后的迭代器无效。
    void remove(qsizetype i, qsizetype n = 1);

    void removeFirst() noexcept; //这个好理解,头个

    void removeLast () noexcept; //尾部

    value_type takeFirst() //返回头部元素,并删除这个头部元素
    {   Q_ASSERT(!isEmpty());
        value_type v = std::move(first());
        d->eraseFirst();
        return v;
    }

    value_type takeLast() //返回尾部元素,并删除这个尾部元素
    {   Q_ASSERT(!isEmpty());
        value_type v = std::move(last());
        d->eraseLast();
        return v;
    }

    //Assigns value to all items in the list.
    //If size is different from -1 (the default),
    //the list is resized to size beforehand.
    //将值分配给列表中的所有项目。
    //如果大小与-1(默认值)不同,则列表将预先调整为大小。
    QList<T> & fill(parameter_type t, qsizetype size = -1);

    using QListSpecialMethods<T>::contains;
    using QListSpecialMethods<T>::indexOf;
    using QListSpecialMethods<T>::lastIndexOf;

    //using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
    template <typename AT = T> // qsizetype 就是个有符号整数
    qsizetype count(const AT & t) const noexcept
    {   return qsizetype(
            std::count( data(), data() + size(), t)
                           );
    } //返回列表中值 t 出现的次数。
    //此函数要求值类型具有 operator==()的实现。

    void removeAt(qsizetype i) { remove(i); }
    //Removes the element at index position i.
    //Element removal will preserve the list's capacity
    //and not reduce the amount of allocated memory.

    //从列表中删除所有等于t的元素。
    //如果有任何元素被删除,则返回删除的元素数量。
    template <typename AT = T> //本函同样不会改变 Qlist的内存容量
    qsizetype removeAll(const AT & t)
    {
     return QtPrivate::sequential_erase_with_copy(*this, t);
    }

    //从列表中删除与t比较相等的第一个元素。返回是否实际上删除了元素。
    template <typename AT = T>
    bool removeOne(const AT & t)
    {
        return QtPrivate::sequential_erase_one(*this, t);
    }

    //从列表中删除所有谓词 pred 返回 true 的元素。
    //如果有任何元素被删除,则返回删除的元素数量。
    template <typename Predicate>
    qsizetype removeIf(Predicate pred)
    {
        return QtPrivate::sequential_erase_if(*this, pred);
    }

    T takeAt(qsizetype i) //删除下标 i 处的元素
    {   T t = std::move((*this)[i]);
        remove(i);
        return t;
    }

    //using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
    //Moves the item at index position from to index position to.
    void move(qsizetype from, qsizetype to) //形参是两个下标值
    {   Q_ASSERT_X(from >= 0 && from < size(),
            "QList::move(qsizetype, qsizetype)",
                   "'from' is out-of-range");

        Q_ASSERT_X(to >= 0 && to < size(),
                   "QList::move(qsizetype, qsizetype)",
                   "'to' is out-of-range");
        if (from == to) // don't detach when no-op
            return;

        detach(); //结束隐式共享,准备修改 QList 数组中的数据

        T * const b = d->begin(); //获得裸指针
        if (from < to)
            std::rotate(b + from, b + from + 1, b + to + 1);
        else
            std::rotate(b + to, b + from, b + from + 1);
    }
/*
template <class _FwdIt>
_CONSTEXPR20 _FwdIt rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last) {
    // exchange the ranges [_First, _Mid) and [_Mid, _Last)
    // that is, rotates [_First, _Last) left by distance(_First, _Mid) positions
    // returns the iterator pointing at *_First's new home
*/

    // STL-style  //看来发出迭代器时就停止了隐式共享了
    iterator begin() { detach(); return d->begin(); }
    iterator end  () { detach(); return d->end(); }

    const_iterator begin() const noexcept
    { return d->constBegin(); }
    const_iterator end() const noexcept
    { return d->constEnd(); }

    const_iterator cbegin() const noexcept
    { return d->constBegin(); }
    const_iterator cend() const noexcept
    { return d->constEnd(); }

    const_iterator constBegin() const noexcept
    { return d->constBegin(); }
    const_iterator constEnd() const noexcept
    { return d->constEnd(); }

    reverse_iterator rbegin()
    { return reverse_iterator(end()); }
    reverse_iterator rend()
    { return reverse_iterator(begin()); }

    const_reverse_iterator rbegin() const noexcept
    { return const_reverse_iterator(end()); }
    const_reverse_iterator rend() const noexcept
    { return const_reverse_iterator(begin()); }

    const_reverse_iterator crbegin() const noexcept
    { return const_reverse_iterator(end()); }
    const_reverse_iterator crend() const noexcept
    { return const_reverse_iterator(begin()); }

    //移除 [begin, end) 之间的所有项。
    //返回一个迭代器,值与 end 相同。
    iterator erase(const_iterator begin, const_iterator end);

    //从列表中移除由迭代器 pos 指向的项目,
    //并返回迭代器以获取列表中的下一个项目(可能是 end)
    inline iterator erase(const_iterator pos)
    { return erase(pos, pos+1); }
    //Removes the item pointed to by the iterator pos from the list,
    //and returns an iterator to the next item in the list
    //(which may be end()).

    // more Qt
    inline T& first() //返回头元素的左值引用
    { Q_ASSERT(!isEmpty()); return *begin(); }

    inline const T & first() const noexcept
    { Q_ASSERT(!isEmpty()); return *begin(); }

    inline const T &constFirst() const noexcept
    { Q_ASSERT(!isEmpty()); return *begin(); }

    inline T& last() //返回对最后一个元素的左值引用
    { Q_ASSERT(!isEmpty()); return *( end() - 1); }

    inline const T & last() const noexcept
    { Q_ASSERT(!isEmpty()); return *( end() - 1); }

    inline const T & constLast() const noexcept
    { Q_ASSERT(!isEmpty()); return *( end() - 1); }

    //判断本链表开头的元素是否是形参值
    inline bool startsWith(parameter_type t) const
    { return !isEmpty() && first() == t; }

    //判断本链表结尾的元素是否是形参值
    inline bool endsWith(parameter_type t) const
    { return !isEmpty() && last () == t; }

    QList<T> first(qsizetype n) const
    {   //返回包含此列表的前 n个元素的子列表。
        Q_ASSERT(size_t(n) <= size_t(size()));
        return QList<T>(begin(), begin() + n);
    }

    //返回一个子列表,包含当前列表中从位置 pos开始的 len个元素。
    //如果 leng为-1(默认值),则包含 pos之后的全部元素;
    //否则,包含 len 个元素(或者少于 len个元素的所有剩余元素)。
    QList<T> mid(qsizetype pos, qsizetype len = -1) const;

    //返回一个子列表,包含此列表的最后 n个元素。
    QList<T> last(qsizetype n) const
    {   Q_ASSERT(size_t(n) <= size_t(size()));
        return QList<T>(end() - n, end());
    }

    //返回一个子列表,该子列表包含从位置 pos 开始到列表末尾的所有元素。
    QList<T> sliced(qsizetype pos) const
    {
        Q_ASSERT(size_t(pos) <= size_t(size()));
        return QList<T>(begin() + pos, end());
    }

    //返回一个子列表,该子列表包含此列表的 n个元素,从位置 pos开始。
    QList<T> sliced(qsizetype pos, qsizetype n) const
    {
        Q_ASSERT(size_t(pos) <= size_t(size()));
        Q_ASSERT(n >= 0);
        Q_ASSERT(pos + n <= size());
        return QList<T>(begin() + pos, begin() + pos + n);
    }

    //如果索引 i超出范围,该函数将返回默认值。
    T value(qsizetype i, parameter_type defaultValue) const;

    //返回列表中索引位置/的值。如果索引i超出范围,函数将返回一个默认构造的值。
    //如果您确定 i在范围内,可以使用 at()函数,它稍微快一些。
    T value(qsizetype i) const { return value( i, T() ); }

    void swapItemsAt(qsizetype i, qsizetype j) //交换链表中元素
    {
        Q_ASSERT_X(i >= 0 && i < size() && j >= 0 && j < size(),
                    "QList<T>::swap", "index out of range");
        detach();
        qSwap(d->begin()[i], d->begin()[j]);
    }

    // STL compatibility
    inline void push_back(parameter_type t) { append(t); }
    void push_back(rvalue_ref t) { append(std::move(t)); }

    void push_front(rvalue_ref t) { prepend(std::move(t)); }
    inline void push_front(parameter_type t) { prepend(t); }

    void pop_back() noexcept { removeLast(); }
    void pop_front() noexcept { removeFirst(); }

    //为容器添加一个新元素到末尾。返回新元素的引用。
    //这个新元素使用 args... 作为其构造的参数在原地构建。
    template <typename ...Args>
    reference emplace_back(Args&&... args)
    { return emplaceBack(std::forward<Args>(args)...); }

    inline bool empty() const noexcept
    { return d->size == 0; }

    inline reference front() { return first(); }

    inline const_reference front() const noexcept
    { return first(); }

    inline reference back() { return last(); }
    inline const_reference back() const noexcept
    { return last(); }

    //这个函数是为了STL兼容性而提供的。它等同于squeeze()
    void shrink_to_fit() { squeeze(); }

    // comfort
    QList<T> & operator+=(const QList<T> &l) //表连接
    { append(l); return *this; }  // listA += listB

    QList<T> & operator+=(QList<T> &&l) //移动的表连接
    { append(std::move(l)); return *this; }

    inline QList<T> &operator+=(parameter_type t)
    { append(t); return *this; } //listA +  elemB

    inline QList<T> & operator+=(rvalue_ref t)
    { append(std::move(t)); return *this; }

    inline QList<T> operator+(const QList<T> &l) const
    { QList n = *this; n += l; return n; } //sA + sB

    inline QList<T> operator+(QList<T> &&l) const
    { QList n = *this; n += std::move(l); return n; }

    inline QList<T> & operator<<(QList<T> &&l)
    { *this += std::move(l); return *this; }

    inline QList<T> & operator<<(const QList<T> &l)
    { *this += l; return *this; } //listA << listB

    inline QList<T> & operator<< (parameter_type t)
    { append(t); return *this; } //listA << elemB

    inline QList<T> &operator<<(rvalue_ref t)
    { append(std::move(t)); return *this; }

    // Consider deprecating in 6.4 or later
    static QList<T> fromList(const QList<T> &list) noexcept
    { return list; }

    QList<T> toList() const noexcept { return *this; }

    static inline QList<T>
    fromVector(const QList<T> &vector) noexcept
    { return vector; } //官方建议废弃

    inline QList<T> toVector() const noexcept { return *this; }

    template<qsizetype N> //奇奇怪怪,没有官方注释
    static QList<T> fromReadOnlyData(const T (&t)[N]) noexcept
    {
        return QList<T>({ nullptr, const_cast<T *>(t), N });
    }
};

#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
template <typename InputIterator,
          typename ValueType = typename std::iterator_traits<InputIterator>::value_type,
          QtPrivate::IfIsInputIterator<InputIterator> = true>
QList(InputIterator, InputIterator) -> QList<ValueType>;
#endif

template <typename T> //本函数可能真的缩小了数组
inline void QList<T>::resize_internal(qsizetype newSize)
{
    Q_ASSERT(newSize >= 0);

    if ( d->needsDetach() ||
         newSize > capacity() - d.freeSpaceAtBegin())
    {
        d.detachAndGrow(QArrayData::GrowsAtEnd,
                        newSize - d.size, nullptr, nullptr);
    }
    else if (newSize < size()) {
        d->truncate(newSize);
    }
}

//Warning: reserve() reserves memory
//but does not change the size of the list.
//自Qt5.6以来,resize()不再缩小容量。要释放多余容量,请使用squeeze()。
template <typename T> void QList<T>::reserve(qsizetype asize)
{
    // capacity() == 0 for immutable data,
    //so this will force a detaching below
    if (asize <= capacity() - d.freeSpaceAtBegin()) {
        if (d->flags() & Data::CapacityReserved)
            return;  // already reserved, don't shrink
        if (!d->isShared()) {
            // accept current allocation, don't shrink
            d->setFlag(Data::CapacityReserved);
            return;
        }
    }

 DataPointer detached(Data::allocate(qMax(asize, size())));
    detached->copyAppend(constBegin(), constEnd());
    if (detached.d_ptr())
        detached->setFlag(Data::CapacityReserved);
    d.swap(detached);
}

//Releases any memory not required to store the items.
//The sole purpose of this function is to provide a means of
//fine tuning(微调) QList's memory usage.
//In general, you will rarely ever need to call this function.
template <typename T>
inline void QList<T>::squeeze()
{
    if (!d.isMutable())
        return;
    if (d->needsDetach() || size() < capacity()) {
        // must allocate memory
        DataPointer detached(Data::allocate(size()));
        if (size()) {
            if (d.needsDetach())
                detached->copyAppend(constBegin(), constEnd());
            else
                detached->moveAppend(d.data(), d.data() + d.size);
        }
        d.swap(detached);
    }
    // We're detached so this is fine
    d->clearFlag(Data::CapacityReserved);
}

template <typename T> //范围删除:从下标 i 开始的 n 个元素
inline void QList<T>::remove(qsizetype i, qsizetype n)
{
    Q_ASSERT_X(size_t(i) + size_t(n) <= size_t(d->size),
            "QList::remove", "index out of range");
    Q_ASSERT_X(n >= 0, "QList::remove", "invalid count");

    if (n == 0)     return;

    d.detach();
    d->erase(d->begin() + i, n); //注意是 n 个数量
}

template <typename T>
inline void QList<T>::removeFirst() noexcept
{
    Q_ASSERT(!isEmpty());
    d.detach();
    d->eraseFirst();
}

template <typename T>
inline void QList<T>::removeLast() noexcept
{
    Q_ASSERT(!isEmpty());
    d.detach();
    d->eraseLast();
}


template<typename T>
inline T QList<T>:: //返回下标 i 处的元素,并提供默认值
value(qsizetype i, parameter_type defaultValue) const
{
    return size_t(i) < size_t(d->size)
               ? at(i)
               : defaultValue;
}

template <typename T>
inline void
QList<T>::append(const_iterator i1, const_iterator i2)
{
    d->growAppend(i1, i2);
}

template <typename T>
inline void QList<T>::append(QList<T> &&other)
{
    Q_ASSERT(&other != this);
    if (other.isEmpty())   return;

    if (other.d->needsDetach() ||
        !std::is_nothrow_move_constructible_v<T>)
        return append(other);

    // due to precondition &other != this,
    //we can unconditionally modify 'this'
    d.detachAndGrow(QArrayData::GrowsAtEnd,
                    other.size(), nullptr, nullptr);
    Q_ASSERT(d.freeSpaceAtEnd() >= other.size());
    d->moveAppend(other.begin(), other.end());
}

//在需要频繁在列表前面插入元素时,
//emplaceFront 提供了比 prepend 更高效的插入方式。????
//void prepend(parameter_type t) { emplaceFront(t); }
template<typename T>
template<typename... Args> //在头部插入并构造元素
inline typename QList<T>::reference //返回值
QList<T>::emplaceFront(Args &&... args)
{
    d->emplace(0, std::forward<Args>(args)...);
    return *d.begin();
}

//#define Q_LIKELY(expr)  __builtin_expect(!!(expr), true)
//提示编译器,所包围的条件 expr 很可能评估为 true。
//使用此宏可以帮助编译器对代码进行优化
template <typename T>
inline typename QList<T>::iterator
QList<T>::insert(qsizetype i, qsizetype n, parameter_type t)
{
    Q_ASSERT_X(size_t(i) <= size_t(d->size),
               "QList<T>::insert", "index out of range");
    Q_ASSERT_X(n >= 0, "QList::insert", "invalid count");
    if (Q_LIKELY(n))
        d->insert(i, n, t);
    return d.begin() + i;
}

//通过在位置i插入一个新元素来扩展容器。
//这个新元素使用 args 作为其构造的参数,直接在原地构造。
//返回指向新元素的迭代器。
template <typename T>
template <typename ...Args> //在下标 i 处插入并构造元素
typename QList<T>::iterator
QList<T>::emplace(qsizetype i, Args&&... args)
{
    Q_ASSERT_X(i >= 0 && i <= d->size, "QList<T>::insert", "index out of range");
    d->emplace(i, std::forward<Args>(args)...);
    return d.begin() + i;
}

template<typename T>
template<typename... Args> //尾部构造
inline typename QList<T>::reference //返回值
QList<T>::emplaceBack(Args &&... args)
{
    d->emplace(d->size, std::forward<Args>(args)...);
    return *(d.end() - 1);
}

//Removes all the items from begin up to (but not including) end.
//Returns an iterator to the same item
//that end referred to before the call.
template <typename T>
typename QList<T>::iterator
QList<T>::erase(const_iterator abegin, const_iterator aend)
{   Q_ASSERT_X(isValidIterator(abegin),
        "QList::erase",
        "The specified iterator argument 'abegin' is invalid");
    Q_ASSERT_X(isValidIterator(aend),
        "QList::erase",
        "The specified iterator argument 'aend' is invalid");
    Q_ASSERT(aend >= abegin);

    qsizetype i = std::distance(constBegin(), abegin);
    qsizetype n = std::distance(abegin, aend);
    remove(i, n);

    return d.begin() + i;
}

//Assigns value to all items in the list.
//If size is different from -1 (the default),
//the list is resized to size beforehand.
template <typename T>
inline QList<T> &
QList<T>::fill(parameter_type t, qsizetype newSize)
{
    if (newSize == -1)     newSize = size();

    if (d->needsDetach() || newSize > capacity()) {
        // must allocate memory
        DataPointer detached(
            Data::allocate(d->detachCapacity(newSize)));
        detached->copyAppend(newSize, t);
        d.swap(detached);
    } else {
        // we're detached
        const T copy(t);
        d->assign(d.begin(),  //qMin(a, b)
                  d.begin() + qMin( size(), newSize),
                  t);

        if (newSize > size()) {
            d->copyAppend(newSize - size(), copy);
        } else if (newSize < size()) {
            d->truncate(newSize);
        }
    }
    return *this;
}

//*********至此,终于结束容器源码 Qlist<T> = vector

(3)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值