00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef LLVM_ADT_ILIST_H
00039 #define LLVM_ADT_ILIST_H
00040
00041 #include <algorithm>
00042 #include <cassert>
00043 #include <cstddef>
00044 #include <iterator>
00045
00046 namespace llvm {
00047
00048 template<typename NodeTy, typename Traits> class iplist;
00049 template<typename NodeTy> class ilist_iterator;
00050
00054 template<typename NodeTy>
00055 struct ilist_nextprev_traits {
00056 static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
00057 static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
00058 static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
00059 static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
00060
00061 static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
00062 static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
00063 };
00064
00065 template<typename NodeTy>
00066 struct ilist_traits;
00067
00074 template<typename NodeTy>
00075 struct ilist_sentinel_traits {
00077 static NodeTy *createSentinel() { return new NodeTy(); }
00078
00080 static void destroySentinel(NodeTy *N) { delete N; }
00081
00085 static NodeTy *provideInitialHead() { return 0; }
00086
00090 static NodeTy *ensureHead(NodeTy *&Head) {
00091 if (!Head) {
00092 Head = ilist_traits<NodeTy>::createSentinel();
00093 ilist_traits<NodeTy>::noteHead(Head, Head);
00094 ilist_traits<NodeTy>::setNext(Head, 0);
00095 return Head;
00096 }
00097 return ilist_traits<NodeTy>::getPrev(Head);
00098 }
00099
00101 static void noteHead(NodeTy *NewHead, NodeTy *Sentinel) {
00102 ilist_traits<NodeTy>::setPrev(NewHead, Sentinel);
00103 }
00104 };
00105
00109 template<typename NodeTy>
00110 struct ilist_node_traits {
00111 static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
00112 static void deleteNode(NodeTy *V) { delete V; }
00113
00114 void addNodeToList(NodeTy *) {}
00115 void removeNodeFromList(NodeTy *) {}
00116 void transferNodesFromList(ilist_node_traits & ,
00117 ilist_iterator<NodeTy> ,
00118 ilist_iterator<NodeTy> ) {}
00119 };
00120
00125 template<typename NodeTy>
00126 struct ilist_default_traits : public ilist_nextprev_traits<NodeTy>,
00127 public ilist_sentinel_traits<NodeTy>,
00128 public ilist_node_traits<NodeTy> {
00129 };
00130
00131
00132
00133 template<typename NodeTy>
00134 struct ilist_traits : public ilist_default_traits<NodeTy> {};
00135
00136
00137 template<typename Ty>
00138 struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
00139
00140
00141
00142
00143 template<typename NodeTy>
00144 class ilist_iterator
00145 : public std::iterator<std::bidirectional_iterator_tag, NodeTy, ptrdiff_t> {
00146
00147 public:
00148 typedef ilist_traits<NodeTy> Traits;
00149 typedef std::iterator<std::bidirectional_iterator_tag,
00150 NodeTy, ptrdiff_t> super;
00151
00152 typedef typename super::value_type value_type;
00153 typedef typename super::difference_type difference_type;
00154 typedef typename super::pointer pointer;
00155 typedef typename super::reference reference;
00156 private:
00157 pointer NodePtr;
00158
00159
00160
00161
00162
00163 void operator[](difference_type) const;
00164 void operator+(difference_type) const;
00165 void operator-(difference_type) const;
00166 void operator+=(difference_type) const;
00167 void operator-=(difference_type) const;
00168 template<class T> void operator<(T) const;
00169 template<class T> void operator<=(T) const;
00170 template<class T> void operator>(T) const;
00171 template<class T> void operator>=(T) const;
00172 template<class T> void operator-(T) const;
00173 public:
00174
00175 ilist_iterator(pointer NP) : NodePtr(NP) {}
00176 ilist_iterator(reference NR) : NodePtr(&NR) {}
00177 ilist_iterator() : NodePtr(0) {}
00178
00179
00180
00181 template<class node_ty>
00182 ilist_iterator(const ilist_iterator<node_ty> &RHS)
00183 : NodePtr(RHS.getNodePtrUnchecked()) {}
00184
00185
00186
00187 template<class node_ty>
00188 const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
00189 NodePtr = RHS.getNodePtrUnchecked();
00190 return *this;
00191 }
00192
00193
00194 operator pointer() const {
00195 return NodePtr;
00196 }
00197
00198 reference operator*() const {
00199 return *NodePtr;
00200 }
00201 pointer operator->() const { return &operator*(); }
00202
00203
00204 bool operator==(const ilist_iterator &RHS) const {
00205 return NodePtr == RHS.NodePtr;
00206 }
00207 bool operator!=(const ilist_iterator &RHS) const {
00208 return NodePtr != RHS.NodePtr;
00209 }
00210
00211
00212 ilist_iterator &operator--() {
00213 NodePtr = Traits::getPrev(NodePtr);
00214 assert(NodePtr && "--'d off the beginning of an ilist!");
00215 return *this;
00216 }
00217 ilist_iterator &operator++() {
00218 NodePtr = Traits::getNext(NodePtr);
00219 return *this;
00220 }
00221 ilist_iterator operator--(int) {
00222 ilist_iterator tmp = *this;
00223 --*this;
00224 return tmp;
00225 }
00226 ilist_iterator operator++(int) {
00227 ilist_iterator tmp = *this;
00228 ++*this;
00229 return tmp;
00230 }
00231
00232
00233 pointer getNodePtrUnchecked() const { return NodePtr; }
00234 };
00235
00236
00237
00238 template<typename T>
00239 void operator-(int, ilist_iterator<T>);
00240 template<typename T>
00241 void operator-(ilist_iterator<T>,int);
00242
00243 template<typename T>
00244 void operator+(int, ilist_iterator<T>);
00245 template<typename T>
00246 void operator+(ilist_iterator<T>,int);
00247
00248
00249
00250 template<typename T>
00251 bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
00252 return LHS != RHS.getNodePtrUnchecked();
00253 }
00254 template<typename T>
00255 bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
00256 return LHS == RHS.getNodePtrUnchecked();
00257 }
00258 template<typename T>
00259 bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
00260 return LHS != RHS.getNodePtrUnchecked();
00261 }
00262 template<typename T>
00263 bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
00264 return LHS == RHS.getNodePtrUnchecked();
00265 }
00266
00267
00268
00269
00270
00271 template<typename From> struct simplify_type;
00272
00273 template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
00274 typedef NodeTy* SimpleType;
00275
00276 static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
00277 return &*Node;
00278 }
00279 };
00280 template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
00281 typedef NodeTy* SimpleType;
00282
00283 static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
00284 return &*Node;
00285 }
00286 };
00287
00288
00289
00290
00311 template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
00312 class iplist : public Traits {
00313 mutable NodeTy *Head;
00314
00315
00316
00317
00318
00319 NodeTy *getTail() { return this->ensureHead(Head); }
00320 const NodeTy *getTail() const { return this->ensureHead(Head); }
00321 void setTail(NodeTy *N) const { this->noteHead(Head, N); }
00322
00325 void CreateLazySentinel() const {
00326 this->ensureHead(Head);
00327 }
00328
00329 static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
00330 static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
00331
00332
00333
00334 iplist(const iplist &);
00335 void operator=(const iplist &);
00336
00337 public:
00338 typedef NodeTy *pointer;
00339 typedef const NodeTy *const_pointer;
00340 typedef NodeTy &reference;
00341 typedef const NodeTy &const_reference;
00342 typedef NodeTy value_type;
00343 typedef ilist_iterator<NodeTy> iterator;
00344 typedef ilist_iterator<const NodeTy> const_iterator;
00345 typedef size_t size_type;
00346 typedef ptrdiff_t difference_type;
00347 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00348 typedef std::reverse_iterator<iterator> reverse_iterator;
00349
00350 iplist() : Head(this->provideInitialHead()) {}
00351 ~iplist() {
00352 if (!Head) return;
00353 clear();
00354 Traits::destroySentinel(getTail());
00355 }
00356
00357
00358 iterator begin() {
00359 CreateLazySentinel();
00360 return iterator(Head);
00361 }
00362 const_iterator begin() const {
00363 CreateLazySentinel();
00364 return const_iterator(Head);
00365 }
00366 iterator end() {
00367 CreateLazySentinel();
00368 return iterator(getTail());
00369 }
00370 const_iterator end() const {
00371 CreateLazySentinel();
00372 return const_iterator(getTail());
00373 }
00374
00375
00376 reverse_iterator rbegin() { return reverse_iterator(end()); }
00377 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
00378 reverse_iterator rend() { return reverse_iterator(begin()); }
00379 const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
00380
00381
00382
00383 size_type max_size() const { return size_type(-1); }
00384 bool empty() const { return Head == 0 || Head == getTail(); }
00385
00386
00387 reference front() {
00388 assert(!empty() && "Called front() on empty list!");
00389 return *Head;
00390 }
00391 const_reference front() const {
00392 assert(!empty() && "Called front() on empty list!");
00393 return *Head;
00394 }
00395 reference back() {
00396 assert(!empty() && "Called back() on empty list!");
00397 return *this->getPrev(getTail());
00398 }
00399 const_reference back() const {
00400 assert(!empty() && "Called back() on empty list!");
00401 return *this->getPrev(getTail());
00402 }
00403
00404 void swap(iplist &RHS) {
00405 assert(0 && "Swap does not use list traits callback correctly yet!");
00406 std::swap(Head, RHS.Head);
00407 }
00408
00409 iterator insert(iterator where, NodeTy *New) {
00410 NodeTy *CurNode = where.getNodePtrUnchecked();
00411 NodeTy *PrevNode = this->getPrev(CurNode);
00412 this->setNext(New, CurNode);
00413 this->setPrev(New, PrevNode);
00414
00415 if (CurNode != Head)
00416 this->setNext(PrevNode, New);
00417 else
00418 Head = New;
00419 this->setPrev(CurNode, New);
00420
00421 this->addNodeToList(New);
00422 return New;
00423 }
00424
00425 iterator insertAfter(iterator where, NodeTy *New) {
00426 if (empty())
00427 return insert(begin(), New);
00428 else
00429 return insert(++where, New);
00430 }
00431
00432 NodeTy *remove(iterator &IT) {
00433 assert(IT != end() && "Cannot remove end of list!");
00434 NodeTy *Node = &*IT;
00435 NodeTy *NextNode = this->getNext(Node);
00436 NodeTy *PrevNode = this->getPrev(Node);
00437
00438 if (Node != Head)
00439 this->setNext(PrevNode, NextNode);
00440 else
00441 Head = NextNode;
00442 this->setPrev(NextNode, PrevNode);
00443 IT = NextNode;
00444 this->removeNodeFromList(Node);
00445
00446
00447
00448
00449
00450
00451 this->setNext(Node, 0);
00452 this->setPrev(Node, 0);
00453 return Node;
00454 }
00455
00456 NodeTy *remove(const iterator &IT) {
00457 iterator MutIt = IT;
00458 return remove(MutIt);
00459 }
00460
00461
00462 iterator erase(iterator where) {
00463 this->deleteNode(remove(where));
00464 return where;
00465 }
00466
00467
00468 private:
00469
00470
00471
00472 void transfer(iterator position, iplist &L2, iterator first, iterator last) {
00473 assert(first != last && "Should be checked by callers");
00474
00475 if (position != last) {
00476
00477
00478 NodeTy *ThisSentinel = getTail();
00479 setTail(0);
00480 NodeTy *L2Sentinel = L2.getTail();
00481 L2.setTail(0);
00482
00483
00484 NodeTy *First = &*first, *Prev = this->getPrev(First);
00485 NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
00486 if (Prev)
00487 this->setNext(Prev, Next);
00488 else
00489 L2.Head = Next;
00490 this->setPrev(Next, Prev);
00491
00492
00493 NodeTy *PosNext = position.getNodePtrUnchecked();
00494 NodeTy *PosPrev = this->getPrev(PosNext);
00495
00496
00497 if (PosPrev)
00498 this->setNext(PosPrev, First);
00499 else
00500 Head = First;
00501 this->setPrev(First, PosPrev);
00502
00503
00504 this->setNext(Last, PosNext);
00505 this->setPrev(PosNext, Last);
00506
00507 this->transferNodesFromList(L2, First, PosNext);
00508
00509
00510 L2.setTail(L2Sentinel);
00511 setTail(ThisSentinel);
00512 }
00513 }
00514
00515 public:
00516
00517
00518
00519
00520
00521 size_type size() const {
00522 if (Head == 0) return 0;
00523 return std::distance(begin(), end());
00524 }
00525
00526 iterator erase(iterator first, iterator last) {
00527 while (first != last)
00528 first = erase(first);
00529 return last;
00530 }
00531
00532 void clear() { if (Head) erase(begin(), end()); }
00533
00534
00535 void push_front(NodeTy *val) { insert(begin(), val); }
00536 void push_back(NodeTy *val) { insert(end(), val); }
00537 void pop_front() {
00538 assert(!empty() && "pop_front() on empty list!");
00539 erase(begin());
00540 }
00541 void pop_back() {
00542 assert(!empty() && "pop_back() on empty list!");
00543 iterator t = end(); erase(--t);
00544 }
00545
00546
00547 template<class InIt> void insert(iterator where, InIt first, InIt last) {
00548 for (; first != last; ++first) insert(where, *first);
00549 }
00550
00551
00552 void splice(iterator where, iplist &L2) {
00553 if (!L2.empty())
00554 transfer(where, L2, L2.begin(), L2.end());
00555 }
00556 void splice(iterator where, iplist &L2, iterator first) {
00557 iterator last = first; ++last;
00558 if (where == first || where == last) return;
00559 transfer(where, L2, first, last);
00560 }
00561 void splice(iterator where, iplist &L2, iterator first, iterator last) {
00562 if (first != last) transfer(where, L2, first, last);
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 void erase(const NodeTy &val) {
00575 for (iterator I = begin(), E = end(); I != E; ) {
00576 iterator next = I; ++next;
00577 if (*I == val) erase(I);
00578 I = next;
00579 }
00580 }
00581 template<class Pr1> void erase_if(Pr1 pred) {
00582 for (iterator I = begin(), E = end(); I != E; ) {
00583 iterator next = I; ++next;
00584 if (pred(*I)) erase(I);
00585 I = next;
00586 }
00587 }
00588
00589 template<class Pr2> void unique(Pr2 pred) {
00590 if (empty()) return;
00591 for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
00592 if (pred(*I))
00593 erase(Next);
00594 else
00595 I = Next;
00596 Next = I;
00597 }
00598 }
00599 void unique() { unique(op_equal); }
00600
00601 template<class Pr3> void merge(iplist &right, Pr3 pred) {
00602 iterator first1 = begin(), last1 = end();
00603 iterator first2 = right.begin(), last2 = right.end();
00604 while (first1 != last1 && first2 != last2)
00605 if (pred(*first2, *first1)) {
00606 iterator next = first2;
00607 transfer(first1, right, first2, ++next);
00608 first2 = next;
00609 } else {
00610 ++first1;
00611 }
00612 if (first2 != last2) transfer(last1, right, first2, last2);
00613 }
00614 void merge(iplist &right) { return merge(right, op_less); }
00615
00616 template<class Pr3> void sort(Pr3 pred);
00617 void sort() { sort(op_less); }
00618 };
00619
00620
00621 template<typename NodeTy>
00622 struct ilist : public iplist<NodeTy> {
00623 typedef typename iplist<NodeTy>::size_type size_type;
00624 typedef typename iplist<NodeTy>::iterator iterator;
00625
00626 ilist() {}
00627 ilist(const ilist &right) {
00628 insert(this->begin(), right.begin(), right.end());
00629 }
00630 explicit ilist(size_type count) {
00631 insert(this->begin(), count, NodeTy());
00632 }
00633 ilist(size_type count, const NodeTy &val) {
00634 insert(this->begin(), count, val);
00635 }
00636 template<class InIt> ilist(InIt first, InIt last) {
00637 insert(this->begin(), first, last);
00638 }
00639
00640
00641 using iplist<NodeTy>::insert;
00642 using iplist<NodeTy>::push_front;
00643 using iplist<NodeTy>::push_back;
00644
00645
00646 iterator insert(iterator where, const NodeTy &val) {
00647 return insert(where, this->createNode(val));
00648 }
00649
00650
00651
00652 void push_front(const NodeTy &val) { insert(this->begin(), val); }
00653 void push_back(const NodeTy &val) { insert(this->end(), val); }
00654
00655
00656 template<class InIt> void insert(iterator where, InIt first, InIt last) {
00657 for (; first != last; ++first) insert(where, *first);
00658 }
00659 void insert(iterator where, size_type count, const NodeTy &val) {
00660 for (; count != 0; --count) insert(where, val);
00661 }
00662
00663
00664 void assign(size_type count, const NodeTy &val) {
00665 iterator I = this->begin();
00666 for (; I != this->end() && count != 0; ++I, --count)
00667 *I = val;
00668 if (count != 0)
00669 insert(this->end(), val, val);
00670 else
00671 erase(I, this->end());
00672 }
00673 template<class InIt> void assign(InIt first1, InIt last1) {
00674 iterator first2 = this->begin(), last2 = this->end();
00675 for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
00676 *first1 = *first2;
00677 if (first2 == last2)
00678 erase(first1, last1);
00679 else
00680 insert(last1, first2, last2);
00681 }
00682
00683
00684
00685 void resize(size_type newsize, NodeTy val) {
00686 iterator i = this->begin();
00687 size_type len = 0;
00688 for ( ; i != this->end() && len < newsize; ++i, ++len) ;
00689
00690 if (len == newsize)
00691 erase(i, this->end());
00692 else
00693 insert(this->end(), newsize - len, val);
00694 }
00695 void resize(size_type newsize) { resize(newsize, NodeTy()); }
00696 };
00697
00698 }
00699
00700 namespace std {
00701
00702 template<class Ty>
00703 void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
00704 Left.swap(Right);
00705 }
00706 }
00707
00708 #endif // LLVM_ADT_ILIST_H