75 lines
1.9 KiB
C++
75 lines
1.9 KiB
C++
|
#include "list.hpp"
|
||
|
#include <cstdio>
|
||
|
|
||
|
// pop the last block
|
||
|
block* list_unlink (list* l) {
|
||
|
// we need a list
|
||
|
if (!l) return nullptr;
|
||
|
block* b = l->end;
|
||
|
// can't unlink from an empty list
|
||
|
if (!b) return nullptr;
|
||
|
// remove b
|
||
|
if (b->prev) {
|
||
|
// b is not the only element of the list
|
||
|
// chop of the tail
|
||
|
l->end = b->prev;
|
||
|
// bandage the wound
|
||
|
l->end->next = nullptr;
|
||
|
// wrap the severed end
|
||
|
b->prev = nullptr;
|
||
|
} else {
|
||
|
// b is the only element of the list
|
||
|
l->start = nullptr;
|
||
|
l->end = nullptr;
|
||
|
}
|
||
|
// if we get here, we've removed element b from the list
|
||
|
l->length--;
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
// push a block
|
||
|
void list_link (list* l, block* b) {
|
||
|
// can't link to a nonexistent list
|
||
|
if (!l) return;
|
||
|
// can't append nullptr;
|
||
|
if (!b) return;
|
||
|
if (l->start == nullptr) {
|
||
|
// b is the only element of the list
|
||
|
l->start = b;
|
||
|
l->end = b;
|
||
|
} else {
|
||
|
// make b the next element of the list
|
||
|
b->prev = l->end;
|
||
|
l->end->next = b;
|
||
|
// terminate the list
|
||
|
b->next = nullptr;
|
||
|
// update end
|
||
|
l->end = b;
|
||
|
}
|
||
|
l->length++;
|
||
|
}
|
||
|
|
||
|
// push a lot of blocks
|
||
|
// this is slow, but the pointer arithmetic *has* to be done for each block
|
||
|
// so it's not really as slow as it would be, were that not the case.
|
||
|
void list_init (list *l, block *m, int size) {
|
||
|
// move each block of memory into the freelist, by linking it to the end
|
||
|
for (int b = 0; b < size; b++) {
|
||
|
list_link(l, &(m[b]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// YAML-like, because I like YAML
|
||
|
void list_print(list *l) {
|
||
|
if (!l) return;
|
||
|
std::printf("l_%p:\n - start: '%p',\n - end: '%p',\n - length: '%d',\n - blocks:",l,l->start,l->end,l->length);
|
||
|
block* b = l->start;
|
||
|
if (b) {
|
||
|
do {
|
||
|
std::printf("\n - b_%p: [prev: '%p', next: '%p', data: '%d']",b,b->prev,b->next,b->data);
|
||
|
} while (b = b->next);
|
||
|
std::printf("\n");
|
||
|
} else {
|
||
|
std::printf(" []\n");
|
||
|
}
|
||
|
}
|