Reduct  v1.0.4-3-gdaf0d70
A functional and immutable language.
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1#ifndef REDUCT_LIST_H
2#define REDUCT_LIST_H 1
3
4struct reduct;
5struct reduct_item;
6
7#include "defs.h"
8
9/**
10 * @file list.h
11 * @brief List management.
12 * @defgroup list List
13 *
14 * A list is a persistent data structure implemented using a bit-mapped vector trie.
15 *
16 * The list is made up of a "tree" of nodes along with a "tail" node, with each node storing a fixed size array of
17 * either children or elements within the list.
18 *
19 * When an element is added to a list, it will be appended to the array within the tail node, once the tail node is
20 * full, it is "pushed" to the front of the tree, which may require increasing the depth of tree.
21 *
22 * @see [Persistent vectors, Part 2 -- Immutability and persistence]
23 * (https://dmiller.github.io/clojure-clr-next/general/2023/02/12/PersistentVector-part-2.html)
24 *
25 */
26
27#define REDUCT_LIST_BITS 2 ///< Number of bits per level in the trie.
28#define REDUCT_LIST_WIDTH (1 << REDUCT_LIST_BITS) ///< The number of children per node.
29#define REDUCT_LIST_MASK (REDUCT_LIST_WIDTH - 1) ///< Mask for the index at each level.
30
31/**
32 * @brief List node structure.
33 * @struct reduct_list_node_t
34 */
35typedef struct reduct_list_node
36{
37 union {
38 struct reduct_list_node* children[REDUCT_LIST_WIDTH];
40 };
42
43/**
44 * @brief List structure.
45 * @struct reduct_list_t
46 */
47typedef struct reduct_list
48{
49 reduct_uint32_t length; ///< Total number of elements.
50 reduct_uint32_t shift; ///< The amount to shift the index to compute access paths.
51 reduct_list_node_t* root; ///< Pointer to the trie root node.
52 reduct_list_node_t* tail; ///< Pointer to the tail node.
54
55/**
56 * @brief Create a new editable list.
57 *
58 * @param reduct Pointer to the Reduct structure.
59 * @return A pointer to the newly created list.
60 */
62
63/**
64 * @brief Create a new list with an updated value at the specified index.
65 *
66 * @param reduct Pointer to the Reduct structure.
67 * @param list Pointer to the source list.
68 * @param index The index to update.
69 * @param val The new value to set.
70 * @return A pointer to the newly created list.
71 */
72REDUCT_API reduct_list_t* reduct_list_assoc(struct reduct* reduct, reduct_list_t* list, reduct_size_t index,
73 reduct_handle_t val);
74
75/**
76 * @brief Create a new list with the element at the specified index removed.
77 *
78 * @param reduct Pointer to the Reduct structure.
79 * @param list Pointer to the source list.
80 * @param index The index of the element to remove.
81 * @return A pointer to the newly created list.
82 */
83REDUCT_API reduct_list_t* reduct_list_dissoc(struct reduct* reduct, reduct_list_t* list, reduct_size_t index);
84
85/**
86 * @brief Create a new list by slicing an existing list.
87 *
88 * @param reduct Pointer to the Reduct structure.
89 * @param list Pointer to the source list.
90 * @param start The starting index (inclusive).
91 * @param end The ending index (exclusive).
92 * @return A pointer to the newly created list slice.
93 */
94REDUCT_API reduct_list_t* reduct_list_slice(struct reduct* reduct, reduct_list_t* list, reduct_size_t start,
95 reduct_size_t end);
96
97/**
98 * @brief Get the nth element of the list.
99 *
100 * @param reduct Pointer to the Reduct structure.
101 * @param list Pointer to the list.
102 * @param index The index of the element to retrieve.
103 * @return The handle of the nth element.
104 */
105REDUCT_API reduct_handle_t reduct_list_nth(struct reduct* reduct, reduct_list_t* list, reduct_size_t index);
106
107/**
108 * @brief Get the nth element of the list as an item.
109 *
110 * @param reduct Pointer to the Reduct structure.
111 * @param list Pointer to the list.
112 * @param index The index of the element to retrieve.
113 * @return A pointer to the item of the nth element.
114 */
115REDUCT_API struct reduct_item* reduct_list_nth_item(struct reduct* reduct, reduct_list_t* list, reduct_size_t index);
116
117/**
118 * @brief Append an element to the list.
119 *
120 * @param reduct Pointer to the Reduct structure.
121 * @param list The target list (must be editable).
122 * @param val Handle to the value to append.
123 */
124REDUCT_API void reduct_list_append(struct reduct* reduct, reduct_list_t* list, reduct_handle_t val);
125
126/**
127 * @brief Append all elements from one list to another.
128 *
129 * @param reduct Pointer to the Reduct structure.
130 * @param list The target list (must be editable).
131 * @param other The source list to copy from.
132 */
133REDUCT_API void reduct_list_append_list(struct reduct* reduct, reduct_list_t* list, reduct_list_t* other);
134
135/**
136 * @brief List iterator structure.
137 */
145
146/**
147 * @brief Calculate the offset of the tail node.
148 */
149#define REDUCT_LIST_TAIL_OFFSET(_list) (((_list)->length > 0) ? (((_list)->length - 1) & ~REDUCT_LIST_MASK) : 0)
150
151/**
152 * @brief Create a initializer for a list iterator.
153 *
154 * @param _list The list to iterate over.
155 */
156#define REDUCT_LIST_ITER(_list) {(_list), 0, REDUCT_NULL, REDUCT_LIST_TAIL_OFFSET(_list)}
157
158/**
159 * @brief Create a initializer for a list iterator start at a specific index.
160 *
161 * @param _list The list to iterate over.
162 * @param _start The starting index.
163 */
164#define REDUCT_LIST_ITER_AT(_list, _start) {(_list), (_start), REDUCT_NULL, REDUCT_LIST_TAIL_OFFSET(_list)}
165
166/**
167 * @brief Get the next element from the iterator.
168 *
169 * @param iter Pointer to the iterator.
170 * @param out Pointer to store the retrieved handle.
171 * @return REDUCT_TRUE if an element was retrieved, REDUCT_FALSE if the end was reached.
172 */
174
175/**
176 * @brief Macro for iterating over all elements in a list.
177 *
178 * @param _handle The reduct_handle_t variable to store each element.
179 * @param _list Pointer to the reduct_list_t to iterate.
180 */
181#define REDUCT_LIST_FOR_EACH(_handle, _list) \
182 for (reduct_list_iter_t _iter = REDUCT_LIST_ITER(_list); reduct_list_iter_next(&_iter, (_handle));)
183
184/**
185 * @brief Macro for iterating over elements in a list starting from a specific index.
186 *
187 * @param _handle The reduct_handle_t variable to store each element.
188 * @param _list Pointer to the reduct_list_t to iterate.
189 * @param _start The starting index.
190 */
191#define REDUCT_LIST_FOR_EACH_AT(_handle, _list, _start) \
192 for (reduct_list_iter_t _iter = REDUCT_LIST_ITER_AT(_list, _start); reduct_list_iter_next(&_iter, (_handle));)
193
194#endif
size_t reduct_size_t
Definition defs.h:100
reduct_bool_t
Boolean type.
Definition defs.h:135
reduct_uint64_t reduct_handle_t
Handle type.
Definition defs.h:189
uint32_t reduct_uint32_t
Definition defs.h:95
#define REDUCT_API
Definition defs.h:7
REDUCT_API reduct_handle_t reduct_list_nth(struct reduct *reduct, reduct_list_t *list, reduct_size_t index)
Get the nth element of the list.
Definition list_impl.h:157
REDUCT_API reduct_list_t * reduct_list_dissoc(struct reduct *reduct, reduct_list_t *list, reduct_size_t index)
Create a new list with the element at the specified index removed.
Definition list_impl.h:106
REDUCT_API reduct_list_t * reduct_list_assoc(struct reduct *reduct, reduct_list_t *list, reduct_size_t index, reduct_handle_t val)
Create a new list with an updated value at the specified index.
Definition list_impl.h:74
REDUCT_API reduct_list_t * reduct_list_slice(struct reduct *reduct, reduct_list_t *list, reduct_size_t start, reduct_size_t end)
Create a new list by slicing an existing list.
Definition list_impl.h:131
REDUCT_API void reduct_list_append(struct reduct *reduct, reduct_list_t *list, reduct_handle_t val)
Append an element to the list.
#define REDUCT_LIST_WIDTH
The number of children per node.
Definition list.h:28
REDUCT_API reduct_bool_t reduct_list_iter_next(reduct_list_iter_t *iter, reduct_handle_t *out)
Get the next element from the iterator.
Definition list_impl.h:255
REDUCT_API void reduct_list_append_list(struct reduct *reduct, reduct_list_t *list, reduct_list_t *other)
Append all elements from one list to another.
REDUCT_API reduct_list_t * reduct_list_new(struct reduct *reduct)
Create a new editable list.
REDUCT_API struct reduct_item * reduct_list_nth_item(struct reduct *reduct, reduct_list_t *list, reduct_size_t index)
Get the nth element of the list as an item.
Definition list_impl.h:172
List iterator structure.
Definition list.h:139
reduct_list_t * list
Definition list.h:140
reduct_size_t index
Definition list.h:141
reduct_size_t tailOffset
Definition list.h:143
reduct_list_node_t * leaf
Definition list.h:142
List node structure.
Definition list.h:36
List structure.
Definition list.h:48
reduct_list_node_t * tail
Pointer to the tail node.
Definition list.h:52
reduct_list_node_t * root
Pointer to the trie root node.
Definition list.h:51
reduct_uint32_t shift
The amount to shift the index to compute access paths.
Definition list.h:50
reduct_uint32_t length
Total number of elements.
Definition list.h:49