package core:container/handle_map
Overview
Handle-based map using either fixed-length arrays, or exponential arrays from "core:container/xar".
Example:
import hm "core:container/handle_map"
Handle :: hm.Handle32
Entity :: struct {
handle: Handle,
pos: [2]f32,
}
{ // static map
entities: hm.Static_Handle_Map(1024, Entity, Handle)
h1 := hm.add(&entities, Entity{pos = {1, 4}})
h2 := hm.add(&entities, Entity{pos = {9, 16}})
if e, ok := hm.get(&entities, h2); ok {
e.pos.x += 32
}
hm.remove(&entities, h1)
h3 := hm.add(&entities, Entity{pos = {6, 7}})
assert(hm.is_valid(entities, h3))
it := hm.iterator_make(&entities)
for e, h in hm.iterate(&it) {
assert(hm.is_valid(entities, h))
e.pos += {1, 2}
}
}
{ // dynamic map
entities: hm.Dynamic_Handle_Map(Entity, Handle)
hm.dynamic_init(&entities, context.allocator)
defer hm.dynamic_destroy(&entities)
h1 := hm.add(&entities, Entity{pos = {1, 4}})
h2 := hm.add(&entities, Entity{pos = {9, 16}})
if e, ok := hm.get(&entities, h2); ok {
e.pos.x += 32
}
hm.remove(&entities, h1)
h3 := hm.add(&entities, Entity{pos = {6, 7}})
assert(hm.is_valid(&entities, h3))
it := hm.iterator_make(&entities)
for e, h in hm.iterate(&it) {
assert(hm.is_valid(&entities, h))
e.pos += {1, 2}
}
}
This file contains pre-defined Handle types. It also contains procedure groups that work with both static and dynamic handle maps.
Index
Constants (0)
This section is empty.
Variables (0)
This section is empty.
Procedures (20)
Types
Dynamic_Handle_Map ¶
Dynamic_Handle_Map :: struct($T: typeid, $Handle_Type: typeid) where intrinsics.type_has_field(Handle_Type, "idx"), intrinsics.type_has_field(Handle_Type, "gen"), intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "idx")), intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "gen")), intrinsics.type_field_type(Handle_Type, "idx") == intrinsics.type_field_type(Handle_Type, "gen"), intrinsics.type_has_field(T, "handle"), intrinsics.type_field_type(T, "handle") == Handle_Type { … // See source for fields }
Related Procedures With Parameters
- dynamic_add
- dynamic_cap
- dynamic_clear
- dynamic_destroy
- dynamic_get
- dynamic_init
- dynamic_is_valid
- dynamic_iterator_make
- dynamic_len
- dynamic_remove
- add (procedure groups)
- cap (procedure groups)
- clear (procedure groups)
- get (procedure groups)
- is_valid (procedure groups)
- iterator_make (procedure groups)
- len (procedure groups)
- remove (procedure groups)
Dynamic_Handle_Map_Iterator ¶
Dynamic_Handle_Map_Iterator :: struct($D: typeid) { … // See source for fields }
An iterator for a handle map.
Related Procedures With Parameters
- dynamic_iterate
- iterate (procedure groups)
Handle16 ¶
Default 16-bit Handle type which can be used for handle maps which only need a maximum of 254 (1<<8 - 2) items
Handle32 ¶
Default 32-bit Handle type which can be used for handle maps which only need a maximum of 65534 (1<<16 - 2) items
Handle64 ¶
Default 64-bit Handle type which can be used for handle maps which only need a maximum of 4294967294 (1<<32 - 2) items
Static_Handle_Map ¶
Static_Handle_Map :: struct($N: uint, $T: typeid, $Handle_Type: typeid) where 0 < N, N < uint(1 << 31 - 1), intrinsics.type_has_field(Handle_Type, "idx"), intrinsics.type_has_field(Handle_Type, "gen"), intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "idx")), intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "gen")), intrinsics.type_field_type(Handle_Type, "idx") == intrinsics.type_field_type(Handle_Type, "gen"), N < uint(max(intrinsics.type_field_type(Handle_Type, "idx"))), intrinsics.type_has_field(T, "handle"), intrinsics.type_field_type(T, "handle") == Handle_Type { … // See source for fields }
Related Procedures With Parameters
- static_add
- static_cap
- static_clear
- static_get
- static_is_valid
- static_iterator_make
- static_len
- static_remove
- add (procedure groups)
- cap (procedure groups)
- clear (procedure groups)
- get (procedure groups)
- is_valid (procedure groups)
- iterator_make (procedure groups)
- len (procedure groups)
- remove (procedure groups)
Static_Handle_Map_Iterator ¶
Static_Handle_Map_Iterator :: struct($H: typeid) { … // See source for fields }
An iterator for a handle map.
Related Procedures With Parameters
- static_iterate
- iterate (procedure groups)
Constants
This section is empty.
Variables
This section is empty.
Procedures
dynamic_add ¶
@(require_results) dynamic_add :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), item: $T, loc := #caller_location) -> (handle: $Handle_Type, err: runtime.Allocator_Error) #optional_ok {…}
Related Procedure Groups
dynamic_cap ¶
@(require_results) dynamic_cap :: proc "contextless" (m: $D/Dynamic_Handle_Map($T, $Handle_Type)) -> uint {…}
Related Procedure Groups
dynamic_clear ¶
dynamic_clear :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) {…}
Related Procedure Groups
dynamic_destroy ¶
dynamic_destroy :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) {…}
dynamic_get ¶
@(require_results) dynamic_get :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), h: $Handle_Type) -> ($^T, bool) #optional_ok {…}
Related Procedure Groups
dynamic_init ¶
dynamic_init :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), allocator: runtime.Allocator) {…}
dynamic_is_valid ¶
@(require_results) dynamic_is_valid :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), h: $Handle_Type) -> bool {…}
Related Procedure Groups
dynamic_iterate ¶
@(require_results) dynamic_iterate :: proc "contextless" (it: ^$DHI/Dynamic_Handle_Map_Iterator($D)) -> (val: $^T, h: $Handle_Type, ok: bool) {…}
Iterate over a handle map. It will skip over unused item slots (e.g. handle.idx == 0). Usage:
it := hm.dynamic_iterator_make(&the_dynamic_handle_map)
for item, handle in hm.iterate(&it) {
...
}
Related Procedure Groups
dynamic_iterator_make ¶
@(require_results) dynamic_iterator_make :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) -> $Dynamic_Handle_Map_Iterator(D) {…}
Makes an iterator from a handle map.
Related Procedure Groups
dynamic_len ¶
@(require_results) dynamic_len :: proc "contextless" (m: $D/Dynamic_Handle_Map($T, $Handle_Type)) -> uint {…}
Returns the number of possibly valid items in the handle map.
Related Procedure Groups
dynamic_remove ¶
dynamic_remove :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), h: $Handle_Type, loc := #caller_location) -> (found: bool, err: runtime.Allocator_Error) {…}
Related Procedure Groups
static_add ¶
@(require_results) static_add :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type), item: $T) -> (handle: $Handle_Type, ok: bool) #optional_ok {…}
add a value of type T to the handle map. This will return a pointer to the item and an optional boolean to check for validity.
Related Procedure Groups
static_cap ¶
@(require_results) static_cap :: proc "contextless" (m: $H/Static_Handle_Map($N, $T, $Handle_Type)) -> uint {…}
Returns the capacity of the items in a handle map.
This is equivalent to N-1 as the zero value is reserved for the zero-value sentinel.
Related Procedure Groups
static_clear ¶
static_clear :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type)) {…}
clear the handle map by zeroing all of the memory.
Internally this does not do m^ = {} but rather uses intrinsics.mem_zero explicitly improve performance.
Related Procedure Groups
static_get ¶
@(require_results) static_get :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type), h: $Handle_Type) -> ($^T, bool) #optional_ok {…}
get a stable pointer of type ^T by resolving the handle h. If the handle is not valid, then nil, false is returned.
Related Procedure Groups
static_is_valid ¶
@(require_results) static_is_valid :: proc "contextless" (m: $H/Static_Handle_Map($N, $T, $Handle_Type), h: $Handle_Type) -> bool {…}
Returns true when the handle h is valid relating to the handle map.
Related Procedure Groups
static_iterate ¶
@(require_results) static_iterate :: proc "contextless" (it: ^$HI/Static_Handle_Map_Iterator($H)) -> (val: $^T, h: $Handle_Type, ok: bool) {…}
Iterate over a handle map. It will skip over unused item slots (e.g. handle.idx == 0). Usage:
it := hm.iterator_make(&the_handle_map)
for item, handle in hm.iterate(&it) {
...
}
Related Procedure Groups
static_iterator_make ¶
@(require_results) static_iterator_make :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type)) -> $Static_Handle_Map_Iterator(H) {…}
Makes an iterator from a handle map.
Related Procedure Groups
static_len ¶
@(require_results) static_len :: proc "contextless" (m: $H/Static_Handle_Map($N, $T, $Handle_Type)) -> uint {…}
Returns the number of possibly valid items in the handle map.
Related Procedure Groups
static_remove ¶
static_remove :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type), h: $Handle_Type) -> bool {…}
remove an item from the handle map from the handle h.
Related Procedure Groups
Procedure Groups
add ¶
add :: proc{ static_add, dynamic_add, }
cap ¶
cap :: proc{ static_cap, dynamic_cap, }
clear ¶
clear :: proc{ static_clear, dynamic_clear, }
get ¶
get :: proc{ static_get, dynamic_get, }
is_valid ¶
is_valid :: proc{ static_is_valid, dynamic_is_valid, }
iterate ¶
iterate :: proc{ static_iterate, dynamic_iterate, }
iterator_make ¶
iterator_make :: proc{ static_iterator_make, dynamic_iterator_make, }
len ¶
len :: proc{ static_len, dynamic_len, }
remove ¶
remove :: proc{ static_remove, dynamic_remove, }
Source Files
Generation Information
Generated with odin version dev-2026-09 (vendor "odin") Windows_amd64 @ 2026-09-12 22:45:50.838723800 +0000 UTC