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 {…}
dynamic_cap ¶
@(require_results) dynamic_cap :: proc "contextless" (m: $D/Dynamic_Handle_Map($T, $Handle_Type)) -> uint {…}
dynamic_clear ¶
dynamic_clear :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) {…}
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 {…}
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 {…}
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) {
...
}
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.
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.
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) {…}
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.
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.
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.
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.
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.
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) {
...
}
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.
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.
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.
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-10 (vendor "odin") Windows_amd64 @ 2026-10-23 23:43:08.089658900 +0000 UTC