位于 llvm/include/llvm/[[ADT]]/ilist.hnode
== 简介 ==
主要实现侵入式连接列表模板(Intrusive Linked List Template),实际是双向的列表。dom
主要类是 iplist, ilist 用于实现 列表模板。ide
其它是主要类的辅助的 iterator, traits 的实现。函数
这个文件定义类用于实现一个侵入式(intrusive)双向连接列表,也即列表中每一个元素节点必须包含一个 next 和 previous 字段来做为链表指针。ui
This file defines classes to implement an intrusive doubly linked list class(i.e. each node of the list must contain a next and previous field for the list.this
== 实现的类 ==
* ilist_nextprev_traits -- 提供 T 类型缺省 get|set Prev|Next 访问策略。
* ilist_sentinel_traits -- 哨兵(sentinel)节点新建、删除、访问策略。
* ilist_node_traits -- 节点缺省操做策略实现。
* ilist_default_traits -- 缺省的 next,prev,sentinel,node 访问。
* ilist_traits -- 缺省 ilist 模板特性,留给特化用。
* ilist_iterator指针
* [[iplist]]
* [[ilist]]
模板类 ilist 实现时,在链表建立的时候分配一个 '尾(tail)' 节点(使用 ilist_traits<>::createSentinel() 方法)。这个 tail 节点很是须要,由于用户须要使用它计算 end()-1。为此,若是用户直接访问 next/prev 指针指向的链表,将在尾部看到一个额外的连接(sentinel 哨兵节点),它应该被忽略的。ip
为使用 ilist(iplist),要求元素类 T 必须实现 (get|set)(Next|Prev) 方法来获取/设置指针,或者特化 ilist_traits<T> 以访问 next/prev 指针。ci
The ilist class is implemented by allocating a 'tail' node when the list is
created (using ilist_traits<>::createSentinel()). This tail node is
absolutely required because the user must be able to compute end()-1. Because
of this, users of the direct next/prev links will see an extra link on the
end of the list, which should be ignored.get
* 参考 llvm/ADT/[[ilist_node.h]]
* Sentinels
== ilist_nextprev_traits ==
模板类 [[ilist_nextprev_traits]] 实现模板 traits 来为 ilist 提供缺省的 next/prev 指针公共操做的实现。
A fragment for template traits for intrusive list that provides default next/prev implementations for common operations.
类概要:
<syntaxhighlight lang="cpp">
template<typename T> struct ilist_nextprev_traits {
getNext(),getPrev() // 实现为 T->getNext(),T->getPrev()
// 也即缺省要求 T 有 getNext, getPrev 方法来获取指针
setNext(), setPrev() // 要求 T 有 setNext, setPrev 方法
}
</syntaxhighlight>
这种实现方式意味着能够特化 ilist_nextprev_traits<T> 来为本身的 T 类定义 get|set Next|Prev 的访问方式。
== ilist_sentinel_traits ==
模板类 [[ilist_sentinel_traits]] 为 ilist 提供缺省的哨兵(sentinel)节点公共操做的实现。
[[ilist_sentinel_traits]] 实现了一种延迟哨兵分配的策略。哨兵节点存储在 Head.prev 成员中。
A fragment for template traits for intrusive list that provides default sentinel implementations for common operations.
ilist_sentinel_traits implements a lazy dynamic sentinel allocation
strategy. The sentinel is stored in the prev field of ilist's Head.
类概要:
<syntaxhighlight lang="cpp">
template<typename T> struct ilist_sentinel_traits {
createSentinel() // 注1。建立一个哨兵节点,缺省实现为 new T()
destroySentinel() // 同 createSentinel() 匹配,用于释放哨兵节点。
provideInitialHead() // 建立 ilist 的时候提供缺省 Head 指针。返回 null 表示延迟分配。
ensureHead() // 确保有一个 Head 指针。返回 sentinel 的指针。
noteHead() // 保存 sentinel 指针到合适的(缺省的)位置。
}
</syntaxhighlight>
* 注1:这里要分配一个额外的 T() 做为哨兵节点,为此若是 sizeof(T) 比较大会形成空间浪费。而且要求 T 要提供一个缺省构造函数。
* 注1:为此某些特定类如 Value(及其派生类体系),实现有本身的 ilist_sentinel_traits 特化版,其不分配 Value 作为哨兵节点。参见 [[Value]], [[GlobalVariable]] 。
这个类用于提供延迟建立 Head, sentinel 节点策略的一种实现。固然也能特化它以知足特定须要。
== ilist_node_traits ==
模板类 ilist_node_traits 为 ilist 提供缺省的节点相关操做。
ilist_node_traits - A fragment for template traits for intrusive list
that provides default node related operations.
类概要:
<syntaxhighlight lang="cpp">
template<T=NODE_TYPE> struct ilist_node_traits {
createNode() // 建立新节点,缺省为 new T()
deleteNode() // 释放节点,缺省为 delete
// 其它几个方法暂略。
}
</syntaxhighlight>
== ilist_default_traits ==
模板类 ilist_default_traits 为 ilist 提供缺省的模板特性(traits)。经过今后类派生,可以方便的得到 ilist 所需的公共操做的缺省实现。
ilist_default_traits - Default template traits for intrusive list.
By inheriting from this, you can easily use default implementations
for all common operations.
类概要:
<syntaxhighlight lang="cpp">
template<typename NodeTy>
struct ilist_default_traits
: public ilist_nextprev_traits<NodeTy>, // 提供 next,prev 访问
public ilist_sentinel_traits<NodeTy>, // 提供 sentinel 访问
public ilist_node_traits<NodeTy> { // 提供 node 访问
}
</syntaxhighlight>
ilist, iplist 通常经过此类提供的方法来实现对数据的建立、删除、及访问。
== ilist_traits ==
为 ilist 提供模板特性。经过特化这个模板,你能改变如何保存 next/prev 指针。。。
Template traits for intrusive list. By specializing this template class, you
can change what next/prev fields are used to store the links...
模板 trait 类 ilist_traits 用于得到对链表元素中 next, previous 指针的访问。若是 ilist_traits 没有对元素类型进行特化,则它缺省使用 getNext(), getPrev() 方法来访问 next, previous 指针。
The ilist_traits trait class is used to gain access to the next and previous fields of the node type that the list is instantiated with. If it is not
specialized, the list defaults to using the getPrev(), getNext() method calls
to get the next and previous pointers.
类概要:
<syntaxhighlight lang="cpp">
template<typename NodeTy>
struct ilist_traits : public ilist_default_traits<NodeTy> {
// 没有本身的数据和方法,留给特化版特化用。
};
</syntaxhighlight>
* 特化版 const Ty 的特化:
template<typename Ty>
struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
== ilist_iterator ==
ilist 的迭代器。实现为 std 的双向迭代器(bi-directional)。非 random-access 的。
实现中使用 ilist_traits<NodeTy> 提供的方式来访问 next/prev 节点。
具体参见 std 迭代器的实现。
== ilist_iterator 针对 simplify_type 的特化 ==
在 [[isa]] 和 [[cast]] 模板函数中,大量使用了 simplify_type<> 来获取类型的信息。
这里 ilist.h 中,针对 ilist_iterator 提供了 [[simplify_type]] 的特化,从中能够直接获取 NodeTy* 的原始类型,及其值。也包括对 const ilist_iterator 的特化。
稍后有机会实验这个状况。
== 参见 == * [[iplist]] -- ilist 的基本实现。 * [[ilist]] -- 派生自 iplist,实现 ilist。