ilist.h revision cbe40cfe96a6bb3f2da56445269c2c71e55e0e56
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
237a39058aaed4540fc37681cad728b99546595b2e8David Blaikie// These are to catch errors when people try to use them as random access
238a39058aaed4540fc37681cad728b99546595b2e8David Blaikie// iterators.
23971be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
240a39058aaed4540fc37681cad728b99546595b2e8David Blaikievoid operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
24171be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
242a39058aaed4540fc37681cad728b99546595b2e8David Blaikievoid operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
24371be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
24471be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
245a39058aaed4540fc37681cad728b99546595b2e8David Blaikievoid operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
24671be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
247a39058aaed4540fc37681cad728b99546595b2e8David Blaikievoid operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
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
2777fe65d691dcce550d53ec9310913aab67ab6d654Rafael Espindola  static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
278011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
279011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
280011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
281011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
2827fe65d691dcce550d53ec9310913aab67ab6d654Rafael Espindola  typedef /*const*/ 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); }
385cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
386cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer    return Head == 0 || Head == getTail();
387cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer  }
3887e70829632f82de15db187845666aaca6e04b792Chris Lattner
3897e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back accessor functions...
3907e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference front() {
3917e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3927e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3937e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3947e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference front() const {
3957e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3967e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3977e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3987e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference back() {
3997e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
400c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    return *this->getPrev(getTail());
4017e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4027e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference back() const {
4037e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
404c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    return *this->getPrev(getTail());
4057e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4067e70829632f82de15db187845666aaca6e04b792Chris Lattner
4077e70829632f82de15db187845666aaca6e04b792Chris Lattner  void swap(iplist &RHS) {
408d68a07650cdb2e18f18f362ba533459aa10e01b6Dan Gohman    assert(0 && "Swap does not use list traits callback correctly yet!");
4097e70829632f82de15db187845666aaca6e04b792Chris Lattner    std::swap(Head, RHS.Head);
4107e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4117e70829632f82de15db187845666aaca6e04b792Chris Lattner
4127e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, NodeTy *New) {
413a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman    NodeTy *CurNode = where.getNodePtrUnchecked();
414a2769a33c94f021a609a462b28ebea069eba6f74Misha Brukman    NodeTy *PrevNode = this->getPrev(CurNode);
415c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setNext(New, CurNode);
416c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(New, PrevNode);
4177e70829632f82de15db187845666aaca6e04b792Chris Lattner
41847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (CurNode != Head)  // Is PrevNode off the beginning of the list?
419c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(PrevNode, New);
4207e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
4217e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = New;
422c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(CurNode, New);
4237e70829632f82de15db187845666aaca6e04b792Chris Lattner
424c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->addNodeToList(New);  // Notify traits that we added a node...
4257e70829632f82de15db187845666aaca6e04b792Chris Lattner    return New;
4267e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4277e70829632f82de15db187845666aaca6e04b792Chris Lattner
4283ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner  iterator insertAfter(iterator where, NodeTy *New) {
429085a9ebbc705c6e7d3fd8c692ef1c46fdfb885ceMisha Brukman    if (empty())
4303ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner      return insert(begin(), New);
4313ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner    else
4323ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner      return insert(++where, New);
4333ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner  }
4343ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner
4357e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(iterator &IT) {
4367e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(IT != end() && "Cannot remove end of list!");
4377e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *Node = &*IT;
438c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    NodeTy *NextNode = this->getNext(Node);
439c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    NodeTy *PrevNode = this->getPrev(Node);
4407e70829632f82de15db187845666aaca6e04b792Chris Lattner
44147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (Node != Head)  // Is PrevNode off the beginning of the list?
442c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(PrevNode, NextNode);
4437e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
4447e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = NextNode;
445c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(NextNode, PrevNode);
4467e70829632f82de15db187845666aaca6e04b792Chris Lattner    IT = NextNode;
4472b5326e7240ac524812016bc3700e12045bf0eb1Steve Naroff    this->removeNodeFromList(Node);  // Notify traits that we removed a node...
448e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman
4492896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // Set the next/prev pointers of the current node to null.  This isn't
4502896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // strictly required, but this catches errors where a node is removed from
4512896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // an ilist (and potentially deleted) with iterators still pointing at it.
4522896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // When those iterators are incremented or decremented, they will assert on
4532896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // the null next/prev pointer instead of "usually working".
454c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setNext(Node, 0);
455c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet    this->setPrev(Node, 0);
4567e70829632f82de15db187845666aaca6e04b792Chris Lattner    return Node;
4577e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4587e70829632f82de15db187845666aaca6e04b792Chris Lattner
4597e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(const iterator &IT) {
4607e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator MutIt = IT;
4617e70829632f82de15db187845666aaca6e04b792Chris Lattner    return remove(MutIt);
4627e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4637e70829632f82de15db187845666aaca6e04b792Chris Lattner
4647e70829632f82de15db187845666aaca6e04b792Chris Lattner  // erase - remove a node from the controlled sequence... and delete it.
4657e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator where) {
466c03c46a6af3d53172d48d9e4d36748a40c878cffDouglas Gregor    this->deleteNode(remove(where));
4677e70829632f82de15db187845666aaca6e04b792Chris Lattner    return where;
4687e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4697e70829632f82de15db187845666aaca6e04b792Chris Lattner
4707c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// Remove all nodes from the list like clear(), but do not call
4717c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// removeNodeFromList() or deleteNode().
4727c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  ///
4737c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// This should only be used immediately before freeing nodes in bulk to
4747c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  /// avoid traversing the list and bringing all the nodes into cache.
4757c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  void clearAndLeakNodesUnsafely() {
4767c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen    if (Head) {
4777c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen      Head = getTail();
4787c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen      this->setPrev(Head, Head);
4797c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen    }
4807c5c12bd4d60070c90161df9f6ae078c1f7b1ce5Jakob Stoklund Olesen  }
4817e70829632f82de15db187845666aaca6e04b792Chris Lattner
4827e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
4837e70829632f82de15db187845666aaca6e04b792Chris Lattner  // transfer - The heart of the splice function.  Move linked list nodes from
4847e70829632f82de15db187845666aaca6e04b792Chris Lattner  // [first, last) into position.
4857e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4867e70829632f82de15db187845666aaca6e04b792Chris Lattner  void transfer(iterator position, iplist &L2, iterator first, iterator last) {
4877e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(first != last && "Should be checked by callers");
4887f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen    // Position cannot be contained in the range to be transferred.
4897f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen    // Check for the most common mistake.
4907f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen    assert(position != first &&
4917f1d6d688f6ae288a16a4151e8a27b518d97f6f7Jakob Stoklund Olesen           "Insertion point can't be one of the transferred nodes");
49247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
4937e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (position != last) {
49447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // Note: we have to be careful about the case when we move the first node
49547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // in the list.  This node is the list sentinel node and we can't move it.
49647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *ThisSentinel = getTail();
49747e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(0);
49847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *L2Sentinel = L2.getTail();
49947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(0);
50047e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
5017e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Remove [first, last) from its old position.
50223e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *First = &*first, *Prev = this->getPrev(First);
50323e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
5047e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (Prev)
505c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(Prev, Next);
5067e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5077e70829632f82de15db187845666aaca6e04b792Chris Lattner        L2.Head = Next;
508c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(Next, Prev);
5097e70829632f82de15db187845666aaca6e04b792Chris Lattner
5107e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Splice [first, last) into its new position.
5117e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosNext = position.getNodePtrUnchecked();
51223e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      NodeTy *PosPrev = this->getPrev(PosNext);
5137e70829632f82de15db187845666aaca6e04b792Chris Lattner
5147e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix head of list...
5157e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (PosPrev)
516c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet        this->setNext(PosPrev, First);
5177e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5187e70829632f82de15db187845666aaca6e04b792Chris Lattner        Head = First;
519c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(First, PosPrev);
5207e70829632f82de15db187845666aaca6e04b792Chris Lattner
5217e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix end of list...
522c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setNext(Last, PosNext);
523c1edbfc2bac278ef050615f403c1bc74ef44cf14Cedric Venet      this->setPrev(PosNext, Last);
5247e70829632f82de15db187845666aaca6e04b792Chris Lattner
52523e1e727bd8c890ebe060e8f756085efb42697dcTorok Edwin      this->transferNodesFromList(L2, First, PosNext);
52647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
527e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman      // Now that everything is set, restore the pointers to the list sentinels.
52847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(L2Sentinel);
52947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(ThisSentinel);
5307e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5317e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5327e70829632f82de15db187845666aaca6e04b792Chris Lattner
5337e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
5347e70829632f82de15db187845666aaca6e04b792Chris Lattner
5357e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5367e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Functionality derived from other functions defined above...
5377e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5387e70829632f82de15db187845666aaca6e04b792Chris Lattner
539cbe40cfe96a6bb3f2da56445269c2c71e55e0e56Benjamin Kramer  size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const {
540e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman    if (Head == 0) return 0; // Don't require construction of sentinel if empty.
5416bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner    return std::distance(begin(), end());
5427e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5437e70829632f82de15db187845666aaca6e04b792Chris Lattner
5447e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator first, iterator last) {
5457e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first != last)
5467e70829632f82de15db187845666aaca6e04b792Chris Lattner      first = erase(first);
5477e70829632f82de15db187845666aaca6e04b792Chris Lattner    return last;
5487e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5497e70829632f82de15db187845666aaca6e04b792Chris Lattner
5506de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void clear() { if (Head) erase(begin(), end()); }
5517e70829632f82de15db187845666aaca6e04b792Chris Lattner
5527e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
5537e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_front(NodeTy *val) { insert(begin(), val); }
5547e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_back(NodeTy *val) { insert(end(), val); }
5557e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_front() {
5567e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_front() on empty list!");
5577e70829632f82de15db187845666aaca6e04b792Chris Lattner    erase(begin());
5587e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5597e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_back() {
5607e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_back() on empty list!");
5617e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator t = end(); erase(--t);
5627e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5637e70829632f82de15db187845666aaca6e04b792Chris Lattner
5647e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
5657e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
5667e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
5677e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5687e70829632f82de15db187845666aaca6e04b792Chris Lattner
5697e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Splice members - defined in terms of transfer...
5707e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2) {
5717e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!L2.empty())
5727e70829632f82de15db187845666aaca6e04b792Chris Lattner      transfer(where, L2, L2.begin(), L2.end());
5737e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5747e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first) {
5757e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator last = first; ++last;
5767e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (where == first || where == last) return; // No change
5777e70829632f82de15db187845666aaca6e04b792Chris Lattner    transfer(where, L2, first, last);
5787e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5797e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first, iterator last) {
5807e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first != last) transfer(where, L2, first, last);
5817e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5827e70829632f82de15db187845666aaca6e04b792Chris Lattner
5837e70829632f82de15db187845666aaca6e04b792Chris Lattner
5847e70829632f82de15db187845666aaca6e04b792Chris Lattner
5857e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
5867e70829632f82de15db187845666aaca6e04b792Chris Lattner  // High-Level Functionality that shouldn't really be here, but is part of list
5877e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5887e70829632f82de15db187845666aaca6e04b792Chris Lattner
5897e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These two functions are actually called remove/remove_if in list<>, but
5907e70829632f82de15db187845666aaca6e04b792Chris Lattner  // they actually do the job of erase, rename them accordingly.
5917e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5927e70829632f82de15db187845666aaca6e04b792Chris Lattner  void erase(const NodeTy &val) {
5937e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
5947e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
5957e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (*I == val) erase(I);
5967e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5977e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5987e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5997e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr1> void erase_if(Pr1 pred) {
6007e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
6017e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
6027e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I)) erase(I);
6037e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
6047e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
6057e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6067e70829632f82de15db187845666aaca6e04b792Chris Lattner
6077e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr2> void unique(Pr2 pred) {
6087e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (empty()) return;
6097e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
6107e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I))
6117e70829632f82de15db187845666aaca6e04b792Chris Lattner        erase(Next);
6127e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
6137e70829632f82de15db187845666aaca6e04b792Chris Lattner        I = Next;
6147e70829632f82de15db187845666aaca6e04b792Chris Lattner      Next = I;
6157e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
6167e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6177e70829632f82de15db187845666aaca6e04b792Chris Lattner  void unique() { unique(op_equal); }
6187e70829632f82de15db187845666aaca6e04b792Chris Lattner
6197e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void merge(iplist &right, Pr3 pred) {
6207e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first1 = begin(), last1 = end();
6217e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first2 = right.begin(), last2 = right.end();
6227e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first1 != last1 && first2 != last2)
6237e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*first2, *first1)) {
6247e70829632f82de15db187845666aaca6e04b792Chris Lattner        iterator next = first2;
6257e70829632f82de15db187845666aaca6e04b792Chris Lattner        transfer(first1, right, first2, ++next);
6267e70829632f82de15db187845666aaca6e04b792Chris Lattner        first2 = next;
6277e70829632f82de15db187845666aaca6e04b792Chris Lattner      } else {
6287e70829632f82de15db187845666aaca6e04b792Chris Lattner        ++first1;
6297e70829632f82de15db187845666aaca6e04b792Chris Lattner      }
6307e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 != last2) transfer(last1, right, first2, last2);
6317e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6327e70829632f82de15db187845666aaca6e04b792Chris Lattner  void merge(iplist &right) { return merge(right, op_less); }
6337e70829632f82de15db187845666aaca6e04b792Chris Lattner
6347e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void sort(Pr3 pred);
6357e70829632f82de15db187845666aaca6e04b792Chris Lattner  void sort() { sort(op_less); }
6367e70829632f82de15db187845666aaca6e04b792Chris Lattner};
6377e70829632f82de15db187845666aaca6e04b792Chris Lattner
6387e70829632f82de15db187845666aaca6e04b792Chris Lattner
6397e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
6407e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist : public iplist<NodeTy> {
641a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::size_type size_type;
642a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::iterator iterator;
643a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
6447e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist() {}
6457e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(const ilist &right) {
64640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), right.begin(), right.end());
6477e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6487e70829632f82de15db187845666aaca6e04b792Chris Lattner  explicit ilist(size_type count) {
64940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, NodeTy());
650e21a6bae806d13e644a92b3df23e4d5b78bdb75cMisha Brukman  }
6517e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(size_type count, const NodeTy &val) {
65240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, val);
6537e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6547e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> ilist(InIt first, InIt last) {
65540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), first, last);
6567e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6577e70829632f82de15db187845666aaca6e04b792Chris Lattner
65883b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  // bring hidden functions into scope
65983b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::insert;
66083b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::push_front;
66183b5752747ea14696b0e51904722c38771f22eb7Gabor Greif  using iplist<NodeTy>::push_back;
6627e70829632f82de15db187845666aaca6e04b792Chris Lattner
6637e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Main implementation here - Insert for a node passed by value...
6647e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, const NodeTy &val) {
665eb751d8c2da1a9b0d84139e19e20288d9b978451John McCall    return insert(where, this->createNode(val));
6667e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6677e70829632f82de15db187845666aaca6e04b792Chris Lattner
6687e70829632f82de15db187845666aaca6e04b792Chris Lattner
6697e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
67040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_front(const NodeTy &val) { insert(this->begin(), val); }
67140c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_back(const NodeTy &val) { insert(this->end(), val); }
6727e70829632f82de15db187845666aaca6e04b792Chris Lattner
6737e70829632f82de15db187845666aaca6e04b792Chris Lattner  void insert(iterator where, size_type count, const NodeTy &val) {
6747e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; count != 0; --count) insert(where, val);
6757e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6767e70829632f82de15db187845666aaca6e04b792Chris Lattner
6777e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Assign special forms...
6787e70829632f82de15db187845666aaca6e04b792Chris Lattner  void assign(size_type count, const NodeTy &val) {
67940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator I = this->begin();
68040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for (; I != this->end() && count != 0; ++I, --count)
6817e70829632f82de15db187845666aaca6e04b792Chris Lattner      *I = val;
6827e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (count != 0)
68340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), val, val);
6847e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
68540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(I, this->end());
6867e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
68740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  template<class InIt> void assign(InIt first1, InIt last1) {
68840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator first2 = this->begin(), last2 = this->end();
6897e70829632f82de15db187845666aaca6e04b792Chris Lattner    for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
6907e70829632f82de15db187845666aaca6e04b792Chris Lattner      *first1 = *first2;
6917e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 == last2)
6927e70829632f82de15db187845666aaca6e04b792Chris Lattner      erase(first1, last1);
6937e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
6947e70829632f82de15db187845666aaca6e04b792Chris Lattner      insert(last1, first2, last2);
6957e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6967e70829632f82de15db187845666aaca6e04b792Chris Lattner
6977e70829632f82de15db187845666aaca6e04b792Chris Lattner
6987e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Resize members...
6997e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize, NodeTy val) {
70040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator i = this->begin();
7017e70829632f82de15db187845666aaca6e04b792Chris Lattner    size_type len = 0;
70240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
7037e70829632f82de15db187845666aaca6e04b792Chris Lattner
7047e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (len == newsize)
70540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(i, this->end());
7067e70829632f82de15db187845666aaca6e04b792Chris Lattner    else                                          // i == end()
70740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), newsize - len, val);
7087e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7097e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize) { resize(newsize, NodeTy()); }
7107e70829632f82de15db187845666aaca6e04b792Chris Lattner};
7117e70829632f82de15db187845666aaca6e04b792Chris Lattner
712d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
713d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
7147e70829632f82de15db187845666aaca6e04b792Chris Lattnernamespace std {
7157e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Ensure that swap uses the fast list swap...
7167e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Ty>
717d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
7187e70829632f82de15db187845666aaca6e04b792Chris Lattner    Left.swap(Right);
7197e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
7207e70829632f82de15db187845666aaca6e04b792Chris Lattner}  // End 'std' extensions...
7217e70829632f82de15db187845666aaca6e04b792Chris Lattner
7221ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#endif // LLVM_ADT_ILIST_H
723