spz3/List.h

110 lines
2.5 KiB
C
Raw Normal View History

2025-03-31 17:19:43 +03:00
#ifndef LIST_H
#define LIST_H
template<typename T>
class List {
T *head, *tail;
unsigned int num;
const unsigned int idx;
public:
explicit List(unsigned int idx);
T *first();
T *last();
void insert_head(T *elem);
void insert_tail(T *elem);
void insert_before(T *elem1, T *elem2);
void remove(T *elem);
bool is_empty();
[[nodiscard]] unsigned int get_num() const;
};
#define for_each_in_list(elem, list) \
for ( \
(elem) = (list)->first(); \
(elem) != nullptr; \
(elem) = (list)->next(elem) \
)
template<typename T>
List<T>::List(const unsigned int idx) : head{nullptr}, tail{nullptr}, num{0}, idx{idx} {
}
template<typename T>
T * List<T>::first() {
return this->head;
}
template<typename T>
T * List<T>::last() {
return this->tail;
}
template<typename T>
void List<T>::insert_head(T *elem) {
const unsigned int idx{this->idx};
elem->next[idx] = this->head;
elem->prev[idx] = nullptr;
if (this->head != nullptr)
this->head->prev[idx] = elem;
if (this->tail == nullptr)
this->tail = elem;
this->head = elem;
++this->num;
}
template<typename T>
void List<T>::insert_tail(T *elem) {
const unsigned int idx{this->idx};
elem->next[idx] = nullptr;
elem->prev[idx] = this->tail;
if (this->tail != nullptr)
this->tail->next[idx] = elem;
if (this->head == nullptr)
this->head = elem;
this->tail = elem;
++this->num;
}
template<typename T>
void List<T>::insert_before(T *elem1, T *elem2) {
const unsigned int idx{this->idx};
elem1->next[idx] = elem2;
elem1->prev[idx] = elem2->prev[idx];
elem2->prev[idx] = elem1;
if (elem1->prev[idx] == nullptr)
this->head = elem1;
else
elem1->prev[idx]->next[idx] = elem1;
++this->num;
}
template<typename T>
void List<T>::remove(T *elem) {
const unsigned int idx{this->idx};
if (elem->next[idx] != nullptr)
elem->next[idx]->prev[idx] = elem->prev[idx];
if (elem->prev[idx] != nullptr)
elem->prev[idx]->next[idx] = elem->next[idx];
if (this->head == elem)
this->head = elem->next[idx];
if (this->tail == elem)
this->tail = elem->prev[idx];
--this->num;
}
template<typename T>
bool List<T>::is_empty() {
return this->num == 0;
}
template<typename T>
unsigned int List<T>::get_num() const {
return this->num;
}
#endif //LIST_H