ilist.h revision 1ff4ed726bb8526d1e49030245365f8c86a8bb49
143d1fd449f1a0ac9d9dafa0b9569bb6b2e976198Anton Korobeynikov//==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==//
2b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
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.
7b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
97e70829632f82de15db187845666aaca6e04b792Chris Lattner//
107e70829632f82de15db187845666aaca6e04b792Chris Lattner// This file defines classes to implement an intrusive doubly linked list class
1147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner// (i.e. each node of the list must contain a next and previous field for the
127e70829632f82de15db187845666aaca6e04b792Chris Lattner// list.
137e70829632f82de15db187845666aaca6e04b792Chris Lattner//
147e70829632f82de15db187845666aaca6e04b792Chris Lattner// The ilist_traits trait class is used to gain access to the next and previous
157e70829632f82de15db187845666aaca6e04b792Chris Lattner// fields of the node type that the list is instantiated with.  If it is not
167e70829632f82de15db187845666aaca6e04b792Chris Lattner// specialized, the list defaults to using the getPrev(), getNext() method calls
177e70829632f82de15db187845666aaca6e04b792Chris Lattner// to get the next and previous pointers.
187e70829632f82de15db187845666aaca6e04b792Chris Lattner//
197e70829632f82de15db187845666aaca6e04b792Chris Lattner// The ilist class itself, should be a plug in replacement for list, assuming
207e70829632f82de15db187845666aaca6e04b792Chris Lattner// that the nodes contain next/prev pointers.  This list replacement does not
21094aa6ce47f0f0604469e0a24bde131ce6326938Nick Lewycky// provide a constant time size() method, so be careful to use empty() when you
22a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner// really want to know if it's empty.
237e70829632f82de15db187845666aaca6e04b792Chris Lattner//
247e70829632f82de15db187845666aaca6e04b792Chris Lattner// The ilist class is implemented by allocating a 'tail' node when the list is
2547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner// created (using ilist_traits<>::createSentinel()).  This tail node is
267e70829632f82de15db187845666aaca6e04b792Chris Lattner// absolutely required because the user must be able to compute end()-1. Because
277e70829632f82de15db187845666aaca6e04b792Chris Lattner// of this, users of the direct next/prev links will see an extra link on the
287e70829632f82de15db187845666aaca6e04b792Chris Lattner// end of the list, which should be ignored.
297e70829632f82de15db187845666aaca6e04b792Chris Lattner//
307e70829632f82de15db187845666aaca6e04b792Chris Lattner// Requirements for a user of this list:
317e70829632f82de15db187845666aaca6e04b792Chris Lattner//
327e70829632f82de15db187845666aaca6e04b792Chris Lattner//   1. The user must provide {g|s}et{Next|Prev} methods, or specialize
337e70829632f82de15db187845666aaca6e04b792Chris Lattner//      ilist_traits to provide an alternate way of getting and setting next and
347e70829632f82de15db187845666aaca6e04b792Chris Lattner//      prev links.
357e70829632f82de15db187845666aaca6e04b792Chris Lattner//
367e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
377e70829632f82de15db187845666aaca6e04b792Chris Lattner
381ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#ifndef LLVM_ADT_ILIST_H
391ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#define LLVM_ADT_ILIST_H
407e70829632f82de15db187845666aaca6e04b792Chris Lattner
4143d1fd449f1a0ac9d9dafa0b9569bb6b2e976198Anton Korobeynikov#include "llvm/ADT/iterator.h"
42803f03e217ec25cf71b2b6dea65da2e377527b6bChris Lattner#include <cassert>
43ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstdlib>
447e70829632f82de15db187845666aaca6e04b792Chris Lattner
45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
46d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
477e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits> class iplist;
487e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy> class ilist_iterator;
497e70829632f82de15db187845666aaca6e04b792Chris Lattner
507e70829632f82de15db187845666aaca6e04b792Chris Lattner// Template traits for intrusive list.  By specializing this template class, you
517e70829632f82de15db187845666aaca6e04b792Chris Lattner// can change what next/prev fields are used to store the links...
527e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
537e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist_traits {
547e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
557e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
567e70829632f82de15db187845666aaca6e04b792Chris Lattner  static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
577e70829632f82de15db187845666aaca6e04b792Chris Lattner  static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
587e70829632f82de15db187845666aaca6e04b792Chris Lattner
597e70829632f82de15db187845666aaca6e04b792Chris Lattner  static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
607e70829632f82de15db187845666aaca6e04b792Chris Lattner  static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
617e70829632f82de15db187845666aaca6e04b792Chris Lattner
627e70829632f82de15db187845666aaca6e04b792Chris Lattner  static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
637e70829632f82de15db187845666aaca6e04b792Chris Lattner
64bca81448ac8e19c588c9a4ad16fc70732b76327cChris Lattner  static NodeTy *createSentinel() { return new NodeTy(); }
65bca81448ac8e19c588c9a4ad16fc70732b76327cChris Lattner  static void destroySentinel(NodeTy *N) { delete N; }
667e70829632f82de15db187845666aaca6e04b792Chris Lattner
677e70829632f82de15db187845666aaca6e04b792Chris Lattner  void addNodeToList(NodeTy *NTy) {}
687e70829632f82de15db187845666aaca6e04b792Chris Lattner  void removeNodeFromList(NodeTy *NTy) {}
697e70829632f82de15db187845666aaca6e04b792Chris Lattner  void transferNodesFromList(iplist<NodeTy, ilist_traits> &L2,
707e70829632f82de15db187845666aaca6e04b792Chris Lattner                             ilist_iterator<NodeTy> first,
717e70829632f82de15db187845666aaca6e04b792Chris Lattner                             ilist_iterator<NodeTy> last) {}
727e70829632f82de15db187845666aaca6e04b792Chris Lattner};
737e70829632f82de15db187845666aaca6e04b792Chris Lattner
747e70829632f82de15db187845666aaca6e04b792Chris Lattner// Const traits are the same as nonconst traits...
757e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename Ty>
767e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist_traits<const Ty> : public ilist_traits<Ty> {};
777e70829632f82de15db187845666aaca6e04b792Chris Lattner
787e70829632f82de15db187845666aaca6e04b792Chris Lattner
797e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
807e70829632f82de15db187845666aaca6e04b792Chris Lattner// ilist_iterator<Node> - Iterator for intrusive list.
817e70829632f82de15db187845666aaca6e04b792Chris Lattner//
827e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
83a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattnerclass ilist_iterator
840d219edad2fd5e7b400ecd49ac833a7a3199af60Chris Lattner  : public bidirectional_iterator<NodeTy, ptrdiff_t> {
857e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_traits<NodeTy> Traits;
860d219edad2fd5e7b400ecd49ac833a7a3199af60Chris Lattner  typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
87a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
8832862da7c7107d792d25a885f9bd2d0402ae7126Chris Lattnerpublic:
8932862da7c7107d792d25a885f9bd2d0402ae7126Chris Lattner  typedef size_t size_type;
90a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::pointer pointer;
91a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename super::reference reference;
9232862da7c7107d792d25a885f9bd2d0402ae7126Chris Lattnerprivate:
937e70829632f82de15db187845666aaca6e04b792Chris Lattner  pointer NodePtr;
947e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
957e70829632f82de15db187845666aaca6e04b792Chris Lattner
967e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(pointer NP) : NodePtr(NP) {}
9733adbcc87d92c6c3e620870c804f4a2533ecc850Vikram S. Adve  ilist_iterator(reference NR) : NodePtr(&NR) {}
987e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator() : NodePtr(0) {}
997e70829632f82de15db187845666aaca6e04b792Chris Lattner
1007e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow constructing a const iterator from
1017e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
1027e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class node_ty>
1037e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator(const ilist_iterator<node_ty> &RHS)
1047e70829632f82de15db187845666aaca6e04b792Chris Lattner    : NodePtr(RHS.getNodePtrUnchecked()) {}
1057e70829632f82de15db187845666aaca6e04b792Chris Lattner
1067e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is templated so that we can allow assigning to a const iterator from
1077e70829632f82de15db187845666aaca6e04b792Chris Lattner  // a nonconst iterator...
1087e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class node_ty>
1097e70829632f82de15db187845666aaca6e04b792Chris Lattner  const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
1107e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = RHS.getNodePtrUnchecked();
1117e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
1127e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1137e70829632f82de15db187845666aaca6e04b792Chris Lattner
1147e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Accessors...
1157e70829632f82de15db187845666aaca6e04b792Chris Lattner  operator pointer() const {
1167e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
1177e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr;
1187e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1197e70829632f82de15db187845666aaca6e04b792Chris Lattner
1207e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference operator*() const {
1217e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
1227e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *NodePtr;
1237e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1247e70829632f82de15db187845666aaca6e04b792Chris Lattner  pointer operator->() { return &operator*(); }
1257e70829632f82de15db187845666aaca6e04b792Chris Lattner  const pointer operator->() const { return &operator*(); }
1267e70829632f82de15db187845666aaca6e04b792Chris Lattner
1277e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Comparison operators
1287e70829632f82de15db187845666aaca6e04b792Chris Lattner  bool operator==(const ilist_iterator &RHS) const {
1297e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr == RHS.NodePtr;
1307e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1317e70829632f82de15db187845666aaca6e04b792Chris Lattner  bool operator!=(const ilist_iterator &RHS) const {
1327e70829632f82de15db187845666aaca6e04b792Chris Lattner    return NodePtr != RHS.NodePtr;
1337e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1347e70829632f82de15db187845666aaca6e04b792Chris Lattner
1357e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Increment and decrement operators...
1367e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator &operator--() {      // predecrement - Back up
1377e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getPrev(NodePtr);
13847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    assert(Traits::getNext(NodePtr) && "--'d off the beginning of an ilist!");
1397e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
1407e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1417e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator &operator++() {      // preincrement - Advance
1427e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodePtr = Traits::getNext(NodePtr);
1437e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(NodePtr && "++'d off the end of an ilist!");
1447e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *this;
1457e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1467e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator operator--(int) {    // postdecrement operators...
1477e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
1487e70829632f82de15db187845666aaca6e04b792Chris Lattner    --*this;
1497e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
1507e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1517e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist_iterator operator++(int) {    // postincrement operators...
1527e70829632f82de15db187845666aaca6e04b792Chris Lattner    ilist_iterator tmp = *this;
1537e70829632f82de15db187845666aaca6e04b792Chris Lattner    ++*this;
1547e70829632f82de15db187845666aaca6e04b792Chris Lattner    return tmp;
1557e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1567e70829632f82de15db187845666aaca6e04b792Chris Lattner
1572cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Internal interface, do not use...
1582cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  pointer getNodePtrUnchecked() const { return NodePtr; }
1592cca3008e86aa5448a629c744064daecb531bf94Chris Lattner};
1602cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
16171be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos// do not implement. this is to catch errors when people try to use
16271be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos// them as random access iterators
16371be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
16471be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator-(int, ilist_iterator<T>);
16571be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
16671be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator-(ilist_iterator<T>,int);
16771be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
16871be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
16971be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator+(int, ilist_iterator<T>);
17071be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenostemplate<typename T>
17171be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenosvoid operator+(ilist_iterator<T>,int);
17271be6db3efd233ae7eafe3e23ad9d9ac70bf0706Alkis Evlogimenos
173cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman// operator!=/operator== - Allow mixed comparisons without dereferencing
174cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman// the iterator, which could very likely be pointing to end().
175cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
176cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
177cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS != RHS.getNodePtrUnchecked();
178cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
179cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
180cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
181cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS == RHS.getNodePtrUnchecked();
182cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
183cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
184cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
185cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS != RHS.getNodePtrUnchecked();
186cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
187cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemantemplate<typename T>
188cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begemanbool operator==(T* LHS, const ilist_iterator<T> &RHS) {
189cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman  return LHS == RHS.getNodePtrUnchecked();
190cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman}
191cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman
192cb647519d34184fe41aa7e072076ae70634bc3d7Nate Begeman
193011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// Allow ilist_iterators to convert into pointers to a node automatically when
194011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner// used by the dyn_cast, cast, isa mechanisms...
195011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
196011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename From> struct simplify_type;
197011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
198011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
199011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
200011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
201011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
202011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
203011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
204011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
205011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattnertemplate<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
206011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  typedef NodeTy* SimpleType;
207011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
208011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
209011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner    return &*Node;
210011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner  }
211011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner};
212011ce8d2e401855877803fb6d972a6f6c22242a5Chris Lattner
2137e70829632f82de15db187845666aaca6e04b792Chris Lattner
2147e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
2157e70829632f82de15db187845666aaca6e04b792Chris Lattner//
2166de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// iplist - The subset of list functionality that can safely be used on nodes
2176de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// of polymorphic types, i.e. a heterogenous list with a common base class that
2186de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// holds the next/prev pointers.  The only state of the list itself is a single
2196de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// pointer to the head of the list.
2206de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
2216de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// This list can be in one of three interesting states:
2226de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 1. The list may be completely unconstructed.  In this case, the head
2236de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    pointer is null.  When in this form, any query for an iterator (e.g.
2246de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    begin() or end()) causes the list to transparently change to state #2.
2256de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 2. The list may be empty, but contain a sentinal for the end iterator. This
2266de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    sentinal is created by the Traits::createSentinel method and is a link
2276de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    in the list.  When the list is empty, the pointer in the iplist points
2286de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    to the sentinal.  Once the sentinal is constructed, it
2296de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    is not destroyed until the list is.
2306de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner/// 3. The list may contain actual objects in it, which are stored as a doubly
2316de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    linked list of nodes.  One invariant of the list is that the predecessor
2326de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    of the first node in the list always points to the last node in the list,
2336de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    and the successor pointer for the sentinal (which always stays at the
2346de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///    end of the list) is always null.
2356de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner///
2367e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
2377e70829632f82de15db187845666aaca6e04b792Chris Lattnerclass iplist : public Traits {
2386de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  mutable NodeTy *Head;
23947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
24047e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // Use the prev node pointer of 'head' as the tail pointer.  This is really a
24147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // circularly linked list where we snip the 'next' link from the sentinel node
24247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // back to the first node in the list (to preserve assertions about going off
24347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  // the end of the list).
24447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  NodeTy *getTail() { return getPrev(Head); }
24547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner  const NodeTy *getTail() const { return getPrev(Head); }
2466de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void setTail(NodeTy *N) const { setPrev(Head, N); }
2476de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner
2486de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  /// CreateLazySentinal - This method verifies whether the sentinal for the
2496de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  /// list has been created and lazily makes it if not.
2506de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void CreateLazySentinal() const {
2516de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    if (Head != 0) return;
2526de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    Head = Traits::createSentinel();
2536de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    setNext(Head, 0);
2546de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    setTail(Head);
2556de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
2567e70829632f82de15db187845666aaca6e04b792Chris Lattner
2577e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
2587e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
2597e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
2607e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy *pointer;
2617e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy *const_pointer;
2627e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy &reference;
2637e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const NodeTy &const_reference;
2647e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef NodeTy value_type;
2657e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<NodeTy> iterator;
2667e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ilist_iterator<const NodeTy> const_iterator;
2677e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef size_t size_type;
2687e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef ptrdiff_t difference_type;
2694a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
2704a9f9337511441af0624e754ad9b2b1262ee584dAnand Shukla  typedef std::reverse_iterator<iterator>  reverse_iterator;
2717e70829632f82de15db187845666aaca6e04b792Chris Lattner
2726de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iplist() : Head(0) {}
2736de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  ~iplist() {
2746de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    if (!Head) return;
2756de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    clear();
2766de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    Traits::destroySentinel(getTail());
2777e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
2787e70829632f82de15db187845666aaca6e04b792Chris Lattner
2792cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Iterator creation methods.
2806de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator begin() {
2816de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    CreateLazySentinal();
2826de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return iterator(Head);
2836de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
2846de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator begin() const {
2856de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    CreateLazySentinal();
2866de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(Head);
2876de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
2886de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  iterator end() {
2896de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    CreateLazySentinal();
2906de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return iterator(getTail());
2916de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
2926de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_iterator end() const {
2936de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    CreateLazySentinal();
2946de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    return const_iterator(getTail());
2956de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  }
2967e70829632f82de15db187845666aaca6e04b792Chris Lattner
2972cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // reverse iterator creation methods.
2987e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rbegin()            { return reverse_iterator(end()); }
2997e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
3007e70829632f82de15db187845666aaca6e04b792Chris Lattner  reverse_iterator rend()              { return reverse_iterator(begin()); }
3016de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
3027e70829632f82de15db187845666aaca6e04b792Chris Lattner
3032cca3008e86aa5448a629c744064daecb531bf94Chris Lattner
3042cca3008e86aa5448a629c744064daecb531bf94Chris Lattner  // Miscellaneous inspection routines.
3057e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type max_size() const { return size_type(-1); }
3066de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  bool empty() const { return Head == 0 || Head == getTail(); }
3077e70829632f82de15db187845666aaca6e04b792Chris Lattner
3087e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back accessor functions...
3097e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference front() {
3107e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3117e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3127e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3137e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference front() const {
3147e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called front() on empty list!");
3157e70829632f82de15db187845666aaca6e04b792Chris Lattner    return *Head;
3167e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3177e70829632f82de15db187845666aaca6e04b792Chris Lattner  reference back() {
3187e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
31947e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    return *getPrev(getTail());
3207e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3217e70829632f82de15db187845666aaca6e04b792Chris Lattner  const_reference back() const {
3227e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "Called back() on empty list!");
32347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    return *getPrev(getTail());
3247e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3257e70829632f82de15db187845666aaca6e04b792Chris Lattner
3267e70829632f82de15db187845666aaca6e04b792Chris Lattner  void swap(iplist &RHS) {
3277e70829632f82de15db187845666aaca6e04b792Chris Lattner    abort();     // Swap does not use list traits callback correctly yet!
3287e70829632f82de15db187845666aaca6e04b792Chris Lattner    std::swap(Head, RHS.Head);
3297e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3307e70829632f82de15db187845666aaca6e04b792Chris Lattner
3317e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, NodeTy *New) {
3327e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *CurNode = where.getNodePtrUnchecked(), *PrevNode = getPrev(CurNode);
3337e70829632f82de15db187845666aaca6e04b792Chris Lattner    setNext(New, CurNode);
3347e70829632f82de15db187845666aaca6e04b792Chris Lattner    setPrev(New, PrevNode);
3357e70829632f82de15db187845666aaca6e04b792Chris Lattner
33647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (CurNode != Head)  // Is PrevNode off the beginning of the list?
3377e70829632f82de15db187845666aaca6e04b792Chris Lattner      setNext(PrevNode, New);
3387e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
3397e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = New;
3407e70829632f82de15db187845666aaca6e04b792Chris Lattner    setPrev(CurNode, New);
3417e70829632f82de15db187845666aaca6e04b792Chris Lattner
3427e70829632f82de15db187845666aaca6e04b792Chris Lattner    addNodeToList(New);  // Notify traits that we added a node...
3437e70829632f82de15db187845666aaca6e04b792Chris Lattner    return New;
3447e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3457e70829632f82de15db187845666aaca6e04b792Chris Lattner
3467e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(iterator &IT) {
3477e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(IT != end() && "Cannot remove end of list!");
3487e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *Node = &*IT;
3497e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *NextNode = getNext(Node);
3507e70829632f82de15db187845666aaca6e04b792Chris Lattner    NodeTy *PrevNode = getPrev(Node);
3517e70829632f82de15db187845666aaca6e04b792Chris Lattner
35247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner    if (Node != Head)  // Is PrevNode off the beginning of the list?
3537e70829632f82de15db187845666aaca6e04b792Chris Lattner      setNext(PrevNode, NextNode);
3547e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
3557e70829632f82de15db187845666aaca6e04b792Chris Lattner      Head = NextNode;
3567e70829632f82de15db187845666aaca6e04b792Chris Lattner    setPrev(NextNode, PrevNode);
3577e70829632f82de15db187845666aaca6e04b792Chris Lattner    IT = NextNode;
358825b02d5ee74031ca8f872a761a79b137225f818Chris Lattner    removeNodeFromList(Node);  // Notify traits that we removed a node...
3592896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner
3602896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // Set the next/prev pointers of the current node to null.  This isn't
3612896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // strictly required, but this catches errors where a node is removed from
3622896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // an ilist (and potentially deleted) with iterators still pointing at it.
3632896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // When those iterators are incremented or decremented, they will assert on
3642896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    // the null next/prev pointer instead of "usually working".
3652896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    setNext(Node, 0);
3662896652be29de97a6e08b5cccc015096f4ed17b5Chris Lattner    setPrev(Node, 0);
3677e70829632f82de15db187845666aaca6e04b792Chris Lattner    return Node;
3687e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3697e70829632f82de15db187845666aaca6e04b792Chris Lattner
3707e70829632f82de15db187845666aaca6e04b792Chris Lattner  NodeTy *remove(const iterator &IT) {
3717e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator MutIt = IT;
3727e70829632f82de15db187845666aaca6e04b792Chris Lattner    return remove(MutIt);
3737e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3747e70829632f82de15db187845666aaca6e04b792Chris Lattner
3757e70829632f82de15db187845666aaca6e04b792Chris Lattner  // erase - remove a node from the controlled sequence... and delete it.
3767e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator where) {
3777e70829632f82de15db187845666aaca6e04b792Chris Lattner    delete remove(where);
3787e70829632f82de15db187845666aaca6e04b792Chris Lattner    return where;
3797e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
3807e70829632f82de15db187845666aaca6e04b792Chris Lattner
3817e70829632f82de15db187845666aaca6e04b792Chris Lattner
3827e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
3837e70829632f82de15db187845666aaca6e04b792Chris Lattner  // transfer - The heart of the splice function.  Move linked list nodes from
3847e70829632f82de15db187845666aaca6e04b792Chris Lattner  // [first, last) into position.
3857e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
3867e70829632f82de15db187845666aaca6e04b792Chris Lattner  void transfer(iterator position, iplist &L2, iterator first, iterator last) {
3877e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(first != last && "Should be checked by callers");
38847e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
3897e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (position != last) {
39047e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // Note: we have to be careful about the case when we move the first node
39147e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // in the list.  This node is the list sentinel node and we can't move it.
39247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *ThisSentinel = getTail();
39347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(0);
39447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      NodeTy *L2Sentinel = L2.getTail();
39547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(0);
39647e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
3977e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Remove [first, last) from its old position.
3987e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *First = &*first, *Prev = getPrev(First);
3997e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
4007e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (Prev)
4017e70829632f82de15db187845666aaca6e04b792Chris Lattner        setNext(Prev, Next);
4027e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
4037e70829632f82de15db187845666aaca6e04b792Chris Lattner        L2.Head = Next;
4047e70829632f82de15db187845666aaca6e04b792Chris Lattner      setPrev(Next, Prev);
4057e70829632f82de15db187845666aaca6e04b792Chris Lattner
4067e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Splice [first, last) into its new position.
4077e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosNext = position.getNodePtrUnchecked();
4087e70829632f82de15db187845666aaca6e04b792Chris Lattner      NodeTy *PosPrev = getPrev(PosNext);
4097e70829632f82de15db187845666aaca6e04b792Chris Lattner
4107e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix head of list...
4117e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (PosPrev)
4127e70829632f82de15db187845666aaca6e04b792Chris Lattner        setNext(PosPrev, First);
4137e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
4147e70829632f82de15db187845666aaca6e04b792Chris Lattner        Head = First;
4157e70829632f82de15db187845666aaca6e04b792Chris Lattner      setPrev(First, PosPrev);
4167e70829632f82de15db187845666aaca6e04b792Chris Lattner
4177e70829632f82de15db187845666aaca6e04b792Chris Lattner      // Fix end of list...
4187e70829632f82de15db187845666aaca6e04b792Chris Lattner      setNext(Last, PosNext);
4197e70829632f82de15db187845666aaca6e04b792Chris Lattner      setPrev(PosNext, Last);
4207e70829632f82de15db187845666aaca6e04b792Chris Lattner
4217e70829632f82de15db187845666aaca6e04b792Chris Lattner      transferNodesFromList(L2, First, PosNext);
42247e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner
42347e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      // Now that everything is set, restore the pointers to the list sentinals.
42447e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      L2.setTail(L2Sentinel);
42547e756c11edbaa9a4916687eceaa4ec94c0aae3bChris Lattner      setTail(ThisSentinel);
4267e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
4277e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4287e70829632f82de15db187845666aaca6e04b792Chris Lattner
4297e70829632f82de15db187845666aaca6e04b792Chris Lattnerpublic:
4307e70829632f82de15db187845666aaca6e04b792Chris Lattner
4317e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
4327e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Functionality derived from other functions defined above...
4337e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4347e70829632f82de15db187845666aaca6e04b792Chris Lattner
4357e70829632f82de15db187845666aaca6e04b792Chris Lattner  size_type size() const {
4366de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner    if (Head == 0) return 0; // Don't require construction of sentinal if empty.
4376bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner#if __GNUC__ == 2
4386bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner    // GCC 2.95 has a broken std::distance
4397e70829632f82de15db187845666aaca6e04b792Chris Lattner    size_type Result = 0;
4407e70829632f82de15db187845666aaca6e04b792Chris Lattner    std::distance(begin(), end(), Result);
4417e70829632f82de15db187845666aaca6e04b792Chris Lattner    return Result;
4426bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner#else
4436bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner    return std::distance(begin(), end());
4446bf7ca5f6f1c26bf8fb579ba456dae7c6e6f7e3aChris Lattner#endif
4457e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4467e70829632f82de15db187845666aaca6e04b792Chris Lattner
4477e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator erase(iterator first, iterator last) {
4487e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first != last)
4497e70829632f82de15db187845666aaca6e04b792Chris Lattner      first = erase(first);
4507e70829632f82de15db187845666aaca6e04b792Chris Lattner    return last;
4517e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4527e70829632f82de15db187845666aaca6e04b792Chris Lattner
4536de84985a434bfd6e55323ad5cd9959d15aa554aChris Lattner  void clear() { if (Head) erase(begin(), end()); }
4547e70829632f82de15db187845666aaca6e04b792Chris Lattner
4557e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
4567e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_front(NodeTy *val) { insert(begin(), val); }
4577e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_back(NodeTy *val) { insert(end(), val); }
4587e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_front() {
4597e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_front() on empty list!");
4607e70829632f82de15db187845666aaca6e04b792Chris Lattner    erase(begin());
4617e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4627e70829632f82de15db187845666aaca6e04b792Chris Lattner  void pop_back() {
4637e70829632f82de15db187845666aaca6e04b792Chris Lattner    assert(!empty() && "pop_back() on empty list!");
4647e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator t = end(); erase(--t);
4657e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4667e70829632f82de15db187845666aaca6e04b792Chris Lattner
4677e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
4687e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
4697e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
4707e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4717e70829632f82de15db187845666aaca6e04b792Chris Lattner
4727e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Splice members - defined in terms of transfer...
4737e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2) {
4747e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (!L2.empty())
4757e70829632f82de15db187845666aaca6e04b792Chris Lattner      transfer(where, L2, L2.begin(), L2.end());
4767e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4777e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first) {
4787e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator last = first; ++last;
4797e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (where == first || where == last) return; // No change
4807e70829632f82de15db187845666aaca6e04b792Chris Lattner    transfer(where, L2, first, last);
4817e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4827e70829632f82de15db187845666aaca6e04b792Chris Lattner  void splice(iterator where, iplist &L2, iterator first, iterator last) {
4837e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first != last) transfer(where, L2, first, last);
4847e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
4857e70829632f82de15db187845666aaca6e04b792Chris Lattner
4867e70829632f82de15db187845666aaca6e04b792Chris Lattner
4877e70829632f82de15db187845666aaca6e04b792Chris Lattner
4887e70829632f82de15db187845666aaca6e04b792Chris Lattner  //===----------------------------------------------------------------------===
4897e70829632f82de15db187845666aaca6e04b792Chris Lattner  // High-Level Functionality that shouldn't really be here, but is part of list
4907e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4917e70829632f82de15db187845666aaca6e04b792Chris Lattner
4927e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These two functions are actually called remove/remove_if in list<>, but
4937e70829632f82de15db187845666aaca6e04b792Chris Lattner  // they actually do the job of erase, rename them accordingly.
4947e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
4957e70829632f82de15db187845666aaca6e04b792Chris Lattner  void erase(const NodeTy &val) {
4967e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
4977e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
4987e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (*I == val) erase(I);
4997e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5007e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5017e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5027e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr1> void erase_if(Pr1 pred) {
5037e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(); I != E; ) {
5047e70829632f82de15db187845666aaca6e04b792Chris Lattner      iterator next = I; ++next;
5057e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I)) erase(I);
5067e70829632f82de15db187845666aaca6e04b792Chris Lattner      I = next;
5077e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5087e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5097e70829632f82de15db187845666aaca6e04b792Chris Lattner
5107e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr2> void unique(Pr2 pred) {
5117e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (empty()) return;
5127e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
5137e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*I))
5147e70829632f82de15db187845666aaca6e04b792Chris Lattner        erase(Next);
5157e70829632f82de15db187845666aaca6e04b792Chris Lattner      else
5167e70829632f82de15db187845666aaca6e04b792Chris Lattner        I = Next;
5177e70829632f82de15db187845666aaca6e04b792Chris Lattner      Next = I;
5187e70829632f82de15db187845666aaca6e04b792Chris Lattner    }
5197e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5207e70829632f82de15db187845666aaca6e04b792Chris Lattner  void unique() { unique(op_equal); }
5217e70829632f82de15db187845666aaca6e04b792Chris Lattner
5227e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void merge(iplist &right, Pr3 pred) {
5237e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first1 = begin(), last1 = end();
5247e70829632f82de15db187845666aaca6e04b792Chris Lattner    iterator first2 = right.begin(), last2 = right.end();
5257e70829632f82de15db187845666aaca6e04b792Chris Lattner    while (first1 != last1 && first2 != last2)
5267e70829632f82de15db187845666aaca6e04b792Chris Lattner      if (pred(*first2, *first1)) {
5277e70829632f82de15db187845666aaca6e04b792Chris Lattner        iterator next = first2;
5287e70829632f82de15db187845666aaca6e04b792Chris Lattner        transfer(first1, right, first2, ++next);
5297e70829632f82de15db187845666aaca6e04b792Chris Lattner        first2 = next;
5307e70829632f82de15db187845666aaca6e04b792Chris Lattner      } else {
5317e70829632f82de15db187845666aaca6e04b792Chris Lattner        ++first1;
5327e70829632f82de15db187845666aaca6e04b792Chris Lattner      }
5337e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 != last2) transfer(last1, right, first2, last2);
5347e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5357e70829632f82de15db187845666aaca6e04b792Chris Lattner  void merge(iplist &right) { return merge(right, op_less); }
5367e70829632f82de15db187845666aaca6e04b792Chris Lattner
5377e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Pr3> void sort(Pr3 pred);
5387e70829632f82de15db187845666aaca6e04b792Chris Lattner  void sort() { sort(op_less); }
5397e70829632f82de15db187845666aaca6e04b792Chris Lattner  void reverse();
5407e70829632f82de15db187845666aaca6e04b792Chris Lattner};
5417e70829632f82de15db187845666aaca6e04b792Chris Lattner
5427e70829632f82de15db187845666aaca6e04b792Chris Lattner
5437e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename NodeTy>
5447e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct ilist : public iplist<NodeTy> {
545a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::size_type size_type;
546a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner  typedef typename iplist<NodeTy>::iterator iterator;
547a1cb4737b04a92f57b1b9dcd8a24c68db5035401Chris Lattner
5487e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist() {}
5497e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(const ilist &right) {
55040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), right.begin(), right.end());
5517e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5527e70829632f82de15db187845666aaca6e04b792Chris Lattner  explicit ilist(size_type count) {
55340c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, NodeTy());
5547e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5557e70829632f82de15db187845666aaca6e04b792Chris Lattner  ilist(size_type count, const NodeTy &val) {
55640c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), count, val);
5577e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5587e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> ilist(InIt first, InIt last) {
55940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    insert(this->begin(), first, last);
5607e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5617e70829632f82de15db187845666aaca6e04b792Chris Lattner
5627e70829632f82de15db187845666aaca6e04b792Chris Lattner
5637e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Forwarding functions: A workaround for GCC 2.95 which does not correctly
5647e70829632f82de15db187845666aaca6e04b792Chris Lattner  // support 'using' declarations to bring a hidden member into scope.
5657e70829632f82de15db187845666aaca6e04b792Chris Lattner  //
5667e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator a, NodeTy *b){ return iplist<NodeTy>::insert(a, b); }
5677e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_front(NodeTy *a) { iplist<NodeTy>::push_front(a); }
5687e70829632f82de15db187845666aaca6e04b792Chris Lattner  void push_back(NodeTy *a)  { iplist<NodeTy>::push_back(a); }
5697e70829632f82de15db187845666aaca6e04b792Chris Lattner
5707e70829632f82de15db187845666aaca6e04b792Chris Lattner
5717e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Main implementation here - Insert for a node passed by value...
5727e70829632f82de15db187845666aaca6e04b792Chris Lattner  iterator insert(iterator where, const NodeTy &val) {
5737e70829632f82de15db187845666aaca6e04b792Chris Lattner    return insert(where, createNode(val));
5747e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5757e70829632f82de15db187845666aaca6e04b792Chris Lattner
5767e70829632f82de15db187845666aaca6e04b792Chris Lattner
5777e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Front and back inserters...
57840c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_front(const NodeTy &val) { insert(this->begin(), val); }
57940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  void push_back(const NodeTy &val) { insert(this->end(), val); }
5807e70829632f82de15db187845666aaca6e04b792Chris Lattner
5817e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Special forms of insert...
5827e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class InIt> void insert(iterator where, InIt first, InIt last) {
5837e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; first != last; ++first) insert(where, *first);
5847e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5857e70829632f82de15db187845666aaca6e04b792Chris Lattner  void insert(iterator where, size_type count, const NodeTy &val) {
5867e70829632f82de15db187845666aaca6e04b792Chris Lattner    for (; count != 0; --count) insert(where, val);
5877e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
5887e70829632f82de15db187845666aaca6e04b792Chris Lattner
5897e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Assign special forms...
5907e70829632f82de15db187845666aaca6e04b792Chris Lattner  void assign(size_type count, const NodeTy &val) {
59140c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator I = this->begin();
59240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for (; I != this->end() && count != 0; ++I, --count)
5937e70829632f82de15db187845666aaca6e04b792Chris Lattner      *I = val;
5947e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (count != 0)
59540c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), val, val);
5967e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
59740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(I, this->end());
5987e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
59940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner  template<class InIt> void assign(InIt first1, InIt last1) {
60040c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator first2 = this->begin(), last2 = this->end();
6017e70829632f82de15db187845666aaca6e04b792Chris Lattner    for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
6027e70829632f82de15db187845666aaca6e04b792Chris Lattner      *first1 = *first2;
6037e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (first2 == last2)
6047e70829632f82de15db187845666aaca6e04b792Chris Lattner      erase(first1, last1);
6057e70829632f82de15db187845666aaca6e04b792Chris Lattner    else
6067e70829632f82de15db187845666aaca6e04b792Chris Lattner      insert(last1, first2, last2);
6077e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6087e70829632f82de15db187845666aaca6e04b792Chris Lattner
6097e70829632f82de15db187845666aaca6e04b792Chris Lattner
6107e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Resize members...
6117e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize, NodeTy val) {
61240c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    iterator i = this->begin();
6137e70829632f82de15db187845666aaca6e04b792Chris Lattner    size_type len = 0;
61440c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner    for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
6157e70829632f82de15db187845666aaca6e04b792Chris Lattner
6167e70829632f82de15db187845666aaca6e04b792Chris Lattner    if (len == newsize)
61740c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      erase(i, this->end());
6187e70829632f82de15db187845666aaca6e04b792Chris Lattner    else                                          // i == end()
61940c6fb6cac80367c2bec32295d4448e540f2d253Chris Lattner      insert(this->end(), newsize - len, val);
6207e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6217e70829632f82de15db187845666aaca6e04b792Chris Lattner  void resize(size_type newsize) { resize(newsize, NodeTy()); }
6227e70829632f82de15db187845666aaca6e04b792Chris Lattner};
6237e70829632f82de15db187845666aaca6e04b792Chris Lattner
624d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
625d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
6267e70829632f82de15db187845666aaca6e04b792Chris Lattnernamespace std {
6277e70829632f82de15db187845666aaca6e04b792Chris Lattner  // Ensure that swap uses the fast list swap...
6287e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class Ty>
629d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke  void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
6307e70829632f82de15db187845666aaca6e04b792Chris Lattner    Left.swap(Right);
6317e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
6327e70829632f82de15db187845666aaca6e04b792Chris Lattner}  // End 'std' extensions...
6337e70829632f82de15db187845666aaca6e04b792Chris Lattner
6341ff4ed726bb8526d1e49030245365f8c86a8bb49Anton Korobeynikov#endif // LLVM_ADT_ILIST_H
635