Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/templates/self_list.h
9973 views
1
/**************************************************************************/
2
/* self_list.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/error/error_macros.h"
34
#include "core/templates/sort_list.h"
35
#include "core/typedefs.h"
36
37
template <typename T>
38
class SelfList {
39
public:
40
class List {
41
SelfList<T> *_first = nullptr;
42
SelfList<T> *_last = nullptr;
43
44
public:
45
void add(SelfList<T> *p_elem) {
46
ERR_FAIL_COND(p_elem->_root);
47
48
p_elem->_root = this;
49
p_elem->_next = _first;
50
p_elem->_prev = nullptr;
51
52
if (_first) {
53
_first->_prev = p_elem;
54
55
} else {
56
_last = p_elem;
57
}
58
59
_first = p_elem;
60
}
61
62
void add_last(SelfList<T> *p_elem) {
63
ERR_FAIL_COND(p_elem->_root);
64
65
p_elem->_root = this;
66
p_elem->_next = nullptr;
67
p_elem->_prev = _last;
68
69
if (_last) {
70
_last->_next = p_elem;
71
72
} else {
73
_first = p_elem;
74
}
75
76
_last = p_elem;
77
}
78
79
void remove(SelfList<T> *p_elem) {
80
ERR_FAIL_COND(p_elem->_root != this);
81
if (p_elem->_next) {
82
p_elem->_next->_prev = p_elem->_prev;
83
}
84
85
if (p_elem->_prev) {
86
p_elem->_prev->_next = p_elem->_next;
87
}
88
89
if (_first == p_elem) {
90
_first = p_elem->_next;
91
}
92
93
if (_last == p_elem) {
94
_last = p_elem->_prev;
95
}
96
97
p_elem->_next = nullptr;
98
p_elem->_prev = nullptr;
99
p_elem->_root = nullptr;
100
}
101
102
void clear() {
103
while (_first) {
104
remove(_first);
105
}
106
}
107
108
void sort() {
109
sort_custom<Comparator<T>>();
110
}
111
112
template <typename C>
113
void sort_custom() {
114
if (_first == _last) {
115
return;
116
}
117
118
struct PtrComparator {
119
C compare;
120
_FORCE_INLINE_ bool operator()(const T *p_a, const T *p_b) const { return compare(*p_a, *p_b); }
121
};
122
using Element = SelfList<T>;
123
SortList<Element, T *, &Element::_self, &Element::_prev, &Element::_next, PtrComparator> sorter;
124
sorter.sort(_first, _last);
125
}
126
127
_FORCE_INLINE_ SelfList<T> *first() { return _first; }
128
_FORCE_INLINE_ const SelfList<T> *first() const { return _first; }
129
130
// Forbid copying, which has broken behavior.
131
void operator=(const List &) = delete;
132
133
_FORCE_INLINE_ List() {}
134
_FORCE_INLINE_ ~List() {
135
// A self list must be empty on destruction.
136
DEV_ASSERT(_first == nullptr);
137
}
138
};
139
140
private:
141
List *_root = nullptr;
142
T *_self = nullptr;
143
SelfList<T> *_next = nullptr;
144
SelfList<T> *_prev = nullptr;
145
146
public:
147
_FORCE_INLINE_ bool in_list() const { return _root; }
148
_FORCE_INLINE_ void remove_from_list() {
149
if (_root) {
150
_root->remove(this);
151
}
152
}
153
_FORCE_INLINE_ SelfList<T> *next() { return _next; }
154
_FORCE_INLINE_ SelfList<T> *prev() { return _prev; }
155
_FORCE_INLINE_ const SelfList<T> *next() const { return _next; }
156
_FORCE_INLINE_ const SelfList<T> *prev() const { return _prev; }
157
_FORCE_INLINE_ T *self() const { return _self; }
158
159
// Forbid copying, which has broken behavior.
160
void operator=(const SelfList<T> &) = delete;
161
162
_FORCE_INLINE_ SelfList(T *p_self) {
163
_self = p_self;
164
}
165
166
_FORCE_INLINE_ ~SelfList() {
167
if (_root) {
168
_root->remove(this);
169
}
170
}
171
};
172
173