/3rd_party/llvm/include/llvm/ADT/ilist.h

https://code.google.com/p/softart/ · C++ Header · 722 lines · 462 code · 100 blank · 160 comment · 88 complexity · da692daf2fc683e7a6021157e4a297cf MD5 · raw file

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