aboutsummaryrefslogtreecommitdiff
path: root/backend/List.hpp
blob: 634f14b17929daec77b618510bcea16189f62cc3 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
#pragma once

#include "List.h"

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

template <typename T>
void List<T>::push_back(const T & el) {
	ListLink<T> * link = new ListLink<T> {
		.prev = this->head,
		.next = nullptr,
		.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)
		this->head = link->prev;
	else
		link->next->prev = link->prev;
	if (link->prev == nullptr)
		this->tail = link->next;
	else
		link->prev->next = link->next;

	delete 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;
	delete 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;
		delete link;
		link = next;
	}
	this->head = nullptr;
	this->tail = nullptr;
	this->length = 0;
}

template <typename T>
T & List<T>::operator [] (size_t index) const {
	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();
}

template <typename T>
List<T>::~List() {
	this->clear();
}