LLVM API Documentation
00001 //==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines classes to implement an intrusive doubly linked list class 00011 // (i.e. each node of the list must contain a next and previous field for the 00012 // list. 00013 // 00014 // The ilist_traits trait class is used to gain access to the next and previous 00015 // fields of the node type that the list is instantiated with. If it is not 00016 // specialized, the list defaults to using the getPrev(), getNext() method calls 00017 // to get the next and previous pointers. 00018 // 00019 // The ilist class itself, should be a plug in replacement for list, assuming 00020 // that the nodes contain next/prev pointers. This list replacement does not 00021 // provide a constant time size() method, so be careful to use empty() when you 00022 // really want to know if it's empty. 00023 // 00024 // The ilist class is implemented by allocating a 'tail' node when the list is 00025 // created (using ilist_traits<>::createSentinel()). This tail node is 00026 // absolutely required because the user must be able to compute end()-1. Because 00027 // of this, users of the direct next/prev links will see an extra link on the 00028 // end of the list, which should be ignored. 00029 // 00030 // Requirements for a user of this list: 00031 // 00032 // 1. The user must provide {g|s}et{Next|Prev} methods, or specialize 00033 // ilist_traits to provide an alternate way of getting and setting next and 00034 // prev links. 00035 // 00036 //===----------------------------------------------------------------------===// 00037 00038 #ifndef LLVM_ADT_ILIST_H 00039 #define LLVM_ADT_ILIST_H 00040 00041 #include "llvm/ADT/iterator.h" 00042 #include <cassert> 00043 00044 namespace llvm { 00045 00046 template<typename NodeTy, typename Traits> class iplist; 00047 template<typename NodeTy> class ilist_iterator; 00048 00049 /// ilist_nextprev_traits - A fragment for template traits for intrusive list 00050 /// that provides default next/prev implementations for common operations. 00051 /// 00052 template<typename NodeTy> 00053 struct ilist_nextprev_traits { 00054 static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); } 00055 static NodeTy *getNext(NodeTy *N) { return N->getNext(); } 00056 static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); } 00057 static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); } 00058 00059 static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); } 00060 static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); } 00061 }; 00062 00063 /// ilist_sentinel_traits - A fragment for template traits for intrusive list 00064 /// that provides default sentinel implementations for common operations. 00065 /// 00066 template<typename NodeTy> 00067 struct ilist_sentinel_traits { 00068 static NodeTy *createSentinel() { return new NodeTy(); } 00069 static void destroySentinel(NodeTy *N) { delete N; } 00070 }; 00071 00072 /// ilist_default_traits - Default template traits for intrusive list. 00073 /// By inheriting from this, you can easily use default implementations 00074 /// for all common operations. 00075 /// 00076 template<typename NodeTy> 00077 struct ilist_default_traits : ilist_nextprev_traits<NodeTy>, 00078 ilist_sentinel_traits<NodeTy> { 00079 static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); } 00080 static void deleteNode(NodeTy *V) { delete V; } 00081 00082 void addNodeToList(NodeTy *) {} 00083 void removeNodeFromList(NodeTy *) {} 00084 void transferNodesFromList(ilist_default_traits & /*SrcTraits*/, 00085 ilist_iterator<NodeTy> /*first*/, 00086 ilist_iterator<NodeTy> /*last*/) {} 00087 }; 00088 00089 // Template traits for intrusive list. By specializing this template class, you 00090 // can change what next/prev fields are used to store the links... 00091 template<typename NodeTy> 00092 struct ilist_traits : ilist_default_traits<NodeTy> {}; 00093 00094 // Const traits are the same as nonconst traits... 00095 template<typename Ty> 00096 struct ilist_traits<const Ty> : public ilist_traits<Ty> {}; 00097 00098 //===----------------------------------------------------------------------===// 00099 // ilist_iterator<Node> - Iterator for intrusive list. 00100 // 00101 template<typename NodeTy> 00102 class ilist_iterator 00103 : public bidirectional_iterator<NodeTy, ptrdiff_t> { 00104 00105 public: 00106 typedef ilist_traits<NodeTy> Traits; 00107 typedef bidirectional_iterator<NodeTy, ptrdiff_t> super; 00108 00109 typedef typename super::value_type value_type; 00110 typedef typename super::difference_type difference_type; 00111 typedef typename super::pointer pointer; 00112 typedef typename super::reference reference; 00113 private: 00114 pointer NodePtr; 00115 00116 // ilist_iterator is not a random-access iterator, but it has an 00117 // implicit conversion to pointer-type, which is. Declare (but 00118 // don't define) these functions as private to help catch 00119 // accidental misuse. 00120 void operator[](difference_type) const; 00121 void operator+(difference_type) const; 00122 void operator-(difference_type) const; 00123 void operator+=(difference_type) const; 00124 void operator-=(difference_type) const; 00125 template<class T> void operator<(T) const; 00126 template<class T> void operator<=(T) const; 00127 template<class T> void operator>(T) const; 00128 template<class T> void operator>=(T) const; 00129 template<class T> void operator-(T) const; 00130 public: 00131 00132 ilist_iterator(pointer NP) : NodePtr(NP) {} 00133 ilist_iterator(reference NR) : NodePtr(&NR) {} 00134 ilist_iterator() : NodePtr(0) {} 00135 00136 // This is templated so that we can allow constructing a const iterator from 00137 // a nonconst iterator... 00138 template<class node_ty> 00139 ilist_iterator(const ilist_iterator<node_ty> &RHS) 00140 : NodePtr(RHS.getNodePtrUnchecked()) {} 00141 00142 // This is templated so that we can allow assigning to a const iterator from 00143 // a nonconst iterator... 00144 template<class node_ty> 00145 const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) { 00146 NodePtr = RHS.getNodePtrUnchecked(); 00147 return *this; 00148 } 00149 00150 // Accessors... 00151 operator pointer() const { 00152 assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!"); 00153 return NodePtr; 00154 } 00155 00156 reference operator*() const { 00157 assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!"); 00158 return *NodePtr; 00159 } 00160 pointer operator->() const { return &operator*(); } 00161 00162 // Comparison operators 00163 bool operator==(const ilist_iterator &RHS) const { 00164 return NodePtr == RHS.NodePtr; 00165 } 00166 bool operator!=(const ilist_iterator &RHS) const { 00167 return NodePtr != RHS.NodePtr; 00168 } 00169 00170 // Increment and decrement operators... 00171 ilist_iterator &operator--() { // predecrement - Back up 00172 NodePtr = Traits::getPrev(NodePtr); 00173 assert(Traits::getNext(NodePtr) && "--'d off the beginning of an ilist!"); 00174 return *this; 00175 } 00176 ilist_iterator &operator++() { // preincrement - Advance 00177 NodePtr = Traits::getNext(NodePtr); 00178 assert(NodePtr && "++'d off the end of an ilist!"); 00179 return *this; 00180 } 00181 ilist_iterator operator--(int) { // postdecrement operators... 00182 ilist_iterator tmp = *this; 00183 --*this; 00184 return tmp; 00185 } 00186 ilist_iterator operator++(int) { // postincrement operators... 00187 ilist_iterator tmp = *this; 00188 ++*this; 00189 return tmp; 00190 } 00191 00192 // Internal interface, do not use... 00193 pointer getNodePtrUnchecked() const { return NodePtr; } 00194 }; 00195 00196 // do not implement. this is to catch errors when people try to use 00197 // them as random access iterators 00198 template<typename T> 00199 void operator-(int, ilist_iterator<T>); 00200 template<typename T> 00201 void operator-(ilist_iterator<T>,int); 00202 00203 template<typename T> 00204 void operator+(int, ilist_iterator<T>); 00205 template<typename T> 00206 void operator+(ilist_iterator<T>,int); 00207 00208 // operator!=/operator== - Allow mixed comparisons without dereferencing 00209 // the iterator, which could very likely be pointing to end(). 00210 template<typename T> 00211 bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) { 00212 return LHS != RHS.getNodePtrUnchecked(); 00213 } 00214 template<typename T> 00215 bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) { 00216 return LHS == RHS.getNodePtrUnchecked(); 00217 } 00218 template<typename T> 00219 bool operator!=(T* LHS, const ilist_iterator<T> &RHS) { 00220 return LHS != RHS.getNodePtrUnchecked(); 00221 } 00222 template<typename T> 00223 bool operator==(T* LHS, const ilist_iterator<T> &RHS) { 00224 return LHS == RHS.getNodePtrUnchecked(); 00225 } 00226 00227 00228 // Allow ilist_iterators to convert into pointers to a node automatically when 00229 // used by the dyn_cast, cast, isa mechanisms... 00230 00231 template<typename From> struct simplify_type; 00232 00233 template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > { 00234 typedef NodeTy* SimpleType; 00235 00236 static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { 00237 return &*Node; 00238 } 00239 }; 00240 template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > { 00241 typedef NodeTy* SimpleType; 00242 00243 static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { 00244 return &*Node; 00245 } 00246 }; 00247 00248 00249 //===----------------------------------------------------------------------===// 00250 // 00251 /// iplist - The subset of list functionality that can safely be used on nodes 00252 /// of polymorphic types, i.e. a heterogenous list with a common base class that 00253 /// holds the next/prev pointers. The only state of the list itself is a single 00254 /// pointer to the head of the list. 00255 /// 00256 /// This list can be in one of three interesting states: 00257 /// 1. The list may be completely unconstructed. In this case, the head 00258 /// pointer is null. When in this form, any query for an iterator (e.g. 00259 /// begin() or end()) causes the list to transparently change to state #2. 00260 /// 2. The list may be empty, but contain a sentinel for the end iterator. This 00261 /// sentinel is created by the Traits::createSentinel method and is a link 00262 /// in the list. When the list is empty, the pointer in the iplist points 00263 /// to the sentinel. Once the sentinel is constructed, it 00264 /// is not destroyed until the list is. 00265 /// 3. The list may contain actual objects in it, which are stored as a doubly 00266 /// linked list of nodes. One invariant of the list is that the predecessor 00267 /// of the first node in the list always points to the last node in the list, 00268 /// and the successor pointer for the sentinel (which always stays at the 00269 /// end of the list) is always null. 00270 /// 00271 template<typename NodeTy, typename Traits=ilist_traits<NodeTy> > 00272 class iplist : public Traits { 00273 mutable NodeTy *Head; 00274 00275 // Use the prev node pointer of 'head' as the tail pointer. This is really a 00276 // circularly linked list where we snip the 'next' link from the sentinel node 00277 // back to the first node in the list (to preserve assertions about going off 00278 // the end of the list). 00279 NodeTy *getTail() { return this->getPrev(Head); } 00280 const NodeTy *getTail() const { return this->getPrev(Head); } 00281 void setTail(NodeTy *N) const { this->setPrev(Head, N); } 00282 00283 /// CreateLazySentinel - This method verifies whether the sentinel for the 00284 /// list has been created and lazily makes it if not. 00285 void CreateLazySentinel() const { 00286 if (Head != 0) return; 00287 Head = Traits::createSentinel(); 00288 this->setNext(Head, 0); 00289 setTail(Head); 00290 } 00291 00292 static bool op_less(NodeTy &L, NodeTy &R) { return L < R; } 00293 static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; } 00294 00295 // No fundamental reason why iplist can't by copyable, but the default 00296 // copy/copy-assign won't do. 00297 iplist(const iplist &); // do not implement 00298 void operator=(const iplist &); // do not implement 00299 00300 public: 00301 typedef NodeTy *pointer; 00302 typedef const NodeTy *const_pointer; 00303 typedef NodeTy &reference; 00304 typedef const NodeTy &const_reference; 00305 typedef NodeTy value_type; 00306 typedef ilist_iterator<NodeTy> iterator; 00307 typedef ilist_iterator<const NodeTy> const_iterator; 00308 typedef size_t size_type; 00309 typedef ptrdiff_t difference_type; 00310 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00311 typedef std::reverse_iterator<iterator> reverse_iterator; 00312 00313 iplist() : Head(0) {} 00314 ~iplist() { 00315 if (!Head) return; 00316 clear(); 00317 Traits::destroySentinel(getTail()); 00318 } 00319 00320 // Iterator creation methods. 00321 iterator begin() { 00322 CreateLazySentinel(); 00323 return iterator(Head); 00324 } 00325 const_iterator begin() const { 00326 CreateLazySentinel(); 00327 return const_iterator(Head); 00328 } 00329 iterator end() { 00330 CreateLazySentinel(); 00331 return iterator(getTail()); 00332 } 00333 const_iterator end() const { 00334 CreateLazySentinel(); 00335 return const_iterator(getTail()); 00336 } 00337 00338 // reverse iterator creation methods. 00339 reverse_iterator rbegin() { return reverse_iterator(end()); } 00340 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } 00341 reverse_iterator rend() { return reverse_iterator(begin()); } 00342 const_reverse_iterator rend() const { return const_reverse_iterator(begin());} 00343 00344 00345 // Miscellaneous inspection routines. 00346 size_type max_size() const { return size_type(-1); } 00347 bool empty() const { return Head == 0 || Head == getTail(); } 00348 00349 // Front and back accessor functions... 00350 reference front() { 00351 assert(!empty() && "Called front() on empty list!"); 00352 return *Head; 00353 } 00354 const_reference front() const { 00355 assert(!empty() && "Called front() on empty list!"); 00356 return *Head; 00357 } 00358 reference back() { 00359 assert(!empty() && "Called back() on empty list!"); 00360 return *this->getPrev(getTail()); 00361 } 00362 const_reference back() const { 00363 assert(!empty() && "Called back() on empty list!"); 00364 return *this->getPrev(getTail()); 00365 } 00366 00367 void swap(iplist &RHS) { 00368 assert(0 && "Swap does not use list traits callback correctly yet!"); 00369 std::swap(Head, RHS.Head); 00370 } 00371 00372 iterator insert(iterator where, NodeTy *New) { 00373 NodeTy *CurNode = where.getNodePtrUnchecked(), *PrevNode = this->getPrev(CurNode); 00374 this->setNext(New, CurNode); 00375 this->setPrev(New, PrevNode); 00376 00377 if (CurNode != Head) // Is PrevNode off the beginning of the list? 00378 this->setNext(PrevNode, New); 00379 else 00380 Head = New; 00381 this->setPrev(CurNode, New); 00382 00383 this->addNodeToList(New); // Notify traits that we added a node... 00384 return New; 00385 } 00386 00387 iterator insertAfter(iterator where, NodeTy *New) { 00388 if (empty()) 00389 return insert(begin(), New); 00390 else 00391 return insert(++where, New); 00392 } 00393 00394 NodeTy *remove(iterator &IT) { 00395 assert(IT != end() && "Cannot remove end of list!"); 00396 NodeTy *Node = &*IT; 00397 NodeTy *NextNode = this->getNext(Node); 00398 NodeTy *PrevNode = this->getPrev(Node); 00399 00400 if (Node != Head) // Is PrevNode off the beginning of the list? 00401 this->setNext(PrevNode, NextNode); 00402 else 00403 Head = NextNode; 00404 this->setPrev(NextNode, PrevNode); 00405 IT = NextNode; 00406 this->removeNodeFromList(Node); // Notify traits that we removed a node... 00407 00408 // Set the next/prev pointers of the current node to null. This isn't 00409 // strictly required, but this catches errors where a node is removed from 00410 // an ilist (and potentially deleted) with iterators still pointing at it. 00411 // When those iterators are incremented or decremented, they will assert on 00412 // the null next/prev pointer instead of "usually working". 00413 this->setNext(Node, 0); 00414 this->setPrev(Node, 0); 00415 return Node; 00416 } 00417 00418 NodeTy *remove(const iterator &IT) { 00419 iterator MutIt = IT; 00420 return remove(MutIt); 00421 } 00422 00423 // erase - remove a node from the controlled sequence... and delete it. 00424 iterator erase(iterator where) { 00425 this->deleteNode(remove(where)); 00426 return where; 00427 } 00428 00429 00430 private: 00431 // transfer - The heart of the splice function. Move linked list nodes from 00432 // [first, last) into position. 00433 // 00434 void transfer(iterator position, iplist &L2, iterator first, iterator last) { 00435 assert(first != last && "Should be checked by callers"); 00436 00437 if (position != last) { 00438 // Note: we have to be careful about the case when we move the first node 00439 // in the list. This node is the list sentinel node and we can't move it. 00440 NodeTy *ThisSentinel = getTail(); 00441 setTail(0); 00442 NodeTy *L2Sentinel = L2.getTail(); 00443 L2.setTail(0); 00444 00445 // Remove [first, last) from its old position. 00446 NodeTy *First = &*first, *Prev = getPrev(First); 00447 NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next); 00448 if (Prev) 00449 this->setNext(Prev, Next); 00450 else 00451 L2.Head = Next; 00452 this->setPrev(Next, Prev); 00453 00454 // Splice [first, last) into its new position. 00455 NodeTy *PosNext = position.getNodePtrUnchecked(); 00456 NodeTy *PosPrev = getPrev(PosNext); 00457 00458 // Fix head of list... 00459 if (PosPrev) 00460 this->setNext(PosPrev, First); 00461 else 00462 Head = First; 00463 this->setPrev(First, PosPrev); 00464 00465 // Fix end of list... 00466 this->setNext(Last, PosNext); 00467 this->setPrev(PosNext, Last); 00468 00469 transferNodesFromList(L2, First, PosNext); 00470 00471 // Now that everything is set, restore the pointers to the list sentinels. 00472 L2.setTail(L2Sentinel); 00473 setTail(ThisSentinel); 00474 } 00475 } 00476 00477 public: 00478 00479 //===----------------------------------------------------------------------=== 00480 // Functionality derived from other functions defined above... 00481 // 00482 00483 size_type size() const { 00484 if (Head == 0) return 0; // Don't require construction of sentinel if empty. 00485 #if __GNUC__ == 2 00486 // GCC 2.95 has a broken std::distance 00487 size_type Result = 0; 00488 std::distance(begin(), end(), Result); 00489 return Result; 00490 #else 00491 return std::distance(begin(), end()); 00492 #endif 00493 } 00494 00495 iterator erase(iterator first, iterator last) { 00496 while (first != last) 00497 first = erase(first); 00498 return last; 00499 } 00500 00501 void clear() { if (Head) erase(begin(), end()); } 00502 00503 // Front and back inserters... 00504 void push_front(NodeTy *val) { insert(begin(), val); } 00505 void push_back(NodeTy *val) { insert(end(), val); } 00506 void pop_front() { 00507 assert(!empty() && "pop_front() on empty list!"); 00508 erase(begin()); 00509 } 00510 void pop_back() { 00511 assert(!empty() && "pop_back() on empty list!"); 00512 iterator t = end(); erase(--t); 00513 } 00514 00515 // Special forms of insert... 00516 template<class InIt> void insert(iterator where, InIt first, InIt last) { 00517 for (; first != last; ++first) insert(where, *first); 00518 } 00519 00520 // Splice members - defined in terms of transfer... 00521 void splice(iterator where, iplist &L2) { 00522 if (!L2.empty()) 00523 transfer(where, L2, L2.begin(), L2.end()); 00524 } 00525 void splice(iterator where, iplist &L2, iterator first) { 00526 iterator last = first; ++last; 00527 if (where == first || where == last) return; // No change 00528 transfer(where, L2, first, last); 00529 } 00530 void splice(iterator where, iplist &L2, iterator first, iterator last) { 00531 if (first != last) transfer(where, L2, first, last); 00532 } 00533 00534 00535 00536 //===----------------------------------------------------------------------=== 00537 // High-Level Functionality that shouldn't really be here, but is part of list 00538 // 00539 00540 // These two functions are actually called remove/remove_if in list<>, but 00541 // they actually do the job of erase, rename them accordingly. 00542 // 00543 void erase(const NodeTy &val) { 00544 for (iterator I = begin(), E = end(); I != E; ) { 00545 iterator next = I; ++next; 00546 if (*I == val) erase(I); 00547 I = next; 00548 } 00549 } 00550 template<class Pr1> void erase_if(Pr1 pred) { 00551 for (iterator I = begin(), E = end(); I != E; ) { 00552 iterator next = I; ++next; 00553 if (pred(*I)) erase(I); 00554 I = next; 00555 } 00556 } 00557 00558 template<class Pr2> void unique(Pr2 pred) { 00559 if (empty()) return; 00560 for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) { 00561 if (pred(*I)) 00562 erase(Next); 00563 else 00564 I = Next; 00565 Next = I; 00566 } 00567 } 00568 void unique() { unique(op_equal); } 00569 00570 template<class Pr3> void merge(iplist &right, Pr3 pred) { 00571 iterator first1 = begin(), last1 = end(); 00572 iterator first2 = right.begin(), last2 = right.end(); 00573 while (first1 != last1 && first2 != last2) 00574 if (pred(*first2, *first1)) { 00575 iterator next = first2; 00576 transfer(first1, right, first2, ++next); 00577 first2 = next; 00578 } else { 00579 ++first1; 00580 } 00581 if (first2 != last2) transfer(last1, right, first2, last2); 00582 } 00583 void merge(iplist &right) { return merge(right, op_less); } 00584 00585 template<class Pr3> void sort(Pr3 pred); 00586 void sort() { sort(op_less); } 00587 void reverse(); 00588 }; 00589 00590 00591 template<typename NodeTy> 00592 struct ilist : public iplist<NodeTy> { 00593 typedef typename iplist<NodeTy>::size_type size_type; 00594 typedef typename iplist<NodeTy>::iterator iterator; 00595 00596 ilist() {} 00597 ilist(const ilist &right) { 00598 insert(this->begin(), right.begin(), right.end()); 00599 } 00600 explicit ilist(size_type count) { 00601 insert(this->begin(), count, NodeTy()); 00602 } 00603 ilist(size_type count, const NodeTy &val) { 00604 insert(this->begin(), count, val); 00605 } 00606 template<class InIt> ilist(InIt first, InIt last) { 00607 insert(this->begin(), first, last); 00608 } 00609 00610 00611 // Forwarding functions: A workaround for GCC 2.95 which does not correctly 00612 // support 'using' declarations to bring a hidden member into scope. 00613 // 00614 iterator insert(iterator a, NodeTy *b){ return iplist<NodeTy>::insert(a, b); } 00615 void push_front(NodeTy *a) { iplist<NodeTy>::push_front(a); } 00616 void push_back(NodeTy *a) { iplist<NodeTy>::push_back(a); } 00617 00618 00619 // Main implementation here - Insert for a node passed by value... 00620 iterator insert(iterator where, const NodeTy &val) { 00621 return insert(where, createNode(val)); 00622 } 00623 00624 00625 // Front and back inserters... 00626 void push_front(const NodeTy &val) { insert(this->begin(), val); } 00627 void push_back(const NodeTy &val) { insert(this->end(), val); } 00628 00629 // Special forms of insert... 00630 template<class InIt> void insert(iterator where, InIt first, InIt last) { 00631 for (; first != last; ++first) insert(where, *first); 00632 } 00633 void insert(iterator where, size_type count, const NodeTy &val) { 00634 for (; count != 0; --count) insert(where, val); 00635 } 00636 00637 // Assign special forms... 00638 void assign(size_type count, const NodeTy &val) { 00639 iterator I = this->begin(); 00640 for (; I != this->end() && count != 0; ++I, --count) 00641 *I = val; 00642 if (count != 0) 00643 insert(this->end(), val, val); 00644 else 00645 erase(I, this->end()); 00646 } 00647 template<class InIt> void assign(InIt first1, InIt last1) { 00648 iterator first2 = this->begin(), last2 = this->end(); 00649 for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) 00650 *first1 = *first2; 00651 if (first2 == last2) 00652 erase(first1, last1); 00653 else 00654 insert(last1, first2, last2); 00655 } 00656 00657 00658 // Resize members... 00659 void resize(size_type newsize, NodeTy val) { 00660 iterator i = this->begin(); 00661 size_type len = 0; 00662 for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ; 00663 00664 if (len == newsize) 00665 erase(i, this->end()); 00666 else // i == end() 00667 insert(this->end(), newsize - len, val); 00668 } 00669 void resize(size_type newsize) { resize(newsize, NodeTy()); } 00670 }; 00671 00672 } // End llvm namespace 00673 00674 namespace std { 00675 // Ensure that swap uses the fast list swap... 00676 template<class Ty> 00677 void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) { 00678 Left.swap(Right); 00679 } 00680 } // End 'std' extensions... 00681 00682 #endif // LLVM_ADT_ILIST_H