aboutsummaryrefslogtreecommitdiff
path: root/backend/List.hpp
blob: a0d9289b65082687cde5187cdea35180c98a65e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#pragma once

#include "List.h"

template <typename T>
size_t List<T>::size() {
	return this->length;
}

template <typename T>
void List<T>::push_back(T & el) {
	ListLink<T> * link = static_cast<ListLink<T> *>(malloc(sizeof(ListLink<T>)));
	link->prev = this->head;
	link->next = nullptr;
	link->value = el;
	if (this->head != nullptr) this->head->next = link;
	if (this->head == nullptr) this->tail = link;
	this->head = link;
	this->length++;
}

template <typename T>
void List<T>::remove(const T & target) {
	ListLink<T> * link = nullptr;
	for (link = this->tail; link != nullptr; link = link->next) {
		if (link->value == target) break;
	}
	if (link == nullptr) return; // target not in list

	if (link->next != nullptr) link->next->prev = link->prev;
	if (link->prev != nullptr) link->prev->next = link->next;
	free(link);
	this->length--;
}

template <typename T>
void List<T>::pop_back() {
	if (this->head == nullptr) return; // empty list

	ListLink<T> * secondlast = this->head->prev;
	if (secondlast != nullptr)
		secondlast->next = nullptr;
	free(this->head);
	if (this->tail == this->head)
		this->tail = nullptr;
	this->head = secondlast;

	this->length--;
}

template <typename T>
void List<T>::clear() {
	ListLink<T> * link = this->tail;
	while (link != nullptr) {
		ListLink<T> * next = link->next;
		free(link);
		link = next;
	}
	this->head = nullptr;
	this->tail = nullptr;
	this->length = 0;
}

template <typename T>
T & List<T>::operator [] (size_t index) {
	ListLink<T> * link = this->tail;
	for (size_t i = 0; i < index; i++)
		link = link->next;
	return link->value;
}

template <typename T>
ListRange<T> List<T>::range() {
	return { *this };
}

template <typename T>
ListIterator<T> List<T>::begin() {
	return this->range().begin();
}

template <typename T>
ListIterator<T> List<T>::end() {
	return this->range().end();
}