-//===-- <Support/ilist> - Intrusive Linked List Template ---------*- C++ -*--=//
+//===-- llvm/ADT/ilist - Intrusive Linked List Template ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
//
// This file defines classes to implement an intrusive doubly linked list class
// (ie each node of the list must contain a next and previous field for the
//
//===----------------------------------------------------------------------===//
-#ifndef SUPPORT_ILIST
-#define SUPPORT_ILIST
+#ifndef LLVM_ADT_ILIST
+#define LLVM_ADT_ILIST
+
+#include "llvm/ADT/iterator"
+#include <cassert>
-#include <algorithm>
-#include <Support/iterator>
+namespace llvm {
template<typename NodeTy, typename Traits> class iplist;
template<typename NodeTy> class ilist_iterator;
static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
- static NodeTy *createNode() { return new NodeTy(); }
static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
+ static NodeTy *createSentinel() { return new NodeTy(); }
+ static void destroySentinel(NodeTy *N) { delete N; }
void addNodeToList(NodeTy *NTy) {}
void removeNodeFromList(NodeTy *NTy) {}
typedef ilist_traits<NodeTy> Traits;
typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
+public:
+ typedef size_t size_type;
typedef typename super::pointer pointer;
typedef typename super::reference reference;
+private:
pointer NodePtr;
public:
- typedef size_t size_type;
ilist_iterator(pointer NP) : NodePtr(NP) {}
ilist_iterator(reference NR) : NodePtr(&NR) {}
return tmp;
}
-
- // Dummy operators to make errors apparent...
- template<class X> void operator+(X Val) {}
- template<class X> void operator-(X Val) {}
-
// Internal interface, do not use...
pointer getNodePtrUnchecked() const { return NodePtr; }
};
+// do not implement. this is to catch errors when people try to use
+// them as random access iterators
+template<typename T>
+void operator-(int, ilist_iterator<T>);
+template<typename T>
+void operator-(ilist_iterator<T>,int);
+
+template<typename T>
+void operator+(int, ilist_iterator<T>);
+template<typename T>
+void operator+(ilist_iterator<T>,int);
+
+// operator!=/operator== - Allow mixed comparisons without dereferencing
+// the iterator, which could very likely be pointing to end().
+template<typename T>
+bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+
+
// Allow ilist_iterators to convert into pointers to a node automatically when
// used by the dyn_cast, cast, isa mechanisms...
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
- iplist() : Head(createNode()), Tail(Head) {
+ iplist() : Head(Traits::createSentinel()), Tail(Head) {
setNext(Head, 0);
setPrev(Head, 0);
}
- ~iplist() { clear(); delete Tail; }
+ ~iplist() { clear(); Traits::destroySentinel(Tail); }
- // Iterator creation methods...
+ // Iterator creation methods.
iterator begin() { return iterator(Head); }
const_iterator begin() const { return const_iterator(Head); }
iterator end() { return iterator(Tail); }
const_iterator end() const { return const_iterator(Tail); }
- // reverse iterator creation methods...
+ // reverse iterator creation methods.
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
- // Miscellaneous inspection routines...
+
+ // Miscellaneous inspection routines.
size_type max_size() const { return size_type(-1); }
bool empty() const { return Head == Tail; }
Head = NextNode;
setPrev(NextNode, PrevNode);
IT = NextNode;
- removeNodeFromList(Node); // Notify traits that we added a node...
+ removeNodeFromList(Node); // Notify traits that we removed a node...
return Node;
}
//
size_type size() const {
-#if __GNUC__ == 3
- size_type Result = std::distance(begin(), end());
-#else
+#if __GNUC__ == 2
+ // GCC 2.95 has a broken std::distance
size_type Result = 0;
std::distance(begin(), end(), Result);
-#endif
return Result;
+#else
+ return std::distance(begin(), end());
+#endif
}
iterator erase(iterator first, iterator last) {
ilist() {}
ilist(const ilist &right) {
- insert(begin(), right.begin(), right.end());
+ insert(this->begin(), right.begin(), right.end());
}
explicit ilist(size_type count) {
- insert(begin(), count, NodeTy());
+ insert(this->begin(), count, NodeTy());
}
ilist(size_type count, const NodeTy &val) {
- insert(begin(), count, val);
+ insert(this->begin(), count, val);
}
template<class InIt> ilist(InIt first, InIt last) {
- insert(begin(), first, last);
+ insert(this->begin(), first, last);
}
// Front and back inserters...
- void push_front(const NodeTy &val) { insert(begin(), val); }
- void push_back(const NodeTy &val) { insert(end(), val); }
+ void push_front(const NodeTy &val) { insert(this->begin(), val); }
+ void push_back(const NodeTy &val) { insert(this->end(), val); }
// Special forms of insert...
template<class InIt> void insert(iterator where, InIt first, InIt last) {
// Assign special forms...
void assign(size_type count, const NodeTy &val) {
- iterator I = begin();
- for (; I != end() && count != 0; ++I, --count)
+ iterator I = this->begin();
+ for (; I != this->end() && count != 0; ++I, --count)
*I = val;
if (count != 0)
- insert(end(), n, val);
+ insert(this->end(), val, val);
else
- erase(I, end());
+ erase(I, this->end());
}
- template<class InIt> void assign(InIt first, InIt last) {
- iterator first1 = begin(), last1 = end();
+ template<class InIt> void assign(InIt first1, InIt last1) {
+ iterator first2 = this->begin(), last2 = this->end();
for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
*first1 = *first2;
if (first2 == last2)
// Resize members...
void resize(size_type newsize, NodeTy val) {
- iterator i = begin();
+ iterator i = this->begin();
size_type len = 0;
- for ( ; i != end() && len < newsize; ++i, ++len) /* empty*/ ;
+ for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
if (len == newsize)
- erase(i, end());
+ erase(i, this->end());
else // i == end()
- insert(end(), newsize - len, val);
+ insert(this->end(), newsize - len, val);
}
void resize(size_type newsize) { resize(newsize, NodeTy()); }
};
+} // End llvm namespace
+
namespace std {
// Ensure that swap uses the fast list swap...
template<class Ty>
- void swap(iplist<Ty> &Left, iplist<Ty> &Right) {
+ void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
Left.swap(Right);
}
} // End 'std' extensions...