cons
Loading...
Searching...
No Matches
cons_node.c
Go to the documentation of this file.
1/* SPDX-License-Identifier: MIT */
2
13#include <cons_node.h>
14
15/*
16 * This definition exists as a token. It does nothing in practice
17 * because a node's cell (currently) lives at the start of the node's
18 * structure. Subtracting a zero offset (the offset of a cell from its
19 * node) does nothing. The compiler does all the work. Nothing happens
20 * at runtime. This exists to preserve container correctness and to
21 * avoid undefined behaviour.
22 */
23#ifdef containerof
24#define NODE_FROM_CELL(_cell_) containerof(_cell_, struct cons_node, cell)
25#else
26#define NODE_FROM_CELL(_cell_) ((struct cons_node *)((char *)(_cell_) - offsetof(struct cons_node, cell)))
27#endif
28
29/*
30 * The following ternary operator is not strictly necessary, but better
31 * to check for the NULL pointer before doing the container adjustment,
32 * as it avoids unnecessary pointer arithmetic when the input is NULL.
33 */
34static inline struct cons_node *node_from_cell(struct cons *cell) { return CONS_NOT_NIL_P(cell) ? NODE_FROM_CELL(cell) : NULL; }
35
36struct cons_node *cons_car_node(struct cons_node *node) { return (struct cons_node *)cons_car(&node->cell); }
37
38struct cons_node *cons_cdr_node(struct cons_node *node) { return node_from_cell(cons_cdr(&node->cell)); }
39
40struct cons_node *cons_sub_node(struct cons_node *node) { return node_from_cell(node->head); }
41
42/*
43 * Constructs a tree of nodes.
44 */
45struct cons_node *cons_node(struct cons_node *sub, struct cons_node *super) {
46 /*
47 * Prevent a node from being its own super-node. Avoids creating a
48 * cycle in the tree, which would lead to undefined behaviour when
49 * traversing. If the sub-node is the same as the super-node, the
50 * function does not modify the tree structure.
51 */
52 if (sub == super)
53 return super;
54 struct cons_node *car = cons_car_node(sub);
55 if (car != NULL) {
56 /*
57 * The sub-node already has a super-node. Remove the sub-node from
58 * the list of sub-nodes of the current super-node. Remove it even
59 * if the current super-node is the same as the new super-node,
60 * because the sub-node may be in a different position in the list
61 * of sub-nodes of the new super-node when re-constructing the same
62 * sub-super linkage.
63 */
64 (void)cons_remove(&car->head, &sub->cell);
65 cons_rplaca(&sub->cell, NULL);
66 }
67 if (super != NULL) {
68 /*
69 * The new super-node is not NULL. Prepend the sub-node to the list
70 * of sub-nodes of the new super-node. Set the car field of the
71 * sub-node to point to the new super-node.
72 *
73 * This could be redundant if the sub-node is already a sub-node of
74 * the new super-node, but it is simpler to just do it
75 * unconditionally than to check for that case.
76 */
77 (void)cons(&super->head, &sub->cell);
78 cons_rplaca(&sub->cell, super);
79 }
80 return super;
81}
static struct cons * cons_cdr(const struct cons *cell)
Accessor for the cdr field of a cons cell.
Definition cons.h:104
static void * cons_car(const struct cons *cell)
Accessor for the car field of a cons cell.
Definition cons.h:97
#define CONS_NOT_NIL_P(_cell)
Returns true if the cons cell is not CONS_NIL.
Definition cons.h:42
struct cons * cons_remove(struct cons **list, struct cons *cell)
Destructively removes the specified cons cell from the list.
Definition cons.c:81
static void cons_rplaca(struct cons *cell, void *car)
Mutator for the car field of a cons cell.
Definition cons.h:111
struct cons_node * cons_car_node(struct cons_node *node)
Accessor for the parent node (super-node) of a cons node.
Definition cons_node.c:36
struct cons_node * cons_cdr_node(struct cons_node *node)
Accessor for the next sibling node of a cons node.
Definition cons_node.c:38
struct cons_node * cons_sub_node(struct cons_node *node)
Accessor for the first child node (sub-node) of a cons node.
Definition cons_node.c:40
Defines the structure and functions for cons nodes.
Structure representing a cons node.
Definition cons_node.h:44
struct cons * head
Pointer to the list of child nodes (sub-nodes).
Definition cons_node.h:62
struct cons cell
The cons cell forming the basis of the node.
Definition cons_node.h:55
Construct cell structure for building linked lists.
Definition cons.h:73