位於 llvm/include/llvm/[[ADT]]/[[ilist.h]] html
參見:
* http://llvm.org/docs/ProgrammersManual.html#dss_ilist
* [[ilist.h]], [[ilist]]
* intrusive -- 侵入的、貫入的、打擾的、闖入的。node
== 簡介 ==
ilist/iplist 被稱爲是侵入式的(intrusive),緣由在於它要求其模板參數類 T 裏面提供有 next/prev 指針,而且實現 getNext(), setNext(), getPrev(), setPrev() 的函數。ide
ilist_iterator 模板類用於實現 ilist/iplist 的遍歷。函數
其實現可看作是一個典型的 std list 容器類。參見 std。測試
<B>缺點</B>:須要 T 提供缺省構造,用於產生哨兵(sentinel)節點,及提供 getNext(), getPrev() 等函數用於訪問 prev/next 節點。this
iplist - list 容器的子集。可用於多態類,也即有一個公共基類 其保存 next/prev 指針。ilist 自身只是保存了一個鏈表 list 的頭指針。指針
== 類概要 ==
<syntaxhighlight lang="cpp">
template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
class iplist : public Traits { // 注1
Node_Type *Head; // 注2.鏈表第一個元素指針。
pointer, reference 等 STL 標準容器類型定義。
this(), ~this() // 注3。構造,析構。
begin(), end(), size(), empty(), front(), back() 等標準容器方法。
push(), pop(), swap(), insert(), erase(), remove() 等操縱方法。
splice(), erase_if(), unique(), merge(), sort() 等列表常見方法。
}
</syntaxhighlight>htm
* 注1:使用 Traits 做爲基類,其提供 next,prev,sentinel,node 訪問策略。
* 注2:鏈表的 Head 元素在構造時,使用 Traits 提供的策略初始化。
** 通常當新建一個 iplist 的時候,Head == null,沒有構造 sentinel 節點。僅當訪問 begin(), push() 等方法須要的時候,纔會''延遲''建立 sentinel 節點。
** Head.prev 指向 sentinel 節點。 sentinel.prev 指向鏈表的 Last 節點。
** sentinel.next 爲 null。對象
* 注3:構造中初始化 Head,使用 Traits 中提供的策略方法;析構中使用 Traits 中方法刪除節點,及銷燬 sentinel 哨兵節點。參見 [[ilist_traits]]
* 注4:size() 方法會遍歷全部節點統計數量,因此效率會比較低。也許新策略容許若是保存一個 size 字段更好?
* 注5:sizeof(iplist<T>) 通常是 4,也即 Head 指針的大小。若是 Traits 特化保存有數據,則 sizeof() 可能不是這個值。這種狀況出如今 ilist_traits<Value> 特化中。繼承
== iplist 更多說明 ==
模板類 iplist 有以下的三個有趣的狀態:
* 1. 鏈表未構造任何節點狀態。此狀況下,Head 指針爲 null。在此狀況下,任何對枚舉器的獲取(如調用 begin(), end() 等方法)都會透明地轉換到狀態2.
* 2. 鏈表爲空(empty),但包含一個哨兵(sentinel)節點,以實現 end 枚舉器指針。這個哨兵節點經過 Traits::createSentinel() 方法建立,而後連接到 iplist 的末尾。當列表處於這個 empty 空狀態的時候,Head 指針指向哨兵節點。哨兵節點一旦建立,則直到列表析構的時候纔會被刪除。
* 3. 鏈表可能包含實際的對象,其使用節點雙向連接列表鏈接。一個不變的狀況是:列表的第一個節點(Head)的 prev 指針老是指向鏈表的最後一個節點(哨兵節點),哨兵節點的 next 指針老是 null。
額外:
* 畫出圖會更清晰一些。
* 用 VC2010 測試的時候,還有一個小編譯錯誤: warning C4355: 「this」: 用於基成員初始值設定項列表。在這裏: iplist() : Head(this->provideInitialHead()) 。
== ilist ==
模板類 ilist 繼承自 iplist<T>,並對其進行了一些小的擴展:
* 提供新的多種構造方式。
* 提供 insert() 的傳遞引用參數 const T& 重載形式。iplist 使用的是 T* 指針參數。使用這種 insert 須要提供複製構造,如 Value(const Value&).
* ilist 對於 [[Value]], [[GlobalVariable]], [[Instruction]] 等類構成的雙向鏈表特別合適。