Add a helper class (APSInt) which can represent an APInt along with sign
[oota-llvm.git] / include / llvm / ADT / ilist
index 09c951c2572d57e9818cd5d4f47595815a898347..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
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef INCLUDED_SUPPORT_ILIST
-#define INCLUDED_SUPPORT_ILIST
+#ifndef LLVM_ADT_ILIST
+#define LLVM_ADT_ILIST
 
-#include <assert.h>
-#include <iterator>
-#include <algorithm>
+#include "llvm/ADT/iterator"
+#include <cassert>
+
+namespace llvm {
 
 template<typename NodeTy, typename Traits> class iplist;
 template<typename NodeTy> class ilist_iterator;
@@ -50,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) {}
@@ -71,22 +80,20 @@ struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
 //
 template<typename NodeTy>
 class ilist_iterator
-#if __GNUC__ == 3
-  : public std::iterator<std::bidirectional_iterator_tag, NodeTy> {
-  typedef std::iterator<std::bidirectional_iterator_tag, NodeTy> super;
-#else
-  : public std::bidirectional_iterator<NodeTy, ptrdiff_t> {
-  typedef std::bidirectional_iterator<NodeTy, ptrdiff_t> super;
-#endif
+  : public bidirectional_iterator<NodeTy, ptrdiff_t> {
   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) {}
   ilist_iterator() : NodePtr(0) {}
 
   // This is templated so that we can allow constructing a const iterator from
@@ -146,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;
+  }
+};
+
 
 //===----------------------------------------------------------------------===//
 //
@@ -181,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; }
 
@@ -254,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;
   }
 
@@ -312,13 +367,14 @@ public:
   //
 
   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) {
@@ -424,16 +480,16 @@ struct ilist : public iplist<NodeTy> {
 
   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);
   }
 
 
@@ -452,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) {
@@ -465,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)
@@ -486,22 +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...