summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2021-04-01 23:04:18 -0700
committerGravatar bunnei2021-05-05 16:40:49 -0700
commit66f2ad716be8f880e5bb6cc572c76812073f6db4 (patch)
treed6df5e7aed98f9c59e6a79072089cb5a7ee7802b /src/core/hle/kernel
parentcommon: bit_util: Add BIT macro. (diff)
downloadyuzu-66f2ad716be8f880e5bb6cc572c76812073f6db4.tar.gz
yuzu-66f2ad716be8f880e5bb6cc572c76812073f6db4.tar.xz
yuzu-66f2ad716be8f880e5bb6cc572c76812073f6db4.zip
hle: kernel: Add initial impl. of KLinkedList.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_linked_list.h233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/core/hle/kernel/k_linked_list.h b/src/core/hle/kernel/k_linked_list.h
new file mode 100644
index 000000000..8362b6eda
--- /dev/null
+++ b/src/core/hle/kernel/k_linked_list.h
@@ -0,0 +1,233 @@
1// Copyright 2021 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <boost/intrusive/list.hpp>
8
9#include "common/assert.h"
10#include "core/hle/kernel/slab_helpers.h"
11
12namespace Kernel {
13
14class KLinkedListNode : public boost::intrusive::list_base_hook<>,
15 public KSlabAllocated<KLinkedListNode> {
16private:
17 void* m_item;
18
19public:
20 KLinkedListNode() : m_item(nullptr) {}
21
22 constexpr void Initialize(void* it) {
23 m_item = it;
24 }
25
26 constexpr void* GetItem() const {
27 return m_item;
28 }
29};
30
31template <typename T>
32class KLinkedList : private boost::intrusive::list<KLinkedListNode> {
33private:
34 using BaseList = boost::intrusive::list<KLinkedListNode>;
35
36public:
37 template <bool Const>
38 class Iterator;
39
40 using value_type = T;
41 using size_type = size_t;
42 using difference_type = ptrdiff_t;
43 using pointer = value_type*;
44 using const_pointer = const value_type*;
45 using reference = value_type&;
46 using const_reference = const value_type&;
47 using iterator = Iterator<false>;
48 using const_iterator = Iterator<true>;
49 using reverse_iterator = std::reverse_iterator<iterator>;
50 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
51
52 template <bool Const>
53 class Iterator {
54 private:
55 using BaseIterator = BaseList::iterator;
56 friend class KLinkedList;
57
58 public:
59 using iterator_category = std::bidirectional_iterator_tag;
60 using value_type = typename KLinkedList::value_type;
61 using difference_type = typename KLinkedList::difference_type;
62 using pointer = typename std::conditional<Const, KLinkedList::const_pointer,
63 KLinkedList::pointer>::type;
64 using reference = typename std::conditional<Const, KLinkedList::const_reference,
65 KLinkedList::reference>::type;
66
67 private:
68 BaseIterator m_base_it;
69
70 public:
71 explicit Iterator(BaseIterator it) : m_base_it(it) {}
72
73 pointer GetItem() const {
74 return static_cast<pointer>(m_base_it->GetItem());
75 }
76
77 bool operator==(const Iterator& rhs) const {
78 return m_base_it == rhs.m_base_it;
79 }
80
81 bool operator!=(const Iterator& rhs) const {
82 return !(*this == rhs);
83 }
84
85 pointer operator->() const {
86 return this->GetItem();
87 }
88
89 reference operator*() const {
90 return *this->GetItem();
91 }
92
93 Iterator& operator++() {
94 ++m_base_it;
95 return *this;
96 }
97
98 Iterator& operator--() {
99 --m_base_it;
100 return *this;
101 }
102
103 Iterator operator++(int) {
104 const Iterator it{*this};
105 ++(*this);
106 return it;
107 }
108
109 Iterator operator--(int) {
110 const Iterator it{*this};
111 --(*this);
112 return it;
113 }
114
115 operator Iterator<true>() const {
116 return Iterator<true>(m_base_it);
117 }
118 };
119
120public:
121 constexpr KLinkedList() : BaseList() {}
122
123 ~KLinkedList() {
124 // Erase all elements.
125 for (auto it = this->begin(); it != this->end(); it = this->erase(it)) {
126 }
127
128 // Ensure we succeeded.
129 ASSERT(this->empty());
130 }
131
132 // Iterator accessors.
133 iterator begin() {
134 return iterator(BaseList::begin());
135 }
136
137 const_iterator begin() const {
138 return const_iterator(BaseList::begin());
139 }
140
141 iterator end() {
142 return iterator(BaseList::end());
143 }
144
145 const_iterator end() const {
146 return const_iterator(BaseList::end());
147 }
148
149 const_iterator cbegin() const {
150 return this->begin();
151 }
152
153 const_iterator cend() const {
154 return this->end();
155 }
156
157 reverse_iterator rbegin() {
158 return reverse_iterator(this->end());
159 }
160
161 const_reverse_iterator rbegin() const {
162 return const_reverse_iterator(this->end());
163 }
164
165 reverse_iterator rend() {
166 return reverse_iterator(this->begin());
167 }
168
169 const_reverse_iterator rend() const {
170 return const_reverse_iterator(this->begin());
171 }
172
173 const_reverse_iterator crbegin() const {
174 return this->rbegin();
175 }
176
177 const_reverse_iterator crend() const {
178 return this->rend();
179 }
180
181 // Content management.
182 using BaseList::empty;
183 using BaseList::size;
184
185 reference back() {
186 return *(--this->end());
187 }
188
189 const_reference back() const {
190 return *(--this->end());
191 }
192
193 reference front() {
194 return *this->begin();
195 }
196
197 const_reference front() const {
198 return *this->begin();
199 }
200
201 iterator insert(const_iterator pos, reference ref) {
202 KLinkedListNode* node = KLinkedListNode::Allocate();
203 ASSERT(node != nullptr);
204 node->Initialize(std::addressof(ref));
205 return iterator(BaseList::insert(pos.m_base_it, *node));
206 }
207
208 void push_back(reference ref) {
209 this->insert(this->end(), ref);
210 }
211
212 void push_front(reference ref) {
213 this->insert(this->begin(), ref);
214 }
215
216 void pop_back() {
217 this->erase(--this->end());
218 }
219
220 void pop_front() {
221 this->erase(this->begin());
222 }
223
224 iterator erase(const iterator pos) {
225 KLinkedListNode* freed_node = std::addressof(*pos.m_base_it);
226 iterator ret = iterator(BaseList::erase(pos.m_base_it));
227 KLinkedListNode::Free(freed_node);
228
229 return ret;
230 }
231};
232
233} // namespace Kernel