UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
IoContainers.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6
7namespace UE::Private
8{
9
10template <typename TypeTraits>
12{
13public:
14 using ElementType = typename TypeTraits::ElementType;
15
17 : Element(InElement)
18 { }
19
20 ElementType& operator*() const { check(Element); return *Element; }
21 explicit operator bool() { return Element != nullptr; }
22 void operator++() { check(Element); Element = TypeTraits::GetNext(Element); }
23 bool operator!=(const TIntrusiveListIterator& Other) const { return Element != Other.Element; }
24
25private:
26 ElementType* Element;
27};
28
29template <typename Type, typename TypeTraits>
31{
32public:
33 using ElementType = Type;
34
38
39 ElementType& operator*() const { check(Element); return *Element; }
40 explicit operator bool() { return Element != nullptr; }
41 void operator++() { check(Element); Element = TypeTraits::GetNext(Element); }
42 bool operator!=(const TIntrusiveTwoWayListIterator& Other) const { return Element != Other.Element; }
43
44private:
45 ElementType* Element;
46};
47
48} // namespace UE::Private
49
50template <typename Type>
52{
53 using ElementType = Type;
54
55 static Type* GetNext(const ElementType* Element)
56 {
57 return Element->Next;
58 }
59
60 static void SetNext(ElementType* Element, ElementType* Next)
61 {
62 Element->Next = Next;
63 }
64};
65
66template <typename TypeTraits>
68{
69public:
70 using ElementType = typename TypeTraits::ElementType;
73
74 TIntrusiveList() = default;
77 : Head(Other.Head)
78 , Tail(Other.Tail)
79 {
80 Other.Head = Other.Tail = nullptr;
81 }
82 explicit TIntrusiveList(ElementType* Element)
83 {
84 Head = Tail = Element;
85 }
86
89 {
90 Head = Other.Head;
91 Tail = Other.Tail;
92 Other.Head = Other.Tail = nullptr;
93 return *this;
94 }
95
96 void AddHead(ElementType* Element)
97 {
98 check(Element != nullptr && TypeTraits::GetNext(Element) == nullptr);
99
100 if (Tail == nullptr)
101 {
102 check(Head == nullptr);
103 Tail = Element;
104 }
105 else
106 {
107 TypeTraits::SetNext(Element, Head);
108 }
109 Head = Element;
110 }
111
112 void AddTail(ElementType* Element)
113 {
114 check(Element != nullptr && TypeTraits::GetNext(Element) == nullptr);
115
116 if (Tail != nullptr)
117 {
118 check(Head != nullptr);
119 TypeTraits::SetNext(Tail, Element);
120 Tail = Element;
121 }
122 else
123 {
124 check(Head == nullptr);
125 Head = Tail = Element;
126 }
127 }
128
130 {
131 check(First && Last);
132 check(TypeTraits::GetNext(First) != nullptr || First == Last);
133
134 if (Tail != nullptr)
135 {
136 check(Head != nullptr);
137 TypeTraits::SetNext(Tail, First);
138 Tail = Last;
139 }
140 else
141 {
142 check(Head == nullptr);
143 Head = First;
144 Tail = Last;
145 }
146 }
147
149 {
150 if (!Other.IsEmpty())
151 {
152 AddTail(Other.Head, Other.Tail);
153 Other.Head = Other.Tail = nullptr;
154 }
155 }
156
158 {
159 ElementType* Element = Head;
160 if (Element != nullptr)
161 {
162 Head = TypeTraits::GetNext(Element);
163 if (Head == nullptr)
164 {
165 Tail = nullptr;
166 }
167 TypeTraits::SetNext(Element, nullptr);
168 }
169
170 return Element;
171 }
172
174 {
175 return Head;
176 }
177
178 bool Remove(ElementType* Element)
179 {
180 if (Element == nullptr || IsEmpty())
181 {
182 return false;
183 }
184
185 if (Element == Head)
186 {
187 PopHead();
188 return true;
189 }
190
191 ElementType* It = Head;
192 ElementType* NextElement = TypeTraits::GetNext(It);
193 while (NextElement != nullptr && NextElement != Element)
194 {
195 It = NextElement;
196 NextElement = TypeTraits::GetNext(It);
197 }
198
199 if (NextElement != Element)
200 {
201 return false;
202 }
203
204 It->Next = TypeTraits::GetNext(Element);
205 TypeTraits::SetNext(Element, nullptr);
206 if (Element == Tail)
207 {
208 Tail = It;
209 }
210
211 return true;
212 }
213
220 template<typename PredicateType>
222 {
223 check(Element != nullptr && TypeTraits::GetNext(Element) == nullptr);
224
225 if (IsEmpty() || Predicate(*Element, *Head))
226 {
227 AddHead(Element);
228 return;
229 }
230
231 ElementType* It = Head;
232 ElementType* NextElement = TypeTraits::GetNext(It);
233 while (NextElement != nullptr)
234 {
235 if (Predicate(*Element, *NextElement))
236 {
237 TypeTraits::SetNext(It, Element);
238 TypeTraits::SetNext(Element, NextElement);
239 return;
240 }
241
242 It = NextElement;
243 NextElement = TypeTraits::GetNext(It);
244 }
245
246 AddTail(Element);
247 }
248
249 bool IsEmpty() const { return Head == nullptr; }
250 ElementType* GetHead() { return Head; }
251 const ElementType* GetHead() const { return Head; }
252 ElementType* GetTail() { return Tail; }
253 const ElementType* GetTail() const { return Tail; }
254
255 FIterator begin() { return FIterator(Head); }
256 FConstIterator begin() const { return FConstIterator(Head); }
257 FIterator end() { return FIterator(nullptr); }
258 FConstIterator end() const { return FConstIterator(nullptr); }
259
260private:
261 ElementType* Head = nullptr;
262 ElementType* Tail = nullptr;
263};
264
265template <typename Type>
267{
268 using ElementType = Type;
269
270 static Type* GetNext(const ElementType* Element)
271 {
272 return Element->Next;
273 }
274
275 static void SetNext(ElementType* Element, ElementType* Next)
276 {
277 Element->Next = Next;
278 }
279
280 static Type* GetPrev(const ElementType* Element)
281 {
282 return Element->Prev;
283 }
284
285 static void SetPrev(ElementType* Element, ElementType* Prev)
286 {
287 Element->Prev = Prev;
288 }
289};
290
291template <typename ElementType, typename TypeTraits = TIntrusiveTwoWayListTraits<ElementType>>
293{
294public:
295
298
302 : Head(Other.Head)
303 , Tail(Other.Tail)
304 {
305 Other.Head = Other.Tail = nullptr;
306 }
307 explicit TIntrusiveTwoWayList(ElementType* Element)
308 {
309 Head = Tail = Element;
310 }
311
314 {
315 Head = Other.Head;
316 Tail = Other.Tail;
317 Other.Head = Other.Tail = nullptr;
318 return *this;
319 }
320
321 void AddTail(ElementType* Element)
322 {
323 check(Element != nullptr && TypeTraits::GetNext(Element) == nullptr && TypeTraits::GetPrev(Element) == nullptr);
324
325 if (Tail != nullptr)
326 {
327 check(Head != nullptr);
328 TypeTraits::SetNext(Tail, Element);
329 TypeTraits::SetPrev(Element, Tail);
330 Tail = Element;
331 }
332 else
333 {
334 check(Head == nullptr);
335 Head = Tail = Element;
336 }
337 }
338
339 void AddHead(ElementType* Element)
340 {
341 check(Element != nullptr && TypeTraits::GetNext(Element) == nullptr && TypeTraits::GetPrev(Element) == nullptr);
342
343 if (Head != nullptr)
344 {
345 check(Tail != nullptr);
346 TypeTraits::SetNext(Element, Head);
347 TypeTraits::SetPrev(Head, Element);
348 Head = Element;
349 }
350 else
351 {
352 check(Tail == nullptr);
353 Head = Tail = Element;
354 }
355 }
356
357 [[nodiscard]] ElementType* PopHead()
358 {
359 ElementType* Element = Head;
360 if (Element != nullptr)
361 {
362 Head = TypeTraits::GetNext(Element);
363 TypeTraits::SetNext(Element, nullptr);
364
365 if (Head != nullptr)
366 {
367 TypeTraits::SetPrev(Head, nullptr);
368 }
369 else
370 {
371 Tail = nullptr;
372 }
373 }
374
375 return Element;
376 }
377
378 [[nodiscard]] ElementType* PeekHead()
379 {
380 return Head;
381 }
382
383 bool IsEmpty() const { return Head == nullptr; }
384 ElementType* GetHead() { return Head; }
385 const ElementType* GetHead() const { return Head; }
386 ElementType* GetTail() { return Tail; }
387 const ElementType* GetTail() const { return Tail; }
388
389 FIterator begin() { return FIterator(Head); }
390 FConstIterator begin() const { return FConstIterator(Head); }
391 FIterator end() { return FIterator(nullptr); }
392 FConstIterator end() const { return FConstIterator(nullptr); }
393
394 void Remove(ElementType* Element)
395 {
396 check(Element != nullptr);
397
398 if (Head == Element && Tail == Element)
399 {
400 check(TypeTraits::GetNext(Element) == nullptr);
401 check(TypeTraits::GetPrev(Element) == nullptr);
402
403 Head = Tail = nullptr;
404 }
405 else if (Head == Element)
406 {
407 check(TypeTraits::GetPrev(Element) == nullptr);
408
409 Head = TypeTraits::GetNext(Element);
410 TypeTraits::SetPrev(Head, nullptr);
411 TypeTraits::SetNext(Element, nullptr);
412 }
413 else if (Tail == Element)
414 {
415 check(Element->Next == nullptr);
416
417 Tail = TypeTraits::GetPrev(Element);
418 TypeTraits::SetNext(Tail, nullptr);
419 TypeTraits::SetPrev(Element, nullptr);
420 }
421 else
422 {
423 ElementType* NextElement = TypeTraits::GetNext(Element);
424 ElementType* PrevElement = TypeTraits::GetPrev(Element);
425
426 TypeTraits::SetPrev(NextElement, PrevElement);
427 TypeTraits::SetNext(PrevElement, NextElement);
428
429 TypeTraits::SetNext(Element, nullptr);
430 TypeTraits::SetPrev(Element, nullptr);
431 }
432 }
433
434private:
435 ElementType* Head = nullptr;
436 ElementType* Tail = nullptr;
437};
#define check(expr)
Definition AssertionMacros.h:314
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const bool
Definition NetworkReplayStreaming.h:178
Definition IoContainers.h:68
ElementType * PopHead()
Definition IoContainers.h:157
UE::Private::TIntrusiveListIterator< TypeTraits > FIterator
Definition IoContainers.h:71
ElementType * GetTail()
Definition IoContainers.h:252
UE::Private::TIntrusiveListIterator< const TypeTraits > FConstIterator
Definition IoContainers.h:72
ElementType * GetHead()
Definition IoContainers.h:250
void AddHead(ElementType *Element)
Definition IoContainers.h:96
void AddTail(ElementType *Element)
Definition IoContainers.h:112
FIterator begin()
Definition IoContainers.h:255
FIterator end()
Definition IoContainers.h:257
const ElementType * GetTail() const
Definition IoContainers.h:253
FConstIterator begin() const
Definition IoContainers.h:256
TIntrusiveList(const TIntrusiveList &)=delete
FConstIterator end() const
Definition IoContainers.h:258
bool IsEmpty() const
Definition IoContainers.h:249
bool Remove(ElementType *Element)
Definition IoContainers.h:178
void AddTail(ElementType *First, ElementType *Last)
Definition IoContainers.h:129
TIntrusiveList(TIntrusiveList &&Other)
Definition IoContainers.h:76
void AddTail(TIntrusiveList &&Other)
Definition IoContainers.h:148
typename TypeTraits::ElementType ElementType
Definition IoContainers.h:70
ElementType * PeekHead()
Definition IoContainers.h:173
TIntrusiveList()=default
void AddOrInsertBefore(ElementType *Element, PredicateType Predicate)
Definition IoContainers.h:221
TIntrusiveList(ElementType *Element)
Definition IoContainers.h:82
TIntrusiveList & operator=(const TIntrusiveList &)=delete
TIntrusiveList & operator=(TIntrusiveList &&Other)
Definition IoContainers.h:88
const ElementType * GetHead() const
Definition IoContainers.h:251
Definition IoContainers.h:293
const ElementType * GetTail() const
Definition IoContainers.h:387
UE::Private::TIntrusiveTwoWayListIterator< ElementType, TypeTraits > FIterator
Definition IoContainers.h:296
FIterator end()
Definition IoContainers.h:391
TIntrusiveTwoWayList(TIntrusiveTwoWayList &&Other)
Definition IoContainers.h:301
TIntrusiveTwoWayList(ElementType *Element)
Definition IoContainers.h:307
FConstIterator end() const
Definition IoContainers.h:392
TIntrusiveTwoWayList()=default
void Remove(ElementType *Element)
Definition IoContainers.h:394
FConstIterator begin() const
Definition IoContainers.h:390
const ElementType * GetHead() const
Definition IoContainers.h:385
void AddTail(ElementType *Element)
Definition IoContainers.h:321
ElementType * GetTail()
Definition IoContainers.h:386
FIterator begin()
Definition IoContainers.h:389
ElementType * PopHead()
Definition IoContainers.h:357
TIntrusiveTwoWayList & operator=(const TIntrusiveTwoWayList &)=delete
void AddHead(ElementType *Element)
Definition IoContainers.h:339
ElementType * GetHead()
Definition IoContainers.h:384
bool IsEmpty() const
Definition IoContainers.h:383
ElementType * PeekHead()
Definition IoContainers.h:378
TIntrusiveTwoWayList(const TIntrusiveTwoWayList &)=delete
UE::Private::TIntrusiveTwoWayListIterator< ElementType, const TypeTraits > FConstIterator
Definition IoContainers.h:297
TIntrusiveTwoWayList & operator=(TIntrusiveTwoWayList &&Other)
Definition IoContainers.h:313
Definition IoContainers.h:12
TIntrusiveListIterator(ElementType *InElement)
Definition IoContainers.h:16
ElementType & operator*() const
Definition IoContainers.h:20
void operator++()
Definition IoContainers.h:22
bool operator!=(const TIntrusiveListIterator &Other) const
Definition IoContainers.h:23
typename TypeTraits::ElementType ElementType
Definition IoContainers.h:14
Definition IoContainers.h:31
ElementType & operator*() const
Definition IoContainers.h:39
TIntrusiveTwoWayListIterator(ElementType *InElement)
Definition IoContainers.h:35
void operator++()
Definition IoContainers.h:41
Type ElementType
Definition IoContainers.h:33
bool operator!=(const TIntrusiveTwoWayListIterator &Other) const
Definition IoContainers.h:42
Definition PackageReader.cpp:44
Definition IoContainers.h:52
Type ElementType
Definition IoContainers.h:53
static void SetNext(ElementType *Element, ElementType *Next)
Definition IoContainers.h:60
static Type * GetNext(const ElementType *Element)
Definition IoContainers.h:55
Definition IoContainers.h:267
static void SetNext(ElementType *Element, ElementType *Next)
Definition IoContainers.h:275
Type ElementType
Definition IoContainers.h:268
static void SetPrev(ElementType *Element, ElementType *Prev)
Definition IoContainers.h:285
static Type * GetNext(const ElementType *Element)
Definition IoContainers.h:270
static Type * GetPrev(const ElementType *Element)
Definition IoContainers.h:280