ilist.h revision 5c5f5a2ec2dd49bd3049fa0a55aca4956fc56ff2
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
4143d1fd449f1a0ac9d9dafa0b9569bb6b2e976198Anton Korobeynikov#include "llvm/ADT/iterator.h"
42803f03e217ec25cf71b2b6dea65da2e377527b6bChris Lattner#include <cassert>
437e70829632f82de15db187845666aaca6e04b792Chris Lattner
44d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
467e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits> class iplist;
477e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy> class ilist_iterator;
487e70829632f82de15db187845666aaca6e04b792Chris Lattner
49fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// ilist_nextprev_traits - A fragment for template traits for intrusive list
50fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// that provides default next/prev implementations for common operations.
51fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
527e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
53fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanstruct ilist_nextprev_traits {
547e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
557e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
567e70829632f82de15db187845666aaca6e04b792Chris Lattner  static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
577e70829632f82de15db187845666aaca6e04b792Chris Lattner  static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
587e70829632f82de15db187845666aaca6e04b792Chris Lattner
597e70829632f82de15db187845666aaca6e04b792Chris Lattner  static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
607e70829632f82de15db187845666aaca6e04b792Chris Lattner  static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
61fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman};
627e70829632f82de15db187845666aaca6e04b792Chris Lattner
63c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greiftemplate<typename NodeTy>
64c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greifstruct ilist_traits;
65c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
66fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// ilist_sentinel_traits - A fragment for template traits for intrusive list
67fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/// that provides default sentinel implementations for common operations.
68fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
69c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif/// ilist_sentinel_traits implements a lazy dynamic sentinel allocation
70c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif/// strategy. The sentinel is stored in the prev field of ilist's Head.
71c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif///
72fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
73fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanstruct ilist_sentinel_traits {
74c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// createSentinel - create the dynamic sentinel
75bca81448ac8e19c588c9a4ad16fc70732b76327cChris Lattner  static NodeTy *createSentinel() { return new NodeTy(); }
76c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
77c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// destroySentinel - deallocate the dynamic sentinel
78bca81448ac8e19c588c9a4ad16fc70732b76327cChris Lattner  static void destroySentinel(NodeTy *N) { delete N; }
79c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
80c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// provideInitialHead - when constructing an ilist, provide a starting
81c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// value for its Head
82c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// @return null node to indicate that it needs to be allocated later
83c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  static NodeTy *provideInitialHead() { return 0; }
84c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
85c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// ensureHead - make sure that Head is either already
86c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// initialized or assigned a fresh sentinel
87c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// @return the sentinel
88c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  static NodeTy *ensureHead(NodeTy *&Head) {
89c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    if (!Head) {
90c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      Head = ilist_traits<NodeTy>::createSentinel();
91c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      ilist_traits<NodeTy>::noteHead(Head, Head);
92c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      ilist_traits<NodeTy>::setNext(Head, 0);
93c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      return Head;
94c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    }
95c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    return ilist_traits<NodeTy>::getPrev(Head);
96c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  }
97c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif
98c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  /// noteHead - stash the sentinel into its default location
99c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  static void noteHead(NodeTy *NewHead, NodeTy *Sentinel) {
100c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    ilist_traits<NodeTy>::setPrev(NewHead, Sentinel);
101c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  }
102fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman};
103fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman
104b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// ilist_node_traits - A fragment for template traits for intrusive list
105b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// that provides default node related operations.
106fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
107fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
108b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greifstruct ilist_node_traits {
109fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman  static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
110fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman  static void deleteNode(NodeTy *V) { delete V; }
1117e70829632f82de15db187845666aaca6e04b792Chris Lattner
112eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling  void addNodeToList(NodeTy *) {}
113eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling  void removeNodeFromList(NodeTy *) {}
114b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif  void transferNodesFromList(ilist_node_traits &    /*SrcTraits*/,
115eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling                             ilist_iterator<NodeTy> /*first*/,
116eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling                             ilist_iterator<NodeTy> /*last*/) {}
1177e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1187e70829632f82de15db187845666aaca6e04b792Chris Lattner
119b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// ilist_default_traits - Default template traits for intrusive list.
120b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// By inheriting from this, you can easily use default implementations
121b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// for all common operations.
122b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif///
123b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greiftemplate<typename NodeTy>
124b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greifstruct ilist_default_traits : ilist_nextprev_traits<NodeTy>,
125b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif                              ilist_sentinel_traits<NodeTy>,
126b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif                              ilist_node_traits<NodeTy> {
127b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif};
128b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif
129fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// Template traits for intrusive list.  By specializing this template class, you
130fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// can change what next/prev fields are used to store the links...
131fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
132fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanstruct ilist_traits : ilist_default_traits<NodeTy> {};
133fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman
1347e70829632f82de15db187845666aaca6e04b792Chris Lattner// Const traits are the same as nonconst traits...
1357e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename Ty>
1367e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist_traits<const Ty> : public ilist_traits<Ty> {};
1377e70829632f82de15db187845666aaca6e04b792Chris Lattner
1387e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
1397e70829632f82de15db187845666aaca6e04b792Chris Lattner// ilist_iterator<Node> - Iterator for intrusive list.
1407e70829632f82de15db187845666aaca6e04b792Chris Lattner//
1417e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
142a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattnerclass ilist_iterator
1430d219edad2fd5e7b400ecd49ac833a7a3199af60Chris Lattner  : public bidirectional_iterator<NodeTy, ptrdiff_t> {
144e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
145ccaa6540fc2866ab36f6ebecf6df101f613f8aa7Ted Kremenekpublic:
1467e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_traits<NodeTy> Traits;
1470d219edad2fd5e7b400ecd49ac833a7a3199af60Chris Lattner  typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
148a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
1492c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  typedef typename super::value_type value_type;
1502c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  typedef typename super::difference_type difference_type;
151a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::pointer pointer;
152a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::reference reference;
15332862da7c7107d792d25a885f9bd2d0402ae7126Chris Lattnerprivate:
1547e70829632f82de15db187845666aaca6e04b792Chris Lattner  pointer NodePtr;
155066075030ad46b3494480a5f79f05443f947aca7Nick Lewycky
1562c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // ilist_iterator is not a random-access iterator, but it has an
1572c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // implicit conversion to pointer-type, which is. Declare (but
1582c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // don't define) these functions as private to help catch
1592c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // accidental misuse.
1602c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator[](difference_type) const;
1612c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator+(difference_type) const;
1622c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator-(difference_type) const;
1632c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator+=(difference_type) const;
1642c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator-=(difference_type) const;
1652c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator<(T) const;
1662c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator<=(T) const;
1672c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator>(T) const;
1682c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator>=(T) const;
1692c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator-(T) const;
1707e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
1717e70829632f82de15db187845666aaca6e04b792Chris Lattner
1727e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(pointer NP) : NodePtr(NP) {}
17333adbcc87d92c6c3e620870c804f4a2533ecc850Vikram S. Adve  ilist_iterator(reference NR) : NodePtr(&NR) {}
1747e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator() : NodePtr(0) {}
1757e70829632f82de15db187845666aaca6e04b792Chris Lattner
1767e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow constructing a const iterator from
1777e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
1787e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class node_ty>
1797e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(const ilist_iterator<node_ty> &RHS)
1807e70829632f82de15db187845666aaca6e04b792Chris Lattner    : NodePtr(RHS.getNodePtrUnchecked()) {}
1817e70829632f82de15db187845666aaca6e04b792Chris Lattner
1827e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow assigning to a const iterator from
1837e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
1847e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class node_ty>
1857e70829632f82de15db187845666aaca6e04b792Chris Lattner  const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
1867e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = RHS.getNodePtrUnchecked();
1877e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
1887e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1897e70829632f82de15db187845666aaca6e04b792Chris Lattner
1907e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Accessors...
1917e70829632f82de15db187845666aaca6e04b792Chris Lattner  operator pointer() const {
1927e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
1937e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr;
1947e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1957e70829632f82de15db187845666aaca6e04b792Chris Lattner
1967e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference operator*() const {
1977e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
1987e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *NodePtr;
1997e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
200e14d81deeb6bb3404ffee5e59ecb88304f112f4aDan Gohman  pointer operator->() const { return &operator*(); }
2017e70829632f82de15db187845666aaca6e04b792Chris Lattner
2027e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Comparison operators
2037e70829632f82de15db187845666aaca6e04b792Chris Lattner  bool operator==(const ilist_iterator &RHS) const {
2047e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr == RHS.NodePtr;
2057e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2067e70829632f82de15db187845666aaca6e04b792Chris Lattner  bool operator!=(const ilist_iterator &RHS) const {
2077e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr != RHS.NodePtr;
2087e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2097e70829632f82de15db187845666aaca6e04b792Chris Lattner
2107e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Increment and decrement operators...
2117e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator &operator--() {      // predecrement - Back up
2127e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getPrev(NodePtr);
2135c5f5a2ec2dd49bd3049fa0a55aca4956fc56ff2Chris Lattner    assert(NodePtr && "--'d off the beginning of an ilist!");
2147e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2157e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2167e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator &operator++() {      // preincrement - Advance
2177e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getNext(NodePtr);
2187e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(NodePtr && "++'d off the end of an ilist!");
2197e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2207e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2217e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator operator--(int) {    // postdecrement operators...
2227e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
2237e70829632f82de15db187845666aaca6e04b792Chris Lattner    --*this;
2247e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
2257e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2267e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator operator++(int) {    // postincrement operators...
2277e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
2287e70829632f82de15db187845666aaca6e04b792Chris Lattner    ++*this;
2297e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
2307e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2317e70829632f82de15db187845666aaca6e04b792Chris Lattner
2322cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Internal interface, do not use...
2332cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  pointer getNodePtrUnchecked() const { return NodePtr; }
2342cca3008e86aa5448a629c744064daecb531bf94Chris Lattner};
2352cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
23671be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos// do not implement. this is to catch errors when people try to use
23771be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos// them as random access iterators
23871be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
23971be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator-(int, ilist_iterator<T>);
24071be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24171be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator-(ilist_iterator<T>,int);
24271be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
24371be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24471be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator+(int, ilist_iterator<T>);
24571be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24671be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator+(ilist_iterator<T>,int);
24771be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
248cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman// operator!=/operator== - Allow mixed comparisons without dereferencing
249cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman// the iterator, which could very likely be pointing to end().
250cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
251cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
252cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS != RHS.getNodePtrUnchecked();
253cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
254cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
255cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
256cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS == RHS.getNodePtrUnchecked();
257cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
258cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
259cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
260cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS != RHS.getNodePtrUnchecked();
261cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
262cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
263cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator==(T* LHS, const ilist_iterator<T> &RHS) {
264cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS == RHS.getNodePtrUnchecked();
265cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
266cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman
267cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman
268011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// Allow ilist_iterators to convert into pointers to a node automatically when
269011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// used by the dyn_cast, cast, isa mechanisms...
270011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
271011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename From> struct simplify_type;
272011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
273011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
274011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
275e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
276011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
277011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
278011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
279011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
280011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
281011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
282e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
283011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
284011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
285011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
286011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
287011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
2887e70829632f82de15db187845666aaca6e04b792Chris Lattner
2897e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
2907e70829632f82de15db187845666aaca6e04b792Chris Lattner//
2916de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// iplist - The subset of list functionality that can safely be used on nodes
2926de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// of polymorphic types, i.e. a heterogenous list with a common base class that
2936de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// holds the next/prev pointers.  The only state of the list itself is a single
2946de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// pointer to the head of the list.
2956de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
2966de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// This list can be in one of three interesting states:
2976de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 1. The list may be completely unconstructed.  In this case, the head
2986de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    pointer is null.  When in this form, any query for an iterator (e.g.
2996de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    begin() or end()) causes the list to transparently change to state #2.
300e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman/// 2. The list may be empty, but contain a sentinel for the end iterator. This
301e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    sentinel is created by the Traits::createSentinel method and is a link
3026de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    in the list.  When the list is empty, the pointer in the iplist points
303e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    to the sentinel.  Once the sentinel is constructed, it
3046de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    is not destroyed until the list is.
3056de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 3. The list may contain actual objects in it, which are stored as a doubly
3066de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    linked list of nodes.  One invariant of the list is that the predecessor
3076de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    of the first node in the list always points to the last node in the list,
308e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    and the successor pointer for the sentinel (which always stays at the
309e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    end of the list) is always null.
3106de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
3117e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
3127e70829632f82de15db187845666aaca6e04b792Chris Lattnerclass iplist : public Traits {
3136de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  mutable NodeTy *Head;
31447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
31547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // Use the prev node pointer of 'head' as the tail pointer.  This is really a
31647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // circularly linked list where we snip the 'next' link from the sentinel node
31747e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // back to the first node in the list (to preserve assertions about going off
31847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // the end of the list).
319c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  NodeTy *getTail() { return this->ensureHead(Head); }
320c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  const NodeTy *getTail() const { return this->ensureHead(Head); }
321c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  void setTail(NodeTy *N) const { this->noteHead(Head, N); }
322e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
323e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  /// CreateLazySentinel - This method verifies whether the sentinel for the
3246de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  /// list has been created and lazily makes it if not.
325e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  void CreateLazySentinel() const {
326c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif    this->Traits::ensureHead(Head);
3276de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3287e70829632f82de15db187845666aaca6e04b792Chris Lattner
3297e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
3307e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
3319ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman
3329ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman  // No fundamental reason why iplist can't by copyable, but the default
3339ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman  // copy/copy-assign won't do.
3349ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman  iplist(const iplist &);         // do not implement
3359ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman  void operator=(const iplist &); // do not implement
3369ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman
3377e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
3387e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy *pointer;
3397e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy *const_pointer;
3407e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy &reference;
3417e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy &const_reference;
3427e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy value_type;
3437e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<NodeTy> iterator;
3447e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<const NodeTy> const_iterator;
3457e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef size_t size_type;
3467e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ptrdiff_t difference_type;
3474a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
3484a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<iterator>  reverse_iterator;
3497e70829632f82de15db187845666aaca6e04b792Chris Lattner
350c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  iplist() : Head(this->Traits::provideInitialHead()) {}
3516de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  ~iplist() {
3526de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    if (!Head) return;
3536de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    clear();
3546de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    Traits::destroySentinel(getTail());
3557e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3567e70829632f82de15db187845666aaca6e04b792Chris Lattner
3572cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Iterator creation methods.
3586de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator begin() {
359e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
360e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    return iterator(Head);
3616de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3626de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator begin() const {
363e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3646de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(Head);
3656de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3666de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator end() {
367e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3686de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return iterator(getTail());
3696de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3706de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator end() const {
371e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3726de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(getTail());
3736de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3747e70829632f82de15db187845666aaca6e04b792Chris Lattner
3752cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // reverse iterator creation methods.
3767e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rbegin()            { return reverse_iterator(end()); }
3777e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
3787e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rend()              { return reverse_iterator(begin()); }
3796de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
3807e70829632f82de15db187845666aaca6e04b792Chris Lattner
3812cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
3822cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Miscellaneous inspection routines.
3837e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type max_size() const { return size_type(-1); }
3846de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  bool empty() const { return Head == 0 || Head == getTail(); }
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...
4227e70829632f82de15db187845666aaca6e04b792Chris Lattner    return 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);
4437e70829632f82de15db187845666aaca6e04b792Chris Lattner    IT = 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".
451c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setNext(Node, 0);
452c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(Node, 0);
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
4617e70829632f82de15db187845666aaca6e04b792Chris Lattner  // erase - remove a node from the controlled sequence... and delete it.
4627e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator where) {
463c03c46a6af3d53172d48d9e4d36748a40c878cffDouglas Gregor    this->deleteNode(remove(where));
4647e70829632f82de15db187845666aaca6e04b792Chris Lattner    return where;
4657e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4667e70829632f82de15db187845666aaca6e04b792Chris Lattner
4677e70829632f82de15db187845666aaca6e04b792Chris Lattner
4687e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
4697e70829632f82de15db187845666aaca6e04b792Chris Lattner  // transfer - The heart of the splice function.  Move linked list nodes from
4707e70829632f82de15db187845666aaca6e04b792Chris Lattner  // [first, last) into position.
4717e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4727e70829632f82de15db187845666aaca6e04b792Chris Lattner  void transfer(iterator position, iplist &L2, iterator first, iterator last) {
4737e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(first != last && "Should be checked by callers");
47447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
4757e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (position != last) {
47647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // Note: we have to be careful about the case when we move the first node
47747e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // in the list.  This node is the list sentinel node and we can't move it.
47847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *ThisSentinel = getTail();
47947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(0);
48047e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *L2Sentinel = L2.getTail();
48147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(0);
48247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
4837e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Remove [first, last) from its old position.
4847e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *First = &*first, *Prev = getPrev(First);
4857e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
4867e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (Prev)
487c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(Prev, Next);
4887e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
4897e70829632f82de15db187845666aaca6e04b792Chris Lattner        L2.Head = Next;
490c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(Next, Prev);
4917e70829632f82de15db187845666aaca6e04b792Chris Lattner
4927e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Splice [first, last) into its new position.
4937e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosNext = position.getNodePtrUnchecked();
4947e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosPrev = getPrev(PosNext);
4957e70829632f82de15db187845666aaca6e04b792Chris Lattner
4967e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix head of list...
4977e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (PosPrev)
498c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(PosPrev, First);
4997e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5007e70829632f82de15db187845666aaca6e04b792Chris Lattner        Head = First;
501c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(First, PosPrev);
5027e70829632f82de15db187845666aaca6e04b792Chris Lattner
5037e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix end of list...
504c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(Last, PosNext);
505c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(PosNext, Last);
5067e70829632f82de15db187845666aaca6e04b792Chris Lattner
5077e70829632f82de15db187845666aaca6e04b792Chris Lattner      transferNodesFromList(L2, First, PosNext);
50847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
509e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman      // Now that everything is set, restore the pointers to the list sentinels.
51047e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(L2Sentinel);
51147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(ThisSentinel);
5127e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5137e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5147e70829632f82de15db187845666aaca6e04b792Chris Lattner
5157e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
5167e70829632f82de15db187845666aaca6e04b792Chris Lattner
5177e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5187e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Functionality derived from other functions defined above...
5197e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5207e70829632f82de15db187845666aaca6e04b792Chris Lattner
5217e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type size() const {
522e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    if (Head == 0) return 0; // Don't require construction of sentinel if empty.
5236bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner    return std::distance(begin(), end());
5247e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5257e70829632f82de15db187845666aaca6e04b792Chris Lattner
5267e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator first, iterator last) {
5277e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first != last)
5287e70829632f82de15db187845666aaca6e04b792Chris Lattner      first = erase(first);
5297e70829632f82de15db187845666aaca6e04b792Chris Lattner    return last;
5307e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5317e70829632f82de15db187845666aaca6e04b792Chris Lattner
5326de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void clear() { if (Head) erase(begin(), end()); }
5337e70829632f82de15db187845666aaca6e04b792Chris Lattner
5347e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
5357e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_front(NodeTy *val) { insert(begin(), val); }
5367e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_back(NodeTy *val) { insert(end(), val); }
5377e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_front() {
5387e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_front() on empty list!");
5397e70829632f82de15db187845666aaca6e04b792Chris Lattner    erase(begin());
5407e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5417e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_back() {
5427e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_back() on empty list!");
5437e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator t = end(); erase(--t);
5447e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5457e70829632f82de15db187845666aaca6e04b792Chris Lattner
5467e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
5477e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
5487e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
5497e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5507e70829632f82de15db187845666aaca6e04b792Chris Lattner
5517e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Splice members - defined in terms of transfer...
5527e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2) {
5537e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!L2.empty())
5547e70829632f82de15db187845666aaca6e04b792Chris Lattner      transfer(where, L2, L2.begin(), L2.end());
5557e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5567e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first) {
5577e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator last = first; ++last;
5587e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (where == first || where == last) return; // No change
5597e70829632f82de15db187845666aaca6e04b792Chris Lattner    transfer(where, L2, first, last);
5607e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5617e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first, iterator last) {
5627e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first != last) transfer(where, L2, first, last);
5637e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5647e70829632f82de15db187845666aaca6e04b792Chris Lattner
5657e70829632f82de15db187845666aaca6e04b792Chris Lattner
5667e70829632f82de15db187845666aaca6e04b792Chris Lattner
5677e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5687e70829632f82de15db187845666aaca6e04b792Chris Lattner  // High-Level Functionality that shouldn't really be here, but is part of list
5697e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5707e70829632f82de15db187845666aaca6e04b792Chris Lattner
5717e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These two functions are actually called remove/remove_if in list<>, but
5727e70829632f82de15db187845666aaca6e04b792Chris Lattner  // they actually do the job of erase, rename them accordingly.
5737e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5747e70829632f82de15db187845666aaca6e04b792Chris Lattner  void erase(const NodeTy &val) {
5757e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
5767e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
5777e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (*I == val) erase(I);
5787e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5797e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5807e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5817e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr1> void erase_if(Pr1 pred) {
5827e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
5837e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
5847e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I)) erase(I);
5857e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5867e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5877e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5887e70829632f82de15db187845666aaca6e04b792Chris Lattner
5897e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr2> void unique(Pr2 pred) {
5907e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (empty()) return;
5917e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
5927e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I))
5937e70829632f82de15db187845666aaca6e04b792Chris Lattner        erase(Next);
5947e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5957e70829632f82de15db187845666aaca6e04b792Chris Lattner        I = Next;
5967e70829632f82de15db187845666aaca6e04b792Chris Lattner      Next = I;
5977e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5987e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5997e70829632f82de15db187845666aaca6e04b792Chris Lattner  void unique() { unique(op_equal); }
6007e70829632f82de15db187845666aaca6e04b792Chris Lattner
6017e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void merge(iplist &right, Pr3 pred) {
6027e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first1 = begin(), last1 = end();
6037e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first2 = right.begin(), last2 = right.end();
6047e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first1 != last1 && first2 != last2)
6057e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*first2, *first1)) {
6067e70829632f82de15db187845666aaca6e04b792Chris Lattner        iterator next = first2;
6077e70829632f82de15db187845666aaca6e04b792Chris Lattner        transfer(first1, right, first2, ++next);
6087e70829632f82de15db187845666aaca6e04b792Chris Lattner        first2 = next;
6097e70829632f82de15db187845666aaca6e04b792Chris Lattner      } else {
6107e70829632f82de15db187845666aaca6e04b792Chris Lattner        ++first1;
6117e70829632f82de15db187845666aaca6e04b792Chris Lattner      }
6127e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 != last2) transfer(last1, right, first2, last2);
6137e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6147e70829632f82de15db187845666aaca6e04b792Chris Lattner  void merge(iplist &right) { return merge(right, op_less); }
6157e70829632f82de15db187845666aaca6e04b792Chris Lattner
6167e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void sort(Pr3 pred);
6177e70829632f82de15db187845666aaca6e04b792Chris Lattner  void sort() { sort(op_less); }
6187e70829632f82de15db187845666aaca6e04b792Chris Lattner  void reverse();
6197e70829632f82de15db187845666aaca6e04b792Chris Lattner};
6207e70829632f82de15db187845666aaca6e04b792Chris Lattner
6217e70829632f82de15db187845666aaca6e04b792Chris Lattner
6227e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
6237e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist : public iplist<NodeTy> {
624a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::size_type size_type;
625a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::iterator iterator;
626a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
6277e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist() {}
6287e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(const ilist &right) {
62940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), right.begin(), right.end());
6307e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6317e70829632f82de15db187845666aaca6e04b792Chris Lattner  explicit ilist(size_type count) {
63240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, NodeTy());
633e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  }
6347e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(size_type count, const NodeTy &val) {
63540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, val);
6367e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6377e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> ilist(InIt first, InIt last) {
63840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), first, last);
6397e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6407e70829632f82de15db187845666aaca6e04b792Chris Lattner
64183b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  // bring hidden functions into scope
64283b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::insert;
64383b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::push_front;
64483b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::push_back;
6457e70829632f82de15db187845666aaca6e04b792Chris Lattner
6467e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Main implementation here - Insert for a node passed by value...
6477e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, const NodeTy &val) {
6487e70829632f82de15db187845666aaca6e04b792Chris Lattner    return insert(where, createNode(val));
6497e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6507e70829632f82de15db187845666aaca6e04b792Chris Lattner
6517e70829632f82de15db187845666aaca6e04b792Chris Lattner
6527e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
65340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_front(const NodeTy &val) { insert(this->begin(), val); }
65440c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_back(const NodeTy &val) { insert(this->end(), val); }
6557e70829632f82de15db187845666aaca6e04b792Chris Lattner
6567e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
6577e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
6587e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
6597e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6607e70829632f82de15db187845666aaca6e04b792Chris Lattner  void insert(iterator where, size_type count, const NodeTy &val) {
6617e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; count != 0; --count) insert(where, val);
6627e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6637e70829632f82de15db187845666aaca6e04b792Chris Lattner
6647e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Assign special forms...
6657e70829632f82de15db187845666aaca6e04b792Chris Lattner  void assign(size_type count, const NodeTy &val) {
66640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator I = this->begin();
66740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for (; I != this->end() && count != 0; ++I, --count)
6687e70829632f82de15db187845666aaca6e04b792Chris Lattner      *I = val;
6697e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (count != 0)
67040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), val, val);
6717e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
67240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(I, this->end());
6737e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
67440c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  template<class InIt> void assign(InIt first1, InIt last1) {
67540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator first2 = this->begin(), last2 = this->end();
6767e70829632f82de15db187845666aaca6e04b792Chris Lattner    for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
6777e70829632f82de15db187845666aaca6e04b792Chris Lattner      *first1 = *first2;
6787e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 == last2)
6797e70829632f82de15db187845666aaca6e04b792Chris Lattner      erase(first1, last1);
6807e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
6817e70829632f82de15db187845666aaca6e04b792Chris Lattner      insert(last1, first2, last2);
6827e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6837e70829632f82de15db187845666aaca6e04b792Chris Lattner
6847e70829632f82de15db187845666aaca6e04b792Chris Lattner
6857e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Resize members...
6867e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize, NodeTy val) {
68740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator i = this->begin();
6887e70829632f82de15db187845666aaca6e04b792Chris Lattner    size_type len = 0;
68940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
6907e70829632f82de15db187845666aaca6e04b792Chris Lattner
6917e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (len == newsize)
69240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(i, this->end());
6937e70829632f82de15db187845666aaca6e04b792Chris Lattner    else                                          // i == end()
69440c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), newsize - len, val);
6957e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6967e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize) { resize(newsize, NodeTy()); }
6977e70829632f82de15db187845666aaca6e04b792Chris Lattner};
6987e70829632f82de15db187845666aaca6e04b792Chris Lattner
699d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
700d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
7017e70829632f82de15db187845666aaca6e04b792Chris Lattnernamespace std {
7027e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Ensure that swap uses the fast list swap...
7037e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Ty>
704d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
7057e70829632f82de15db187845666aaca6e04b792Chris Lattner    Left.swap(Right);
7067e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7077e70829632f82de15db187845666aaca6e04b792Chris Lattner}  // End 'std' extensions...
7087e70829632f82de15db187845666aaca6e04b792Chris Lattner
7091ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#endif // LLVM_ADT_ILIST_H
710