AlgoPlus v0.1.0
Loading...
Searching...
No Matches
table.h
1
6
7#ifndef TABLE_H
8#define TABLE_H
9
10#ifdef __cplusplus
11#include <cassert>
12#include <functional>
13#include <iostream>
14#include <memory>
15#include <ranges>
16#endif
17
18template <typename T> class table {
19 private:
20 struct node {
21 T info;
22 size_t _idx;
23 std::shared_ptr<node> ptr_right;
24 std::shared_ptr<node> ptr_left;
25 explicit node() : ptr_right(nullptr), ptr_left(nullptr), _idx(0) {}
26 };
27
28 size_t _size;
29 std::shared_ptr<node> root;
30 std::shared_ptr<node> tail;
31 std::shared_ptr<node> _itr;
32
33 public:
34 explicit table() noexcept : root(nullptr), tail(nullptr), _itr(nullptr), _size(0) {}
35 table(const table<T>& t) noexcept : root(t.root), tail(t.tail), _size(t._size) {}
36
37 size_t size() { return this->_size; }
38
39 template <typename... Args> void push_front(Args&&... keys);
40
41 template <typename... Args> void push_back(Args&&... keys);
42
43 void pop_front();
44
45 void pop_back();
46
47 bool empty();
48
49 std::vector<T> vectorize();
50
51 class Iterator;
52
53 Iterator begin() { return Iterator(root); }
54
55 Iterator end() { return Iterator(nullptr); }
56
57 T& operator[](const size_t& index) {
58 assert(index < _size && index >= 0);
59 if (index == 0) {
60 return this->root->info;
61 }
62
63 if (index == _size - 1) {
64 return this->tail->info;
65 }
66
67 if (_itr->_idx < index) {
68 while (_itr->_idx != index) {
69 _itr = _itr->ptr_right;
70 }
71 } else {
72 while (_itr->_idx != index) {
73 _itr = _itr->ptr_left;
74 }
75 }
76
77 return _itr->info;
78 }
79
80 table<T>& operator=(const table<T>& t) {
81 if (this == &t) [[unlikely]] {
82 return *this;
83 } else [[likely]] {
84 this->root = t.root;
85 this->tail = t.tail;
86 }
87 return *(this);
88 }
89 friend std::ostream& operator<<(std::ostream& out, const table<T>& t) {
90 if (t.root == nullptr) [[unlikely]] {
91 return out;
92 } else [[likely]] {
93 std::shared_ptr<node> tmp = t.root;
94 while (tmp != nullptr) {
95 out << tmp->info << " ";
96 tmp = tmp->ptr_right;
97 }
98 }
99 return out;
100 }
101
102 protected:
103 void _check_update() {
104 if (this->root == nullptr) {
105 return;
106 }
107 std::shared_ptr<node> tmp = this->root;
108 size_t idx = 0;
109 while (tmp != nullptr) {
110 tmp->_idx = idx++;
111 tmp = tmp->ptr_right;
112 }
113 }
114};
115
116template <typename T> template <typename... Args> void table<T>::push_front(Args&&... keys) {
117 auto _insert = [&](const T&& key) -> void {
118 std::shared_ptr<node> nn = std::make_shared<node>();
119 nn->info = key;
120 if (this->root == nullptr) [[unlikely]] {
121 nn->_idx = 0;
122 this->root = nn;
123 this->tail = nn;
124 this->_itr = nn;
125 this->_size++;
126 return;
127 } else [[likely]] {
128 std::shared_ptr<node> tmp = root;
129 nn->_idx = 0;
130 this->root = nn;
131 this->root->ptr_right = tmp;
132 tmp->ptr_left = this->root;
133 }
134 this->_size++;
135 };
136 (std::invoke(_insert, std::forward<Args>(keys)), ...);
137 _check_update();
138}
139
140template <typename T> template <typename... Args> void table<T>::push_back(Args&&... keys) {
141 auto _insert = [&](const T&& key) -> void {
142 std::shared_ptr<node> nn = std::make_shared<node>();
143 nn->info = key;
144 if (this->root == nullptr) [[unlikely]] {
145 nn->_idx = 0;
146 this->root = nn;
147 this->tail = nn;
148 this->_itr = nn;
149 this->_size++;
150 return;
151 } else [[likely]] {
152 std::shared_ptr<node> tmp = tail;
153 nn->_idx = tail->_idx + 1;
154 this->tail = nn;
155 tmp->ptr_right = tail;
156 this->tail->ptr_left = tmp;
157 }
158 this->_size++;
159 };
160 (std::invoke(_insert, std::forward<Args>(keys)), ...);
161}
162
163template <typename T> void table<T>::pop_back() {
164 if (this->tail == nullptr) [[unlikely]] {
165 return;
166 } else [[likely]] {
167 this->tail = this->tail->ptr_left;
168 }
169 _size--;
170}
171
172template <typename T> void table<T>::pop_front() {
173 if (this->root == nullptr) [[unlikely]] {
174 return;
175 } else [[likely]] {
176 this->root = this->root->ptr_right;
177 }
178 _size--;
179 _check_update();
180}
181
182template <typename T> bool table<T>::empty() {
183 return this->_size == 0;
184}
185
186template <typename T> std::vector<T> table<T>::vectorize() {
187 if (this->root == nullptr) {
188 return {};
189 }
190 std::vector<T> vec;
191 for (auto it = this->begin(); it != this->end(); it++) {
192 vec.push_back(*(it));
193 }
194 return vec;
195}
196
197template <typename T> class table<T>::Iterator {
198 private:
199 std::shared_ptr<node> curr_root;
200
201 public:
202 explicit Iterator(const std::shared_ptr<node>& ptr) noexcept : curr_root(ptr) {}
203
204 Iterator& operator=(std::shared_ptr<node> current) {
205 this->curr_root = current;
206 return *(this);
207 }
208
209 Iterator& operator++() {
210 if (curr_root) {
211 curr_root = curr_root->ptr_right;
212 }
213 return *(this);
214 }
215
216 Iterator operator++(int) {
217 Iterator it = *this;
218 ++*(this);
219 return it;
220 }
221
222 Iterator& operator--() {
223 if (curr_root) {
224 curr_root = curr_root->ptr_left;
225 }
226 return *(this);
227 }
228
229 Iterator operator--(int) {
230 Iterator it = *this;
231 --*(this);
232 return it;
233 }
234
235 bool operator!=(const Iterator& it) { return curr_root != it.curr_root; }
236
237 T operator*() { return curr_root->info; }
238};
239
240#endif
Definition table.h:197
@ key
the parser read a key of a value in an object
Definition json.hpp:11716