Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
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"
6#include "Misc/AssertionMacros.h"
7
8template <class ContainerType>
10{
11public:
12 explicit TLinkedListIteratorBase(ContainerType* FirstLink)
14 { }
15
16 /**
17 * Advances the iterator to the next element.
18 */
20 {
23 }
24
26 {
27 Next();
28 return *this;
29 }
30
32 {
33 auto Tmp = *this;
34 Next();
35 return Tmp;
36 }
37
38 /** conversion to "bool" returning true if the iterator is valid. */
39 FORCEINLINE explicit operator bool() const
40 {
41 return CurrentLink != nullptr;
42 }
43
46protected:
47
48 ContainerType* CurrentLink;
49};
50
51template <class ContainerType, class ElementType>
52class TLinkedListIterator : public TLinkedListIteratorBase<ContainerType>
53{
54 typedef TLinkedListIteratorBase<ContainerType> Super;
55
56public:
57 explicit TLinkedListIterator(ContainerType* FirstLink)
59 {
60 }
61
62 // Accessors.
63 FORCEINLINE ElementType& operator->() const
64 {
66 return **(this->CurrentLink);
67 }
68
69 FORCEINLINE ElementType& operator*() const
70 {
72 return **(this->CurrentLink);
73 }
74};
75
76template <class ContainerType, class ElementType>
78{
79 typedef TLinkedListIteratorBase<ElementType> Super;
80
81public:
82 explicit TIntrusiveLinkedListIterator(ElementType* FirstLink)
84 {
85 }
86
87 // Accessors.
88 FORCEINLINE ElementType& operator->() const
89 {
91 return *(this->CurrentLink);
92 }
93
94 FORCEINLINE ElementType& operator*() const
95 {
97 return *(this->CurrentLink);
98 }
99};
100
101
102/**
103 * Base linked list class, used to implement methods shared by intrusive/non-intrusive linked lists
104 */
105template <class ContainerType, class ElementType, template<class, class> class IteratorType>
107{
108public:
109 /**
110 * Used to iterate over the elements of a linked list.
111 */
112 typedef IteratorType<ContainerType, ElementType> TIterator;
113 typedef IteratorType<ContainerType, const ElementType> TConstIterator;
114
115
116 /**
117 * Default constructor (empty list)
118 */
120 : NextLink(NULL)
121 , PrevLink(NULL)
122 {
123 }
124
125 /**
126 * Removes this element from the list in constant time.
127 *
128 * This function is safe to call even if the element is not linked.
129 */
131 {
132 if( NextLink )
133 {
135 }
136 if( PrevLink )
137 {
139 }
140 // Make it safe to call Unlink again.
141 NextLink = nullptr;
142 PrevLink = nullptr;
143 }
144
145
146 /**
147 * Adds this element to a list, before the given element.
148 *
149 * @param Before The link to insert this element before.
150 */
151 FORCEINLINE void LinkBefore(ContainerType* Before)
152 {
153 checkSlow(Before != NULL);
154
157
159
160 if (PrevLink != NULL)
161 {
162 *PrevLink = (ContainerType*)this;
163 }
164 }
165
166 /**
167 * Adds this element to the linked list, after the specified element
168 *
169 * @param After The link to insert this element after.
170 */
171 FORCEINLINE void LinkAfter(ContainerType* After)
172 {
173 checkSlow(After != NULL);
174
177 *PrevLink = (ContainerType*)this;
178
179 if (NextLink != NULL)
180 {
182 }
183 }
184
185 /**
186 * Adds this element to the linked list, replacing the specified element.
187 * This is equivalent to calling LinkBefore(Replace); Replace->Unlink();
188 *
189 * @param Replace Pointer to the element to be replaced
190 */
191 FORCEINLINE void LinkReplace(ContainerType* Replace)
192 {
193 checkSlow(Replace != NULL);
194
197
200
201 if (PrevLink != NULL)
202 {
203 *PrevLink = (ContainerType*)this;
204 }
205
206 if (NextLink != NULL)
207 {
209 }
210
211 ReplacePrev = NULL;
212 ReplaceNext = NULL;
213 }
214
215
216 /**
217 * Adds this element as the head of the linked list, linking the input Head pointer to this element,
218 * so that when the element is linked/unlinked, the Head linked list pointer will be correctly updated.
219 *
220 * If Head already has an element, this functions like LinkBefore.
221 *
222 * @param Head Pointer to the head of the linked list - this pointer should be the main reference point for the linked list
223 */
224 FORCEINLINE void LinkHead(ContainerType*& Head)
225 {
226 if (Head != NULL)
227 {
229 }
230
231 NextLink = Head;
232 PrevLink = &Head;
233 Head = (ContainerType*)this;
234 }
235
236
237 /**
238 * Returns whether element is currently linked.
239 *
240 * @return true if currently linked, false otherwise
241 */
243 {
244 return PrevLink != nullptr;
245 }
246
247 FORCEINLINE ContainerType** GetPrevLink() const
248 {
249 return PrevLink;
250 }
251
252 FORCEINLINE ContainerType* GetNextLink() const
253 {
254 return NextLink;
255 }
256
257 FORCEINLINE ContainerType* Next()
258 {
259 return NextLink;
260 }
261
262private:
263 /** The next link in the linked list */
264 ContainerType* NextLink;
265
266 /** Pointer to 'NextLink', within the previous link in the linked list */
267 ContainerType** PrevLink;
268
269
270 FORCEINLINE friend TIterator begin( ContainerType& List) { return TIterator (&List); }
271 FORCEINLINE friend TConstIterator begin(const ContainerType& List) { return TConstIterator(const_cast<ContainerType*>(&List)); }
272 FORCEINLINE friend TIterator end ( ContainerType& List) { return TIterator (nullptr); }
273 FORCEINLINE friend TConstIterator end (const ContainerType& List) { return TConstIterator(nullptr); }
274};
275
276/**
277 * Encapsulates a link in a single linked list with constant access time.
278 *
279 * This linked list is non-intrusive, i.e. it stores a copy of the element passed to it (typically a pointer)
280 */
281template <class ElementType>
283{
285
286public:
287 /** Default constructor (empty list). */
289 : Super()
290 {
291 }
292
293 /**
294 * Creates a new linked list with a single element.
295 *
296 * @param InElement The element to add to the list.
297 */
298 explicit TLinkedList(const ElementType& InElement)
299 : Super()
301 {
302 }
303
304
305 // Accessors.
306 FORCEINLINE ElementType* operator->()
307 {
308 return &Element;
309 }
310 FORCEINLINE const ElementType* operator->() const
311 {
312 return &Element;
313 }
314 FORCEINLINE ElementType& operator*()
315 {
316 return Element;
317 }
318 FORCEINLINE const ElementType& operator*() const
319 {
320 return Element;
321 }
322
323
324private:
325 ElementType Element;
326};
327
328/**
329 * Encapsulates a link in a single linked list with constant access time.
330 * Structs/classes must inherit this, to use it, e.g: struct FMyStruct : public TIntrusiveLinkedList<FMyStruct>
331 *
332 * This linked list is intrusive, i.e. the element is a subclass of this link, so that each link IS the element.
333 *
334 * Never reference TIntrusiveLinkedList outside of the above class/struct inheritance, only ever refer to the struct, e.g:
335 * FMyStruct* MyLinkedList = NULL;
336 *
337 * FMyStruct* StructLink = new FMyStruct();
338 * StructLink->LinkHead(MyLinkedList);
339 *
340 * for (FMyStruct::TIterator It(MyLinkedList); It; It.Next())
341 * {
342 * ...
343 * }
344 */
345template <class ElementType>
347{
349
350public:
351 /** Default constructor (empty list). */
353 : Super()
354 {
355 }
356};
357
358
359template <class NodeType, class ElementType>
361{
362public:
363
364 explicit TDoubleLinkedListIterator(NodeType* StartingNode)
366 { }
367
368 /** conversion to "bool" returning true if the iterator is valid. */
369 FORCEINLINE explicit operator bool() const
370 {
371 return CurrentNode != nullptr;
372 }
373
375 {
378 return *this;
379 }
380
382 {
383 auto Tmp = *this;
384 ++(*this);
385 return Tmp;
386 }
387
389 {
392 return *this;
393 }
394
396 {
397 auto Tmp = *this;
398 --(*this);
399 return Tmp;
400 }
401
402 // Accessors.
403 ElementType& operator->() const
404 {
406 return CurrentNode->GetValue();
407 }
408
409 ElementType& operator*() const
410 {
412 return CurrentNode->GetValue();
413 }
414
415 NodeType* GetNode() const
416 {
418 return CurrentNode;
419 }
420
421 bool operator==(const TDoubleLinkedListIterator& Rhs) const { return CurrentNode == Rhs.CurrentNode; }
422 bool operator!=(const TDoubleLinkedListIterator& Rhs) const { return CurrentNode != Rhs.CurrentNode; }
423
424private:
425 NodeType* CurrentNode;
426};
427
428
429/**
430 * Double linked list.
431 *
432 * @see TIntrusiveDoubleLinkedList
433 */
434template <class ElementType>
436{
437public:
439 {
440 public:
441 friend class TDoubleLinkedList;
442
443 /** Constructor */
444 TDoubleLinkedListNode( const ElementType& InValue )
445 : Value(InValue), NextNode(nullptr), PrevNode(nullptr)
446 { }
447
448 const ElementType& GetValue() const
449 {
450 return Value;
451 }
452
453 ElementType& GetValue()
454 {
455 return Value;
456 }
457
459 {
460 return NextNode;
461 }
462
464 {
465 return NextNode;
466 }
467
469 {
470 return PrevNode;
471 }
472
474 {
475 return PrevNode;
476 }
477
478 protected:
479 ElementType Value;
482 };
483
484 /**
485 * Used to iterate over the elements of a linked list.
486 */
489
490 /** Constructors. */
492 : HeadNode(nullptr)
493 , TailNode(nullptr)
494 , ListSize(0)
495 { }
496
497 /** Destructor */
499 {
500 Empty();
501 }
502
503 // Adding/Removing methods
504
505 /**
506 * Add the specified value to the beginning of the list, making that value the new head of the list.
507 *
508 * @param InElement the value to add to the list.
509 * @return whether the node was successfully added into the list.
510 * @see GetHead, InsertNode, RemoveNode
511 */
512 bool AddHead( const ElementType& InElement )
513 {
515 }
516
518 {
519 if (NewNode == nullptr)
520 {
521 return false;
522 }
523
524 // have an existing head node - change the head node to point to this one
525 if ( HeadNode != nullptr )
526 {
530 }
531 else
532 {
534 }
535
537 return true;
538 }
539
540 /**
541 * Append the specified value to the end of the list
542 *
543 * @param InElement the value to add to the list.
544 * @return whether the node was successfully added into the list
545 * @see GetTail, InsertNode, RemoveNode
546 */
547 bool AddTail( const ElementType& InElement )
548 {
550 }
551
553 {
554 if ( NewNode == nullptr )
555 {
556 return false;
557 }
558
559 if ( TailNode != nullptr )
560 {
564 }
565 else
566 {
568 }
569
571 return true;
572 }
573
574 /**
575 * Insert the specified value into the list at an arbitrary point.
576 *
577 * @param InElement the value to insert into the list
578 * @param NodeToInsertBefore the new node will be inserted into the list at the current location of this node
579 * if nullptr, the new node will become the new head of the list
580 * @return whether the node was successfully added into the list
581 * @see Empty, RemoveNode
582 */
583 bool InsertNode( const ElementType& InElement, TDoubleLinkedListNode* NodeToInsertBefore=nullptr )
584 {
586 }
587
588 bool InsertNode( TDoubleLinkedListNode* NewNode, TDoubleLinkedListNode* NodeToInsertBefore=nullptr )
589 {
590 if ( NewNode == nullptr )
591 {
592 return false;
593 }
594
595 if ( NodeToInsertBefore == nullptr || NodeToInsertBefore == HeadNode )
596 {
597 return AddHead(NewNode);
598 }
599
602
605
607 return true;
608 }
609
610 /**
611 * Remove the node corresponding to InElement.
612 *
613 * @param InElement The value to remove from the list.
614 * @see Empty, InsertNode
615 */
616 void RemoveNode( const ElementType& InElement )
617 {
620 }
621
622 /**
623 * Removes the node specified.
624 *
625 * @param NodeToRemove The node to remove.
626 * @see Empty, InsertNode
627 */
628 void RemoveNode( TDoubleLinkedListNode* NodeToRemove, bool bDeleteNode = true )
629 {
630 if ( NodeToRemove != nullptr )
631 {
632 // 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
633 if ( Num() == 1 )
634 {
636 if (bDeleteNode)
637 {
638 Empty();
639 }
640 else
641 {
643 HeadNode = TailNode = nullptr;
644 SetListSize(0);
645 }
646 return;
647 }
648
649 if ( NodeToRemove == HeadNode )
650 {
652 HeadNode->PrevNode = nullptr;
653 }
654
655 else if ( NodeToRemove == TailNode )
656 {
658 TailNode->NextNode = nullptr;
659 }
660 else
661 {
664 }
665
666 if (bDeleteNode)
667 {
668 delete NodeToRemove;
669 }
670 else
671 {
673 }
675 }
676 }
677
678 /** Removes all nodes from the list. */
679 void Empty()
680 {
682 while ( HeadNode != nullptr )
683 {
685 delete HeadNode;
686 HeadNode = Node;
687 }
688
689 HeadNode = TailNode = nullptr;
690 SetListSize(0);
691 }
692
693 // Accessors.
694
695 /**
696 * Returns the node at the head of the list.
697 *
698 * @return Pointer to the first node.
699 * @see GetTail
700 */
702 {
703 return HeadNode;
704 }
705
706 /**
707 * Returns the node at the end of the list.
708 *
709 * @return Pointer to the last node.
710 * @see GetHead
711 */
713 {
714 return TailNode;
715 }
716
717 /**
718 * Finds the node corresponding to the value specified
719 *
720 * @param InElement the value to find
721 * @return a pointer to the node that contains the value specified, or nullptr of the value couldn't be found
722 */
723 TDoubleLinkedListNode* FindNode( const ElementType& InElement )
724 {
726 while ( Node != nullptr )
727 {
728 if ( Node->GetValue() == InElement )
729 {
730 break;
731 }
732
733 Node = Node->NextNode;
734 }
735
736 return Node;
737 }
738
739 bool Contains( const ElementType& InElement )
740 {
741 return (FindNode(InElement) != nullptr);
742 }
743
744 /**
745 * Returns true if the list is empty and contains no elements.
746 *
747 * @returns True if the list is empty.
748 * @see Num
749 */
750 bool IsEmpty() const
751 {
752 return ListSize == 0;
753 }
754
755 /**
756 * Returns the number of items in the list.
757 *
758 * @return Item count.
759 */
760 int32 Num() const
761 {
762 return ListSize;
763 }
764
765protected:
766
767 /**
768 * Updates the size reported by Num(). Child classes can use this function to conveniently
769 * hook into list additions/removals.
770 *
771 * @param NewListSize the new size for this list
772 */
773 virtual void SetListSize( int32 NewListSize )
774 {
776 }
777
778private:
781 int32 ListSize;
782
785
786 friend TIterator begin( TDoubleLinkedList& List) { return TIterator (List.GetHead()); }
788 friend TIterator end ( TDoubleLinkedList& List) { return TIterator (nullptr); }
789 friend TConstIterator end (const TDoubleLinkedList& List) { return TConstIterator(nullptr); }
790};
791
792
793/*----------------------------------------------------------------------------
794 TList.
795----------------------------------------------------------------------------*/
796
797//
798// Simple single-linked list template.
799//
800template <class ElementType> class TList
801{
802public:
803
804 ElementType Element;
805 TList<ElementType>* Next;
806
807 // Constructor.
808
809 TList(const ElementType &InElement, TList<ElementType>* InNext = nullptr)
810 {
812 Next = InNext;
813 }
814};
#define checkSlow(expr)
#define FORCEINLINE
Definition Platform.h:644
TDoubleLinkedListNode * GetPrevNode()
Definition List.h:468
TDoubleLinkedListNode * PrevNode
Definition List.h:481
TDoubleLinkedListNode * GetNextNode()
Definition List.h:458
TDoubleLinkedListNode(const ElementType &InValue)
Definition List.h:444
const TDoubleLinkedListNode * GetPrevNode() const
Definition List.h:473
TDoubleLinkedListNode * NextNode
Definition List.h:480
const ElementType & GetValue() const
Definition List.h:448
const TDoubleLinkedListNode * GetNextNode() const
Definition List.h:463
friend TConstIterator begin(const TDoubleLinkedList &List)
Definition List.h:787
int32 ListSize
Definition List.h:781
void RemoveNode(const ElementType &InElement)
Definition List.h:616
bool Contains(const ElementType &InElement)
Definition List.h:739
friend TConstIterator end(const TDoubleLinkedList &List)
Definition List.h:789
TDoubleLinkedListNode * GetHead() const
Definition List.h:701
TDoubleLinkedListNode * HeadNode
Definition List.h:779
TDoubleLinkedListNode * GetTail() const
Definition List.h:712
bool AddTail(TDoubleLinkedListNode *NewNode)
Definition List.h:552
TDoubleLinkedListNode * TailNode
Definition List.h:780
TDoubleLinkedListIterator< TDoubleLinkedListNode, ElementType > TIterator
Definition List.h:487
bool AddTail(const ElementType &InElement)
Definition List.h:547
friend TIterator begin(TDoubleLinkedList &List)
Definition List.h:786
bool InsertNode(const ElementType &InElement, TDoubleLinkedListNode *NodeToInsertBefore=nullptr)
Definition List.h:583
void Empty()
Definition List.h:679
void RemoveNode(TDoubleLinkedListNode *NodeToRemove, bool bDeleteNode=true)
Definition List.h:628
virtual ~TDoubleLinkedList()
Definition List.h:498
bool InsertNode(TDoubleLinkedListNode *NewNode, TDoubleLinkedListNode *NodeToInsertBefore=nullptr)
Definition List.h:588
friend TIterator end(TDoubleLinkedList &List)
Definition List.h:788
bool AddHead(TDoubleLinkedListNode *NewNode)
Definition List.h:517
bool AddHead(const ElementType &InElement)
Definition List.h:512
virtual void SetListSize(int32 NewListSize)
Definition List.h:773
TDoubleLinkedListIterator< TDoubleLinkedListNode, const ElementType > TConstIterator
Definition List.h:488
TDoubleLinkedList & operator=(const TDoubleLinkedList &)
int32 Num() const
Definition List.h:760
TDoubleLinkedListNode * FindNode(const ElementType &InElement)
Definition List.h:723
TDoubleLinkedList(const TDoubleLinkedList &)
bool IsEmpty() const
Definition List.h:750
TDoubleLinkedListIterator(NodeType *StartingNode)
Definition List.h:364
TDoubleLinkedListIterator & operator++()
Definition List.h:374
FORCEINLINE operator bool() const
Definition List.h:369
ElementType & operator*() const
Definition List.h:409
TDoubleLinkedListIterator operator--(int)
Definition List.h:395
NodeType * GetNode() const
Definition List.h:415
TDoubleLinkedListIterator & operator--()
Definition List.h:388
TDoubleLinkedListIterator operator++(int)
Definition List.h:381
NodeType * CurrentNode
Definition List.h:425
bool operator==(const TDoubleLinkedListIterator &Rhs) const
Definition List.h:421
bool operator!=(const TDoubleLinkedListIterator &Rhs) const
Definition List.h:422
ElementType & operator->() const
Definition List.h:403
TLinkedListBase< ElementType, ElementType, TIntrusiveLinkedListIterator > Super
Definition List.h:348
TIntrusiveLinkedListIterator(ElementType *FirstLink)
Definition List.h:82
TLinkedListIteratorBase< ElementType > Super
Definition List.h:79
FORCEINLINE ElementType & operator->() const
Definition List.h:88
FORCEINLINE ElementType & operator*() const
Definition List.h:94
FORCEINLINE ContainerType * GetNextLink() const
Definition List.h:252
FORCEINLINE friend TConstIterator end(const ContainerType &List)
Definition List.h:273
FORCEINLINE void LinkBefore(ContainerType *Before)
Definition List.h:151
IteratorType< ContainerType, const ElementType > TConstIterator
Definition List.h:113
FORCEINLINE void LinkAfter(ContainerType *After)
Definition List.h:171
FORCEINLINE ContainerType * Next()
Definition List.h:257
FORCEINLINE ContainerType ** GetPrevLink() const
Definition List.h:247
FORCEINLINE friend TIterator end(ContainerType &List)
Definition List.h:272
TLinkedListBase()
Definition List.h:119
FORCEINLINE void LinkHead(ContainerType *&Head)
Definition List.h:224
FORCEINLINE friend TIterator begin(ContainerType &List)
Definition List.h:270
ContainerType ** PrevLink
Definition List.h:267
ContainerType * NextLink
Definition List.h:264
FORCEINLINE void LinkReplace(ContainerType *Replace)
Definition List.h:191
FORCEINLINE friend TConstIterator begin(const ContainerType &List)
Definition List.h:271
FORCEINLINE void Unlink()
Definition List.h:130
IteratorType< ContainerType, ElementType > TIterator
Definition List.h:112
FORCEINLINE bool IsLinked()
Definition List.h:242
TLinkedListBase< TLinkedList< ElementType >, ElementType, TLinkedListIterator > Super
Definition List.h:284
FORCEINLINE ElementType & operator*()
Definition List.h:314
TLinkedList(const ElementType &InElement)
Definition List.h:298
ElementType Element
Definition List.h:325
TLinkedList()
Definition List.h:288
FORCEINLINE const ElementType * operator->() const
Definition List.h:310
FORCEINLINE const ElementType & operator*() const
Definition List.h:318
FORCEINLINE ElementType * operator->()
Definition List.h:306
FORCEINLINE TLinkedListIteratorBase operator++(int)
Definition List.h:31
FORCEINLINE operator bool() const
Definition List.h:39
ContainerType * CurrentLink
Definition List.h:48
FORCEINLINE void Next()
Definition List.h:19
FORCEINLINE bool operator==(const TLinkedListIteratorBase &Rhs) const
Definition List.h:44
FORCEINLINE TLinkedListIteratorBase & operator++()
Definition List.h:25
FORCEINLINE bool operator!=(const TLinkedListIteratorBase &Rhs) const
Definition List.h:45
TLinkedListIteratorBase(ContainerType *FirstLink)
Definition List.h:12
TLinkedListIteratorBase< ContainerType > Super
Definition List.h:54
TLinkedListIterator(ContainerType *FirstLink)
Definition List.h:57
FORCEINLINE ElementType & operator*() const
Definition List.h:69
FORCEINLINE ElementType & operator->() const
Definition List.h:63
Definition List.h:801
TList(const ElementType &InElement, TList< ElementType > *InNext=nullptr)
Definition List.h:809
ElementType Element
Definition List.h:804
TList< ElementType > * Next
Definition List.h:805