diff options
| author | NicknEma <62065135+NicknEma@users.noreply.github.com> | 2024-07-12 15:37:34 +0200 |
|---|---|---|
| committer | NicknEma <62065135+NicknEma@users.noreply.github.com> | 2024-07-12 15:37:34 +0200 |
| commit | c75a872909191631f5e5282d37014b51a34a9724 (patch) | |
| tree | 5df0af9ac1daff48921fa6c97d93d1354909136f /core/container | |
| parent | a348a7e84efbf971048359e4bdf17d6006a79b5f (diff) | |
Write doc comments in intrusive_list.odin
Write description, inputs/returns and some examples for each procedure
Diffstat (limited to 'core/container')
| -rw-r--r-- | core/container/intrusive/list/intrusive_list.odin | 191 |
1 files changed, 189 insertions, 2 deletions
diff --git a/core/container/intrusive/list/intrusive_list.odin b/core/container/intrusive/list/intrusive_list.odin index 1a3175002..6989dfa21 100644 --- a/core/container/intrusive/list/intrusive_list.odin +++ b/core/container/intrusive/list/intrusive_list.odin @@ -18,11 +18,18 @@ List :: struct { tail: ^Node, } - +// The list link you must include in your own structure. Node :: struct { prev, next: ^Node, } +/* +Inserts 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 +*/ push_front :: proc "contextless" (list: ^List, node: ^Node) { if list.head != nil { list.head.prev = node @@ -33,7 +40,13 @@ push_front :: proc "contextless" (list: ^List, node: ^Node) { node.prev, node.next = nil, nil } } +/* +Inserts 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_back :: proc "contextless" (list: ^List, node: ^Node) { if list.tail != nil { list.tail.next = node @@ -45,6 +58,13 @@ push_back :: proc "contextless" (list: ^List, node: ^Node) { } } +/* +Removes 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 :: proc "contextless" (list: ^List, node: ^Node) { if node != nil { if node.next != nil { @@ -61,7 +81,13 @@ remove :: proc "contextless" (list: ^List, node: ^Node) { } } } +/* +Removes from the given list all elements that satisfy a condition. +**Inputs** +- list: The container list +- to_erase: The condition procedure. It should return `true` if a node should be removed, `false` otherwise +*/ remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) { for node := list.head; node != nil; { next := node.next @@ -82,7 +108,13 @@ remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) { node = next } } +/* +Removes from the given list all elements that satisfy a condition. +**Inputs** +- list: The container list +- to_erase: The _contextless_ condition procedure. It should return `true` if a node should be removed, `false` otherwise +*/ remove_by_proc_contextless :: proc(list: ^List, to_erase: proc "contextless" (^Node) -> bool) { for node := list.head; node != nil; { next := node.next @@ -104,12 +136,26 @@ remove_by_proc_contextless :: proc(list: ^List, to_erase: proc "contextless" (^N } } +/* +Checks if the given list does not contain any element. +**Inputs** +- list: The container list +**Returns** `true` if `list` is empty, `false` otherwise +*/ is_empty :: proc "contextless" (list: ^List) -> bool { return list.head == nil } +/* +Removes 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 +*/ pop_front :: proc "contextless" (list: ^List) -> ^Node { link := list.head if link == nil { @@ -130,6 +176,14 @@ pop_front :: proc "contextless" (list: ^List) -> ^Node { return link } +/* +Removes 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_back :: proc "contextless" (list: ^List) -> ^Node { link := list.tail if link == nil { @@ -151,29 +205,122 @@ pop_back :: proc "contextless" (list: ^List) -> ^Node { } + Iterator :: struct($T: typeid) { curr: ^Node, offset: uintptr, } +/* +Creates an iterator pointing at the head of the given list. + +**Inputs** +- list: The container list +- T: The type of the list's elements +- field_name: The name of the node field in the `T` structure + +**Returns** An iterator pointing at the head of `list` + +Example: + + My_Struct :: struct { + node : list.Node, + value: int, + } + + l: list.List + it := list.iterator_head(l, My_Struct, "node") + +*/ iterator_head :: proc "contextless" (list: List, $T: typeid, $field_name: string) -> Iterator(T) where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Node { return {list.head, offset_of_by_string(T, field_name)} } +/* +Creates an iterator pointing at the tail of the given list. + +**Inputs** +- list: The container list +- T: The type of the list's elements +- field_name: The name of the node field in the `T` structure + +**Returns** An iterator pointing at the tail of `list` + +Example: + My_Struct :: struct { + node : list.Node, + value: int, + } + + l: list.List + it := list.iterator_tail(l, My_Struct, "node") + +*/ iterator_tail :: proc "contextless" (list: List, $T: typeid, $field_name: string) -> Iterator(T) where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Node { return {list.tail, offset_of_by_string(T, field_name)} } +/* +Creates 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 `T` structure +**Returns** An iterator pointing at `node` + +*/ iterator_from_node :: proc "contextless" (node: ^Node, $T: typeid, $field_name: string) -> Iterator(T) where intrinsics.type_has_field(T, field_name), intrinsics.type_field_type(T, field_name) == Node { return {node, offset_of_by_string(T, field_name)} } +/* +Retrieves the next element in a list and advances the iterator. + +**Inputs** +- it: The iterator + +**Returns** +- ptr: The next list element +- ok: `true` if the element is valid (the iterator could advance), `false` otherwise + +Example: + + import "core:fmt" + import "core:container/intrusive/list" + + iterate_next_example :: proc() { + l: list.List + + one := My_Struct{value=1} + two := My_Struct{value=2} + + list.push_back(&l, &one.node) + list.push_back(&l, &two.node) + + it := list.iterator_head(&l, My_Struct, "node") + for num in list.iterate_next(&it) { + fmt.println(num) + } + } + + My_Struct :: struct { + node : list.Node, + value: int, + } + +Output: + + 1 + 2 + +*/ iterate_next :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { node := it.curr if node == nil { @@ -183,7 +330,47 @@ iterate_next :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { return (^T)(uintptr(node) - it.offset), true } +/* +Retrieves the previous element in a list and recede the iterator. + +**Inputs** +- it: The iterator + +**Returns** +- ptr: The previous list element +- ok: `true` if the element is valid (the iterator could recede), `false` otherwise + +Example: + import "core:fmt" + import "core:container/intrusive/list" + + iterate_next_example :: proc() { + l: list.List + + one := My_Struct{value=1} + two := My_Struct{value=2} + + list.push_back(&l, &one.node) + list.push_back(&l, &two.node) + + it := list.iterator_tail(&l, My_Struct, "node") + for num in list.iterate_prev(&it) { + fmt.println(num) + } + } + + My_Struct :: struct { + node : list.Node, + value: int, + } + +Output: + + 2 + 1 + +*/ iterate_prev :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { node := it.curr if node == nil { @@ -192,4 +379,4 @@ iterate_prev :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { it.curr = node.prev return (^T)(uintptr(node) - it.offset), true -}
\ No newline at end of file +} |