aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormtarik34b <mtarik34b@gmail.com>2024-09-29 16:03:49 +0200
committermtarik34b <mtarik34b@gmail.com>2024-09-29 16:04:39 +0200
commit82aefd42033f2d34065ceac4eee404b689d2a186 (patch)
tree8dd712b9a0c9b98b5258dbd6a5b6be9390d0c6f7
parent085b72577468f305d8816e77da7402316221a06a (diff)
Add documentation to `runtime.container_of`
-rw-r--r--base/runtime/core_builtin.odin33
1 files changed, 33 insertions, 0 deletions
diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin
index 67d249d11..dbeff51d4 100644
--- a/base/runtime/core_builtin.odin
+++ b/base/runtime/core_builtin.odin
@@ -6,6 +6,39 @@ import "base:intrinsics"
Maybe :: union($T: typeid) {T}
+/*
+Recovers the containing/parent struct from a pointer to one of its fields.
+Works by "walking back" to the struct's starting address using the offset between the field and the struct.
+
+Inputs:
+- ptr: Pointer to the field of a container struct
+- T: The type of the container struct
+- field_name: The name of the field in the `T` struct
+
+Returns:
+- A pointer to the container struct based on a pointer to a field in it
+
+Example:
+ package container_of
+ import "base:runtime"
+
+ Node :: struct {
+ value: int,
+ prev: ^Node,
+ next: ^Node,
+ }
+
+ main :: proc() {
+ node: Node
+ field_ptr := &node.next
+ container_struct_ptr: ^Node = runtime.container_of(field_ptr, Node, "next")
+ assert(container_struct_ptr == &node)
+ assert(uintptr(field_ptr) - uintptr(container_struct_ptr) == size_of(node.value) + size_of(node.prev))
+ }
+
+Output:
+ ^Node
+*/
@(builtin, require_results)
container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T
where intrinsics.type_has_field(T, field_name),