OSDN Git Service

make traits more flexible by splitting out node-related fragment
[android-x86/external-llvm.git] / include / llvm / ADT / ilist.h
1 //==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines classes to implement an intrusive doubly linked list class
11 // (i.e. each node of the list must contain a next and previous field for the
12 // list.
13 //
14 // The ilist_traits trait class is used to gain access to the next and previous
15 // fields of the node type that the list is instantiated with.  If it is not
16 // specialized, the list defaults to using the getPrev(), getNext() method calls
17 // to get the next and previous pointers.
18 //
19 // The ilist class itself, should be a plug in replacement for list, assuming
20 // that the nodes contain next/prev pointers.  This list replacement does not
21 // provide a constant time size() method, so be careful to use empty() when you
22 // really want to know if it's empty.
23 //
24 // The ilist class is implemented by allocating a 'tail' node when the list is
25 // created (using ilist_traits<>::createSentinel()).  This tail node is
26 // absolutely required because the user must be able to compute end()-1. Because
27 // of this, users of the direct next/prev links will see an extra link on the
28 // end of the list, which should be ignored.
29 //
30 // Requirements for a user of this list:
31 //
32 //   1. The user must provide {g|s}et{Next|Prev} methods, or specialize
33 //      ilist_traits to provide an alternate way of getting and setting next and
34 //      prev links.
35 //
36 //===----------------------------------------------------------------------===//
37
38 #ifndef LLVM_ADT_ILIST_H
39 #define LLVM_ADT_ILIST_H
40
41 #include "llvm/ADT/iterator.h"
42 #include <cassert>
43
44 namespace llvm {
45
46 template<typename NodeTy, typename Traits> class iplist;
47 template<typename NodeTy> class ilist_iterator;
48
49 /// ilist_nextprev_traits - A fragment for template traits for intrusive list
50 /// that provides default next/prev implementations for common operations.
51 ///
52 template<typename NodeTy>
53 struct ilist_nextprev_traits {
54   static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
55   static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
56   static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
57   static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
58
59   static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
60   static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
61 };
62
63 /// ilist_sentinel_traits - A fragment for template traits for intrusive list
64 /// that provides default sentinel implementations for common operations.
65 ///
66 template<typename NodeTy>
67 struct ilist_sentinel_traits {
68   static NodeTy *createSentinel() { return new NodeTy(); }
69   static void destroySentinel(NodeTy *N) { delete N; }
70 };
71
72 /// ilist_node_traits - A fragment for template traits for intrusive list
73 /// that provides default node related operations.
74 ///
75 template<typename NodeTy>
76 struct ilist_node_traits {
77   static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
78   static void deleteNode(NodeTy *V) { delete V; }
79
80   void addNodeToList(NodeTy *) {}
81   void removeNodeFromList(NodeTy *) {}
82   void transferNodesFromList(ilist_node_traits &    /*SrcTraits*/,
83                              ilist_iterator<NodeTy> /*first*/,
84                              ilist_iterator<NodeTy> /*last*/) {}
85 };
86
87 /// ilist_default_traits - Default template traits for intrusive list.
88 /// By inheriting from this, you can easily use default implementations
89 /// for all common operations.
90 ///
91 template<typename NodeTy>
92 struct ilist_default_traits : ilist_nextprev_traits<NodeTy>,
93                               ilist_sentinel_traits<NodeTy>,
94                               ilist_node_traits<NodeTy> {
95 };
96
97 // Template traits for intrusive list.  By specializing this template class, you
98 // can change what next/prev fields are used to store the links...
99 template<typename NodeTy>
100 struct ilist_traits : ilist_default_traits<NodeTy> {};
101
102 // Const traits are the same as nonconst traits...
103 template<typename Ty>
104 struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
105
106 //===----------------------------------------------------------------------===//
107 // ilist_iterator<Node> - Iterator for intrusive list.
108 //
109 template<typename NodeTy>
110 class ilist_iterator
111   : public bidirectional_iterator<NodeTy, ptrdiff_t> {
112
113 public:
114   typedef ilist_traits<NodeTy> Traits;
115   typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
116
117   typedef typename super::value_type value_type;
118   typedef typename super::difference_type difference_type;
119   typedef typename super::pointer pointer;
120   typedef typename super::reference reference;
121 private:
122   pointer NodePtr;
123
124   // ilist_iterator is not a random-access iterator, but it has an
125   // implicit conversion to pointer-type, which is. Declare (but
126   // don't define) these functions as private to help catch
127   // accidental misuse.
128   void operator[](difference_type) const;
129   void operator+(difference_type) const;
130   void operator-(difference_type) const;
131   void operator+=(difference_type) const;
132   void operator-=(difference_type) const;
133   template<class T> void operator<(T) const;
134   template<class T> void operator<=(T) const;
135   template<class T> void operator>(T) const;
136   template<class T> void operator>=(T) const;
137   template<class T> void operator-(T) const;
138 public:
139
140   ilist_iterator(pointer NP) : NodePtr(NP) {}
141   ilist_iterator(reference NR) : NodePtr(&NR) {}
142   ilist_iterator() : NodePtr(0) {}
143
144   // This is templated so that we can allow constructing a const iterator from
145   // a nonconst iterator...
146   template<class node_ty>
147   ilist_iterator(const ilist_iterator<node_ty> &RHS)
148     : NodePtr(RHS.getNodePtrUnchecked()) {}
149
150   // This is templated so that we can allow assigning to a const iterator from
151   // a nonconst iterator...
152   template<class node_ty>
153   const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
154     NodePtr = RHS.getNodePtrUnchecked();
155     return *this;
156   }
157
158   // Accessors...
159   operator pointer() const {
160     assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
161     return NodePtr;
162   }
163
164   reference operator*() const {
165     assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
166     return *NodePtr;
167   }
168   pointer operator->() const { return &operator*(); }
169
170   // Comparison operators
171   bool operator==(const ilist_iterator &RHS) const {
172     return NodePtr == RHS.NodePtr;
173   }
174   bool operator!=(const ilist_iterator &RHS) const {
175     return NodePtr != RHS.NodePtr;
176   }
177
178   // Increment and decrement operators...
179   ilist_iterator &operator--() {      // predecrement - Back up
180     NodePtr = Traits::getPrev(NodePtr);
181     assert(Traits::getNext(NodePtr) && "--'d off the beginning of an ilist!");
182     return *this;
183   }
184   ilist_iterator &operator++() {      // preincrement - Advance
185     NodePtr = Traits::getNext(NodePtr);
186     assert(NodePtr && "++'d off the end of an ilist!");
187     return *this;
188   }
189   ilist_iterator operator--(int) {    // postdecrement operators...
190     ilist_iterator tmp = *this;
191     --*this;
192     return tmp;
193   }
194   ilist_iterator operator++(int) {    // postincrement operators...
195     ilist_iterator tmp = *this;
196     ++*this;
197     return tmp;
198   }
199
200   // Internal interface, do not use...
201   pointer getNodePtrUnchecked() const { return NodePtr; }
202 };
203
204 // do not implement. this is to catch errors when people try to use
205 // them as random access iterators
206 template<typename T>
207 void operator-(int, ilist_iterator<T>);
208 template<typename T>
209 void operator-(ilist_iterator<T>,int);
210
211 template<typename T>
212 void operator+(int, ilist_iterator<T>);
213 template<typename T>
214 void operator+(ilist_iterator<T>,int);
215
216 // operator!=/operator== - Allow mixed comparisons without dereferencing
217 // the iterator, which could very likely be pointing to end().
218 template<typename T>
219 bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
220   return LHS != RHS.getNodePtrUnchecked();
221 }
222 template<typename T>
223 bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
224   return LHS == RHS.getNodePtrUnchecked();
225 }
226 template<typename T>
227 bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
228   return LHS != RHS.getNodePtrUnchecked();
229 }
230 template<typename T>
231 bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
232   return LHS == RHS.getNodePtrUnchecked();
233 }
234
235
236 // Allow ilist_iterators to convert into pointers to a node automatically when
237 // used by the dyn_cast, cast, isa mechanisms...
238
239 template<typename From> struct simplify_type;
240
241 template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
242   typedef NodeTy* SimpleType;
243
244   static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
245     return &*Node;
246   }
247 };
248 template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
249   typedef NodeTy* SimpleType;
250
251   static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
252     return &*Node;
253   }
254 };
255
256
257 //===----------------------------------------------------------------------===//
258 //
259 /// iplist - The subset of list functionality that can safely be used on nodes
260 /// of polymorphic types, i.e. a heterogenous list with a common base class that
261 /// holds the next/prev pointers.  The only state of the list itself is a single
262 /// pointer to the head of the list.
263 ///
264 /// This list can be in one of three interesting states:
265 /// 1. The list may be completely unconstructed.  In this case, the head
266 ///    pointer is null.  When in this form, any query for an iterator (e.g.
267 ///    begin() or end()) causes the list to transparently change to state #2.
268 /// 2. The list may be empty, but contain a sentinel for the end iterator. This
269 ///    sentinel is created by the Traits::createSentinel method and is a link
270 ///    in the list.  When the list is empty, the pointer in the iplist points
271 ///    to the sentinel.  Once the sentinel is constructed, it
272 ///    is not destroyed until the list is.
273 /// 3. The list may contain actual objects in it, which are stored as a doubly
274 ///    linked list of nodes.  One invariant of the list is that the predecessor
275 ///    of the first node in the list always points to the last node in the list,
276 ///    and the successor pointer for the sentinel (which always stays at the
277 ///    end of the list) is always null.
278 ///
279 template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
280 class iplist : public Traits {
281   mutable NodeTy *Head;
282
283   // Use the prev node pointer of 'head' as the tail pointer.  This is really a
284   // circularly linked list where we snip the 'next' link from the sentinel node
285   // back to the first node in the list (to preserve assertions about going off
286   // the end of the list).
287   NodeTy *getTail() { return this->getPrev(Head); }
288   const NodeTy *getTail() const { return this->getPrev(Head); }
289   void setTail(NodeTy *N) const { this->setPrev(Head, N); }
290
291   /// CreateLazySentinel - This method verifies whether the sentinel for the
292   /// list has been created and lazily makes it if not.
293   void CreateLazySentinel() const {
294     if (Head != 0) return;
295     Head = Traits::createSentinel();
296     this->setNext(Head, 0);
297     setTail(Head);
298   }
299
300   static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
301   static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
302
303   // No fundamental reason why iplist can't by copyable, but the default
304   // copy/copy-assign won't do.
305   iplist(const iplist &);         // do not implement
306   void operator=(const iplist &); // do not implement
307
308 public:
309   typedef NodeTy *pointer;
310   typedef const NodeTy *const_pointer;
311   typedef NodeTy &reference;
312   typedef const NodeTy &const_reference;
313   typedef NodeTy value_type;
314   typedef ilist_iterator<NodeTy> iterator;
315   typedef ilist_iterator<const NodeTy> const_iterator;
316   typedef size_t size_type;
317   typedef ptrdiff_t difference_type;
318   typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
319   typedef std::reverse_iterator<iterator>  reverse_iterator;
320
321   iplist() : Head(0) {}
322   ~iplist() {
323     if (!Head) return;
324     clear();
325     Traits::destroySentinel(getTail());
326   }
327
328   // Iterator creation methods.
329   iterator begin() {
330     CreateLazySentinel();
331     return iterator(Head);
332   }
333   const_iterator begin() const {
334     CreateLazySentinel();
335     return const_iterator(Head);
336   }
337   iterator end() {
338     CreateLazySentinel();
339     return iterator(getTail());
340   }
341   const_iterator end() const {
342     CreateLazySentinel();
343     return const_iterator(getTail());
344   }
345
346   // reverse iterator creation methods.
347   reverse_iterator rbegin()            { return reverse_iterator(end()); }
348   const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
349   reverse_iterator rend()              { return reverse_iterator(begin()); }
350   const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
351
352
353   // Miscellaneous inspection routines.
354   size_type max_size() const { return size_type(-1); }
355   bool empty() const { return Head == 0 || Head == getTail(); }
356
357   // Front and back accessor functions...
358   reference front() {
359     assert(!empty() && "Called front() on empty list!");
360     return *Head;
361   }
362   const_reference front() const {
363     assert(!empty() && "Called front() on empty list!");
364     return *Head;
365   }
366   reference back() {
367     assert(!empty() && "Called back() on empty list!");
368     return *this->getPrev(getTail());
369   }
370   const_reference back() const {
371     assert(!empty() && "Called back() on empty list!");
372     return *this->getPrev(getTail());
373   }
374
375   void swap(iplist &RHS) {
376     assert(0 && "Swap does not use list traits callback correctly yet!");
377     std::swap(Head, RHS.Head);
378   }
379
380   iterator insert(iterator where, NodeTy *New) {
381     NodeTy *CurNode = where.getNodePtrUnchecked();
382     NodeTy *PrevNode = this->getPrev(CurNode);
383     this->setNext(New, CurNode);
384     this->setPrev(New, PrevNode);
385
386     if (CurNode != Head)  // Is PrevNode off the beginning of the list?
387       this->setNext(PrevNode, New);
388     else
389       Head = New;
390     this->setPrev(CurNode, New);
391
392     this->addNodeToList(New);  // Notify traits that we added a node...
393     return New;
394   }
395
396   iterator insertAfter(iterator where, NodeTy *New) {
397     if (empty())
398       return insert(begin(), New);
399     else
400       return insert(++where, New);
401   }
402
403   NodeTy *remove(iterator &IT) {
404     assert(IT != end() && "Cannot remove end of list!");
405     NodeTy *Node = &*IT;
406     NodeTy *NextNode = this->getNext(Node);
407     NodeTy *PrevNode = this->getPrev(Node);
408
409     if (Node != Head)  // Is PrevNode off the beginning of the list?
410       this->setNext(PrevNode, NextNode);
411     else
412       Head = NextNode;
413     this->setPrev(NextNode, PrevNode);
414     IT = NextNode;
415     this->removeNodeFromList(Node);  // Notify traits that we removed a node...
416
417     // Set the next/prev pointers of the current node to null.  This isn't
418     // strictly required, but this catches errors where a node is removed from
419     // an ilist (and potentially deleted) with iterators still pointing at it.
420     // When those iterators are incremented or decremented, they will assert on
421     // the null next/prev pointer instead of "usually working".
422     this->setNext(Node, 0);
423     this->setPrev(Node, 0);
424     return Node;
425   }
426
427   NodeTy *remove(const iterator &IT) {
428     iterator MutIt = IT;
429     return remove(MutIt);
430   }
431
432   // erase - remove a node from the controlled sequence... and delete it.
433   iterator erase(iterator where) {
434     this->deleteNode(remove(where));
435     return where;
436   }
437
438
439 private:
440   // transfer - The heart of the splice function.  Move linked list nodes from
441   // [first, last) into position.
442   //
443   void transfer(iterator position, iplist &L2, iterator first, iterator last) {
444     assert(first != last && "Should be checked by callers");
445
446     if (position != last) {
447       // Note: we have to be careful about the case when we move the first node
448       // in the list.  This node is the list sentinel node and we can't move it.
449       NodeTy *ThisSentinel = getTail();
450       setTail(0);
451       NodeTy *L2Sentinel = L2.getTail();
452       L2.setTail(0);
453
454       // Remove [first, last) from its old position.
455       NodeTy *First = &*first, *Prev = getPrev(First);
456       NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
457       if (Prev)
458         this->setNext(Prev, Next);
459       else
460         L2.Head = Next;
461       this->setPrev(Next, Prev);
462
463       // Splice [first, last) into its new position.
464       NodeTy *PosNext = position.getNodePtrUnchecked();
465       NodeTy *PosPrev = getPrev(PosNext);
466
467       // Fix head of list...
468       if (PosPrev)
469         this->setNext(PosPrev, First);
470       else
471         Head = First;
472       this->setPrev(First, PosPrev);
473
474       // Fix end of list...
475       this->setNext(Last, PosNext);
476       this->setPrev(PosNext, Last);
477
478       transferNodesFromList(L2, First, PosNext);
479
480       // Now that everything is set, restore the pointers to the list sentinels.
481       L2.setTail(L2Sentinel);
482       setTail(ThisSentinel);
483     }
484   }
485
486 public:
487
488   //===----------------------------------------------------------------------===
489   // Functionality derived from other functions defined above...
490   //
491
492   size_type size() const {
493     if (Head == 0) return 0; // Don't require construction of sentinel if empty.
494 #if __GNUC__ == 2
495     // GCC 2.95 has a broken std::distance
496     size_type Result = 0;
497     std::distance(begin(), end(), Result);
498     return Result;
499 #else
500     return std::distance(begin(), end());
501 #endif
502   }
503
504   iterator erase(iterator first, iterator last) {
505     while (first != last)
506       first = erase(first);
507     return last;
508   }
509
510   void clear() { if (Head) erase(begin(), end()); }
511
512   // Front and back inserters...
513   void push_front(NodeTy *val) { insert(begin(), val); }
514   void push_back(NodeTy *val) { insert(end(), val); }
515   void pop_front() {
516     assert(!empty() && "pop_front() on empty list!");
517     erase(begin());
518   }
519   void pop_back() {
520     assert(!empty() && "pop_back() on empty list!");
521     iterator t = end(); erase(--t);
522   }
523
524   // Special forms of insert...
525   template<class InIt> void insert(iterator where, InIt first, InIt last) {
526     for (; first != last; ++first) insert(where, *first);
527   }
528
529   // Splice members - defined in terms of transfer...
530   void splice(iterator where, iplist &L2) {
531     if (!L2.empty())
532       transfer(where, L2, L2.begin(), L2.end());
533   }
534   void splice(iterator where, iplist &L2, iterator first) {
535     iterator last = first; ++last;
536     if (where == first || where == last) return; // No change
537     transfer(where, L2, first, last);
538   }
539   void splice(iterator where, iplist &L2, iterator first, iterator last) {
540     if (first != last) transfer(where, L2, first, last);
541   }
542
543
544
545   //===----------------------------------------------------------------------===
546   // High-Level Functionality that shouldn't really be here, but is part of list
547   //
548
549   // These two functions are actually called remove/remove_if in list<>, but
550   // they actually do the job of erase, rename them accordingly.
551   //
552   void erase(const NodeTy &val) {
553     for (iterator I = begin(), E = end(); I != E; ) {
554       iterator next = I; ++next;
555       if (*I == val) erase(I);
556       I = next;
557     }
558   }
559   template<class Pr1> void erase_if(Pr1 pred) {
560     for (iterator I = begin(), E = end(); I != E; ) {
561       iterator next = I; ++next;
562       if (pred(*I)) erase(I);
563       I = next;
564     }
565   }
566
567   template<class Pr2> void unique(Pr2 pred) {
568     if (empty()) return;
569     for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
570       if (pred(*I))
571         erase(Next);
572       else
573         I = Next;
574       Next = I;
575     }
576   }
577   void unique() { unique(op_equal); }
578
579   template<class Pr3> void merge(iplist &right, Pr3 pred) {
580     iterator first1 = begin(), last1 = end();
581     iterator first2 = right.begin(), last2 = right.end();
582     while (first1 != last1 && first2 != last2)
583       if (pred(*first2, *first1)) {
584         iterator next = first2;
585         transfer(first1, right, first2, ++next);
586         first2 = next;
587       } else {
588         ++first1;
589       }
590     if (first2 != last2) transfer(last1, right, first2, last2);
591   }
592   void merge(iplist &right) { return merge(right, op_less); }
593
594   template<class Pr3> void sort(Pr3 pred);
595   void sort() { sort(op_less); }
596   void reverse();
597 };
598
599
600 template<typename NodeTy>
601 struct ilist : public iplist<NodeTy> {
602   typedef typename iplist<NodeTy>::size_type size_type;
603   typedef typename iplist<NodeTy>::iterator iterator;
604
605   ilist() {}
606   ilist(const ilist &right) {
607     insert(this->begin(), right.begin(), right.end());
608   }
609   explicit ilist(size_type count) {
610     insert(this->begin(), count, NodeTy());
611   }
612   ilist(size_type count, const NodeTy &val) {
613     insert(this->begin(), count, val);
614   }
615   template<class InIt> ilist(InIt first, InIt last) {
616     insert(this->begin(), first, last);
617   }
618
619
620   // Forwarding functions: A workaround for GCC 2.95 which does not correctly
621   // support 'using' declarations to bring a hidden member into scope.
622   //
623   iterator insert(iterator a, NodeTy *b){ return iplist<NodeTy>::insert(a, b); }
624   void push_front(NodeTy *a) { iplist<NodeTy>::push_front(a); }
625   void push_back(NodeTy *a)  { iplist<NodeTy>::push_back(a); }
626
627
628   // Main implementation here - Insert for a node passed by value...
629   iterator insert(iterator where, const NodeTy &val) {
630     return insert(where, createNode(val));
631   }
632
633
634   // Front and back inserters...
635   void push_front(const NodeTy &val) { insert(this->begin(), val); }
636   void push_back(const NodeTy &val) { insert(this->end(), val); }
637
638   // Special forms of insert...
639   template<class InIt> void insert(iterator where, InIt first, InIt last) {
640     for (; first != last; ++first) insert(where, *first);
641   }
642   void insert(iterator where, size_type count, const NodeTy &val) {
643     for (; count != 0; --count) insert(where, val);
644   }
645
646   // Assign special forms...
647   void assign(size_type count, const NodeTy &val) {
648     iterator I = this->begin();
649     for (; I != this->end() && count != 0; ++I, --count)
650       *I = val;
651     if (count != 0)
652       insert(this->end(), val, val);
653     else
654       erase(I, this->end());
655   }
656   template<class InIt> void assign(InIt first1, InIt last1) {
657     iterator first2 = this->begin(), last2 = this->end();
658     for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
659       *first1 = *first2;
660     if (first2 == last2)
661       erase(first1, last1);
662     else
663       insert(last1, first2, last2);
664   }
665
666
667   // Resize members...
668   void resize(size_type newsize, NodeTy val) {
669     iterator i = this->begin();
670     size_type len = 0;
671     for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
672
673     if (len == newsize)
674       erase(i, this->end());
675     else                                          // i == end()
676       insert(this->end(), newsize - len, val);
677   }
678   void resize(size_type newsize) { resize(newsize, NodeTy()); }
679 };
680
681 } // End llvm namespace
682
683 namespace std {
684   // Ensure that swap uses the fast list swap...
685   template<class Ty>
686   void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
687     Left.swap(Right);
688   }
689 }  // End 'std' extensions...
690
691 #endif // LLVM_ADT_ILIST_H