UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
IntrusiveDoubleLinkedList.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
7
8
9// Forward declarations
10template <class NodeType>
12
13template <class ElementType, class ContainerType>
15
16
23template <class InElementType, class ContainerType = InElementType>
25{
26public:
29
34
36 {
38 }
39
41 {
42 return Next != GetThisElement();
43 }
45 {
46 return Next;
47 }
49 {
50 return Prev;
51 }
52
56 inline void Remove()
57 {
58 static_cast<NodeType*>(Next)->Prev = Prev;
59 static_cast<NodeType*>(Prev)->Next = Next;
61 }
62
67 {
68 ElementType* NewNext = static_cast<NodeType*>(NewPrev)->Next;
69 Next = NewNext;
70 Prev = NewPrev;
71 static_cast<NodeType*>(NewNext)->Prev = GetThisElement();
72 static_cast<NodeType*>(NewPrev)->Next = GetThisElement();
73 }
74
79 {
80 ElementType* NewPrev = static_cast<NodeType*>(NewNext)->Prev;
81 Next = NewNext;
82 Prev = NewPrev;
83 static_cast<NodeType*>(NewNext)->Prev = GetThisElement();
84 static_cast<NodeType*>(NewPrev)->Next = GetThisElement();
85 }
86
87protected:
89 friend class TIntrusiveDoubleLinkedList<ElementType, ContainerType>;
90
92 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType* GetThisElement() const { return static_cast<const ElementType*>(this); }
93
96}; // TIntrusiveDoubleLinkedListNode
97
98
102template <class NodeType>
104{
105public:
106 using ElementType = typename NodeType::ElementType;
107
109 : CurrentNode(Node)
110 {
111 }
112
114 {
115 checkSlow(CurrentNode);
116 CurrentNode = CurrentNode->NodeType::Next;
117 return *this;
118 }
119
121 {
122 auto Tmp = *this;
123 ++(*this);
124 return Tmp;
125 }
126
128 {
129 checkSlow(CurrentNode);
130 CurrentNode = CurrentNode->NodeType::Prev;
131 return *this;
132 }
133
135 {
136 auto Tmp = *this;
137 --(*this);
138 return Tmp;
139 }
140
141 // Accessors.
142 [[nodiscard]] inline ElementType& operator->() const
143 {
144 checkSlow(CurrentNode);
145 return *CurrentNode;
146 }
147
148 [[nodiscard]] inline ElementType& operator*() const
149 {
150 checkSlow(CurrentNode);
151 return *CurrentNode;
152 }
153
154 [[nodiscard]] inline ElementType* GetNode() const
155 {
156 checkSlow(CurrentNode);
157 return CurrentNode;
158 }
159
160 [[nodiscard]] UE_FORCEINLINE_HINT bool operator==(const TIntrusiveDoubleLinkedListIterator& Other) const { return CurrentNode == Other.CurrentNode; }
161 [[nodiscard]] UE_FORCEINLINE_HINT bool operator!=(const TIntrusiveDoubleLinkedListIterator& Other) const { return CurrentNode != Other.CurrentNode; }
162
163private:
164 ElementType* CurrentNode;
165}; // TIntrusiveDoubleLinkedListIterator
166
167
173template <class InElementType, class ContainerType = InElementType>
175{
176public:
177
180
184
187
194 {
195 Sentinel.Reset();
196 }
197
198 // Accessors.
199
201 {
202 return Sentinel.Next == GetSentinel();
203 }
205 {
206 return Sentinel.Next != GetSentinel();
207 }
208
209 // Adding/Removing methods
210
212 {
213 static_cast<NodeType*>(Element)->InsertAfter(GetSentinel());
214 }
215
217 {
218 if (Other.IsFilled())
219 {
220 static_cast<NodeType*>(Other.Sentinel.Prev)->Next = Sentinel.Next;
221 static_cast<NodeType*>(Other.Sentinel.Next)->Prev = GetSentinel();
222 static_cast<NodeType*>(Sentinel.Next)->Prev = Other.Sentinel.Prev;
223 Sentinel.Next = Other.Sentinel.Next;
224 Other.Sentinel.Next = Other.Sentinel.Prev = Other.GetSentinel();
225 }
226 }
227
229 {
230 static_cast<NodeType*>(Element)->InsertBefore(GetSentinel());
231 }
232
234 {
235 if (Other.IsFilled())
236 {
237 static_cast<NodeType*>(Other.Sentinel.Next)->Prev = Sentinel.Prev;
238 static_cast<NodeType*>(Other.Sentinel.Prev)->Next = GetSentinel();
239 static_cast<NodeType*>(Sentinel.Prev)->Next = Other.Sentinel.Next;
240 Sentinel.Prev = Other.Sentinel.Prev;
241 Other.Sentinel.Next = Other.Sentinel.Prev = Other.GetSentinel();
242 }
243 }
244
246 {
247 return IsFilled() ? Sentinel.Next : nullptr;
248 }
249
251 {
252 return IsFilled() ? Sentinel.Prev : nullptr;
253 }
254
256 {
257 if (IsEmpty())
258 {
259 return nullptr;
260 }
261
262 ElementType* Head = Sentinel.Next;
263 static_cast<NodeType*>(Head)->Remove();
264 return Head;
265 }
266
268 {
269 if (IsEmpty())
270 {
271 return nullptr;
272 }
273
274 ElementType* Tail = Sentinel.Prev;
275 static_cast<NodeType*>(Tail)->Remove();
276 return Tail;
277 }
278
280 {
281 static_cast<NodeType*>(Element)->Remove();
282 }
283
288
293
296
299 [[nodiscard]] UE_FORCEINLINE_HINT TIterator end() { return TIterator(GetSentinel()); }
300 [[nodiscard]] UE_FORCEINLINE_HINT TConstIterator end() const { return TConstIterator(GetSentinel()); }
301
302private:
303
304 [[nodiscard]] UE_FORCEINLINE_HINT ElementType* GetSentinel() { return static_cast<ElementType*>(&Sentinel); } //-V717
305 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType* GetSentinel() const { return static_cast<const ElementType*>(&Sentinel); } //-V717
306
307 NodeType Sentinel;
308
309}; // TIntrusiveDoubleLinkedList
310
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition IntrusiveDoubleLinkedList.h:104
typename NodeType::ElementType ElementType
Definition IntrusiveDoubleLinkedList.h:106
TIntrusiveDoubleLinkedListIterator & operator--()
Definition IntrusiveDoubleLinkedList.h:127
UE_FORCEINLINE_HINT bool operator==(const TIntrusiveDoubleLinkedListIterator &Other) const
Definition IntrusiveDoubleLinkedList.h:160
UE_FORCEINLINE_HINT TIntrusiveDoubleLinkedListIterator(ElementType *Node)
Definition IntrusiveDoubleLinkedList.h:108
ElementType * GetNode() const
Definition IntrusiveDoubleLinkedList.h:154
ElementType & operator->() const
Definition IntrusiveDoubleLinkedList.h:142
UE_FORCEINLINE_HINT bool operator!=(const TIntrusiveDoubleLinkedListIterator &Other) const
Definition IntrusiveDoubleLinkedList.h:161
TIntrusiveDoubleLinkedListIterator & operator++()
Definition IntrusiveDoubleLinkedList.h:113
TIntrusiveDoubleLinkedListIterator operator--(int)
Definition IntrusiveDoubleLinkedList.h:134
ElementType & operator*() const
Definition IntrusiveDoubleLinkedList.h:148
TIntrusiveDoubleLinkedListIterator operator++(int)
Definition IntrusiveDoubleLinkedList.h:120
Definition IntrusiveDoubleLinkedList.h:25
UE_FORCEINLINE_HINT bool IsInList() const
Definition IntrusiveDoubleLinkedList.h:40
InElementType ElementType
Definition IntrusiveDoubleLinkedList.h:28
UE_FORCEINLINE_HINT ElementType * GetNext() const
Definition IntrusiveDoubleLinkedList.h:44
void Remove()
Definition IntrusiveDoubleLinkedList.h:56
ElementType * Prev
Definition IntrusiveDoubleLinkedList.h:95
UE_FORCEINLINE_HINT ElementType * GetPrev() const
Definition IntrusiveDoubleLinkedList.h:48
void InsertAfter(ElementType *NewPrev)
Definition IntrusiveDoubleLinkedList.h:66
UE_FORCEINLINE_HINT void Reset()
Definition IntrusiveDoubleLinkedList.h:35
ElementType * Next
Definition IntrusiveDoubleLinkedList.h:94
TIntrusiveDoubleLinkedListNode()
Definition IntrusiveDoubleLinkedList.h:30
UE_FORCEINLINE_HINT ElementType * GetThisElement()
Definition IntrusiveDoubleLinkedList.h:91
UE_FORCEINLINE_HINT const ElementType * GetThisElement() const
Definition IntrusiveDoubleLinkedList.h:92
void InsertBefore(ElementType *NewNext)
Definition IntrusiveDoubleLinkedList.h:78
Definition IntrusiveDoubleLinkedList.h:175
UE_FORCEINLINE_HINT TIterator begin()
Definition IntrusiveDoubleLinkedList.h:297
UE_FORCEINLINE_HINT TIntrusiveDoubleLinkedList()
Definition IntrusiveDoubleLinkedList.h:181
TIntrusiveDoubleLinkedListNode< ElementType, ContainerType > NodeType
Definition IntrusiveDoubleLinkedList.h:179
InElementType ElementType
Definition IntrusiveDoubleLinkedList.h:178
UE_FORCEINLINE_HINT ElementType * GetHead()
Definition IntrusiveDoubleLinkedList.h:245
TIntrusiveDoubleLinkedListIterator< const NodeType > TConstIterator
Definition IntrusiveDoubleLinkedList.h:295
TIntrusiveDoubleLinkedListIterator< NodeType > TIterator
Definition IntrusiveDoubleLinkedList.h:294
UE_FORCEINLINE_HINT bool IsEmpty() const
Definition IntrusiveDoubleLinkedList.h:200
UE_FORCEINLINE_HINT TIntrusiveDoubleLinkedList & operator=(const TIntrusiveDoubleLinkedList &)=delete
static UE_FORCEINLINE_HINT void Remove(ElementType *Element)
Definition IntrusiveDoubleLinkedList.h:279
static UE_FORCEINLINE_HINT void InsertAfter(ElementType *InsertThis, ElementType *AfterThis)
Definition IntrusiveDoubleLinkedList.h:284
UE_FORCEINLINE_HINT void AddHead(ElementType *Element)
Definition IntrusiveDoubleLinkedList.h:211
ElementType * PopHead()
Definition IntrusiveDoubleLinkedList.h:255
void AddTail(TIntrusiveDoubleLinkedList &&Other)
Definition IntrusiveDoubleLinkedList.h:233
UE_FORCEINLINE_HINT TConstIterator begin() const
Definition IntrusiveDoubleLinkedList.h:298
UE_FORCEINLINE_HINT TConstIterator end() const
Definition IntrusiveDoubleLinkedList.h:300
UE_FORCEINLINE_HINT TIntrusiveDoubleLinkedList(const TIntrusiveDoubleLinkedList &)=delete
void AddHead(TIntrusiveDoubleLinkedList &&Other)
Definition IntrusiveDoubleLinkedList.h:216
UE_FORCEINLINE_HINT ElementType * GetTail()
Definition IntrusiveDoubleLinkedList.h:250
static UE_FORCEINLINE_HINT void InsertBefore(ElementType *InsertThis, ElementType *BeforeThis)
Definition IntrusiveDoubleLinkedList.h:289
UE_FORCEINLINE_HINT void Reset()
Definition IntrusiveDoubleLinkedList.h:193
ElementType * PopTail()
Definition IntrusiveDoubleLinkedList.h:267
UE_FORCEINLINE_HINT TIterator end()
Definition IntrusiveDoubleLinkedList.h:299
UE_FORCEINLINE_HINT bool IsFilled() const
Definition IntrusiveDoubleLinkedList.h:204
UE_FORCEINLINE_HINT void AddTail(ElementType *Element)
Definition IntrusiveDoubleLinkedList.h:228