1 | //===- llvm/ADT/ilist_base.h - Intrusive List Base --------------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef LLVM_ADT_ILIST_BASE_H |
11 | #define LLVM_ADT_ILIST_BASE_H |
12 | |
13 | #include "llvm/ADT/ilist_node_base.h" |
14 | #include <cassert> |
15 | |
16 | namespace llvm { |
17 | |
18 | /// Implementations of list algorithms using ilist_node_base. |
19 | template <bool EnableSentinelTracking> class ilist_base { |
20 | public: |
21 | using node_base_type = ilist_node_base<EnableSentinelTracking>; |
22 | |
23 | static void insertBeforeImpl(node_base_type &Next, node_base_type &N) { |
24 | node_base_type &Prev = *Next.getPrev(); |
25 | N.setNext(&Next); |
26 | N.setPrev(&Prev); |
27 | Prev.setNext(&N); |
28 | Next.setPrev(&N); |
29 | } |
30 | |
31 | static void removeImpl(node_base_type &N) { |
32 | node_base_type *Prev = N.getPrev(); |
33 | node_base_type *Next = N.getNext(); |
34 | Next->setPrev(Prev); |
35 | Prev->setNext(Next); |
36 | |
37 | // Not strictly necessary, but helps catch a class of bugs. |
38 | N.setPrev(nullptr); |
39 | N.setNext(nullptr); |
40 | } |
41 | |
42 | static void removeRangeImpl(node_base_type &First, node_base_type &Last) { |
43 | node_base_type *Prev = First.getPrev(); |
44 | node_base_type *Final = Last.getPrev(); |
45 | Last.setPrev(Prev); |
46 | Prev->setNext(&Last); |
47 | |
48 | // Not strictly necessary, but helps catch a class of bugs. |
49 | First.setPrev(nullptr); |
50 | Final->setNext(nullptr); |
51 | } |
52 | |
53 | static void transferBeforeImpl(node_base_type &Next, node_base_type &First, |
54 | node_base_type &Last) { |
55 | if (&Next == &Last || &First == &Last) |
56 | return; |
57 | |
58 | // Position cannot be contained in the range to be transferred. |
59 | assert(&Next != &First && |
60 | // Check for the most common mistake. |
61 | "Insertion point can't be one of the transferred nodes" ); |
62 | |
63 | node_base_type &Final = *Last.getPrev(); |
64 | |
65 | // Detach from old list/position. |
66 | First.getPrev()->setNext(&Last); |
67 | Last.setPrev(First.getPrev()); |
68 | |
69 | // Splice [First, Final] into its new list/position. |
70 | node_base_type &Prev = *Next.getPrev(); |
71 | Final.setNext(&Next); |
72 | First.setPrev(&Prev); |
73 | Prev.setNext(&First); |
74 | Next.setPrev(&Final); |
75 | } |
76 | |
77 | template <class T> static void insertBefore(T &Next, T &N) { |
78 | insertBeforeImpl(Next, N); |
79 | } |
80 | |
81 | template <class T> static void remove(T &N) { removeImpl(N); } |
82 | template <class T> static void removeRange(T &First, T &Last) { |
83 | removeRangeImpl(First, Last); |
84 | } |
85 | |
86 | template <class T> static void transferBefore(T &Next, T &First, T &Last) { |
87 | transferBeforeImpl(Next, First, Last); |
88 | } |
89 | }; |
90 | |
91 | } // end namespace llvm |
92 | |
93 | #endif // LLVM_ADT_ILIST_BASE_H |
94 | |