[ADT] Unbreak PointerEmbeddedInt build with MSVC.
[oota-llvm.git] / include / llvm / ADT / ilist_node.h
index 85d7a908096951639b1f51e8725036254f906d3d..7e5a0e0e5ad81d5867ef6710e65d2649bb84cab4 100644 (file)
@@ -39,6 +39,8 @@ protected:
 template<typename NodeTy>
 struct ilist_nextprev_traits;
 
+template <typename NodeTy> class ilist_iterator;
+
 /// ilist_node - Base class that provides next/prev services for nodes
 /// that use ilist_nextprev_traits or ilist_default_traits.
 ///
@@ -55,54 +57,64 @@ class ilist_node : private ilist_half_node<NodeTy> {
 protected:
   ilist_node() : Next(nullptr) {}
 
+public:
+  ilist_iterator<NodeTy> getIterator() {
+    // FIXME: Stop downcasting to create the iterator (potential UB).
+    return ilist_iterator<NodeTy>(static_cast<NodeTy *>(this));
+  }
+  ilist_iterator<const NodeTy> getIterator() const {
+    // FIXME: Stop downcasting to create the iterator (potential UB).
+    return ilist_iterator<const NodeTy>(static_cast<const NodeTy *>(this));
+  }
+};
+
+/// An ilist node that can access its parent list.
+///
+/// Requires \c NodeTy to have \a getParent() to find the parent node, and the
+/// \c ParentTy to have \a getSublistAccess() to get a reference to the list.
+template <typename NodeTy, typename ParentTy>
+class ilist_node_with_parent : public ilist_node<NodeTy> {
+protected:
+  ilist_node_with_parent() = default;
+
+private:
+  /// Forward to NodeTy::getParent().
+  ///
+  /// Note: do not use the name "getParent()".  We want a compile error
+  /// (instead of recursion) when the subclass fails to implement \a
+  /// getParent().
+  const ParentTy *getNodeParent() const {
+    return static_cast<const NodeTy *>(this)->getParent();
+  }
+
 public:
   /// @name Adjacent Node Accessors
   /// @{
-
-  /// \brief Get the previous node, or 0 for the list head.
+  /// \brief Get the previous node, or \c nullptr for the list head.
   NodeTy *getPrevNode() {
-    NodeTy *Prev = this->getPrev();
-
-    // Check for sentinel.
-    if (!Prev->getNext())
-      return nullptr;
-
-    return Prev;
+    // Should be separated to a reused function, but then we couldn't use auto
+    // (and would need the type of the list).
+    const auto &List =
+        getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
+    return List.getPrevNode(*static_cast<NodeTy *>(this));
   }
-
-  /// \brief Get the previous node, or 0 for the list head.
+  /// \brief Get the previous node, or \c nullptr for the list head.
   const NodeTy *getPrevNode() const {
-    const NodeTy *Prev = this->getPrev();
-
-    // Check for sentinel.
-    if (!Prev->getNext())
-      return nullptr;
-
-    return Prev;
+    return const_cast<ilist_node_with_parent *>(this)->getPrevNode();
   }
 
-  /// \brief Get the next node, or 0 for the list tail.
+  /// \brief Get the next node, or \c nullptr for the list tail.
   NodeTy *getNextNode() {
-    NodeTy *Next = getNext();
-
-    // Check for sentinel.
-    if (!Next->getNext())
-      return nullptr;
-
-    return Next;
+    // Should be separated to a reused function, but then we couldn't use auto
+    // (and would need the type of the list).
+    const auto &List =
+        getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
+    return List.getNextNode(*static_cast<NodeTy *>(this));
   }
-
-  /// \brief Get the next node, or 0 for the list tail.
+  /// \brief Get the next node, or \c nullptr for the list tail.
   const NodeTy *getNextNode() const {
-    const NodeTy *Next = getNext();
-
-    // Check for sentinel.
-    if (!Next->getNext())
-      return nullptr;
-
-    return Next;
+    return const_cast<ilist_node_with_parent *>(this)->getNextNode();
   }
-
   /// @}
 };