| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const debug = @import("debug.zig"); | 1 | const debug = @import("debug.zig"); |
| 2 | const assert = debug.assert; | 2 | const assert = debug.assert; |
| 3 | const mem = @import("mem.zig"); | 3 | const mem = @import("mem.zig"); |
| | 4 | const Allocator = mem.Allocator; |
| 4 | | 5 | |
| 5 | /// Generic doubly linked list. | 6 | /// Generic doubly linked list. |
| 6 | pub fn LinkedList(comptime T: type) -> type { | 7 | pub fn LinkedList(comptime T: type) -> type { |
| ... | @@ -15,9 +16,9 @@ pub fn LinkedList(comptime T: type) -> type { | ... | @@ -15,9 +16,9 @@ pub fn LinkedList(comptime T: type) -> type { |
| 15 | | 16 | |
| 16 | pub fn init(data: &const T) -> Node { | 17 | pub fn init(data: &const T) -> Node { |
| 17 | Node { | 18 | Node { |
| 18 | .data = *data, | | |
| 19 | .prev = null, | 19 | .prev = null, |
| 20 | .next = null, | 20 | .next = null, |
| | 21 | .data = *data, |
| 21 | } | 22 | } |
| 22 | } | 23 | } |
| 23 | }; | 24 | }; |
| ... | @@ -157,38 +158,57 @@ pub fn LinkedList(comptime T: type) -> type { | ... | @@ -157,38 +158,57 @@ pub fn LinkedList(comptime T: type) -> type { |
| 157 | return first; | 158 | return first; |
| 158 | } | 159 | } |
| 159 | | 160 | |
| 160 | } | 161 | /// Allocate a new node. |
| 161 | } | 162 | /// |
| 162 | | 163 | /// Arguments: |
| 163 | pub fn testAllocateNode(comptime T: type, list: &LinkedList(T), allocator: &mem.Allocator) -> %&LinkedList(T).Node { | 164 | /// allocator: Dynamic memory allocator. |
| 164 | allocator.create(LinkedList(T).Node) | 165 | /// |
| 165 | } | 166 | /// Returns: |
| | 167 | /// A pointer to the new node. |
| | 168 | pub fn allocateNode(list: &Self, allocator: &Allocator) -> %&Node { |
| | 169 | allocator.create(Node) |
| | 170 | } |
| 166 | | 171 | |
| 167 | pub fn testDestroyNode(comptime T: type, list: &LinkedList(T), node: &LinkedList(T).Node, allocator: &mem.Allocator) { | 172 | /// Deallocate a node. |
| 168 | allocator.destroy(node); | 173 | /// |
| 169 | } | 174 | /// Arguments: |
| | 175 | /// node: Pointer to the node to deallocate. |
| | 176 | /// allocator: Dynamic memory allocator. |
| | 177 | pub fn destroyNode(list: &Self, node: &Node, allocator: &Allocator) { |
| | 178 | allocator.destroy(node); |
| | 179 | } |
| 170 | | 180 | |
| 171 | pub fn testCreateNode(comptime T: type, list: &LinkedList(T), data: &const T, allocator: &mem.Allocator) -> %&LinkedList(T).Node { | 181 | /// Allocate and initialize a node and its data. |
| 172 | var node = %return testAllocateNode(T, list, allocator); | 182 | /// |
| 173 | *node = LinkedList(T).Node.init(data); | 183 | /// Arguments: |
| 174 | return node; | 184 | /// data: The data to put inside the node. |
| | 185 | /// allocator: Dynamic memory allocator. |
| | 186 | /// |
| | 187 | /// Returns: |
| | 188 | /// A pointer to the new node. |
| | 189 | pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node { |
| | 190 | var node = %return list.allocateNode(allocator); |
| | 191 | *node = Node.init(data); |
| | 192 | return node; |
| | 193 | } |
| | 194 | } |
| 175 | } | 195 | } |
| 176 | | 196 | |
| 177 | test "basic linked list test" { | 197 | test "basic linked list test" { |
| 178 | const allocator = &debug.global_allocator; | 198 | const allocator = &debug.global_allocator; |
| 179 | var list = LinkedList(u32).init(); | 199 | var list = LinkedList(u32).init(); |
| 180 | | 200 | |
| 181 | var one = %%testCreateNode(u32, &list, 1, allocator); | 201 | var one = %%list.createNode(1, allocator); |
| 182 | var two = %%testCreateNode(u32, &list, 2, allocator); | 202 | var two = %%list.createNode(2, allocator); |
| 183 | var three = %%testCreateNode(u32, &list, 3, allocator); | 203 | var three = %%list.createNode(3, allocator); |
| 184 | var four = %%testCreateNode(u32, &list, 4, allocator); | 204 | var four = %%list.createNode(4, allocator); |
| 185 | var five = %%testCreateNode(u32, &list, 5, allocator); | 205 | var five = %%list.createNode(5, allocator); |
| 186 | defer { | 206 | defer { |
| 187 | testDestroyNode(u32, &list, one, allocator); | 207 | list.destroyNode(one, allocator); |
| 188 | testDestroyNode(u32, &list, two, allocator); | 208 | list.destroyNode(two, allocator); |
| 189 | testDestroyNode(u32, &list, three, allocator); | 209 | list.destroyNode(three, allocator); |
| 190 | testDestroyNode(u32, &list, four, allocator); | 210 | list.destroyNode(four, allocator); |
| 191 | testDestroyNode(u32, &list, five, allocator); | 211 | list.destroyNode(five, allocator); |
| 192 | } | 212 | } |
| 193 | | 213 | |
| 194 | list.append(two); // {2} | 214 | list.append(two); // {2} |
| ... | @@ -197,7 +217,7 @@ test "basic linked list test" { | ... | @@ -197,7 +217,7 @@ test "basic linked list test" { |
| 197 | list.insertBefore(five, four); // {1, 2, 4, 5} | 217 | list.insertBefore(five, four); // {1, 2, 4, 5} |
| 198 | list.insertAfter(two, three); // {1, 2, 3, 4, 5} | 218 | list.insertAfter(two, three); // {1, 2, 3, 4, 5} |
| 199 | | 219 | |
| 200 | // traverse forwards | 220 | // Traverse forwards. |
| 201 | { | 221 | { |
| 202 | var it = list.first; | 222 | var it = list.first; |
| 203 | var index: u32 = 1; | 223 | var index: u32 = 1; |
| ... | @@ -207,7 +227,7 @@ test "basic linked list test" { | ... | @@ -207,7 +227,7 @@ test "basic linked list test" { |
| 207 | } | 227 | } |
| 208 | } | 228 | } |
| 209 | | 229 | |
| 210 | // traverse backwards | 230 | // Traverse backwards. |
| 211 | { | 231 | { |
| 212 | var it = list.last; | 232 | var it = list.last; |
| 213 | var index: u32 = 1; | 233 | var index: u32 = 1; |