core/container/intrusive/list
container_intrusive_list
Types
3Iterator
Iterator :: struct {}SourceList
List :: struct {
head: ^Node,
tail: ^Node,
}SourceAn intrusive doubly-linked list
As this is an intrusive container, a Node must be embedded in your own structure which is conventionally called a "link". The use of push_front and push_back take the address of this node. Retrieving the data associated with the node requires finding the relative offset of the node of the parent structure. The parent type and field name are given to iterator_* procedures, or to the built-in container_of procedure.
This data structure is two-pointers in size:
8 bytes on 32-bit platforms and 16 bytes on 64-bit platformsNode
Node :: struct {
prev: ^Node,
next: ^Node,
}SourceThe list link you must include in your own structure.
Procedures
13is_empty
is_empty :: proc(list: ^List) -> (bool)SourceChecks whether the given list does not contain any element.
Inputs
- list: The container list
Returns true if list is empty, false otherwise
iterate_next
iterate_next :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool)SourceRetrieves the next element in a list and advances the iterator.
Inputs
- it: The iterator
Returns
- ptr: The next list element
- ok:
trueif the element is valid (the iterator could advance),falseotherwise
Example:
import "core:fmt"
import "core:container/intrusive/list"
iterate_next_example :: proc() {
l: list.List
one := My_Next_Struct{value=1}
two := My_Next_Struct{value=2}
list.push_back(&l, &one.node)
list.push_back(&l, &two.node)
it := list.iterator_head(l, My_Next_Struct, "node")
for num in list.iterate_next(&it) {
fmt.println(num.value)
}
}
My_Next_Struct :: struct {
node : list.Node,
value: int,
}Output:
1
2iterate_prev
iterate_prev :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool)SourceRetrieves the previous element in a list and recede the iterator.
Inputs
- it: The iterator
Returns
- ptr: The previous list element
- ok:
trueif the element is valid (the iterator could recede),falseotherwise
Example:
import "core:fmt"
import "core:container/intrusive/list"
iterate_prev_example :: proc() {
l: list.List
one := My_Prev_Struct{value=1}
two := My_Prev_Struct{value=2}
list.push_back(&l, &one.node)
list.push_back(&l, &two.node)
it := list.iterator_tail(l, My_Prev_Struct, "node")
for num in list.iterate_prev(&it) {
fmt.println(num.value)
}
}
My_Prev_Struct :: struct {
node : list.Node,
value: int,
}Output:
2
1iterator_from_node
iterator_from_node :: proc(node: ^Node, T: typeid, field_name: string) -> (Iterator($T=typeid))SourceCreates an iterator pointing at the specified node of a list.
Inputs
- node: a list node
- T: The type of the list's elements
- field_name: The name of the node field in the
Tstructure
Returns An iterator pointing at node
iterator_head
iterator_head :: proc(list: List, T: typeid, field_name: string) -> (Iterator($T=typeid))SourceCreates an iterator pointing at the head of the given list. For an example, see iterate_next.
Inputs
- list: The container list
- T: The type of the list's elements
- field_name: The name of the node field in the
Tstructure
Returns An iterator pointing at the head of list
iterator_tail
iterator_tail :: proc(list: List, T: typeid, field_name: string) -> (Iterator($T=typeid))SourceCreates an iterator pointing at the tail of the given list. For an example, see iterate_prev.
Inputs
- list: The container list
- T: The type of the list's elements
- field_name: The name of the node field in the
Tstructure
Returns An iterator pointing at the tail of list
pop_back
pop_back :: proc(list: ^List) -> (^Node)SourceRemoves and returns the element at the back of the list with O(1) time complexity.
Inputs
- list: The container list
Returns The node member of the user-defined element structure, or nil if the list is empty
pop_front
pop_front :: proc(list: ^List) -> (^Node)SourceRemoves and returns the element at the front of the list with O(1) time complexity.
Inputs
- list: The container list
Returns The node member of the user-defined element structure, or nil if the list is empty
push_back
push_back :: proc(list: ^List, node: ^Node)SourceInserts a new element at the back of the list with O(1) time complexity.
Inputs
- list: The container list
- node: The node member of the user-defined element structure
push_front
push_front :: proc(list: ^List, node: ^Node)SourceInserts a new element at the front of the list with O(1) time complexity.
Inputs
- list: The container list
- node: The node member of the user-defined element structure
remove
remove :: proc(list: ^List, node: ^Node)SourceRemoves an element from a list with O(1) time complexity.
Inputs
- list: The container list
- node: The node member of the user-defined element structure to be removed
remove_by_proc
remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> (bool))SourceRemoves from the given list all elements that satisfy a condition with O(N) time complexity.
Inputs
- list: The container list
- to_erase: The condition procedure. It should return
trueif a node should be removed,falseotherwise
remove_by_proc_contextless
remove_by_proc_contextless :: proc(list: ^List, to_erase: proc(^Node) -> (bool))SourceRemoves from the given list all elements that satisfy a condition with O(N) time complexity.
Inputs
- list: The container list
- to_erase: The _contextless_ condition procedure. It should return
trueif a node should be removed,falseotherwise