~ubuntu-branches/ubuntu/maverick/clamav/maverick-backports

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/include/llvm/ADT/ilist.h

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Gran, Stephen Gran, Michael Tautschnig
  • Date: 2010-04-26 21:41:18 UTC
  • mfrom: (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100426214118-i6lo606wnh7ywfj6
Tags: 0.96+dfsg-4
[ Stephen Gran ]
* Fixed typo in clamav-milter's postinst

[ Michael Tautschnig ]
* Fixed typo in clamav-freshclam's postinst (closes: #579271)
* Debconf translation updates
  - Portuguese (closes: #579068)

Show diffs side-by-side

added added

removed removed

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