ilist.h revision fc601db2ed899d800ea0a50f7ecf7de2a820cbc1
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
86c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  static NodeTy *provideInitialHead() { return 0; }
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);
95c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif      ilist_traits<NodeTy>::setNext(Head, 0);
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
107b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// ilist_node_traits - A fragment for template traits for intrusive list
108b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// that provides default node related operations.
109fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman///
110fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
111b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greifstruct ilist_node_traits {
112fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman  static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
113fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman  static void deleteNode(NodeTy *V) { delete V; }
1147e70829632f82de15db187845666aaca6e04b792Chris Lattner
115eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling  void addNodeToList(NodeTy *) {}
116eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling  void removeNodeFromList(NodeTy *) {}
117b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif  void transferNodesFromList(ilist_node_traits &    /*SrcTraits*/,
118eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling                             ilist_iterator<NodeTy> /*first*/,
119eb4ab60bed82d15651bf77ae68ad266ec0eeae9dBill Wendling                             ilist_iterator<NodeTy> /*last*/) {}
1207e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1217e70829632f82de15db187845666aaca6e04b792Chris Lattner
122b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// ilist_default_traits - Default template traits for intrusive list.
123b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// By inheriting from this, you can easily use default implementations
124b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif/// for all common operations.
125b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif///
126b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greiftemplate<typename NodeTy>
12759bf4fcc0680e75b408579064d1205a132361196Duncan Sandsstruct ilist_default_traits : public ilist_nextprev_traits<NodeTy>,
12859bf4fcc0680e75b408579064d1205a132361196Duncan Sands                              public ilist_sentinel_traits<NodeTy>,
12959bf4fcc0680e75b408579064d1205a132361196Duncan Sands                              public ilist_node_traits<NodeTy> {
130b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif};
131b141e397d52d9946e93f84c65c6b2e653b026041Gabor Greif
132fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// Template traits for intrusive list.  By specializing this template class, you
133fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman// can change what next/prev fields are used to store the links...
134fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmantemplate<typename NodeTy>
13559bf4fcc0680e75b408579064d1205a132361196Duncan Sandsstruct ilist_traits : public ilist_default_traits<NodeTy> {};
136fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman
1377e70829632f82de15db187845666aaca6e04b792Chris Lattner// Const traits are the same as nonconst traits...
1387e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename Ty>
1397e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist_traits<const Ty> : public ilist_traits<Ty> {};
1407e70829632f82de15db187845666aaca6e04b792Chris Lattner
1417e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
1427e70829632f82de15db187845666aaca6e04b792Chris Lattner// ilist_iterator<Node> - Iterator for intrusive list.
1437e70829632f82de15db187845666aaca6e04b792Chris Lattner//
1447e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
145a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattnerclass ilist_iterator
146f0891be8bdbeeadb39da5575273b6645755fa383Gabor Greif  : public std::iterator<std::bidirectional_iterator_tag, NodeTy, ptrdiff_t> {
147e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
148ccaa6540fc2866ab36f6ebecf6df101f613f8aa7Ted Kremenekpublic:
1497e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_traits<NodeTy> Traits;
1507362ce08cb2c1f0b544b18dbc21630fb4baebcfcGabor Greif  typedef std::iterator<std::bidirectional_iterator_tag,
1517362ce08cb2c1f0b544b18dbc21630fb4baebcfcGabor Greif                        NodeTy, ptrdiff_t> super;
152a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
1532c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  typedef typename super::value_type value_type;
1542c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  typedef typename super::difference_type difference_type;
155a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::pointer pointer;
156a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::reference reference;
15732862da7c7107d792d25a885f9bd2d0402ae7126Chris Lattnerprivate:
1587e70829632f82de15db187845666aaca6e04b792Chris Lattner  pointer NodePtr;
159066075030ad46b3494480a5f79f05443f947aca7Nick Lewycky
1602c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // ilist_iterator is not a random-access iterator, but it has an
1612c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // implicit conversion to pointer-type, which is. Declare (but
1622c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // don't define) these functions as private to help catch
1632c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  // accidental misuse.
1642c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator[](difference_type) const;
1652c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator+(difference_type) const;
1662c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator-(difference_type) const;
1672c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator+=(difference_type) const;
1682c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  void operator-=(difference_type) const;
1692c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator<(T) const;
1702c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator<=(T) const;
1712c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator>(T) const;
1722c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator>=(T) const;
1732c8a1522dbe6f14b728e83b9c555bef27233cc91Dan Gohman  template<class T> void operator-(T) const;
1747e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
1757e70829632f82de15db187845666aaca6e04b792Chris Lattner
1767e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(pointer NP) : NodePtr(NP) {}
17733adbcc87d92c6c3e620870c804f4a2533ecc850Vikram S. Adve  ilist_iterator(reference NR) : NodePtr(&NR) {}
1787e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator() : NodePtr(0) {}
1797e70829632f82de15db187845666aaca6e04b792Chris Lattner
1807e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow constructing a const iterator from
1817e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
1827e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class node_ty>
1837e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(const ilist_iterator<node_ty> &RHS)
1847e70829632f82de15db187845666aaca6e04b792Chris Lattner    : NodePtr(RHS.getNodePtrUnchecked()) {}
1857e70829632f82de15db187845666aaca6e04b792Chris Lattner
1867e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow assigning to a const iterator from
1877e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
1887e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class node_ty>
1897e70829632f82de15db187845666aaca6e04b792Chris Lattner  const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
1907e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = RHS.getNodePtrUnchecked();
1917e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
1927e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1937e70829632f82de15db187845666aaca6e04b792Chris Lattner
1947e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Accessors...
1957e70829632f82de15db187845666aaca6e04b792Chris Lattner  operator pointer() const {
1967e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr;
1977e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1987e70829632f82de15db187845666aaca6e04b792Chris Lattner
1997e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference operator*() const {
2007e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *NodePtr;
2017e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
202e14d81deeb6bb3404ffee5e59ecb88304f112f4aDan Gohman  pointer operator->() const { return &operator*(); }
2037e70829632f82de15db187845666aaca6e04b792Chris Lattner
2047e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Comparison operators
2057e70829632f82de15db187845666aaca6e04b792Chris Lattner  bool operator==(const ilist_iterator &RHS) const {
2067e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr == RHS.NodePtr;
2077e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2087e70829632f82de15db187845666aaca6e04b792Chris Lattner  bool operator!=(const ilist_iterator &RHS) const {
2097e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr != RHS.NodePtr;
2107e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2117e70829632f82de15db187845666aaca6e04b792Chris Lattner
2127e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Increment and decrement operators...
2137e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator &operator--() {      // predecrement - Back up
2147e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getPrev(NodePtr);
2155c5f5a2ec2dd49bd3049fa0a55aca4956fc56ff2Chris Lattner    assert(NodePtr && "--'d off the beginning of an ilist!");
2167e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2177e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2187e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator &operator++() {      // preincrement - Advance
2197e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getNext(NodePtr);
2207e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
2217e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2227e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator operator--(int) {    // postdecrement operators...
2237e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
2247e70829632f82de15db187845666aaca6e04b792Chris Lattner    --*this;
2257e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
2267e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2277e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator operator++(int) {    // postincrement operators...
2287e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
2297e70829632f82de15db187845666aaca6e04b792Chris Lattner    ++*this;
2307e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
2317e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2327e70829632f82de15db187845666aaca6e04b792Chris Lattner
2332cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Internal interface, do not use...
2342cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  pointer getNodePtrUnchecked() const { return NodePtr; }
2352cca3008e86aa5448a629c744064daecb531bf94Chris Lattner};
2362cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
23771be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos// do not implement. this is to catch errors when people try to use
23871be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos// them as random access iterators
23971be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24071be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator-(int, ilist_iterator<T>);
24171be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24271be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator-(ilist_iterator<T>,int);
24371be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
24471be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24571be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator+(int, ilist_iterator<T>);
24671be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
24771be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator+(ilist_iterator<T>,int);
24871be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
249cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman// operator!=/operator== - Allow mixed comparisons without dereferencing
250cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman// the iterator, which could very likely be pointing to end().
251cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
252cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
253cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS != RHS.getNodePtrUnchecked();
254cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
255cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
256cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
257cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS == RHS.getNodePtrUnchecked();
258cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
259cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
260cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
261cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS != RHS.getNodePtrUnchecked();
262cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
263cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
264cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator==(T* LHS, const ilist_iterator<T> &RHS) {
265cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS == RHS.getNodePtrUnchecked();
266cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
267cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman
268cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman
269011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// Allow ilist_iterators to convert into pointers to a node automatically when
270011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// used by the dyn_cast, cast, isa mechanisms...
271011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
272011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename From> struct simplify_type;
273011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
274011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
275011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
276e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
277011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
278011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
279011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
280011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
281011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
282011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
283e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
284011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
285011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
286011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
287011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
288011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
2897e70829632f82de15db187845666aaca6e04b792Chris Lattner
2907e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
2917e70829632f82de15db187845666aaca6e04b792Chris Lattner//
2926de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// iplist - The subset of list functionality that can safely be used on nodes
2937a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner/// of polymorphic types, i.e. a heterogeneous list with a common base class that
2946de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// holds the next/prev pointers.  The only state of the list itself is a single
2956de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// pointer to the head of the list.
2966de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
2976de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// This list can be in one of three interesting states:
2986de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 1. The list may be completely unconstructed.  In this case, the head
2996de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    pointer is null.  When in this form, any query for an iterator (e.g.
3006de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    begin() or end()) causes the list to transparently change to state #2.
301e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman/// 2. The list may be empty, but contain a sentinel for the end iterator. This
302e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    sentinel is created by the Traits::createSentinel method and is a link
3036de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    in the list.  When the list is empty, the pointer in the iplist points
304e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    to the sentinel.  Once the sentinel is constructed, it
3056de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    is not destroyed until the list is.
3066de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 3. The list may contain actual objects in it, which are stored as a doubly
3076de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    linked list of nodes.  One invariant of the list is that the predecessor
3086de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    of the first node in the list always points to the last node in the list,
309e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    and the successor pointer for the sentinel (which always stays at the
310e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman///    end of the list) is always null.
3116de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
3127e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
3137e70829632f82de15db187845666aaca6e04b792Chris Lattnerclass iplist : public Traits {
3146de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  mutable NodeTy *Head;
31547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
31647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // Use the prev node pointer of 'head' as the tail pointer.  This is really a
31747e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // circularly linked list where we snip the 'next' link from the sentinel node
31847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // back to the first node in the list (to preserve assertions about going off
31947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // the end of the list).
320c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  NodeTy *getTail() { return this->ensureHead(Head); }
321c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  const NodeTy *getTail() const { return this->ensureHead(Head); }
322c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif  void setTail(NodeTy *N) const { this->noteHead(Head, N); }
323e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
324e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  /// CreateLazySentinel - This method verifies whether the sentinel for the
3256de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  /// list has been created and lazily makes it if not.
326e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  void CreateLazySentinel() const {
327e2b16504be5b55e6a42819eaf93e0698b529165bGabor Greif    this->ensureHead(Head);
3286de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3297e70829632f82de15db187845666aaca6e04b792Chris Lattner
3307e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
3317e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
3329ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman
333e2b16504be5b55e6a42819eaf93e0698b529165bGabor Greif  // No fundamental reason why iplist can't be copyable, but the default
3349ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman  // copy/copy-assign won't do.
335fc601db2ed899d800ea0a50f7ecf7de2a820cbc1Craig Topper  iplist(const iplist &) LLVM_DELETED_FUNCTION;
336fc601db2ed899d800ea0a50f7ecf7de2a820cbc1Craig Topper  void operator=(const iplist &) LLVM_DELETED_FUNCTION;
3379ff0f0ea39ea71d33887584d10c88dda2038285bDan Gohman
3387e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
3397e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy *pointer;
3407e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy *const_pointer;
3417e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy &reference;
3427e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy &const_reference;
3437e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy value_type;
3447e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<NodeTy> iterator;
3457e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<const NodeTy> const_iterator;
3467e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef size_t size_type;
3477e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ptrdiff_t difference_type;
3484a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
3494a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<iterator>  reverse_iterator;
3507e70829632f82de15db187845666aaca6e04b792Chris Lattner
351e2b16504be5b55e6a42819eaf93e0698b529165bGabor Greif  iplist() : Head(this->provideInitialHead()) {}
3526de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  ~iplist() {
3536de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    if (!Head) return;
3546de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    clear();
3556de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    Traits::destroySentinel(getTail());
3567e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3577e70829632f82de15db187845666aaca6e04b792Chris Lattner
3582cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Iterator creation methods.
3596de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator begin() {
360e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
361e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    return iterator(Head);
3626de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3636de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator begin() const {
364e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3656de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(Head);
3666de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3676de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator end() {
368e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3696de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return iterator(getTail());
3706de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3716de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator end() const {
372e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    CreateLazySentinel();
3736de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(getTail());
3746de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
3757e70829632f82de15db187845666aaca6e04b792Chris Lattner
3762cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // reverse iterator creation methods.
3777e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rbegin()            { return reverse_iterator(end()); }
3787e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
3797e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rend()              { return reverse_iterator(begin()); }
3806de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
3817e70829632f82de15db187845666aaca6e04b792Chris Lattner
3822cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
3832cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Miscellaneous inspection routines.
3847e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type max_size() const { return size_type(-1); }
3856de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  bool empty() const { return Head == 0 || Head == getTail(); }
3867e70829632f82de15db187845666aaca6e04b792Chris Lattner
3877e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back accessor functions...
3887e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference front() {
3897e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3907e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3917e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3927e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference front() const {
3937e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3947e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3957e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3967e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference back() {
3977e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
398c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    return *this->getPrev(getTail());
3997e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4007e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference back() const {
4017e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
402c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    return *this->getPrev(getTail());
4037e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4047e70829632f82de15db187845666aaca6e04b792Chris Lattner
4057e70829632f82de15db187845666aaca6e04b792Chris Lattner  void swap(iplist &RHS) {
406d68a07650cdb2e18f18f362ba533459aa10e01b6Dan Gohman    assert(0 && "Swap does not use list traits callback correctly yet!");
4077e70829632f82de15db187845666aaca6e04b792Chris Lattner    std::swap(Head, RHS.Head);
4087e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4097e70829632f82de15db187845666aaca6e04b792Chris Lattner
4107e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, NodeTy *New) {
411a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman    NodeTy *CurNode = where.getNodePtrUnchecked();
412a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman    NodeTy *PrevNode = this->getPrev(CurNode);
413c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setNext(New, CurNode);
414c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(New, PrevNode);
4157e70829632f82de15db187845666aaca6e04b792Chris Lattner
41647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (CurNode != Head)  // Is PrevNode off the beginning of the list?
417c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(PrevNode, New);
4187e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
4197e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = New;
420c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(CurNode, New);
4217e70829632f82de15db187845666aaca6e04b792Chris Lattner
422c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->addNodeToList(New);  // Notify traits that we added a node...
4237e70829632f82de15db187845666aaca6e04b792Chris Lattner    return New;
4247e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4257e70829632f82de15db187845666aaca6e04b792Chris Lattner
4263ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner  iterator insertAfter(iterator where, NodeTy *New) {
427085a9ebbc705c6e7d3fd8c692ef1c46fdfb885ceMisha Brukman    if (empty())
4283ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner      return insert(begin(), New);
4293ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner    else
4303ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner      return insert(++where, New);
4313ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner  }
4323ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner
4337e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(iterator &IT) {
4347e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(IT != end() && "Cannot remove end of list!");
4357e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *Node = &*IT;
436c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    NodeTy *NextNode = this->getNext(Node);
437c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    NodeTy *PrevNode = this->getPrev(Node);
4387e70829632f82de15db187845666aaca6e04b792Chris Lattner
43947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (Node != Head)  // Is PrevNode off the beginning of the list?
440c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(PrevNode, NextNode);
4417e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
4427e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = NextNode;
443c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(NextNode, PrevNode);
4447e70829632f82de15db187845666aaca6e04b792Chris Lattner    IT = NextNode;
4452b5326e7240ac524812016bc3700e12045bf0eb1Steve Naroff    this->removeNodeFromList(Node);  // Notify traits that we removed a node...
446e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
4472896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // Set the next/prev pointers of the current node to null.  This isn't
4482896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // strictly required, but this catches errors where a node is removed from
4492896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // an ilist (and potentially deleted) with iterators still pointing at it.
4502896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // When those iterators are incremented or decremented, they will assert on
4512896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // the null next/prev pointer instead of "usually working".
452c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setNext(Node, 0);
453c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(Node, 0);
4547e70829632f82de15db187845666aaca6e04b792Chris Lattner    return Node;
4557e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4567e70829632f82de15db187845666aaca6e04b792Chris Lattner
4577e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(const iterator &IT) {
4587e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator MutIt = IT;
4597e70829632f82de15db187845666aaca6e04b792Chris Lattner    return remove(MutIt);
4607e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4617e70829632f82de15db187845666aaca6e04b792Chris Lattner
4627e70829632f82de15db187845666aaca6e04b792Chris Lattner  // erase - remove a node from the controlled sequence... and delete it.
4637e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator where) {
464c03c46a6af3d53172d48d9e4d36748a40c878cffDouglas Gregor    this->deleteNode(remove(where));
4657e70829632f82de15db187845666aaca6e04b792Chris Lattner    return where;
4667e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4677e70829632f82de15db187845666aaca6e04b792Chris Lattner
4687e70829632f82de15db187845666aaca6e04b792Chris Lattner
4697e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
4707e70829632f82de15db187845666aaca6e04b792Chris Lattner  // transfer - The heart of the splice function.  Move linked list nodes from
4717e70829632f82de15db187845666aaca6e04b792Chris Lattner  // [first, last) into position.
4727e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4737e70829632f82de15db187845666aaca6e04b792Chris Lattner  void transfer(iterator position, iplist &L2, iterator first, iterator last) {
4747e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(first != last && "Should be checked by callers");
47547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
4767e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (position != last) {
47747e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // Note: we have to be careful about the case when we move the first node
47847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // in the list.  This node is the list sentinel node and we can't move it.
47947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *ThisSentinel = getTail();
48047e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(0);
48147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *L2Sentinel = L2.getTail();
48247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(0);
48347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
4847e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Remove [first, last) from its old position.
48523e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *First = &*first, *Prev = this->getPrev(First);
48623e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
4877e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (Prev)
488c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(Prev, Next);
4897e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
4907e70829632f82de15db187845666aaca6e04b792Chris Lattner        L2.Head = Next;
491c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(Next, Prev);
4927e70829632f82de15db187845666aaca6e04b792Chris Lattner
4937e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Splice [first, last) into its new position.
4947e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosNext = position.getNodePtrUnchecked();
49523e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *PosPrev = this->getPrev(PosNext);
4967e70829632f82de15db187845666aaca6e04b792Chris Lattner
4977e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix head of list...
4987e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (PosPrev)
499c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(PosPrev, First);
5007e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5017e70829632f82de15db187845666aaca6e04b792Chris Lattner        Head = First;
502c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(First, PosPrev);
5037e70829632f82de15db187845666aaca6e04b792Chris Lattner
5047e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix end of list...
505c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(Last, PosNext);
506c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(PosNext, Last);
5077e70829632f82de15db187845666aaca6e04b792Chris Lattner
50823e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      this->transferNodesFromList(L2, First, PosNext);
50947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
510e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman      // Now that everything is set, restore the pointers to the list sentinels.
51147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(L2Sentinel);
51247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(ThisSentinel);
5137e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5147e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5157e70829632f82de15db187845666aaca6e04b792Chris Lattner
5167e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
5177e70829632f82de15db187845666aaca6e04b792Chris Lattner
5187e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5197e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Functionality derived from other functions defined above...
5207e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5217e70829632f82de15db187845666aaca6e04b792Chris Lattner
5227e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type size() const {
523e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    if (Head == 0) return 0; // Don't require construction of sentinel if empty.
5246bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner    return std::distance(begin(), end());
5257e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5267e70829632f82de15db187845666aaca6e04b792Chris Lattner
5277e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator first, iterator last) {
5287e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first != last)
5297e70829632f82de15db187845666aaca6e04b792Chris Lattner      first = erase(first);
5307e70829632f82de15db187845666aaca6e04b792Chris Lattner    return last;
5317e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5327e70829632f82de15db187845666aaca6e04b792Chris Lattner
5336de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void clear() { if (Head) erase(begin(), end()); }
5347e70829632f82de15db187845666aaca6e04b792Chris Lattner
5357e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
5367e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_front(NodeTy *val) { insert(begin(), val); }
5377e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_back(NodeTy *val) { insert(end(), val); }
5387e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_front() {
5397e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_front() on empty list!");
5407e70829632f82de15db187845666aaca6e04b792Chris Lattner    erase(begin());
5417e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5427e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_back() {
5437e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_back() on empty list!");
5447e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator t = end(); erase(--t);
5457e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5467e70829632f82de15db187845666aaca6e04b792Chris Lattner
5477e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
5487e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
5497e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
5507e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5517e70829632f82de15db187845666aaca6e04b792Chris Lattner
5527e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Splice members - defined in terms of transfer...
5537e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2) {
5547e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!L2.empty())
5557e70829632f82de15db187845666aaca6e04b792Chris Lattner      transfer(where, L2, L2.begin(), L2.end());
5567e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5577e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first) {
5587e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator last = first; ++last;
5597e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (where == first || where == last) return; // No change
5607e70829632f82de15db187845666aaca6e04b792Chris Lattner    transfer(where, L2, first, last);
5617e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5627e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first, iterator last) {
5637e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first != last) transfer(where, L2, first, last);
5647e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5657e70829632f82de15db187845666aaca6e04b792Chris Lattner
5667e70829632f82de15db187845666aaca6e04b792Chris Lattner
5677e70829632f82de15db187845666aaca6e04b792Chris Lattner
5687e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5697e70829632f82de15db187845666aaca6e04b792Chris Lattner  // High-Level Functionality that shouldn't really be here, but is part of list
5707e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5717e70829632f82de15db187845666aaca6e04b792Chris Lattner
5727e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These two functions are actually called remove/remove_if in list<>, but
5737e70829632f82de15db187845666aaca6e04b792Chris Lattner  // they actually do the job of erase, rename them accordingly.
5747e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5757e70829632f82de15db187845666aaca6e04b792Chris Lattner  void erase(const NodeTy &val) {
5767e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
5777e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
5787e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (*I == val) erase(I);
5797e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5807e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5817e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5827e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr1> void erase_if(Pr1 pred) {
5837e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
5847e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
5857e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I)) erase(I);
5867e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5877e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5887e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5897e70829632f82de15db187845666aaca6e04b792Chris Lattner
5907e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr2> void unique(Pr2 pred) {
5917e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (empty()) return;
5927e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
5937e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I))
5947e70829632f82de15db187845666aaca6e04b792Chris Lattner        erase(Next);
5957e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5967e70829632f82de15db187845666aaca6e04b792Chris Lattner        I = Next;
5977e70829632f82de15db187845666aaca6e04b792Chris Lattner      Next = I;
5987e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5997e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6007e70829632f82de15db187845666aaca6e04b792Chris Lattner  void unique() { unique(op_equal); }
6017e70829632f82de15db187845666aaca6e04b792Chris Lattner
6027e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void merge(iplist &right, Pr3 pred) {
6037e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first1 = begin(), last1 = end();
6047e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first2 = right.begin(), last2 = right.end();
6057e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first1 != last1 && first2 != last2)
6067e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*first2, *first1)) {
6077e70829632f82de15db187845666aaca6e04b792Chris Lattner        iterator next = first2;
6087e70829632f82de15db187845666aaca6e04b792Chris Lattner        transfer(first1, right, first2, ++next);
6097e70829632f82de15db187845666aaca6e04b792Chris Lattner        first2 = next;
6107e70829632f82de15db187845666aaca6e04b792Chris Lattner      } else {
6117e70829632f82de15db187845666aaca6e04b792Chris Lattner        ++first1;
6127e70829632f82de15db187845666aaca6e04b792Chris Lattner      }
6137e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 != last2) transfer(last1, right, first2, last2);
6147e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6157e70829632f82de15db187845666aaca6e04b792Chris Lattner  void merge(iplist &right) { return merge(right, op_less); }
6167e70829632f82de15db187845666aaca6e04b792Chris Lattner
6177e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void sort(Pr3 pred);
6187e70829632f82de15db187845666aaca6e04b792Chris Lattner  void sort() { sort(op_less); }
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) {
648eb751d8c2da1a9b0d84139e19e20288d9b978451John McCall    return insert(where, this->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  void insert(iterator where, size_type count, const NodeTy &val) {
6577e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; count != 0; --count) insert(where, val);
6587e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6597e70829632f82de15db187845666aaca6e04b792Chris Lattner
6607e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Assign special forms...
6617e70829632f82de15db187845666aaca6e04b792Chris Lattner  void assign(size_type count, const NodeTy &val) {
66240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator I = this->begin();
66340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for (; I != this->end() && count != 0; ++I, --count)
6647e70829632f82de15db187845666aaca6e04b792Chris Lattner      *I = val;
6657e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (count != 0)
66640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), val, val);
6677e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
66840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(I, this->end());
6697e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
67040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  template<class InIt> void assign(InIt first1, InIt last1) {
67140c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator first2 = this->begin(), last2 = this->end();
6727e70829632f82de15db187845666aaca6e04b792Chris Lattner    for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
6737e70829632f82de15db187845666aaca6e04b792Chris Lattner      *first1 = *first2;
6747e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 == last2)
6757e70829632f82de15db187845666aaca6e04b792Chris Lattner      erase(first1, last1);
6767e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
6777e70829632f82de15db187845666aaca6e04b792Chris Lattner      insert(last1, first2, last2);
6787e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6797e70829632f82de15db187845666aaca6e04b792Chris Lattner
6807e70829632f82de15db187845666aaca6e04b792Chris Lattner
6817e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Resize members...
6827e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize, NodeTy val) {
68340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator i = this->begin();
6847e70829632f82de15db187845666aaca6e04b792Chris Lattner    size_type len = 0;
68540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
6867e70829632f82de15db187845666aaca6e04b792Chris Lattner
6877e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (len == newsize)
68840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(i, this->end());
6897e70829632f82de15db187845666aaca6e04b792Chris Lattner    else                                          // i == end()
69040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), newsize - len, val);
6917e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6927e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize) { resize(newsize, NodeTy()); }
6937e70829632f82de15db187845666aaca6e04b792Chris Lattner};
6947e70829632f82de15db187845666aaca6e04b792Chris Lattner
695d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
696d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
6977e70829632f82de15db187845666aaca6e04b792Chris Lattnernamespace std {
6987e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Ensure that swap uses the fast list swap...
6997e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Ty>
700d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
7017e70829632f82de15db187845666aaca6e04b792Chris Lattner    Left.swap(Right);
7027e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7037e70829632f82de15db187845666aaca6e04b792Chris Lattner}  // End 'std' extensions...
7047e70829632f82de15db187845666aaca6e04b792Chris Lattner
7051ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#endif // LLVM_ADT_ILIST_H
706