143d1fd449f1a0ac9d9dafa0b9569bb6b2e976198Anton Korobeynikov//==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==//
2e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
5234d529e582963ad4b5d83b911cd057fe99d1435Chris Lattner// This file is distributed under the University of Illinois Open Source
6234d529e582963ad4b5d83b911cd057fe99d1435Chris Lattner// License. See LICENSE.TXT for details.
7e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
97e70829632f82de15db187845666aaca6e04b792Chris Lattner//
107e70829632f82de15db187845666aaca6e04b792Chris Lattner// This file defines classes to implement an intrusive doubly linked list class
1147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner// (i.e. each node of the list must contain a next and previous field for the
127e70829632f82de15db187845666aaca6e04b792Chris Lattner// list.
137e70829632f82de15db187845666aaca6e04b792Chris Lattner//
147e70829632f82de15db187845666aaca6e04b792Chris Lattner// The ilist_traits trait class is used to gain access to the next and previous
157e70829632f82de15db187845666aaca6e04b792Chris Lattner// fields of the node type that the list is instantiated with.  If it is not
167e70829632f82de15db187845666aaca6e04b792Chris Lattner// specialized, the list defaults to using the getPrev(), getNext() method calls
177e70829632f82de15db187845666aaca6e04b792Chris Lattner// to get the next and previous pointers.
187e70829632f82de15db187845666aaca6e04b792Chris Lattner//
197e70829632f82de15db187845666aaca6e04b792Chris Lattner// The ilist class itself, should be a plug in replacement for list, assuming
207e70829632f82de15db187845666aaca6e04b792Chris Lattner// that the nodes contain next/prev pointers.  This list replacement does not
21094aa6ce47f0f0604469e0a24bde131ce6326938Nick Lewycky// provide a constant time size() method, so be careful to use empty() when you
22a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner// really want to know if it's empty.
237e70829632f82de15db187845666aaca6e04b792Chris Lattner//
247e70829632f82de15db187845666aaca6e04b792Chris Lattner// The ilist class is implemented by allocating a 'tail' node when the list is
2547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner// created (using ilist_traits<>::createSentinel()).  This tail node is
267e70829632f82de15db187845666aaca6e04b792Chris Lattner// absolutely required because the user must be able to compute end()-1. Because
277e70829632f82de15db187845666aaca6e04b792Chris Lattner// of this, users of the direct next/prev links will see an extra link on the
287e70829632f82de15db187845666aaca6e04b792Chris Lattner// end of the list, which should be ignored.
297e70829632f82de15db187845666aaca6e04b792Chris Lattner//
307e70829632f82de15db187845666aaca6e04b792Chris Lattner// Requirements for a user of this list:
317e70829632f82de15db187845666aaca6e04b792Chris Lattner//
327e70829632f82de15db187845666aaca6e04b792Chris Lattner//   1. The user must provide {g|s}et{Next|Prev} methods, or specialize
337e70829632f82de15db187845666aaca6e04b792Chris Lattner//      ilist_traits to provide an alternate way of getting and setting next and
347e70829632f82de15db187845666aaca6e04b792Chris Lattner//      prev links.
357e70829632f82de15db187845666aaca6e04b792Chris Lattner//
367e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
377e70829632f82de15db187845666aaca6e04b792Chris Lattner
381ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#ifndef LLVM_ADT_ILIST_H
391ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#define LLVM_ADT_ILIST_H
407e70829632f82de15db187845666aaca6e04b792Chris Lattner
41fc601db2ed899d800ea0a50f7ecf7de2a820cbc1Craig Topper#include "llvm/Support/Compiler.h"
42476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <algorithm>
43803f03e217ec25cf71b2b6dea65da2e377527b6bChris Lattner#include <cassert>
44345b378309eabd74a7a43f095dca9a4894bc371eDuncan Sands#include <cstddef>
45f0891be8bdbeeadb39da5575273b6645755fa383Gabor Greif#include <iterator>
467e70829632f82de15db187845666aaca6e04b792Chris Lattner
47d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
48d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
497e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits> class iplist;
507e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy> class ilist_iterator;
517e70829632f82de15db187845666aaca6e04b792Chris Lattner
52fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// ilist_nextprev_traits - A fragment for template traits for intrusive list
53fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// that provides default next/prev implementations for common operations.
54fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
557e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
56fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanstruct ilist_nextprev_traits {
577e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
587e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
597e70829632f82de15db187845666aaca6e04b792Chris Lattner  static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
607e70829632f82de15db187845666aaca6e04b792Chris Lattner  static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
617e70829632f82de15db187845666aaca6e04b792Chris Lattner
627e70829632f82de15db187845666aaca6e04b792Chris Lattner  static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
637e70829632f82de15db187845666aaca6e04b792Chris Lattner  static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
64fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman};
657e70829632f82de15db187845666aaca6e04b792Chris Lattner
66c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greiftemplate<typename NodeTy>
67c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greifstruct ilist_traits;
68c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
69fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// ilist_sentinel_traits - A fragment for template traits for intrusive list
70fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// that provides default sentinel implementations for common operations.
71fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
72c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif/// ilist_sentinel_traits implements a lazy dynamic sentinel allocation
73c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif/// strategy. The sentinel is stored in the prev field of ilist's Head.
74c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif///
75fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
76fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanstruct ilist_sentinel_traits {
77c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// createSentinel - create the dynamic sentinel
78bca81448ac8e19c588c9a4ad16fc70732b76327cChris Lattner  static NodeTy *createSentinel() { return new NodeTy(); }
79c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
80c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// destroySentinel - deallocate the dynamic sentinel
81bca81448ac8e19c588c9a4ad16fc70732b76327cChris Lattner  static void destroySentinel(NodeTy *N) { delete N; }
82c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
83c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// provideInitialHead - when constructing an ilist, provide a starting
84c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// value for its Head
85c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// @return null node to indicate that it needs to be allocated later
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static NodeTy *provideInitialHead() { return nullptr; }
87c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
88c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// ensureHead - make sure that Head is either already
89c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// initialized or assigned a fresh sentinel
90c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// @return the sentinel
91c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  static NodeTy *ensureHead(NodeTy *&Head) {
92c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    if (!Head) {
93c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      Head = ilist_traits<NodeTy>::createSentinel();
94c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      ilist_traits<NodeTy>::noteHead(Head, Head);
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      ilist_traits<NodeTy>::setNext(Head, nullptr);
96c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      return Head;
97c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    }
98c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    return ilist_traits<NodeTy>::getPrev(Head);
99c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  }
100c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
101c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// noteHead - stash the sentinel into its default location
102c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  static void noteHead(NodeTy *NewHead, NodeTy *Sentinel) {
103c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    ilist_traits<NodeTy>::setPrev(NewHead, Sentinel);
104c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  }
105fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman};
106fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman
107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainartemplate <typename NodeTy> class ilist_half_node;
108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainartemplate <typename NodeTy> class ilist_node;
109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Traits with an embedded ilist_node as a sentinel.
111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// FIXME: The downcast in createSentinel() is UB.
113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainartemplate <typename NodeTy> struct ilist_embedded_sentinel_traits {
114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// Get hold of the node that marks the end of the list.
115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *createSentinel() const {
116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Since i(p)lists always publicly derive from their corresponding traits,
117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // placing a data member in this class will augment the i(p)list.  But since
118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // there is a legal viable downcast from it to NodeTy. We use this trick to
120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // sentinel. Dereferencing the sentinel is forbidden (save the
122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // ilist_node<NodeTy>), so no one will ever notice the superposition.
123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return static_cast<NodeTy *>(&Sentinel);
124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  static void destroySentinel(NodeTy *) {}
126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *provideInitialHead() const { return createSentinel(); }
128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  static void noteHead(NodeTy *, NodeTy *) {}
130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarprivate:
132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  mutable ilist_node<NodeTy> Sentinel;
133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar};
134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Trait with an embedded ilist_half_node as a sentinel.
136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// FIXME: The downcast in createSentinel() is UB.
138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainartemplate <typename NodeTy> struct ilist_half_embedded_sentinel_traits {
139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// Get hold of the node that marks the end of the list.
140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *createSentinel() const {
141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // See comment in ilist_embedded_sentinel_traits::createSentinel().
142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return static_cast<NodeTy *>(&Sentinel);
143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  static void destroySentinel(NodeTy *) {}
145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *provideInitialHead() const { return createSentinel(); }
147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  static void noteHead(NodeTy *, NodeTy *) {}
149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarprivate:
151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  mutable ilist_half_node<NodeTy> Sentinel;
152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar};
153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
154b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// ilist_node_traits - A fragment for template traits for intrusive list
155b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// that provides default node related operations.
156fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
157fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
158b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greifstruct ilist_node_traits {
159fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman  static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
160fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman  static void deleteNode(NodeTy *V) { delete V; }
1617e70829632f82de15db187845666aaca6e04b792Chris Lattner
162eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling  void addNodeToList(NodeTy *) {}
163eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling  void removeNodeFromList(NodeTy *) {}
164b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif  void transferNodesFromList(ilist_node_traits &    /*SrcTraits*/,
165eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling                             ilist_iterator<NodeTy> /*first*/,
166eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling                             ilist_iterator<NodeTy> /*last*/) {}
1677e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1687e70829632f82de15db187845666aaca6e04b792Chris Lattner
169b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// ilist_default_traits - Default template traits for intrusive list.
170b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// By inheriting from this, you can easily use default implementations
171b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// for all common operations.
172b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif///
173b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greiftemplate<typename NodeTy>
17459bf4fcc0680e75b408579064d1205a132361196Duncan Sandsstruct ilist_default_traits : public ilist_nextprev_traits<NodeTy>,
17559bf4fcc0680e75b408579064d1205a132361196Duncan Sands                              public ilist_sentinel_traits<NodeTy>,
17659bf4fcc0680e75b408579064d1205a132361196Duncan Sands                              public ilist_node_traits<NodeTy> {
177b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif};
178b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif
179fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// Template traits for intrusive list.  By specializing this template class, you
180fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// can change what next/prev fields are used to store the links...
181fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
18259bf4fcc0680e75b408579064d1205a132361196Duncan Sandsstruct ilist_traits : public ilist_default_traits<NodeTy> {};
183fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman
1847e70829632f82de15db187845666aaca6e04b792Chris Lattner// Const traits are the same as nonconst traits...
1857e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename Ty>
1867e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist_traits<const Ty> : public ilist_traits<Ty> {};
1877e70829632f82de15db187845666aaca6e04b792Chris Lattner
1887e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Iterator for intrusive list.
1907e70829632f82de15db187845666aaca6e04b792Chris Lattner//
191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <typename NodeTy>
192a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattnerclass ilist_iterator
193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    : public std::iterator<std::bidirectional_iterator_tag, NodeTy, ptrdiff_t> {
194ccaa6540fc2866ab36f6ebecf6df101f613f8aa7Ted Kremenekpublic:
1957e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_traits<NodeTy> Traits;
196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  typedef std::iterator<std::bidirectional_iterator_tag, NodeTy, ptrdiff_t>
197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      super;
198a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
1992c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  typedef typename super::value_type value_type;
2002c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  typedef typename super::difference_type difference_type;
201a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::pointer pointer;
202a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::reference reference;
203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
20432862da7c7107d792d25a885f9bd2d0402ae7126Chris Lattnerprivate:
2057e70829632f82de15db187845666aaca6e04b792Chris Lattner  pointer NodePtr;
206066075030ad46b3494480a5f79f05443f947aca7Nick Lewycky
2077e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  explicit ilist_iterator(pointer NP) : NodePtr(NP) {}
209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  explicit ilist_iterator(reference NR) : NodePtr(&NR) {}
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ilist_iterator() : NodePtr(nullptr) {}
2117e70829632f82de15db187845666aaca6e04b792Chris Lattner
2127e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow constructing a const iterator from
2137e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <class node_ty>
2157e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(const ilist_iterator<node_ty> &RHS)
216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      : NodePtr(RHS.getNodePtrUnchecked()) {}
2177e70829632f82de15db187845666aaca6e04b792Chris Lattner
2187e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow assigning to a const iterator from
2197e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <class node_ty>
2217e70829632f82de15db187845666aaca6e04b792Chris Lattner  const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
2227e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = RHS.getNodePtrUnchecked();
2237e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2247e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2257e70829632f82de15db187845666aaca6e04b792Chris Lattner
226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void reset(pointer NP) { NodePtr = NP; }
227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2287e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Accessors...
229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  explicit operator pointer() const { return NodePtr; }
230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  reference operator*() const { return *NodePtr; }
231e14d81deeb6bb3404ffee5e59ecb88304f112f4aDan Gohman  pointer operator->() const { return &operator*(); }
2327e70829632f82de15db187845666aaca6e04b792Chris Lattner
2337e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Comparison operators
234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <class Y> bool operator==(const ilist_iterator<Y> &RHS) const {
235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return NodePtr == RHS.getNodePtrUnchecked();
2367e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <class Y> bool operator!=(const ilist_iterator<Y> &RHS) const {
238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return NodePtr != RHS.getNodePtrUnchecked();
2397e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2407e70829632f82de15db187845666aaca6e04b792Chris Lattner
2417e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Increment and decrement operators...
242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ilist_iterator &operator--() {
2437e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getPrev(NodePtr);
2445c5f5a2ec2dd49bd3049fa0a55aca4956fc56ff2Chris Lattner    assert(NodePtr && "--'d off the beginning of an ilist!");
2457e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2467e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ilist_iterator &operator++() {
2487e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getNext(NodePtr);
2497e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2507e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ilist_iterator operator--(int) {
2527e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
2537e70829632f82de15db187845666aaca6e04b792Chris Lattner    --*this;
2547e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
2557e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
256de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ilist_iterator operator++(int) {
2577e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
2587e70829632f82de15db187845666aaca6e04b792Chris Lattner    ++*this;
2597e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
2607e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2617e70829632f82de15db187845666aaca6e04b792Chris Lattner
2622cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Internal interface, do not use...
2632cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  pointer getNodePtrUnchecked() const { return NodePtr; }
2642cca3008e86aa5448a629c744064daecb531bf94Chris Lattner};
2652cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
266011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// Allow ilist_iterators to convert into pointers to a node automatically when
267011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// used by the dyn_cast, cast, isa mechanisms...
268011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
269011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename From> struct simplify_type;
270011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
271011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
272011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
273e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
2747fe65d691dcce550d53ec9310913aab67ab6d654Rafael Espindola  static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
275011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
276011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
277011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
278011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
2797fe65d691dcce550d53ec9310913aab67ab6d654Rafael Espindola  typedef /*const*/ NodeTy* SimpleType;
280e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
281011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
282011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
283011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
284011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
285011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
2867e70829632f82de15db187845666aaca6e04b792Chris Lattner
2877e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
2887e70829632f82de15db187845666aaca6e04b792Chris Lattner//
2896de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// iplist - The subset of list functionality that can safely be used on nodes
2907a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner/// of polymorphic types, i.e. a heterogeneous list with a common base class that
2916de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// holds the next/prev pointers.  The only state of the list itself is a single
2926de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// pointer to the head of the list.
2936de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
2946de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// This list can be in one of three interesting states:
2956de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 1. The list may be completely unconstructed.  In this case, the head
2966de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    pointer is null.  When in this form, any query for an iterator (e.g.
2976de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    begin() or end()) causes the list to transparently change to state #2.
298e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman/// 2. The list may be empty, but contain a sentinel for the end iterator. This
299e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    sentinel is created by the Traits::createSentinel method and is a link
3006de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    in the list.  When the list is empty, the pointer in the iplist points
301e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    to the sentinel.  Once the sentinel is constructed, it
3026de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    is not destroyed until the list is.
3036de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 3. The list may contain actual objects in it, which are stored as a doubly
3046de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    linked list of nodes.  One invariant of the list is that the predecessor
3056de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    of the first node in the list always points to the last node in the list,
306e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    and the successor pointer for the sentinel (which always stays at the
307e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    end of the list) is always null.
3086de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
3097e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
3107e70829632f82de15db187845666aaca6e04b792Chris Lattnerclass iplist : public Traits {
3116de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  mutable NodeTy *Head;
31247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
31347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // Use the prev node pointer of 'head' as the tail pointer.  This is really a
31447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // circularly linked list where we snip the 'next' link from the sentinel node
31547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // back to the first node in the list (to preserve assertions about going off
31647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // the end of the list).
317c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  NodeTy *getTail() { return this->ensureHead(Head); }
318c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  const NodeTy *getTail() const { return this->ensureHead(Head); }
319c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  void setTail(NodeTy *N) const { this->noteHead(Head, N); }
320e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
321e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  /// CreateLazySentinel - This method verifies whether the sentinel for the
3226de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  /// list has been created and lazily makes it if not.
323e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  void CreateLazySentinel() const {
324e2b16504be5b55e6a42819eaf93e0698b529165bGabor Greif    this->ensureHead(Head);
3256de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3267e70829632f82de15db187845666aaca6e04b792Chris Lattner
3277e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
3287e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
3299ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman
330e2b16504be5b55e6a42819eaf93e0698b529165bGabor Greif  // No fundamental reason why iplist can't be copyable, but the default
3319ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman  // copy/copy-assign won't do.
332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  iplist(const iplist &) = delete;
333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void operator=(const iplist &) = delete;
3349ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman
3357e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
3367e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy *pointer;
3377e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy *const_pointer;
3387e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy &reference;
3397e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy &const_reference;
3407e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy value_type;
3417e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<NodeTy> iterator;
3427e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<const NodeTy> const_iterator;
3437e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef size_t size_type;
3447e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ptrdiff_t difference_type;
3454a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
3464a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<iterator>  reverse_iterator;
3477e70829632f82de15db187845666aaca6e04b792Chris Lattner
348e2b16504be5b55e6a42819eaf93e0698b529165bGabor Greif  iplist() : Head(this->provideInitialHead()) {}
3496de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  ~iplist() {
3506de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    if (!Head) return;
3516de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    clear();
3526de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    Traits::destroySentinel(getTail());
3537e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3547e70829632f82de15db187845666aaca6e04b792Chris Lattner
3552cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Iterator creation methods.
3566de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator begin() {
357e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
358e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    return iterator(Head);
3596de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3606de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator begin() const {
361e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3626de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(Head);
3636de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3646de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator end() {
365e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3666de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return iterator(getTail());
3676de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3686de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator end() const {
369e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3706de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(getTail());
3716de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3727e70829632f82de15db187845666aaca6e04b792Chris Lattner
3732cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // reverse iterator creation methods.
3747e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rbegin()            { return reverse_iterator(end()); }
3757e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
3767e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rend()              { return reverse_iterator(begin()); }
3776de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
3787e70829632f82de15db187845666aaca6e04b792Chris Lattner
3792cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
3802cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Miscellaneous inspection routines.
3817e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type max_size() const { return size_type(-1); }
382cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return !Head || Head == getTail();
384cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer  }
3857e70829632f82de15db187845666aaca6e04b792Chris Lattner
3867e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back accessor functions...
3877e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference front() {
3887e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3897e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3907e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3917e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference front() const {
3927e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3937e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3947e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3957e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference back() {
3967e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
397c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    return *this->getPrev(getTail());
3987e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3997e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference back() const {
4007e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
401c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    return *this->getPrev(getTail());
4027e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4037e70829632f82de15db187845666aaca6e04b792Chris Lattner
4047e70829632f82de15db187845666aaca6e04b792Chris Lattner  void swap(iplist &RHS) {
405d68a07650cdb2e18f18f362ba533459aa10e01b6Dan Gohman    assert(0 && "Swap does not use list traits callback correctly yet!");
4067e70829632f82de15db187845666aaca6e04b792Chris Lattner    std::swap(Head, RHS.Head);
4077e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4087e70829632f82de15db187845666aaca6e04b792Chris Lattner
4097e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, NodeTy *New) {
410a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman    NodeTy *CurNode = where.getNodePtrUnchecked();
411a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman    NodeTy *PrevNode = this->getPrev(CurNode);
412c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setNext(New, CurNode);
413c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(New, PrevNode);
4147e70829632f82de15db187845666aaca6e04b792Chris Lattner
41547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (CurNode != Head)  // Is PrevNode off the beginning of the list?
416c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(PrevNode, New);
4177e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
4187e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = New;
419c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(CurNode, New);
4207e70829632f82de15db187845666aaca6e04b792Chris Lattner
421c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->addNodeToList(New);  // Notify traits that we added a node...
422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return iterator(New);
4237e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4247e70829632f82de15db187845666aaca6e04b792Chris Lattner
4253ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner  iterator insertAfter(iterator where, NodeTy *New) {
426085a9ebbc705c6e7d3fd8c692ef1c46fdfb885ceMisha Brukman    if (empty())
4273ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner      return insert(begin(), New);
4283ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner    else
4293ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner      return insert(++where, New);
4303ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner  }
4313ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner
4327e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(iterator &IT) {
4337e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(IT != end() && "Cannot remove end of list!");
4347e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *Node = &*IT;
435c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    NodeTy *NextNode = this->getNext(Node);
436c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    NodeTy *PrevNode = this->getPrev(Node);
4377e70829632f82de15db187845666aaca6e04b792Chris Lattner
43847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (Node != Head)  // Is PrevNode off the beginning of the list?
439c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(PrevNode, NextNode);
4407e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
4417e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = NextNode;
442c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(NextNode, PrevNode);
443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IT.reset(NextNode);
4442b5326e7240ac524812016bc3700e12045bf0eb1Steve Naroff    this->removeNodeFromList(Node);  // Notify traits that we removed a node...
445e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
4462896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // Set the next/prev pointers of the current node to null.  This isn't
4472896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // strictly required, but this catches errors where a node is removed from
4482896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // an ilist (and potentially deleted) with iterators still pointing at it.
4492896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // When those iterators are incremented or decremented, they will assert on
4502896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // the null next/prev pointer instead of "usually working".
451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    this->setNext(Node, nullptr);
452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    this->setPrev(Node, nullptr);
4537e70829632f82de15db187845666aaca6e04b792Chris Lattner    return Node;
4547e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4557e70829632f82de15db187845666aaca6e04b792Chris Lattner
4567e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(const iterator &IT) {
4577e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator MutIt = IT;
4587e70829632f82de15db187845666aaca6e04b792Chris Lattner    return remove(MutIt);
4597e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4607e70829632f82de15db187845666aaca6e04b792Chris Lattner
461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *remove(NodeTy *IT) { return remove(iterator(IT)); }
462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *remove(NodeTy &IT) { return remove(iterator(IT)); }
463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
4647e70829632f82de15db187845666aaca6e04b792Chris Lattner  // erase - remove a node from the controlled sequence... and delete it.
4657e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator where) {
466c03c46a6af3d53172d48d9e4d36748a40c878cffDouglas Gregor    this->deleteNode(remove(where));
4677e70829632f82de15db187845666aaca6e04b792Chris Lattner    return where;
4687e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4697e70829632f82de15db187845666aaca6e04b792Chris Lattner
470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  iterator erase(NodeTy *IT) { return erase(iterator(IT)); }
471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  iterator erase(NodeTy &IT) { return erase(iterator(IT)); }
472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
4737c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// Remove all nodes from the list like clear(), but do not call
4747c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// removeNodeFromList() or deleteNode().
4757c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  ///
4767c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// This should only be used immediately before freeing nodes in bulk to
4777c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// avoid traversing the list and bringing all the nodes into cache.
4787c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  void clearAndLeakNodesUnsafely() {
4797c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen    if (Head) {
4807c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen      Head = getTail();
4817c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen      this->setPrev(Head, Head);
4827c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen    }
4837c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  }
4847e70829632f82de15db187845666aaca6e04b792Chris Lattner
4857e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
4867e70829632f82de15db187845666aaca6e04b792Chris Lattner  // transfer - The heart of the splice function.  Move linked list nodes from
4877e70829632f82de15db187845666aaca6e04b792Chris Lattner  // [first, last) into position.
4887e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4897e70829632f82de15db187845666aaca6e04b792Chris Lattner  void transfer(iterator position, iplist &L2, iterator first, iterator last) {
4907e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(first != last && "Should be checked by callers");
4917f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen    // Position cannot be contained in the range to be transferred.
4927f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen    // Check for the most common mistake.
4937f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen    assert(position != first &&
4947f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen           "Insertion point can't be one of the transferred nodes");
49547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
4967e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (position != last) {
49747e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // Note: we have to be careful about the case when we move the first node
49847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // in the list.  This node is the list sentinel node and we can't move it.
49947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *ThisSentinel = getTail();
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      setTail(nullptr);
50147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *L2Sentinel = L2.getTail();
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      L2.setTail(nullptr);
50347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
5047e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Remove [first, last) from its old position.
50523e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *First = &*first, *Prev = this->getPrev(First);
50623e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
5077e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (Prev)
508c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(Prev, Next);
5097e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5107e70829632f82de15db187845666aaca6e04b792Chris Lattner        L2.Head = Next;
511c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(Next, Prev);
5127e70829632f82de15db187845666aaca6e04b792Chris Lattner
5137e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Splice [first, last) into its new position.
5147e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosNext = position.getNodePtrUnchecked();
51523e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *PosPrev = this->getPrev(PosNext);
5167e70829632f82de15db187845666aaca6e04b792Chris Lattner
5177e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix head of list...
5187e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (PosPrev)
519c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(PosPrev, First);
5207e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5217e70829632f82de15db187845666aaca6e04b792Chris Lattner        Head = First;
522c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(First, PosPrev);
5237e70829632f82de15db187845666aaca6e04b792Chris Lattner
5247e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix end of list...
525c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(Last, PosNext);
526c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(PosNext, Last);
5277e70829632f82de15db187845666aaca6e04b792Chris Lattner
528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      this->transferNodesFromList(L2, iterator(First), iterator(PosNext));
52947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
530e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman      // Now that everything is set, restore the pointers to the list sentinels.
53147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(L2Sentinel);
53247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(ThisSentinel);
5337e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5347e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5357e70829632f82de15db187845666aaca6e04b792Chris Lattner
5367e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
5377e70829632f82de15db187845666aaca6e04b792Chris Lattner
5387e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5397e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Functionality derived from other functions defined above...
5407e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5417e70829632f82de15db187845666aaca6e04b792Chris Lattner
542cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer  size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const {
543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Head) return 0; // Don't require construction of sentinel if empty.
5446bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner    return std::distance(begin(), end());
5457e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5467e70829632f82de15db187845666aaca6e04b792Chris Lattner
5477e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator first, iterator last) {
5487e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first != last)
5497e70829632f82de15db187845666aaca6e04b792Chris Lattner      first = erase(first);
5507e70829632f82de15db187845666aaca6e04b792Chris Lattner    return last;
5517e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5527e70829632f82de15db187845666aaca6e04b792Chris Lattner
5536de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void clear() { if (Head) erase(begin(), end()); }
5547e70829632f82de15db187845666aaca6e04b792Chris Lattner
5557e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
5567e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_front(NodeTy *val) { insert(begin(), val); }
5577e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_back(NodeTy *val) { insert(end(), val); }
5587e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_front() {
5597e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_front() on empty list!");
5607e70829632f82de15db187845666aaca6e04b792Chris Lattner    erase(begin());
5617e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5627e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_back() {
5637e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_back() on empty list!");
5647e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator t = end(); erase(--t);
5657e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5667e70829632f82de15db187845666aaca6e04b792Chris Lattner
5677e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
5687e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
5697e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
5707e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5717e70829632f82de15db187845666aaca6e04b792Chris Lattner
5727e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Splice members - defined in terms of transfer...
5737e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2) {
5747e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!L2.empty())
5757e70829632f82de15db187845666aaca6e04b792Chris Lattner      transfer(where, L2, L2.begin(), L2.end());
5767e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5777e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first) {
5787e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator last = first; ++last;
5797e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (where == first || where == last) return; // No change
5807e70829632f82de15db187845666aaca6e04b792Chris Lattner    transfer(where, L2, first, last);
5817e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5827e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first, iterator last) {
5837e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first != last) transfer(where, L2, first, last);
5847e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void splice(iterator where, iplist &L2, NodeTy &N) {
586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    splice(where, L2, iterator(N));
587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void splice(iterator where, iplist &L2, NodeTy *N) {
589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    splice(where, L2, iterator(N));
590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <class Compare>
593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void merge(iplist &Right, Compare comp) {
594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (this == &Right)
595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return;
596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    iterator First1 = begin(), Last1 = end();
597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    iterator First2 = Right.begin(), Last2 = Right.end();
598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    while (First1 != Last1 && First2 != Last2) {
599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (comp(*First2, *First1)) {
600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        iterator Next = First2;
601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        transfer(First1, Right, First2, ++Next);
602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        First2 = Next;
603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        ++First1;
605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
606f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (First2 != Last2)
608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      transfer(Last1, Right, First2, Last2);
609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void merge(iplist &Right) { return merge(Right, op_less); }
611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <class Compare>
613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void sort(Compare comp) {
614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // The list is empty, vacuously sorted.
615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (empty())
616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return;
617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // The list has a single element, vacuously sorted.
618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (std::next(begin()) == end())
619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return;
620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Find the split point for the list.
621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    iterator Center = begin(), End = begin();
622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    while (End != end() && std::next(End) != end()) {
623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Center = std::next(Center);
624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      End = std::next(std::next(End));
625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Split the list into two.
627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    iplist RightHalf;
628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RightHalf.splice(RightHalf.begin(), *this, Center, end());
629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Sort the two sublists.
631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    sort(comp);
632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RightHalf.sort(comp);
633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
634f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Merge the two sublists back together.
635f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    merge(RightHalf, comp);
636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void sort() { sort(op_less); }
638f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// \brief Get the previous node, or \c nullptr for the list head.
640f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *getPrevNode(NodeTy &N) const {
641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto I = N.getIterator();
642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (I == begin())
643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return nullptr;
644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return &*std::prev(I);
645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// \brief Get the previous node, or \c nullptr for the list head.
647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const NodeTy *getPrevNode(const NodeTy &N) const {
648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getPrevNode(const_cast<NodeTy &>(N));
649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// \brief Get the next node, or \c nullptr for the list tail.
652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NodeTy *getNextNode(NodeTy &N) const {
653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto Next = std::next(N.getIterator());
654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Next == end())
655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return nullptr;
656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return &*Next;
657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// \brief Get the next node, or \c nullptr for the list tail.
659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const NodeTy *getNextNode(const NodeTy &N) const {
660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getNextNode(const_cast<NodeTy &>(N));
661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
6627e70829632f82de15db187845666aaca6e04b792Chris Lattner};
6637e70829632f82de15db187845666aaca6e04b792Chris Lattner
6647e70829632f82de15db187845666aaca6e04b792Chris Lattner
6657e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
6667e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist : public iplist<NodeTy> {
667a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::size_type size_type;
668a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::iterator iterator;
669a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
6707e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist() {}
6717e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(const ilist &right) {
67240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), right.begin(), right.end());
6737e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6747e70829632f82de15db187845666aaca6e04b792Chris Lattner  explicit ilist(size_type count) {
67540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, NodeTy());
676e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  }
6777e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(size_type count, const NodeTy &val) {
67840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, val);
6797e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6807e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> ilist(InIt first, InIt last) {
68140c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), first, last);
6827e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6837e70829632f82de15db187845666aaca6e04b792Chris Lattner
68483b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  // bring hidden functions into scope
68583b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::insert;
68683b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::push_front;
68783b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::push_back;
6887e70829632f82de15db187845666aaca6e04b792Chris Lattner
6897e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Main implementation here - Insert for a node passed by value...
6907e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, const NodeTy &val) {
691eb751d8c2da1a9b0d84139e19e20288d9b978451John McCall    return insert(where, this->createNode(val));
6927e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6937e70829632f82de15db187845666aaca6e04b792Chris Lattner
6947e70829632f82de15db187845666aaca6e04b792Chris Lattner
6957e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
69640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_front(const NodeTy &val) { insert(this->begin(), val); }
69740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_back(const NodeTy &val) { insert(this->end(), val); }
6987e70829632f82de15db187845666aaca6e04b792Chris Lattner
6997e70829632f82de15db187845666aaca6e04b792Chris Lattner  void insert(iterator where, size_type count, const NodeTy &val) {
7007e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; count != 0; --count) insert(where, val);
7017e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7027e70829632f82de15db187845666aaca6e04b792Chris Lattner
7037e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Assign special forms...
7047e70829632f82de15db187845666aaca6e04b792Chris Lattner  void assign(size_type count, const NodeTy &val) {
70540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator I = this->begin();
70640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for (; I != this->end() && count != 0; ++I, --count)
7077e70829632f82de15db187845666aaca6e04b792Chris Lattner      *I = val;
7087e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (count != 0)
70940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), val, val);
7107e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
71140c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(I, this->end());
7127e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
71340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  template<class InIt> void assign(InIt first1, InIt last1) {
71440c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator first2 = this->begin(), last2 = this->end();
7157e70829632f82de15db187845666aaca6e04b792Chris Lattner    for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
7167e70829632f82de15db187845666aaca6e04b792Chris Lattner      *first1 = *first2;
7177e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 == last2)
7187e70829632f82de15db187845666aaca6e04b792Chris Lattner      erase(first1, last1);
7197e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
7207e70829632f82de15db187845666aaca6e04b792Chris Lattner      insert(last1, first2, last2);
7217e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7227e70829632f82de15db187845666aaca6e04b792Chris Lattner
7237e70829632f82de15db187845666aaca6e04b792Chris Lattner
7247e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Resize members...
7257e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize, NodeTy val) {
72640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator i = this->begin();
7277e70829632f82de15db187845666aaca6e04b792Chris Lattner    size_type len = 0;
72840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
7297e70829632f82de15db187845666aaca6e04b792Chris Lattner
7307e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (len == newsize)
73140c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(i, this->end());
7327e70829632f82de15db187845666aaca6e04b792Chris Lattner    else                                          // i == end()
73340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), newsize - len, val);
7347e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7357e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize) { resize(newsize, NodeTy()); }
7367e70829632f82de15db187845666aaca6e04b792Chris Lattner};
7377e70829632f82de15db187845666aaca6e04b792Chris Lattner
738d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
739d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
7407e70829632f82de15db187845666aaca6e04b792Chris Lattnernamespace std {
7417e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Ensure that swap uses the fast list swap...
7427e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Ty>
743d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
7447e70829632f82de15db187845666aaca6e04b792Chris Lattner    Left.swap(Right);
7457e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7467e70829632f82de15db187845666aaca6e04b792Chris Lattner}  // End 'std' extensions...
7477e70829632f82de15db187845666aaca6e04b792Chris Lattner
7481ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#endif // LLVM_ADT_ILIST_H
749