data-structures-c
Loading...
Searching...
No Matches
list_example.c

Example of how list_template.h header file is used in practice.

#define NAME arena
#define TYPE_DEFINITIONS
#define FUNCTION_DEFINITIONS
#define FUNCTION_LINKAGE static inline
#include "./../../arena/arena_template.h"
#include "container_of.h"
#include "list.h"
#include <stdalign.h>
#include <stdio.h>
static unsigned char buf[4096];
typedef struct {
char c;
struct list_node node;
} char_elm_type;
void list_stack(void)
{
struct arena arena;
arena_init(&arena, sizeof(buf), buf);
struct list_node head;
assert(list_node_is_singular(&head));
{
char_elm_type *first_elm_ptr = arena_allocate_aligned(&arena, alignof(char_elm_type), sizeof(char_elm_type));
first_elm_ptr->c = 'a';
list_node_init(&first_elm_ptr->node);
list_node_add_after(&head, &first_elm_ptr->node);
for (size_t i = 1; i <= 'z' - 'a'; i++) {
char_elm_type *ptr = arena_allocate_aligned(&arena, alignof(char_elm_type), sizeof(char_elm_type));
ptr->c = (char)('a' + i);
list_node_init(&ptr->node);
list_node_add_after(&head, &ptr->node);
}
assert(list_node_is_last(&head, &first_elm_ptr->node));
}
{
char c = 'z';
struct list_node *node_ptr;
LIST_FOR_EACH_SAFE(node_ptr, next_ptr, &head)
{
char_elm_type *elm = container_of_const(node_ptr, char_elm_type, node);
assert(c == elm->c);
if (c == 'm') {
char_elm_type *ptr = arena_allocate_aligned(&arena, alignof(char_elm_type), sizeof(char_elm_type));
ptr->c = 'M';
list_node_init(&ptr->node);
list_node_replace(node_ptr, &ptr->node);
}
c--;
}
assert(c + 1 == 'a');
}
{
char c = 'z';
struct list_node *node_ptr;
LIST_FOR_EACH(node_ptr, &head)
{
char_elm_type *elm = container_of_const(node_ptr, char_elm_type, node);
assert(elm->c != 'm');
if (c == 'm') {
assert(elm->c == 'M');
}
c--;
}
assert(c + 1 == 'a');
}
}
void list_queue(void)
{
struct arena arena;
arena_init(&arena, sizeof(buf), buf);
struct list_node tail;
assert(list_node_is_singular(&tail));
{
char_elm_type *first_elm_ptr = arena_allocate_aligned(&arena, alignof(char_elm_type), sizeof(char_elm_type));
first_elm_ptr->c = 'a';
list_node_init(&first_elm_ptr->node);
list_node_add_before(&tail, &first_elm_ptr->node);
for (size_t i = 1; i <= 'z' - 'a'; i++) {
char_elm_type *ptr = arena_allocate_aligned(&arena, alignof(char_elm_type), sizeof(char_elm_type));
ptr->c = (char)('a' + i);
list_node_init(&ptr->node);
list_node_add_before(&tail, &ptr->node);
}
assert(list_node_is_first(&tail, &first_elm_ptr->node));
}
size_t count = 0;
{
char c = 'a';
struct list_node *node_ptr;
LIST_FOR_EACH_SAFE(node_ptr, next_ptr, &tail)
{
char_elm_type *elm = container_of_const(node_ptr, char_elm_type, node);
assert(c == elm->c);
c++;
}
c--;
assert(c == 'z');
{
char_elm_type *elm = container_of_const(node_ptr, char_elm_type, node);
assert(c == elm->c);
if (c == 'm') {
list_node_remove(node_ptr);
}
c--;
count++;
}
}
size_t new_count = 0;
{
struct list_node *node_ptr;
LIST_FOR_EACH_REVERSE(node_ptr, &tail)
{
new_count++;
}
}
assert(count - 1 == new_count);
}
int main(void)
{
list_stack();
list_queue();
}
void * arena_allocate_aligned(void *self_, const size_t alignment, const size_t size)
Get the pointer to a chunk of the arena. With specific alignment.
Definition arena_template.h:297
void arena_init(void *self_, const size_t len, unsigned char *backing_buf)
Initialize the arena.
Definition arena_template.h:262
bool list_node_is_singular(const list_node_type *node_ptr)
Check if a given list node is singular (and initialized).
Definition list_template.h:304
#define LIST_FOR_EACH_REVERSE(node_ptr, head_ptr)
Iterate over a list in reverse.
Definition list_template.h:106
bool list_node_is_first(const list_node_type *head_ptr, const list_node_type *node_ptr)
Check if a given list node is first in the list (aka after the head).
Definition list_template.h:288
list_node_type * list_node_remove(list_node_type *node_ptr)
Remove a node from the list it resides in.
Definition list_template.h:329
#define LIST_FOR_EACH_SAFE(node_ptr, next_ptr, head_ptr)
Iterate over a list while allowing the current node to be modified.
Definition list_template.h:119
#define LIST_FOR_EACH_REVERSE_SAFE(node_ptr, prev_ptr, head_ptr)
Iterate over a list in reverse while allowing the current node to be modified.
Definition list_template.h:133
void list_node_init(list_node_type *node_ptr)
Initialize a list node.
Definition list_template.h:281
void list_node_add_after(list_node_type *prev_ptr, list_node_type *node_ptr)
Add a node after the given node.
Definition list_template.h:311
void list_node_replace(list_node_type *restrict old_ptr, list_node_type *restrict new_ptr)
Replace a given node by a new node.
Definition list_template.h:340
void list_node_add_before(list_node_type *next_ptr, list_node_type *node_ptr)
Add a node before the given node.
Definition list_template.h:320
#define LIST_FOR_EACH(node_ptr, head_ptr)
Iterate over a list.
Definition list_template.h:94
bool list_node_is_last(const list_node_type *head_ptr, const list_node_type *node_ptr)
Check if a given list node is the last of the list (aka before the head).
Definition list_template.h:296
Arena data struct.
Definition arena_template.h:114
Intrusive list node structure.
Definition list_template.h:153
list_node_type * next_ptr
next node pointer.
Definition list_template.h:155
list_node_type * prev_ptr
prev node pointer.
Definition list_template.h:154