UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
List.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"
8
9template <class ContainerType>
11{
12public:
13 [[nodiscard]] explicit TLinkedListIteratorBase(ContainerType* FirstLink)
15 {
16 }
17
21 inline void Next()
22 {
24 CurrentLink = (ContainerType*)CurrentLink->GetNextLink();
25 }
26
28 {
29 Next();
30 return *this;
31 }
32
34 {
35 auto Tmp = *this;
36 Next();
37 return Tmp;
38 }
39
41 [[nodiscard]] UE_FORCEINLINE_HINT explicit operator bool() const
42 {
43 return CurrentLink != nullptr;
44 }
45
46 [[nodiscard]] UE_FORCEINLINE_HINT bool operator==(const TLinkedListIteratorBase& Rhs) const { return CurrentLink == Rhs.CurrentLink; }
47 [[nodiscard]] UE_FORCEINLINE_HINT bool operator!=(const TLinkedListIteratorBase& Rhs) const { return CurrentLink != Rhs.CurrentLink; }
48protected:
49
50 ContainerType* CurrentLink;
51};
52
53template <class ContainerType, class ElementType>
54class TLinkedListIterator : public TLinkedListIteratorBase<ContainerType>
55{
57
58public:
59 [[nodiscard]] explicit TLinkedListIterator(ContainerType* FirstLink)
61 {
62 }
63
64 // Accessors.
65 inline ElementType& operator->() const
66 {
68 return **(this->CurrentLink);
69 }
70
71 inline ElementType& operator*() const
72 {
74 return **(this->CurrentLink);
75 }
76};
77
78template <class ContainerType, class ElementType>
80{
82
83public:
86 {
87 }
88
89 // Accessors.
90 inline ElementType& operator->() const
91 {
93 return *(this->CurrentLink);
94 }
95
96 inline ElementType& operator*() const
97 {
99 return *(this->CurrentLink);
100 }
101};
102
103
107template <class ContainerType, class ElementType, template<class, class> class IteratorType>
109{
110public:
116
117
122 : NextLink(NULL)
123 , PrevLink(NULL)
124 {
125 }
126
132 inline void Unlink()
133 {
134 if( NextLink )
135 {
136 NextLink->PrevLink = PrevLink;
137 }
138 if( PrevLink )
139 {
140 *PrevLink = NextLink;
141 }
142 // Make it safe to call Unlink again.
143 NextLink = nullptr;
144 PrevLink = nullptr;
145 }
146
147
153 inline void LinkBefore(ContainerType* Before)
154 {
156
157 PrevLink = Before->PrevLink;
158 Before->PrevLink = &NextLink;
159
160 NextLink = Before;
161
162 if (PrevLink != NULL)
163 {
164 *PrevLink = (ContainerType*)this;
165 }
166 }
167
173 inline void LinkAfter(ContainerType* After)
174 {
175 checkSlow(After != NULL);
176
177 PrevLink = &After->NextLink;
178 NextLink = *PrevLink;
179 *PrevLink = (ContainerType*)this;
180
181 if (NextLink != NULL)
182 {
183 NextLink->PrevLink = &NextLink;
184 }
185 }
186
193 inline void LinkReplace(ContainerType* Replace)
194 {
195 checkSlow(Replace != NULL);
196
197 ContainerType**& ReplacePrev = Replace->PrevLink;
198 ContainerType*& ReplaceNext = Replace->NextLink;
199
200 PrevLink = ReplacePrev;
201 NextLink = ReplaceNext;
202
203 if (PrevLink != NULL)
204 {
205 *PrevLink = (ContainerType*)this;
206 }
207
208 if (NextLink != NULL)
209 {
210 NextLink->PrevLink = &NextLink;
211 }
212
215 }
216
217
226 inline void LinkHead(ContainerType*& Head)
227 {
228 if (Head != NULL)
229 {
230 Head->PrevLink = &NextLink;
231 }
232
233 NextLink = Head;
234 PrevLink = &Head;
235 Head = (ContainerType*)this;
236 }
237
238
245 {
246 return PrevLink != nullptr;
247 }
248
249 [[nodiscard]] UE_FORCEINLINE_HINT ContainerType** GetPrevLink() const
250 {
251 return PrevLink;
252 }
253
254 [[nodiscard]] UE_FORCEINLINE_HINT ContainerType* GetNextLink() const
255 {
256 return NextLink;
257 }
258
259 [[nodiscard]] UE_FORCEINLINE_HINT ContainerType* Next()
260 {
261 return NextLink;
262 }
263
264private:
266 ContainerType* NextLink;
267
269 ContainerType** PrevLink;
270
271
272 [[nodiscard]] UE_FORCEINLINE_HINT friend TIterator begin( ContainerType& List) { return TIterator (&List); }
273 [[nodiscard]] UE_FORCEINLINE_HINT friend TConstIterator begin(const ContainerType& List) { return TConstIterator(const_cast<ContainerType*>(&List)); }
274 [[nodiscard]] UE_FORCEINLINE_HINT friend TIterator end ( ContainerType& List) { return TIterator (nullptr); }
275 [[nodiscard]] UE_FORCEINLINE_HINT friend TConstIterator end (const ContainerType& List) { return TConstIterator(nullptr); }
276};
277
283template <class ElementType>
284class TLinkedList : public TLinkedListBase<TLinkedList<ElementType>, ElementType, TLinkedListIterator>
285{
287
288public:
291 : Super()
292 {
293 }
294
300 [[nodiscard]] explicit TLinkedList(const ElementType& InElement)
301 : Super()
302 , Element(InElement)
303 {
304 }
305
306
307 // Accessors.
309 {
310 return &Element;
311 }
312 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType* operator->() const
313 {
314 return &Element;
315 }
317 {
318 return Element;
319 }
320 [[nodiscard]] UE_FORCEINLINE_HINT const ElementType& operator*() const
321 {
322 return Element;
323 }
324
325
326private:
327 ElementType Element;
328};
329
347template <class ElementType>
348class TIntrusiveLinkedList : public TLinkedListBase<ElementType, ElementType, TIntrusiveLinkedListIterator>
349{
351
352public:
355 : Super()
356 {
357 }
358};
359
360
361template <class NodeType, class ElementType>
363{
364public:
365
367 : CurrentNode(StartingNode)
368 {
369 }
370
372 [[nodiscard]] UE_FORCEINLINE_HINT explicit operator bool() const
373 {
374 return CurrentNode != nullptr;
375 }
376
378 {
379 checkSlow(CurrentNode);
380 CurrentNode = CurrentNode->GetNextNode();
381 return *this;
382 }
383
385 {
386 auto Tmp = *this;
387 ++(*this);
388 return Tmp;
389 }
390
392 {
393 checkSlow(CurrentNode);
394 CurrentNode = CurrentNode->GetPrevNode();
395 return *this;
396 }
397
399 {
400 auto Tmp = *this;
401 --(*this);
402 return Tmp;
403 }
404
405 // Accessors.
406 [[nodiscard]] ElementType& operator->() const
407 {
408 checkSlow(CurrentNode);
409 return CurrentNode->GetValue();
410 }
411
412 [[nodiscard]] ElementType& operator*() const
413 {
414 checkSlow(CurrentNode);
415 return CurrentNode->GetValue();
416 }
417
418 [[nodiscard]] NodeType* GetNode() const
419 {
420 checkSlow(CurrentNode);
421 return CurrentNode;
422 }
423
424 [[nodiscard]] bool operator==(const TDoubleLinkedListIterator& Rhs) const { return CurrentNode == Rhs.CurrentNode; }
425 [[nodiscard]] bool operator!=(const TDoubleLinkedListIterator& Rhs) const { return CurrentNode != Rhs.CurrentNode; }
426
427private:
428 NodeType* CurrentNode;
429};
430
431
437template <class ElementType>
439{
440public:
442 {
443 public:
444 friend class TDoubleLinkedList;
445
447 [[nodiscard]] TDoubleLinkedListNode( const ElementType& InValue )
448 : Value(InValue), NextNode(nullptr), PrevNode(nullptr)
449 {
450 }
451
452 [[nodiscard]] const ElementType& GetValue() const
453 {
454 return Value;
455 }
456
457 [[nodiscard]] ElementType& GetValue()
458 {
459 return Value;
460 }
461
463 {
464 return NextNode;
465 }
466
468 {
469 return NextNode;
470 }
471
473 {
474 return PrevNode;
475 }
476
478 {
479 return PrevNode;
480 }
481
482 protected:
483 ElementType Value;
486 };
487
493
496 : HeadNode(nullptr)
497 , TailNode(nullptr)
498 , ListSize(0)
499 {
500 }
501
504 {
505 Empty();
506 }
507
508 // Can't copy
511
515 {
516 Swap(HeadNode, Other.HeadNode);
517 Swap(TailNode, Other.TailNode);
518 Swap(ListSize, Other.ListSize);
519 }
520
522 {
523 Swap(HeadNode, Other.HeadNode);
524 Swap(TailNode, Other.TailNode);
525 Swap(ListSize, Other.ListSize);
526 return *this;
527 }
528
529 // Adding/Removing methods
530
538 bool AddHead( const ElementType& InElement )
539 {
541 }
542
544 {
545 if (NewNode == nullptr)
546 {
547 return false;
548 }
549
550 // have an existing head node - change the head node to point to this one
551 if ( HeadNode != nullptr )
552 {
553 NewNode->NextNode = HeadNode;
554 HeadNode->PrevNode = NewNode;
555 HeadNode = NewNode;
556 }
557 else
558 {
559 HeadNode = TailNode = NewNode;
560 }
561
562 SetListSize(ListSize + 1);
563 return true;
564 }
565
573 bool AddTail( const ElementType& InElement )
574 {
576 }
577
579 {
580 if ( NewNode == nullptr )
581 {
582 return false;
583 }
584
585 if ( TailNode != nullptr )
586 {
587 TailNode->NextNode = NewNode;
588 NewNode->PrevNode = TailNode;
589 TailNode = NewNode;
590 }
591 else
592 {
593 HeadNode = TailNode = NewNode;
594 }
595
596 SetListSize(ListSize + 1);
597 return true;
598 }
599
613
615 {
616 if ( NewNode == nullptr )
617 {
618 return false;
619 }
620
621 if ( NodeToInsertBefore == nullptr || NodeToInsertBefore == HeadNode )
622 {
623 return AddHead(NewNode);
624 }
625
627 NewNode->NextNode = NodeToInsertBefore;
628
630 NodeToInsertBefore->PrevNode = NewNode;
631
632 SetListSize(ListSize + 1);
633 return true;
634 }
635
647
655 {
656 if ( NodeToRemove != nullptr )
657 {
658 // if we only have one node, just call Clear() so that we don't have to do lots of extra checks in the code below
659 if ( Num() == 1 )
660 {
661 checkSlow(NodeToRemove == HeadNode);
662 if (bDeleteNode)
663 {
664 Empty();
665 }
666 else
667 {
668 NodeToRemove->NextNode = NodeToRemove->PrevNode = nullptr;
669 HeadNode = TailNode = nullptr;
670 SetListSize(0);
671 }
672 return;
673 }
674
675 if ( NodeToRemove == HeadNode )
676 {
677 HeadNode = HeadNode->NextNode;
678 HeadNode->PrevNode = nullptr;
679 }
680
681 else if ( NodeToRemove == TailNode )
682 {
683 TailNode = TailNode->PrevNode;
684 TailNode->NextNode = nullptr;
685 }
686 else
687 {
690 }
691
692 if (bDeleteNode)
693 {
694 delete NodeToRemove;
695 }
696 else
697 {
699 }
700 SetListSize(ListSize - 1);
701 }
702 }
703
705 void Empty()
706 {
708 while ( HeadNode != nullptr )
709 {
710 Node = HeadNode->NextNode;
711 delete HeadNode;
712 HeadNode = Node;
713 }
714
715 HeadNode = TailNode = nullptr;
716 SetListSize(0);
717 }
718
719 // Accessors.
720
728 {
729 return HeadNode;
730 }
731
739 {
740 return TailNode;
741 }
742
750 {
751 TDoubleLinkedListNode* Node = HeadNode;
752 while ( Node != nullptr )
753 {
754 if ( Node->GetValue() == InElement )
755 {
756 break;
757 }
758
759 Node = Node->NextNode;
760 }
761
762 return Node;
763 }
764
765 [[nodiscard]] bool Contains( const ElementType& InElement )
766 {
767 return (FindNode(InElement) != nullptr);
768 }
769
776 [[nodiscard]] bool IsEmpty() const
777 {
778 return ListSize == 0;
779 }
780
786 [[nodiscard]] int32 Num() const
787 {
788 return ListSize;
789 }
790
791protected:
792
800 {
801 ListSize = NewListSize;
802 }
803
804private:
805 TDoubleLinkedListNode* HeadNode;
806 TDoubleLinkedListNode* TailNode;
807 int32 ListSize;
808
809 [[nodiscard]] friend TIterator begin( TDoubleLinkedList& List) { return TIterator (List.GetHead()); }
810 [[nodiscard]] friend TConstIterator begin(const TDoubleLinkedList& List) { return TConstIterator(List.GetHead()); }
811 [[nodiscard]] friend TIterator end ( TDoubleLinkedList& List) { return TIterator (nullptr); }
812 [[nodiscard]] friend TConstIterator end (const TDoubleLinkedList& List) { return TConstIterator(nullptr); }
813};
814
815
816/*----------------------------------------------------------------------------
817 TList.
818----------------------------------------------------------------------------*/
819
820//
821// Simple single-linked list template.
822//
823template <class ElementType> class TList
824{
825public:
826
827 ElementType Element;
829
830 // Constructor.
831
832 [[nodiscard]] TList(const ElementType &InElement, TList<ElementType>* InNext = nullptr)
833 {
835 Next = InNext;
836 }
837};
#define NULL
Definition oodle2base.h:134
#define checkSlow(expr)
Definition AssertionMacros.h:332
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const bool
Definition NetworkReplayStreaming.h:178
Definition List.h:363
TDoubleLinkedListIterator(NodeType *StartingNode)
Definition List.h:366
TDoubleLinkedListIterator & operator++()
Definition List.h:377
ElementType & operator*() const
Definition List.h:412
TDoubleLinkedListIterator operator--(int)
Definition List.h:398
NodeType * GetNode() const
Definition List.h:418
TDoubleLinkedListIterator & operator--()
Definition List.h:391
TDoubleLinkedListIterator operator++(int)
Definition List.h:384
bool operator==(const TDoubleLinkedListIterator &Rhs) const
Definition List.h:424
bool operator!=(const TDoubleLinkedListIterator &Rhs) const
Definition List.h:425
ElementType & operator->() const
Definition List.h:406
TDoubleLinkedListNode * GetPrevNode()
Definition List.h:472
TDoubleLinkedListNode * PrevNode
Definition List.h:485
ElementType & GetValue()
Definition List.h:457
TDoubleLinkedListNode * GetNextNode()
Definition List.h:462
TDoubleLinkedListNode(const ElementType &InValue)
Definition List.h:447
const TDoubleLinkedListNode * GetPrevNode() const
Definition List.h:477
TDoubleLinkedListNode * NextNode
Definition List.h:484
const ElementType & GetValue() const
Definition List.h:452
const TDoubleLinkedListNode * GetNextNode() const
Definition List.h:467
ElementType Value
Definition List.h:483
Definition List.h:439
friend TConstIterator begin(const TDoubleLinkedList &List)
Definition List.h:810
void RemoveNode(const ElementType &InElement)
Definition List.h:642
bool Contains(const ElementType &InElement)
Definition List.h:765
friend TConstIterator end(const TDoubleLinkedList &List)
Definition List.h:812
TDoubleLinkedList(const TDoubleLinkedList &)=delete
TDoubleLinkedList & operator=(TDoubleLinkedList &&Other)
Definition List.h:521
TDoubleLinkedListNode * GetHead() const
Definition List.h:727
TDoubleLinkedListNode * GetTail() const
Definition List.h:738
bool AddTail(TDoubleLinkedListNode *NewNode)
Definition List.h:578
TDoubleLinkedListIterator< TDoubleLinkedListNode, ElementType > TIterator
Definition List.h:491
bool AddTail(const ElementType &InElement)
Definition List.h:573
friend TIterator begin(TDoubleLinkedList &List)
Definition List.h:809
bool InsertNode(const ElementType &InElement, TDoubleLinkedListNode *NodeToInsertBefore=nullptr)
Definition List.h:609
void Empty()
Definition List.h:705
void RemoveNode(TDoubleLinkedListNode *NodeToRemove, bool bDeleteNode=true)
Definition List.h:654
virtual ~TDoubleLinkedList()
Definition List.h:503
bool InsertNode(TDoubleLinkedListNode *NewNode, TDoubleLinkedListNode *NodeToInsertBefore=nullptr)
Definition List.h:614
friend TIterator end(TDoubleLinkedList &List)
Definition List.h:811
bool AddHead(TDoubleLinkedListNode *NewNode)
Definition List.h:543
TDoubleLinkedList & operator=(const TDoubleLinkedList &)=delete
bool AddHead(const ElementType &InElement)
Definition List.h:538
virtual void SetListSize(int32 NewListSize)
Definition List.h:799
TDoubleLinkedListIterator< TDoubleLinkedListNode, const ElementType > TConstIterator
Definition List.h:492
TDoubleLinkedList()
Definition List.h:495
int32 Num() const
Definition List.h:786
TDoubleLinkedListNode * FindNode(const ElementType &InElement)
Definition List.h:749
bool IsEmpty() const
Definition List.h:776
TDoubleLinkedList(TDoubleLinkedList &&Other)
Definition List.h:513
Definition List.h:80
TIntrusiveLinkedListIterator(ElementType *FirstLink)
Definition List.h:84
ElementType & operator->() const
Definition List.h:90
ElementType & operator*() const
Definition List.h:96
Definition List.h:349
TIntrusiveLinkedList()
Definition List.h:354
Definition List.h:109
void LinkHead(ContainerType *&Head)
Definition List.h:226
UE_FORCEINLINE_HINT bool IsLinked()
Definition List.h:244
IteratorType< ContainerType, const ElementType > TConstIterator
Definition List.h:115
UE_FORCEINLINE_HINT ContainerType * GetNextLink() const
Definition List.h:254
void LinkAfter(ContainerType *After)
Definition List.h:173
void LinkBefore(ContainerType *Before)
Definition List.h:153
void LinkReplace(ContainerType *Replace)
Definition List.h:193
TLinkedListBase()
Definition List.h:121
UE_FORCEINLINE_HINT friend TConstIterator end(const ContainerType &List)
Definition List.h:275
UE_FORCEINLINE_HINT friend TConstIterator begin(const ContainerType &List)
Definition List.h:273
UE_FORCEINLINE_HINT ContainerType * Next()
Definition List.h:259
void Unlink()
Definition List.h:132
UE_FORCEINLINE_HINT friend TIterator end(ContainerType &List)
Definition List.h:274
UE_FORCEINLINE_HINT ContainerType ** GetPrevLink() const
Definition List.h:249
UE_FORCEINLINE_HINT friend TIterator begin(ContainerType &List)
Definition List.h:272
IteratorType< ContainerType, ElementType > TIterator
Definition List.h:114
Definition List.h:11
UE_FORCEINLINE_HINT bool operator==(const TLinkedListIteratorBase &Rhs) const
Definition List.h:46
ContainerType * CurrentLink
Definition List.h:50
UE_FORCEINLINE_HINT bool operator!=(const TLinkedListIteratorBase &Rhs) const
Definition List.h:47
TLinkedListIteratorBase & operator++()
Definition List.h:27
void Next()
Definition List.h:21
TLinkedListIteratorBase operator++(int)
Definition List.h:33
TLinkedListIteratorBase(ContainerType *FirstLink)
Definition List.h:13
Definition List.h:55
ElementType & operator->() const
Definition List.h:65
TLinkedListIterator(ContainerType *FirstLink)
Definition List.h:59
ElementType & operator*() const
Definition List.h:71
Definition List.h:285
UE_FORCEINLINE_HINT const ElementType & operator*() const
Definition List.h:320
UE_FORCEINLINE_HINT const ElementType * operator->() const
Definition List.h:312
UE_FORCEINLINE_HINT ElementType & operator*()
Definition List.h:316
UE_FORCEINLINE_HINT ElementType * operator->()
Definition List.h:308
TLinkedList(const ElementType &InElement)
Definition List.h:300
TLinkedList()
Definition List.h:290
Definition List.h:824
TList(const ElementType &InElement, TList< ElementType > *InNext=nullptr)
Definition List.h:832
ElementType Element
Definition List.h:827
TList< ElementType > * Next
Definition List.h:828