1#include <basis/seadRawPrint.h>
2#include <container/seadListImpl.h>
3
4namespace sead
5{
6void ListNode::insertBack_(ListNode* node)
7{
8 SEAD_ASSERT_MSG(!node->isLinked(), "node is already linked.");
9 ListNode* next = mNext;
10 mNext = node;
11 node->mPrev = this;
12 node->mNext = next;
13
14 if (next)
15 next->mPrev = node;
16}
17
18void ListNode::insertFront_(ListNode* node)
19{
20 SEAD_ASSERT_MSG(!node->isLinked(), "node is already linked.");
21 ListNode* prev = mPrev;
22 this->mPrev = node;
23 node->mPrev = prev;
24 node->mNext = this;
25 if (prev == NULL)
26 return;
27
28 prev->mNext = node;
29}
30
31void ListNode::erase_()
32{
33 SEAD_ASSERT_MSG(isLinked(), "node is not linked.");
34 if (mPrev != nullptr)
35 mPrev->mNext = mNext;
36
37 if (mNext != nullptr)
38 mNext->mPrev = mPrev;
39
40 mPrev = mNext = NULL;
41}
42
43ListNode* ListImpl::popBack()
44{
45 if (mCount < 1)
46 return nullptr;
47
48 ListNode* back = mStartEnd.mPrev;
49 back->erase_();
50 --mCount;
51 return back;
52}
53
54ListNode* ListImpl::popFront()
55{
56 if (mCount < 1)
57 return nullptr;
58
59 ListNode* front = mStartEnd.mNext;
60 front->erase_();
61 --mCount;
62 return front;
63}
64
65ListNode* ListImpl::nth(s32 index) const
66{
67 if (u32(mCount) <= u32(index))
68 {
69 SEAD_ASSERT_MSG(false, "index exceeded[%d/%d]", index, mCount);
70 return nullptr;
71 }
72
73 ListNode* node = mStartEnd.mNext;
74 for (s32 i = 0; i < index; ++i)
75 node = node->mNext;
76 return node;
77}
78
79s32 ListImpl::indexOf(const ListNode* n) const
80{
81 ListNode* node = mStartEnd.mNext;
82 s32 index = 0;
83 while (node != &mStartEnd)
84 {
85 if (node == n)
86 return index;
87 ++index;
88 node = node->mNext;
89 }
90 return -1;
91}
92
93void ListImpl::clear()
94{
95 ListNode* node = mStartEnd.mNext;
96 while (node != &mStartEnd)
97 {
98 ListNode* next = node->mNext;
99 node->init_();
100 node = next;
101 }
102
103 mCount = 0;
104 mStartEnd.mPrev = &mStartEnd;
105 mStartEnd.mNext = &mStartEnd;
106}
107
108void ListImpl::swap(ListNode* n1, ListNode* n2)
109{
110 SEAD_ASSERT(n1->mPrev && n1->mNext && n2->mPrev && n2->mNext);
111 if (n1 == n2)
112 return;
113
114 ListNode* n1_prev = n1->mPrev;
115 ListNode* n2_prev = n2->mPrev;
116
117 if (n2_prev != n1)
118 {
119 n1->erase_();
120 n2_prev->insertBack_(node: n1);
121 }
122
123 if (n1_prev != n2)
124 {
125 n2->erase_();
126 n1_prev->insertBack_(node: n2);
127 }
128}
129
130} // namespace sead
131