1 //===- llvm/ADT/ilist_node_base.h - Intrusive List Node Base -----*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_ADT_ILIST_NODE_BASE_H 10 #define LLVM_ADT_ILIST_NODE_BASE_H 11 12 #include "llvm/ADT/PointerIntPair.h" 13 14 namespace llvm { 15 16 namespace ilist_detail { 17 18 template <class NodeBase, bool EnableSentinelTracking> class node_base_prevnext; 19 20 template <class NodeBase> class node_base_prevnext<NodeBase, false> { 21 NodeBase *Prev = nullptr; 22 NodeBase *Next = nullptr; 23 24 public: setPrev(NodeBase * Prev)25 void setPrev(NodeBase *Prev) { this->Prev = Prev; } setNext(NodeBase * Next)26 void setNext(NodeBase *Next) { this->Next = Next; } getPrev()27 NodeBase *getPrev() const { return Prev; } getNext()28 NodeBase *getNext() const { return Next; } 29 isKnownSentinel()30 bool isKnownSentinel() const { return false; } initializeSentinel()31 void initializeSentinel() {} 32 }; 33 34 template <class NodeBase> class node_base_prevnext<NodeBase, true> { 35 PointerIntPair<NodeBase *, 1> PrevAndSentinel; 36 NodeBase *Next = nullptr; 37 38 public: setPrev(NodeBase * Prev)39 void setPrev(NodeBase *Prev) { PrevAndSentinel.setPointer(Prev); } setNext(NodeBase * Next)40 void setNext(NodeBase *Next) { this->Next = Next; } getPrev()41 NodeBase *getPrev() const { return PrevAndSentinel.getPointer(); } getNext()42 NodeBase *getNext() const { return Next; } 43 isSentinel()44 bool isSentinel() const { return PrevAndSentinel.getInt(); } isKnownSentinel()45 bool isKnownSentinel() const { return isSentinel(); } initializeSentinel()46 void initializeSentinel() { PrevAndSentinel.setInt(true); } 47 }; 48 49 template <class ParentTy> class node_base_parent { 50 ParentTy *Parent = nullptr; 51 52 public: setNodeBaseParent(ParentTy * Parent)53 void setNodeBaseParent(ParentTy *Parent) { this->Parent = Parent; } getNodeBaseParent()54 inline const ParentTy *getNodeBaseParent() const { return Parent; } getNodeBaseParent()55 inline ParentTy *getNodeBaseParent() { return Parent; } 56 }; 57 template <> class node_base_parent<void> {}; 58 59 } // end namespace ilist_detail 60 61 /// Base class for ilist nodes. 62 /// 63 /// Optionally tracks whether this node is the sentinel. 64 template <bool EnableSentinelTracking, class ParentTy> 65 class ilist_node_base : public ilist_detail::node_base_prevnext< 66 ilist_node_base<EnableSentinelTracking, ParentTy>, 67 EnableSentinelTracking>, 68 public ilist_detail::node_base_parent<ParentTy> {}; 69 70 } // end namespace llvm 71 72 #endif // LLVM_ADT_ILIST_NODE_BASE_H 73