Skip to content

Commit fa99cf8

Browse files
committed
feat: add some sk_ header
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
1 parent 9697e7a commit fa99cf8

6 files changed

Lines changed: 1270 additions & 0 deletions

File tree

src/libcxx/include/sk_list

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/**
2+
* @copyright Copyright The SimpleKernel Contributors
3+
*/
4+
5+
#ifndef SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_LIST_
6+
#define SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_LIST_
7+
8+
#include <cstddef>
9+
#include <new>
10+
11+
namespace sk_std {
12+
13+
struct list_node_base {
14+
list_node_base* prev;
15+
list_node_base* next;
16+
17+
list_node_base() : prev(this), next(this) {}
18+
};
19+
20+
template <typename T>
21+
struct list_node : public list_node_base {
22+
T data;
23+
24+
list_node(const T& val) : list_node_base(), data(val) {}
25+
};
26+
27+
template <typename T>
28+
class list_iterator {
29+
public:
30+
using node_type = list_node<T>;
31+
using base_node_type = list_node_base;
32+
using self_type = list_iterator<T>;
33+
using value_type = T;
34+
using pointer = T*;
35+
using reference = T&;
36+
37+
base_node_type* node;
38+
39+
list_iterator(base_node_type* n) : node(n) {}
40+
41+
reference operator*() const { return static_cast<node_type*>(node)->data; }
42+
pointer operator->() const { return &static_cast<node_type*>(node)->data; }
43+
44+
self_type& operator++() {
45+
node = node->next;
46+
return *this;
47+
}
48+
49+
self_type operator++(int) {
50+
self_type tmp = *this;
51+
node = node->next;
52+
return tmp;
53+
}
54+
55+
self_type& operator--() {
56+
node = node->prev;
57+
return *this;
58+
}
59+
60+
self_type operator--(int) {
61+
self_type tmp = *this;
62+
node = node->prev;
63+
return tmp;
64+
}
65+
66+
bool operator==(const self_type& other) const { return node == other.node; }
67+
bool operator!=(const self_type& other) const { return node != other.node; }
68+
};
69+
70+
template <typename T>
71+
class list_const_iterator {
72+
public:
73+
using node_type = list_node<T>;
74+
using base_node_type = list_node_base;
75+
using self_type = list_const_iterator<T>;
76+
using value_type = T;
77+
using pointer = const T*;
78+
using reference = const T&;
79+
80+
const base_node_type* node;
81+
82+
list_const_iterator(const base_node_type* n) : node(n) {}
83+
84+
reference operator*() const {
85+
return static_cast<const node_type*>(node)->data;
86+
}
87+
pointer operator->() const {
88+
return &static_cast<const node_type*>(node)->data;
89+
}
90+
91+
self_type& operator++() {
92+
node = node->next;
93+
return *this;
94+
}
95+
96+
self_type operator++(int) {
97+
self_type tmp = *this;
98+
node = node->next;
99+
return tmp;
100+
}
101+
102+
self_type& operator--() {
103+
node = node->prev;
104+
return *this;
105+
}
106+
107+
self_type operator--(int) {
108+
self_type tmp = *this;
109+
node = node->prev;
110+
return tmp;
111+
}
112+
113+
bool operator==(const self_type& other) const { return node == other.node; }
114+
bool operator!=(const self_type& other) const { return node != other.node; }
115+
};
116+
117+
template <typename T>
118+
class list {
119+
public:
120+
using node_type = list_node<T>;
121+
using base_node_type = list_node_base;
122+
using iterator = list_iterator<T>;
123+
using const_iterator = list_const_iterator<T>;
124+
using value_type = T;
125+
using reference = value_type&;
126+
using const_reference = const value_type&;
127+
using size_type = size_t;
128+
129+
list() : _size(0) {
130+
// Sentinel already initialized by default ctor of list_node_base
131+
}
132+
133+
~list() { clear(); }
134+
135+
list(const list& other) : _size(0) {
136+
for (const auto& item : other) {
137+
push_back(item);
138+
}
139+
}
140+
141+
list& operator=(const list& other) {
142+
if (this != &other) {
143+
clear();
144+
for (const auto& item : other) {
145+
push_back(item);
146+
}
147+
}
148+
return *this;
149+
}
150+
151+
iterator begin() { return iterator(sentinel.next); }
152+
iterator end() { return iterator(&sentinel); }
153+
const_iterator begin() const { return const_iterator(sentinel.next); }
154+
const_iterator end() const { return const_iterator(&sentinel); }
155+
156+
bool empty() const { return _size == 0; }
157+
size_type size() const { return _size; }
158+
159+
T& front() { return *begin(); }
160+
const T& front() const { return *begin(); }
161+
T& back() { return *(--end()); }
162+
const T& back() const { return *(--end()); }
163+
164+
void push_front(const T& val) { insert(begin(), val); }
165+
166+
void push_back(const T& val) { insert(end(), val); }
167+
168+
void pop_front() { erase(begin()); }
169+
170+
void pop_back() { erase(--end()); }
171+
172+
iterator insert(iterator pos, const T& val) {
173+
node_type* new_node = new node_type(val);
174+
base_node_type* p = pos.node;
175+
base_node_type* prev = p->prev;
176+
177+
new_node->next = p;
178+
new_node->prev = prev;
179+
prev->next = new_node;
180+
p->prev = new_node;
181+
182+
_size++;
183+
return iterator(new_node);
184+
}
185+
186+
iterator erase(iterator pos) {
187+
if (pos == end()) return end();
188+
189+
base_node_type* p = pos.node;
190+
base_node_type* prev = p->prev;
191+
base_node_type* next = p->next;
192+
193+
prev->next = next;
194+
next->prev = prev;
195+
196+
delete static_cast<node_type*>(p);
197+
198+
_size--;
199+
return iterator(next);
200+
}
201+
202+
void clear() {
203+
while (!empty()) {
204+
pop_front();
205+
}
206+
}
207+
208+
private:
209+
list_node_base sentinel;
210+
size_type _size;
211+
};
212+
213+
} // namespace sk_std
214+
215+
#endif // SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_LIST_
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @copyright Copyright The SimpleKernel Contributors
3+
*/
4+
5+
#ifndef SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_PRIORITY_QUEUE_
6+
#define SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_PRIORITY_QUEUE_
7+
8+
#include <algorithm>
9+
#include <functional>
10+
11+
#include "sk_vector"
12+
13+
namespace sk_std {
14+
15+
template <class T, class Container = vector<T>,
16+
class Compare = std::less<typename Container::value_type>>
17+
class priority_queue {
18+
public:
19+
using value_type = typename Container::value_type;
20+
using reference = typename Container::reference;
21+
using const_reference = typename Container::const_reference;
22+
using size_type = typename Container::size_type;
23+
using container_type = Container;
24+
25+
protected:
26+
Container c;
27+
Compare comp;
28+
29+
public:
30+
priority_queue() : c(), comp() {}
31+
32+
explicit priority_queue(const Compare& compare) : c(), comp(compare) {}
33+
34+
priority_queue(const Compare& compare, const Container& cont)
35+
: c(cont), comp(compare) {
36+
std::make_heap(c.begin(), c.end(), comp);
37+
}
38+
39+
priority_queue(const Compare& compare, Container&& cont)
40+
: c(static_cast<Container&&>(cont)), comp(compare) {
41+
std::make_heap(c.begin(), c.end(), comp);
42+
}
43+
44+
bool empty() const { return c.size() == 0; }
45+
46+
size_type size() const { return c.size(); }
47+
48+
const_reference top() const { return c.front(); }
49+
50+
void push(const value_type& value) {
51+
c.push_back(value);
52+
std::push_heap(c.begin(), c.end(), comp);
53+
}
54+
55+
void push(value_type&& value) {
56+
c.push_back(static_cast<value_type&&>(value));
57+
std::push_heap(c.begin(), c.end(), comp);
58+
}
59+
60+
void pop() {
61+
if (c.size() > 0) {
62+
std::pop_heap(c.begin(), c.end(), comp);
63+
c.pop_back();
64+
}
65+
}
66+
};
67+
68+
} // namespace sk_std
69+
70+
#endif // SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_PRIORITY_QUEUE_

src/libcxx/include/sk_queue

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @copyright Copyright The SimpleKernel Contributors
3+
*/
4+
5+
#ifndef SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_QUEUE_
6+
#define SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_QUEUE_
7+
8+
#include "sk_list"
9+
10+
namespace sk_std {
11+
12+
template <class T, class Container = list<T>>
13+
class queue {
14+
public:
15+
using value_type = typename Container::value_type;
16+
using reference = typename Container::reference;
17+
using const_reference = typename Container::const_reference;
18+
using size_type = typename Container::size_type;
19+
using container_type = Container;
20+
21+
protected:
22+
Container c;
23+
24+
public:
25+
explicit queue(const Container& cont = Container()) : c(cont) {}
26+
27+
~queue() = default;
28+
29+
queue(const queue&) = default;
30+
queue(queue&&) = default;
31+
32+
queue& operator=(const queue&) = default;
33+
queue& operator=(queue&&) = default;
34+
35+
bool empty() const { return c.empty(); }
36+
37+
size_type size() const { return c.size(); }
38+
39+
reference front() { return c.front(); }
40+
41+
const_reference front() const { return c.front(); }
42+
43+
reference back() { return c.back(); }
44+
45+
const_reference back() const { return c.back(); }
46+
47+
void push(const value_type& val) { c.push_back(val); }
48+
49+
void pop() { c.pop_front(); }
50+
};
51+
52+
} // namespace sk_std
53+
54+
#endif // SIMPLEKERNEL_SRC_LIBCXX_INCLUDE_SK_QUEUE_

0 commit comments

Comments
 (0)