Add a helper class (APSInt) which can represent an APInt along with sign
[oota-llvm.git] / include / llvm / ADT / ilist
index 7e666c6d97f167c1550f28386acd8ccb25baf423..1d01b63fe73647e4ca28172658bdcba6f1ab0520 100644 (file)
@@ -1,4 +1,11 @@
-//===-- <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
@@ -12,7 +19,7 @@
 // The ilist class itself, should be a plug in replacement for list, assuming
 // that the nodes contain next/prev pointers.  This list replacement does not
 // provides a constant time size() method, so be careful to use empty() when you
-// really want to know if I'm empty.
+// really want to know if it's empty.
 //
 // The ilist class is implemented by allocating a 'tail' node when the list is
 // created (using ilist_traits<>::createEndMarker()).  This tail node is
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef INCLUDED_SUPPORT_ILIST
-#define INCLUDED_SUPPORT_ILIST
+#ifndef LLVM_ADT_ILIST
+#define LLVM_ADT_ILIST
+
+#include "llvm/ADT/iterator"
+#include <cassert>
 
-#include <assert.h>
-#include <iterator>
+namespace llvm {
 
 template<typename NodeTy, typename Traits> class iplist;
 template<typename NodeTy> class ilist_iterator;
@@ -49,9 +58,10 @@ struct ilist_traits {
   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) {}
@@ -69,13 +79,21 @@ struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
 // ilist_iterator<Node> - Iterator for intrusive list.
 //
 template<typename NodeTy>
-class ilist_iterator : public std::bidirectional_iterator<NodeTy, ptrdiff_t> {
+class ilist_iterator
+  : public bidirectional_iterator<NodeTy, ptrdiff_t> {
   typedef ilist_traits<NodeTy> Traits;
-  pointer NodePtr;
+  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:
 
   ilist_iterator(pointer NP) : NodePtr(NP) {}
+  ilist_iterator(reference NR) : NodePtr(&NR) {}
   ilist_iterator() : NodePtr(0) {}
 
   // This is templated so that we can allow constructing a const iterator from
@@ -135,15 +153,62 @@ public:
     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...
+
+template<typename From> struct simplify_type;
+
+template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
+  typedef NodeTy* SimpleType;
+  
+  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+    return &*Node;
+  }
+};
+template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
+  typedef NodeTy* SimpleType;
+  
+  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+    return &*Node;
+  }
+};
+
 
 //===----------------------------------------------------------------------===//
 //
@@ -170,25 +235,26 @@ public:
   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; }
 
@@ -243,7 +309,7 @@ public:
       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;
   }
 
@@ -301,9 +367,14 @@ public:
   //
 
   size_type size() const {
+#if __GNUC__ == 2
+    // GCC 2.95 has a broken std::distance
     size_type Result = 0;
     std::distance(begin(), end(), Result);
     return Result;
+#else
+    return std::distance(begin(), end());
+#endif
   }
 
   iterator erase(iterator first, iterator last) {
@@ -404,18 +475,21 @@ public:
 
 template<typename NodeTy>
 struct ilist : public iplist<NodeTy> {
+  typedef typename iplist<NodeTy>::size_type size_type;
+  typedef typename iplist<NodeTy>::iterator iterator;
+
   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);
   }
 
 
@@ -434,8 +508,8 @@ struct ilist : public iplist<NodeTy> {
 
 
   // 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) {
@@ -447,16 +521,16 @@ struct ilist : public iplist<NodeTy> {
 
   // 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)
@@ -468,23 +542,24 @@ struct ilist : public iplist<NodeTy> {
 
   // 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...