mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00:00
Write doc comments in intrusive_list.odin
Write description, inputs/returns and some examples for each procedure
This commit is contained in:
@@ -18,11 +18,18 @@ List :: struct {
|
|||||||
tail: ^Node,
|
tail: ^Node,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The list link you must include in your own structure.
|
||||||
Node :: struct {
|
Node :: struct {
|
||||||
prev, next: ^Node,
|
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) {
|
push_front :: proc "contextless" (list: ^List, node: ^Node) {
|
||||||
if list.head != nil {
|
if list.head != nil {
|
||||||
list.head.prev = node
|
list.head.prev = node
|
||||||
@@ -33,7 +40,13 @@ push_front :: proc "contextless" (list: ^List, node: ^Node) {
|
|||||||
node.prev, node.next = nil, nil
|
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) {
|
push_back :: proc "contextless" (list: ^List, node: ^Node) {
|
||||||
if list.tail != nil {
|
if list.tail != nil {
|
||||||
list.tail.next = node
|
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) {
|
remove :: proc "contextless" (list: ^List, node: ^Node) {
|
||||||
if node != nil {
|
if node != nil {
|
||||||
if node.next != 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) {
|
remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) {
|
||||||
for node := list.head; node != nil; {
|
for node := list.head; node != nil; {
|
||||||
next := node.next
|
next := node.next
|
||||||
@@ -82,7 +108,13 @@ remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) {
|
|||||||
node = next
|
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) {
|
remove_by_proc_contextless :: proc(list: ^List, to_erase: proc "contextless" (^Node) -> bool) {
|
||||||
for node := list.head; node != nil; {
|
for node := list.head; node != nil; {
|
||||||
next := node.next
|
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 {
|
is_empty :: proc "contextless" (list: ^List) -> bool {
|
||||||
return list.head == nil
|
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 {
|
pop_front :: proc "contextless" (list: ^List) -> ^Node {
|
||||||
link := list.head
|
link := list.head
|
||||||
if link == nil {
|
if link == nil {
|
||||||
@@ -130,6 +176,14 @@ pop_front :: proc "contextless" (list: ^List) -> ^Node {
|
|||||||
return link
|
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 {
|
pop_back :: proc "contextless" (list: ^List) -> ^Node {
|
||||||
link := list.tail
|
link := list.tail
|
||||||
if link == nil {
|
if link == nil {
|
||||||
@@ -151,29 +205,122 @@ pop_back :: proc "contextless" (list: ^List) -> ^Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Iterator :: struct($T: typeid) {
|
Iterator :: struct($T: typeid) {
|
||||||
curr: ^Node,
|
curr: ^Node,
|
||||||
offset: uintptr,
|
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)
|
iterator_head :: proc "contextless" (list: List, $T: typeid, $field_name: string) -> Iterator(T)
|
||||||
where intrinsics.type_has_field(T, field_name),
|
where intrinsics.type_has_field(T, field_name),
|
||||||
intrinsics.type_field_type(T, field_name) == Node {
|
intrinsics.type_field_type(T, field_name) == Node {
|
||||||
return {list.head, offset_of_by_string(T, field_name)}
|
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)
|
iterator_tail :: proc "contextless" (list: List, $T: typeid, $field_name: string) -> Iterator(T)
|
||||||
where intrinsics.type_has_field(T, field_name),
|
where intrinsics.type_has_field(T, field_name),
|
||||||
intrinsics.type_field_type(T, field_name) == Node {
|
intrinsics.type_field_type(T, field_name) == Node {
|
||||||
return {list.tail, offset_of_by_string(T, field_name)}
|
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)
|
iterator_from_node :: proc "contextless" (node: ^Node, $T: typeid, $field_name: string) -> Iterator(T)
|
||||||
where intrinsics.type_has_field(T, field_name),
|
where intrinsics.type_has_field(T, field_name),
|
||||||
intrinsics.type_field_type(T, field_name) == Node {
|
intrinsics.type_field_type(T, field_name) == Node {
|
||||||
return {node, offset_of_by_string(T, field_name)}
|
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) {
|
iterate_next :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) {
|
||||||
node := it.curr
|
node := it.curr
|
||||||
if node == nil {
|
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
|
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) {
|
iterate_prev :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) {
|
||||||
node := it.curr
|
node := it.curr
|
||||||
if node == nil {
|
if node == nil {
|
||||||
@@ -192,4 +379,4 @@ iterate_prev :: proc "contextless" (it: ^Iterator($T)) -> (ptr: ^T, ok: bool) {
|
|||||||
it.curr = node.prev
|
it.curr = node.prev
|
||||||
|
|
||||||
return (^T)(uintptr(node) - it.offset), true
|
return (^T)(uintptr(node) - it.offset), true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user