81 lines
1.9 KiB
C
81 lines
1.9 KiB
C
|
|
#pragma once
|
||
|
|
#include <utility>
|
||
|
|
|
||
|
|
template <typename T, int N>
|
||
|
|
struct callback_list {
|
||
|
|
struct node {
|
||
|
|
T value;
|
||
|
|
node* prev = nullptr;
|
||
|
|
node* next = nullptr;
|
||
|
|
};
|
||
|
|
|
||
|
|
node nodes[N];
|
||
|
|
node* free_head = &nodes[0];
|
||
|
|
node* head = nullptr;
|
||
|
|
|
||
|
|
callback_list() {
|
||
|
|
for (int i = 0; i < N - 1; i++) nodes[i].next = &nodes[i + 1];
|
||
|
|
nodes[N - 1].next = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool empty() const { return head == nullptr; }
|
||
|
|
|
||
|
|
node* insert(T value) {
|
||
|
|
if (!free_head) return nullptr;
|
||
|
|
node* n = free_head;
|
||
|
|
free_head = n->next;
|
||
|
|
n->value = std::move(value);
|
||
|
|
n->prev = nullptr;
|
||
|
|
n->next = head;
|
||
|
|
if (head) head->prev = n;
|
||
|
|
head = n;
|
||
|
|
return n;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Less>
|
||
|
|
node* insert_sorted(T value, Less&& less) {
|
||
|
|
if (!free_head) return nullptr;
|
||
|
|
node* n = free_head;
|
||
|
|
free_head = n->next;
|
||
|
|
n->value = std::move(value);
|
||
|
|
if (!head || less(n->value, head->value)) {
|
||
|
|
n->prev = nullptr;
|
||
|
|
n->next = head;
|
||
|
|
if (head) head->prev = n;
|
||
|
|
head = n;
|
||
|
|
return n;
|
||
|
|
}
|
||
|
|
node* cur = head;
|
||
|
|
while (cur->next && !less(n->value, cur->next->value))
|
||
|
|
cur = cur->next;
|
||
|
|
n->prev = cur;
|
||
|
|
n->next = cur->next;
|
||
|
|
if (cur->next) cur->next->prev = n;
|
||
|
|
cur->next = n;
|
||
|
|
return n;
|
||
|
|
}
|
||
|
|
|
||
|
|
void remove(node* n) {
|
||
|
|
if (!n) return;
|
||
|
|
if (n->prev) n->prev->next = n->next;
|
||
|
|
else head = n->next;
|
||
|
|
if (n->next) n->next->prev = n->prev;
|
||
|
|
n->value = T{};
|
||
|
|
n->next = free_head;
|
||
|
|
n->prev = nullptr;
|
||
|
|
free_head = n;
|
||
|
|
}
|
||
|
|
|
||
|
|
node* front() { return head; }
|
||
|
|
|
||
|
|
template <typename Fn>
|
||
|
|
void for_each(Fn&& fn) {
|
||
|
|
node* cur = head;
|
||
|
|
while (cur) {
|
||
|
|
node* next = cur->next;
|
||
|
|
fn(cur);
|
||
|
|
cur = next;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|