package core:runtime
Overview
This is the runtime code required by the compiler IMPORTANT NOTE(bill): Do not change the order of any of this data The compiler relies upon this _exact_ order
Naming Conventions: In general, Ada_Case for types and snake_case for values
Package Name: snake_case (but prefer single word) Import Name: snake_case (but prefer single word) Types: Ada_Case Enum Values: Ada_Case Procedures: snake_case Local Variables: snake_case Constant Variables: SCREAMING_SNAKE_CASE
IMPORTANT NOTE(bill): type_info_of
cannot be used within a
#shared_global_scope due to the internals of the compiler.
This could change at a later date if the all these data structures are
implemented within the compiler rather than in this "preload" file
Index
Types (76)
- Allocator
- Allocator_Error
- Allocator_Mode
- Allocator_Mode_Set
- Allocator_Proc
- Allocator_Query_Info
- Arena
- Arena_Temp
- Assertion_Failure_Proc
- Calling_Convention
- Context
- DLL_Forward_Reason
- Default_Temp_Allocator
- Equal_Proc
- Hasher_Proc
- Logger
- Logger_Level
- Logger_Option
- Logger_Options
- Logger_Proc
- Map_Cell
- Map_Cell_Info
- Map_Hash
- Map_Info
- Maybe
- Memory_Block
- Odin_Arch_Type
- Odin_Build_Mode_Type
- Odin_Endian_Type
- Odin_OS_Type
- Platform_Endianness
- Raw_Any
- Raw_Cstring
- Raw_Dynamic_Array
- Raw_Map
- Raw_SOA_Footer_Dynamic_Array
- Raw_SOA_Footer_Slice
- Raw_Slice
- Raw_Soa_Pointer
- Raw_String
- Source_Code_Location
- Type_Info
- Type_Info_Any
- Type_Info_Array
- Type_Info_Bit_Set
- Type_Info_Boolean
- Type_Info_Complex
- Type_Info_Dynamic_Array
- Type_Info_Enum
- Type_Info_Enum_Value
- Type_Info_Enumerated_Array
- Type_Info_Flag
- Type_Info_Flags
- Type_Info_Float
- Type_Info_Integer
- Type_Info_Map
- Type_Info_Matrix
- Type_Info_Multi_Pointer
- Type_Info_Named
- Type_Info_Parameters
- Type_Info_Pointer
- Type_Info_Procedure
- Type_Info_Quaternion
- Type_Info_Relative_Pointer
- Type_Info_Relative_Slice
- Type_Info_Rune
- Type_Info_Simd_Vector
- Type_Info_Slice
- Type_Info_Soa_Pointer
- Type_Info_String
- Type_Info_Struct
- Type_Info_Struct_Soa_Kind
- Type_Info_Tuple
- Type_Info_Type_Id
- Type_Info_Union
- Typeid_Kind
Constants (18)
- Byte
- DEFAULT_ALIGNMENT
- DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE
- DEFAULT_RESERVE_CAPACITY
- DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE
- Gigabyte
- HASH_MASK
- INITIAL_HASH_SEED
- Kilobyte
- MAP_CACHE_LINE_LOG2
- MAP_CACHE_LINE_SIZE
- MAP_LOAD_FACTOR
- MAP_MIN_LOG2_CAPACITY
- Megabyte
- NO_DEFAULT_TEMP_ALLOCATOR
- RUNTIME_REQUIRE
- TOMBSTONE_MASK
- Terabyte
Variables (4)
Procedures (287)
- DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD
- abs_complex128
- abs_complex32
- abs_complex64
- abs_f16
- abs_f32
- abs_f64
- abs_quaternion128
- abs_quaternion256
- abs_quaternion64
- align_forward_int
- align_forward_uintptr
- alloc_from_memory_block
- append_elem
- append_elem_string
- append_elems
- append_nothing
- append_soa_elem
- append_soa_elems
- append_string
- arena_alloc
- arena_allocator
- arena_allocator_proc
- arena_check_temp
- arena_destroy
- arena_free_all
- arena_free_last_memory_block
- arena_init
- arena_temp_begin
- arena_temp_end
- arena_temp_ignore
- assert
- assign_at_elem
- assign_at_elem_string
- assign_at_elems
- bounds_check_error
- bounds_check_error_loc
- bounds_trap
- bswap_128
- bswap_16
- bswap_32
- bswap_64
- bswap_f16
- bswap_f32
- bswap_f64
- card
- clear_dynamic_array
- clear_map
- complex128_eq
- complex128_ne
- complex32_eq
- complex32_ne
- complex64_eq
- complex64_ne
- container_of
- copy_from_string
- copy_slice
- cstring_len
- cstring_to_string
- debug_trap
- default_allocator
- default_allocator_proc
- default_assertion_failure_proc
- default_context
- default_hasher
- default_hasher_cstring
- default_hasher_string
- default_logger
- default_logger_proc
- default_temp_allocator
- default_temp_allocator_destroy
- default_temp_allocator_init
- default_temp_allocator_proc
- default_temp_allocator_temp_begin
- default_temp_allocator_temp_end
- delete_cstring
- delete_dynamic_array
- delete_key
- delete_map
- delete_slice
- delete_soa_dynamic_array
- delete_soa_slice
- delete_string
- divmodti4
- divti3
- dynamic_array_expr_error
- dynamic_array_expr_error_loc
- encode_rune
- excl_bit_set
- excl_elem
- excl_elems
- extendhfsf2
- fixdfti
- fixunsdfdi
- fixunsdfti
- floattidf
- floattidf_unsigned
- gnu_f2h_ieee
- gnu_h2f_ieee
- hermitian_adjoint
- incl_bit_set
- incl_elem
- incl_elems
- init_global_temporary_allocator
- inject_at_elem
- inject_at_elem_string
- inject_at_elems
- is_power_of_two_int
- is_power_of_two_uintptr
- make_aligned
- make_dynamic_array
- make_dynamic_array_error_loc
- make_dynamic_array_len
- make_dynamic_array_len_cap
- make_map
- make_map_expr_error_loc
- make_multi_pointer
- make_slice
- make_slice_error_loc
- make_soa_aligned
- make_soa_dynamic_array
- make_soa_dynamic_array_len
- make_soa_dynamic_array_len_cap
- make_soa_slice
- map_alloc_dynamic
- map_cap
- map_cell_index_dynamic
- map_cell_index_dynamic_const
- map_cell_index_static
- map_cell_info
- map_clear_dynamic
- map_data
- map_desired_position
- map_erase_dynamic
- map_exists_dynamic
- map_free_dynamic
- map_get
- map_grow_dynamic
- map_hash_is_deleted
- map_hash_is_empty
- map_hash_is_valid
- map_info
- map_insert
- map_insert_hash_dynamic
- map_kvh_data_dynamic
- map_kvh_data_static
- map_kvh_data_values_dynamic
- map_len
- map_load_factor
- map_log2_cap
- map_lookup_dynamic
- map_probe_distance
- map_reserve_dynamic
- map_resize_threshold
- map_seed
- map_seed_from_map_data
- map_shrink_dynamic
- matrix1x1_adjugate
- matrix1x1_determinant
- matrix1x1_inverse
- matrix1x1_inverse_transpose
- matrix2x2_adjugate
- matrix2x2_determinant
- matrix2x2_inverse
- matrix2x2_inverse_transpose
- matrix3x3_adjugate
- matrix3x3_determinant
- matrix3x3_inverse
- matrix3x3_inverse_transpose
- matrix4x4_adjugate
- matrix4x4_determinant
- matrix4x4_inverse
- matrix4x4_inverse_transpose
- matrix_bounds_check_error
- matrix_minor
- matrix_trace
- max_f16
- max_f32
- max_f64
- mem_alloc
- mem_alloc_bytes
- mem_alloc_non_zeroed
- mem_copy
- mem_copy_non_overlapping
- mem_free
- mem_free_all
- mem_free_bytes
- mem_free_with_size
- mem_resize
- mem_zero
- memory_block_alloc
- memory_block_dealloc
- memory_compare
- memory_compare_zero
- memory_equal
- memset
- min_f16
- min_f32
- min_f64
- modti3
- mul_quaternion128
- mul_quaternion256
- mul_quaternion64
- multi_pointer_slice_expr_error
- multi_pointer_slice_handle_error
- new
- new_aligned
- new_clone
- nil_allocator
- nil_allocator_proc
- ordered_remove
- os_write
- panic
- pop
- pop_front
- pop_front_safe
- pop_safe
- print_any_single
- print_byte
- print_caller_location
- print_encoded_rune
- print_i64
- print_int
- print_rune
- print_string
- print_strings
- print_type
- print_typeid
- print_u64
- print_uint
- print_uintptr
- println_any
- quaternion128_eq
- quaternion128_ne
- quaternion256_eq
- quaternion256_ne
- quaternion64_eq
- quaternion64_ne
- quo_complex128
- quo_complex32
- quo_complex64
- quo_quaternion128
- quo_quaternion256
- quo_quaternion64
- raw_soa_footer_dynamic_array
- raw_soa_footer_slice
- read_cycle_counter
- remove_range
- reserve_dynamic_array
- reserve_map
- reserve_soa
- resize_dynamic_array
- resize_soa
- shrink_dynamic_array
- shrink_map
- slice_expr_error_hi
- slice_expr_error_hi_loc
- slice_expr_error_lo_hi
- slice_expr_error_lo_hi_loc
- slice_handle_error
- string_cmp
- string_decode_last_rune
- string_decode_rune
- string_eq
- string_ge
- string_gt
- string_le
- string_lt
- string_ne
- trap
- truncdfhf2
- truncsfhf2
- type_assertion_check
- type_assertion_check2
- type_assertion_trap
- type_info_base
- type_info_base_without_enum
- type_info_core
- typeid_base
- typeid_base_without_enum
- typeid_core
- udivmod128
- udivmodti4
- udivti3
- umodti3
- unimplemented
- unordered_remove
Procedure Groups (22)
Types
Allocator ¶
Allocator :: struct { procedure: Allocator_Proc, data: rawptr, }
Allocator_Error ¶
Allocator_Error :: enum u8 { None = 0, Out_Of_Memory = 1, Invalid_Pointer = 2, Invalid_Argument = 3, Mode_Not_Implemented = 4, }
Allocator_Mode ¶
Allocator_Mode :: enum u8 { Alloc, Free, Free_All, Resize, Query_Features, Query_Info, Alloc_Non_Zeroed, }
Allocation Stuff
Allocator_Mode_Set ¶
Allocator_Mode_Set :: distinct bit_set[Allocator_Mode]
Allocator_Proc ¶
Allocator_Proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, location := #caller_location) -> ([]u8, Allocator_Error)
Arena ¶
Arena :: struct { backing_allocator: Allocator, curr_block: ^Memory_Block, total_used: uint, total_capacity: uint, minimum_block_size: uint, temp_count: uint, }
Arena_Temp ¶
Arena_Temp :: struct { arena: ^Arena, block: ^Memory_Block, used: uint, }
Assertion_Failure_Proc ¶
Assertion_Failure_Proc :: proc(prefix, message: string, loc: Source_Code_Location) -> !
Allocation Stuff
Calling_Convention ¶
Calling_Convention :: enum u8 { Invalid = 0, Odin = 1, Contextless = 2, CDecl = 3, Std_Call = 4, Fast_Call = 5, None = 6, Naked = 7, Win64 = 9, SysV = 10, }
NOTE(bill): This must match the compiler's
Context ¶
Context :: struct { allocator: Allocator, temp_allocator: Allocator, assertion_failure_proc: Assertion_Failure_Proc, logger: Logger, user_ptr: rawptr, user_index: int, // Internal use only _internal: rawptr, }
DLL_Forward_Reason ¶
DLL_Forward_Reason :: enum u32 { Process_Detach = 0, // About to unload DLL Process_Attach = 1, // Entry point Thread_Attach = 2, Thread_Detach = 3, }
Default_Temp_Allocator ¶
Default_Temp_Allocator :: struct { arena: Arena, }
Equal_Proc ¶
Equal_Proc :: proc "contextless" (_: rawptr, _: rawptr) -> bool
Procedure type to test whether two values of the same type are equal
Hasher_Proc ¶
Hasher_Proc :: proc "contextless" (data: rawptr, seed: uintptr = 0) -> uintptr
Procedure type to hash a value, default seed value is 0
Logger ¶
Logger :: struct { procedure: Logger_Proc, data: rawptr, lowest_level: Logger_Level, options: bit_set[Logger_Option], }
Logger_Level ¶
Logger_Level :: enum uint { Debug = 0, Info = 10, Warning = 20, Error = 30, Fatal = 40, }
Logger_Option ¶
Logger_Option :: enum int { Level, Date, Time, Short_File_Path, Long_File_Path, Line, Procedure, Terminal_Color, Thread_Id, }
Logger_Options ¶
Logger_Options :: bit_set[Logger_Option]
Logger_Proc ¶
Logger_Proc :: proc(data: rawptr, level: Logger_Level, text: string, options: bit_set[Logger_Option], location := #caller_location)
Map_Cell ¶
Map_Cell :: struct($T: typeid) #align MAP_CACHE_LINE_SIZE {}
Map_Cell type that packs multiple T in such a way to ensure that each T stays aligned by align_of(T) and such that align_of(Map_Cell(T)) % MAP_CACHE_LINE_SIZE == 0
This means a value of type T will never straddle a cache-line.
When multiple Ts can fit in a single cache-line the data array will have more than one element. When it cannot, the data array will have one element and an array of Map_Cell(T) will be padded to stay a multiple of MAP_CACHE_LINE_SIZE.
We rely on the type system to do all the arithmetic and padding for us here.
The usual array[index] indexing for []T backed by a []Map_Cell(T) becomes a bit more involved as there now may be internal padding. The indexing now becomes
N :: len(Map_Cell(T){}.data) i := index / N j := index % N cell[i].data[j]
However, since len(Map_Cell(T){}.data) is a compile-time constant, there are some optimizations we can do to eliminate the need for any divisions as N will be bounded by [1, 64).
In the optimal case, len(Map_Cell(T){}.data) = 1 so the cell array can be treated as a regular array of T, which is the case for hashes.
Map_Cell_Info ¶
Map_Cell_Info :: struct { size_of_type: uintptr, // 8-bytes on 64-bit, 4-bytes on 32-bits align_of_type: uintptr, // 8-bytes on 64-bit, 4-bytes on 32-bits size_of_cell: uintptr, // 8-bytes on 64-bit, 4-bytes on 32-bits elements_per_cell: uintptr, }
So we can operate on a cell data structure at runtime without any type information, we have a simple table that stores some traits about the cell.
32-bytes on 64-bit 16-bytes on 32-bit
Map_Hash ¶
Map_Hash :: uintptr
Map_Info ¶
Map_Info :: struct { ks: ^Map_Cell_Info, // 8-bytes on 64-bit, 4-bytes on 32-bit vs: ^Map_Cell_Info, // 8-bytes on 64-bit, 4-bytes on 32-bit key_hasher: proc "contextless" (key: rawptr, seed: uintptr) -> uintptr, // 8-bytes on 64-bit, 4-bytes on 32-bit key_equal: proc "contextless" (lhs, rhs: rawptr) -> bool, }
When working with the type-erased structure at runtime we need information about the map to make working with it possible. This info structure stores that.
Map_Info
and Map_Cell_Info
are read only data structures and cannot be
modified after creation
32-bytes on 64-bit 16-bytes on 32-bit
Memory_Block ¶
Memory_Block :: struct { prev: ^Memory_Block, allocator: Allocator, base: [^]u8, used: uint, capacity: uint, }
Odin_Arch_Type ¶
Odin_Arch_Type :: .Odin_Arch_Type
// Defined internally by the compiler
Odin_Arch_Type :: enum int { Unknown, amd64, i386, arm32, arm64, wasm32, wasm64, }
Odin_Build_Mode_Type ¶
Odin_Build_Mode_Type :: .Odin_Build_Mode_Type
// Defined internally by the compiler
Odin_Build_Mode_Type :: enum int { Executable, Dynamic, Object, Assembly, LLVM_IR, }
Odin_Endian_Type ¶
Odin_Endian_Type :: .Odin_Endian_Type
// Defined internally by the compiler
Odin_Endian_Type :: enum int { Unknown, Little, Big, }
Odin_OS_Type ¶
Odin_OS_Type :: .Odin_OS_Type
// Defined internally by the compiler
Odin_OS_Type :: enum int { Unknown, Windows, Darwin, Linux, Essence, FreeBSD, OpenBSD, WASI, JS, Freestanding, }
Platform_Endianness ¶
Platform_Endianness :: enum u8 { Platform = 0, Little = 1, Big = 2, }
Raw_Cstring ¶
Raw_Cstring :: struct { data: [^]u8, }
Raw_Dynamic_Array ¶
Raw_Dynamic_Array :: struct { data: rawptr, len: int, cap: int, allocator: Allocator, }
Raw_Map ¶
Raw_Map :: struct { // A single allocation spanning all keys, values, and hashes. // { // k: Map_Cell(K) * (capacity / ks_per_cell) // v: Map_Cell(V) * (capacity / vs_per_cell) // h: Map_Cell(H) * (capacity / hs_per_cell) // } // // The data is allocated assuming 64-byte alignment, meaning the address is // always a multiple of 64. This means we have 6 bits of zeros in the pointer // to store the capacity. We can store a value as large as 2^6-1 or 63 in // there. This conveniently is the maximum log2 capacity we can have for a map // as Odin uses signed integers to represent capacity. // // Since the hashes are backed by Map_Hash, which is just a 64-bit unsigned // integer, the cell structure for hashes is unnecessary because 64/8 is 8 and // requires no padding, meaning it can be indexed as a regular array of // Map_Hash directly, though for consistency sake it's written as if it were // an array of Map_Cell(Map_Hash). data: uintptr, // 8-bytes on 64-bits, 4-bytes on 32-bits len: int, // 8-bytes on 64-bits, 4-bytes on 32-bits allocator: Allocator, }
The raw, type-erased representation of a map.
32-bytes on 64-bit 16-bytes on 32-bit
Raw_SOA_Footer_Dynamic_Array ¶
Raw_SOA_Footer_Dynamic_Array :: struct { len: int, cap: int, allocator: Allocator, }
Raw_SOA_Footer_Slice ¶
Raw_SOA_Footer_Slice :: struct { len: int, }
Raw_Slice ¶
Raw_Slice :: struct { data: rawptr, len: int, }
Raw_Soa_Pointer ¶
Raw_Soa_Pointer :: struct { data: rawptr, index: int, }
Raw_String ¶
Raw_String :: struct { data: [^]u8, len: int, }
Source_Code_Location ¶
Source_Code_Location :: struct { file_path: string, line, column: i32, procedure: string, }
Type_Info ¶
Type_Info :: struct { size: int, align: int, flags: Type_Info_Flags, id: typeid, variant: union { Type_Info_Named, Type_Info_Integer, Type_Info_Rune, Type_Info_Float, Type_Info_Complex, Type_Info_Quaternion, Type_Info_String, Type_Info_Boolean, Type_Info_Any, Type_Info_Type_Id, Type_Info_Pointer, Type_Info_Multi_Pointer, Type_Info_Procedure, Type_Info_Array, Type_Info_Enumerated_Array, Type_Info_Dynamic_Array, Type_Info_Slice, Type_Info_Parameters, Type_Info_Struct, Type_Info_Union, Type_Info_Enum, Type_Info_Map, Type_Info_Bit_Set, Type_Info_Simd_Vector, Type_Info_Relative_Pointer, Type_Info_Relative_Slice, Type_Info_Matrix, Type_Info_Soa_Pointer, }, }
Type_Info_Any ¶
Type_Info_Any :: struct {}
Type_Info_Array ¶
Type_Info_Array :: struct { elem: ^Type_Info, elem_size: int, count: int, }
Type_Info_Boolean ¶
Type_Info_Boolean :: struct {}
Type_Info_Complex ¶
Type_Info_Complex :: struct {}
Type_Info_Dynamic_Array ¶
Type_Info_Dynamic_Array :: struct { elem: ^Type_Info, elem_size: int, }
Type_Info_Enum ¶
Type_Info_Enum :: struct { base: ^Type_Info, names: []string, values: []Type_Info_Enum_Value, }
Type_Info_Enum_Value ¶
Type_Info_Enum_Value :: distinct i64
Type_Info_Enumerated_Array ¶
Type_Info_Enumerated_Array :: struct { elem: ^Type_Info, index: ^Type_Info, elem_size: int, count: int, min_value: Type_Info_Enum_Value, max_value: Type_Info_Enum_Value, is_sparse: bool, }
Type_Info_Flag ¶
Type_Info_Flag :: enum u8 { Comparable = 0, Simple_Compare = 1, }
Type_Info_Flags ¶
Type_Info_Flags :: distinct bit_set[Type_Info_Flag; u32]
Type_Info_Float ¶
Type_Info_Float :: struct { endianness: Platform_Endianness, }
Type_Info_Integer ¶
Type_Info_Integer :: struct { signed: bool, endianness: Platform_Endianness, }
Type_Info_Matrix ¶
Type_Info_Matrix :: struct { elem: ^Type_Info, elem_size: int, elem_stride: int, // elem_stride >= row_count row_count: int, column_count: int, }
Type_Info_Multi_Pointer ¶
Type_Info_Multi_Pointer :: struct { elem: ^Type_Info, }
Type_Info_Named ¶
Type_Info_Named :: struct { name: string, base: ^Type_Info, pkg: string, loc: Source_Code_Location, }
Variant Types
Type_Info_Parameters ¶
Type_Info_Parameters :: struct { // Only used for procedures parameters and results types: []^Type_Info, names: []string, }
Type_Info_Pointer ¶
Type_Info_Pointer :: struct { elem: ^Type_Info, }
Type_Info_Procedure ¶
Type_Info_Procedure :: struct { params: ^Type_Info, // Type_Info_Parameters results: ^Type_Info, // Type_Info_Parameters variadic: bool, convention: Calling_Convention, }
Type_Info_Quaternion ¶
Type_Info_Quaternion :: struct {}
Type_Info_Rune ¶
Type_Info_Rune :: struct {}
Type_Info_Simd_Vector ¶
Type_Info_Simd_Vector :: struct { elem: ^Type_Info, elem_size: int, count: int, }
Type_Info_Slice ¶
Type_Info_Slice :: struct { elem: ^Type_Info, elem_size: int, }
Type_Info_Soa_Pointer ¶
Type_Info_Soa_Pointer :: struct { elem: ^Type_Info, }
Type_Info_String ¶
Type_Info_String :: struct { is_cstring: bool, }
Type_Info_Struct ¶
Type_Info_Struct :: struct { types: []^Type_Info, names: []string, offsets: []uintptr, usings: []bool, tags: []string, is_packed: bool, is_raw_union: bool, is_no_copy: bool, custom_align: bool, equal: Equal_Proc, // These are only set iff this structure is an SOA structure soa_kind: Type_Info_Struct_Soa_Kind, soa_base_type: ^Type_Info, soa_len: int, }
Type_Info_Struct_Soa_Kind ¶
Type_Info_Struct_Soa_Kind :: enum u8 { None = 0, Fixed = 1, Slice = 2, Dynamic = 3, }
Type_Info_Type_Id ¶
Type_Info_Type_Id :: struct {}
Type_Info_Union ¶
Type_Info_Union :: struct { variants: []^Type_Info, tag_offset: uintptr, tag_type: ^Type_Info, equal: Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set custom_align: bool, no_nil: bool, shared_nil: bool, }
Typeid_Kind ¶
Typeid_Kind :: enum u8 { Invalid, Integer, Rune, Float, Complex, Quaternion, String, Boolean, Any, Type_Id, Pointer, Multi_Pointer, Procedure, Array, Enumerated_Array, Dynamic_Array, Slice, Tuple, Struct, Union, Enum, Map, Bit_Set, Simd_Vector, Relative_Pointer, Relative_Slice, Matrix, }
NOTE(bill): This must match the compiler's
Constants
DEFAULT_ALIGNMENT ¶
DEFAULT_ALIGNMENT :: 2 * align_of(rawptr)
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE ¶
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: uint(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE)
DEFAULT_RESERVE_CAPACITY ¶
DEFAULT_RESERVE_CAPACITY :: 16
DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE ¶
DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE: int : #config(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE, 4 * Megabyte)
Gigabyte ¶
Gigabyte :: 1024 * Megabyte
HASH_MASK ¶
HASH_MASK :: 1 << (8 * size_of(uintptr) - 1) - 1
INITIAL_HASH_SEED ¶
INITIAL_HASH_SEED :: 0xcbf29ce484222325
Kilobyte ¶
Kilobyte :: 1024 * Byte
MAP_CACHE_LINE_LOG2 ¶
MAP_CACHE_LINE_LOG2 :: 6
This is safe to change. The log2 size of a cache-line. At minimum it has to be six though. Higher cache line sizes are permitted.
MAP_LOAD_FACTOR ¶
MAP_LOAD_FACTOR :: 75
With Robin Hood hashing a maximum load factor of 75% is ideal.
Megabyte ¶
Megabyte :: 1024 * Kilobyte
NO_DEFAULT_TEMP_ALLOCATOR ¶
NO_DEFAULT_TEMP_ALLOCATOR: bool : ODIN_OS == .Freestanding || ODIN_OS == .JS || ODIN_DEFAULT_TO_NIL_ALLOCATOR
RUNTIME_REQUIRE ¶
RUNTIME_REQUIRE :: true
TOMBSTONE_MASK ¶
TOMBSTONE_MASK :: 1 << (size_of(Map_Hash) * 8 - 1)
Terabyte ¶
Terabyte :: 1024 * Gigabyte
Variables
dll_forward_reason ¶
dll_forward_reason: DLL_Forward_Reason
global_default_temp_allocator_data ¶
@(thread_local) global_default_temp_allocator_data: Default_Temp_Allocator
type_table ¶
type_table: []Type_Info
NOTE(bill): only the ones that are needed (not all types) This will be set by the compiler
Procedures
DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD ¶
DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD :: proc(ignore: bool = false, loc := #caller_location) -> (Arena_Temp, Source_Code_Location) {…}
abs_complex128 ¶
abs_complex128 :: proc "contextless" (x: complex128) -> f64 {…}
abs_complex32 ¶
abs_complex32 :: proc "contextless" (x: complex32) -> f16 {…}
abs_complex64 ¶
abs_complex64 :: proc "contextless" (x: complex64) -> f32 {…}
abs_quaternion128 ¶
abs_quaternion128 :: proc "contextless" (x: quaternion128) -> f32 {…}
abs_quaternion256 ¶
abs_quaternion256 :: proc "contextless" (x: quaternion256) -> f64 {…}
abs_quaternion64 ¶
abs_quaternion64 :: proc "contextless" (x: quaternion64) -> f16 {…}
align_forward_int ¶
align_forward_int :: proc(ptr, align: int) -> int {…}
align_forward_uintptr ¶
align_forward_uintptr :: proc(ptr, align: uintptr) -> uintptr {…}
alloc_from_memory_block ¶
alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint) -> (data: []u8, err: Allocator_Error) {…}
append_elem ¶
append_elem :: proc(array: ^$T/[dynamic]$T, arg: $T, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}
append_elem_string ¶
append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $S/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}
The append_string built-in procedure appends a string to the end of a [dynamic]u8 like type
append_elems ¶
append_elems :: proc(array: ^$T/[dynamic]$T, args: ..$T, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}
append_nothing ¶
append_nothing :: proc(array: ^$T/[dynamic]$T, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}
append_soa_elem ¶
append_soa_elem :: proc(array: ^$T/#soa[dynamic]$T, arg: $T, loc := #caller_location) {…}
append_soa_elems ¶
append_soa_elems :: proc(array: ^$T/#soa[dynamic]$T, args: ..$T, loc := #caller_location) {…}
append_string ¶
append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}
The append_string built-in procedure appends multiple strings to the end of a [dynamic]u8 like type
arena_alloc ¶
arena_alloc :: proc(arena: ^Arena, size, alignment: uint, loc := #caller_location) -> (data: []u8, err: Allocator_Error) {…}
arena_allocator_proc ¶
arena_allocator_proc :: proc( allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, location := #caller_location, ) -> (data: []u8, err: Allocator_Error) {…}
arena_check_temp ¶
arena_check_temp :: proc(arena: ^Arena, loc := #caller_location) {…}
arena_destroy ¶
arena_destroy :: proc(arena: ^Arena, loc := #caller_location) {…}
arena_free_all ¶
arena_free_all :: proc(arena: ^Arena, loc := #caller_location) {…}
arena_free_all
will free all but the first memory block, and then reset the memory block
arena_free_last_memory_block ¶
arena_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_location) {…}
arena_init ¶
arena_init :: proc(arena: ^Arena, size: uint, backing_allocator: Allocator, loc := #caller_location) -> Allocator_Error {…}
arena_init
will initialize the arena with a usuable block.
This procedure is not necessary to use the Arena as the default zero as arena_alloc
will set things up if necessary
arena_temp_begin ¶
arena_temp_begin :: proc(arena: ^Arena, loc := #caller_location) -> (temp: Arena_Temp) {…}
arena_temp_end ¶
arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {…}
arena_temp_ignore ¶
arena_temp_ignore :: proc(temp: Arena_Temp, loc := #caller_location) {…}
Ignore the use of a arena_temp_begin
entirely
assert ¶
assert :: proc(condition: bool, message: string = "", loc := #caller_location) {…}
assign_at_elem ¶
assign_at_elem :: proc(array: ^$T/[dynamic]$T, index: int, arg: $T, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}
assign_at_elem_string ¶
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}
assign_at_elems ¶
assign_at_elems :: proc(array: ^$T/[dynamic]$T, index: int, args: ..$T, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}
bounds_check_error ¶
bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) {…}
bounds_check_error_loc ¶
bounds_check_error_loc :: proc "contextless" ( using loc := #caller_location, index, count: int) {…}
bounds_trap ¶
bounds_trap :: proc "contextless" () -> ! {…}
bswap_128 ¶
bswap_128 :: proc "contextless" (x: u128) -> u128 {…}
bswap_16 ¶
bswap_16 :: proc "contextless" (x: u16) -> u16 {…}
bswap_32 ¶
bswap_32 :: proc "contextless" (x: u32) -> u32 {…}
bswap_64 ¶
bswap_64 :: proc "contextless" (x: u64) -> u64 {…}
bswap_f16 ¶
bswap_f16 :: proc "contextless" (f: f16) -> f16 {…}
bswap_f32 ¶
bswap_f32 :: proc "contextless" (f: f32) -> f32 {…}
bswap_f64 ¶
bswap_f64 :: proc "contextless" (f: f64) -> f64 {…}
clear_dynamic_array ¶
clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$T) {…}
clear_dynamic_array
will set the length of a passed dynamic array to 0
Note: Prefer the procedure group clear
.
clear_map ¶
clear_map :: proc "contextless" (m: ^$T/map[$T]$T) {…}
clear_map
will set the length of a passed map to 0
Note: Prefer the procedure group clear
complex128_eq ¶
complex128_eq :: proc "contextless" (a, b: complex128) -> bool {…}
complex128_ne ¶
complex128_ne :: proc "contextless" (a, b: complex128) -> bool {…}
complex32_eq ¶
complex32_eq :: proc "contextless" (a, b: complex32) -> bool {…}
complex32_ne ¶
complex32_ne :: proc "contextless" (a, b: complex32) -> bool {…}
complex64_eq ¶
complex64_eq :: proc "contextless" (a, b: complex64) -> bool {…}
complex64_ne ¶
complex64_ne :: proc "contextless" (a, b: complex64) -> bool {…}
container_of ¶
container_of :: proc "contextless" (ptr: $P/^$T, $T: typeid, $field_name: string = ) -> ^typeid {…}
copy_from_string ¶
copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int {…}
copy_from_string
is a built-in procedure that copies elements from a source slice src
to a destination string dst
.
The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum
of len(src) and len(dst).
Prefer the procedure group copy
.
copy_slice ¶
copy_slice :: proc "contextless" (dst, src: $T/[]$T) -> int {…}
copy_slice
is a built-in procedure that copies elements from a source slice src
to a destination slice dst
.
The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum
of len(src) and len(dst).
Prefer the procedure group copy
.
cstring_len ¶
cstring_len :: proc "contextless" (s: cstring) -> int {…}
cstring_to_string ¶
cstring_to_string :: proc "contextless" (s: cstring) -> string {…}
debug_trap ¶
debug_trap :: intrinsics.debug_trap
default_allocator ¶
default_allocator :: proc() -> Allocator {…}
default_allocator_proc ¶
default_allocator_proc :: proc( allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location, ) -> (data: []u8, err: Allocator_Error) {…}
default_assertion_failure_proc ¶
default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) -> ! {…}
default_context ¶
default_context :: proc "contextless" () -> Context {…}
default_hasher ¶
default_hasher :: proc "contextless" (data: rawptr, seed: uintptr, N: int) -> uintptr {…}
default_hasher_cstring ¶
default_hasher_cstring :: proc "contextless" (data: rawptr, seed: uintptr = 0) -> uintptr {…}
default_hasher_string ¶
default_hasher_string :: proc "contextless" (data: rawptr, seed: uintptr = 0) -> uintptr {…}
default_logger ¶
default_logger :: proc() -> Logger {…}
default_logger_proc ¶
default_logger_proc :: proc(data: rawptr, level: Logger_Level, text: string, options: bit_set[Logger_Option], location := #caller_location) {…}
default_temp_allocator ¶
default_temp_allocator :: proc(allocator: ^Default_Temp_Allocator) -> Allocator {…}
default_temp_allocator_destroy ¶
default_temp_allocator_destroy :: proc(s: ^Default_Temp_Allocator) {…}
default_temp_allocator_init ¶
default_temp_allocator_init :: proc(s: ^Default_Temp_Allocator, size: int, backing_allocator := context.allocator) {…}
default_temp_allocator_proc ¶
default_temp_allocator_proc :: proc( allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location, ) -> (data: []u8, err: Allocator_Error) {…}
default_temp_allocator_temp_begin ¶
default_temp_allocator_temp_begin :: proc( using loc: Source_Code_Location) -> (temp: Arena_Temp) {…}
default_temp_allocator_temp_end ¶
default_temp_allocator_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {…}
delete_cstring ¶
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}
delete_cstring
will try to free the underlying data of the passed string, with the given allocator
if the allocator supports this operation.
Note: Prefer the procedure group delete
.
delete_dynamic_array ¶
delete_dynamic_array :: proc(array: $T/[dynamic]$T, loc := #caller_location) -> Allocator_Error {…}
delete_dynamic_array
will try to free the underlying data of the passed dynamic array, with the given allocator
if the allocator supports this operation.
Note: Prefer the procedure group delete
.
delete_key ¶
delete_key :: proc(m: ^$T/map[$T]$T, key: $T) -> (deleted_key: $T, deleted_value: $T) {…}
The delete_key built-in procedure deletes the element with the specified key (m[key]) from the map. If m is nil, or there is no such element, this procedure is a no-op
delete_map ¶
delete_map :: proc(m: $T/map[$T]$T, loc := #caller_location) -> Allocator_Error {…}
delete_map
will try to free the underlying data of the passed map, with the given allocator
if the allocator supports this operation.
Note: Prefer the procedure group delete
.
delete_slice ¶
delete_slice :: proc(array: $T/[]$T, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}
delete_slice
will try to free the underlying data of the passed sliced, with the given allocator
if the allocator supports this operation.
Note: Prefer the procedure group delete
.
delete_soa_dynamic_array ¶
delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$T, loc := #caller_location) {…}
delete_soa_slice ¶
delete_soa_slice :: proc(array: $T/#soa[]$T, allocator := context.allocator, loc := #caller_location) {…}
delete_string ¶
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}
delete_string
will try to free the underlying data of the passed string, with the given allocator
if the allocator supports this operation.
Note: Prefer the procedure group delete
.
divmodti4 ¶
divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {…}
dynamic_array_expr_error ¶
dynamic_array_expr_error :: proc "contextless" ( file: string, line, column: i32, low, high, max: int, ) {…}
dynamic_array_expr_error_loc ¶
dynamic_array_expr_error_loc :: proc "contextless" ( using loc := #caller_location, low, high, max: int) {…}
encode_rune ¶
encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {…}
excl_bit_set ¶
excl_bit_set :: proc(s: ^$S/bit_set[$T], other: $S/bit_set[$T]) {…}
excl_elem ¶
excl_elem :: proc(s: ^$S/bit_set[$T], elem: $T) {…}
excl_elems ¶
excl_elems :: proc(s: ^$S/bit_set[$T], elems: ..$T) {…}
extendhfsf2 ¶
extendhfsf2 :: proc "c" (value: u16) -> f32 {…}
fixunsdfdi ¶
fixunsdfdi :: proc "c" (a: f64) -> i128 {…}
fixunsdfti ¶
fixunsdfti :: proc "c" (a: f64) -> u128 {…}
floattidf ¶
floattidf :: proc "c" (a: i128) -> f64 {…}
floattidf_unsigned ¶
floattidf_unsigned :: proc "c" (a: u128) -> f64 {…}
gnu_f2h_ieee ¶
gnu_f2h_ieee :: proc "c" (value: f32) -> u16 {…}
gnu_h2f_ieee ¶
gnu_h2f_ieee :: proc "c" (value: u16) -> f32 {…}
hermitian_adjoint ¶
hermitian_adjoint :: proc "contextless" (m: $M/matrix[0, 0]$T) -> $M/matrix[0, 0]$T {…}
incl_bit_set ¶
incl_bit_set :: proc(s: ^$S/bit_set[$T], other: $S/bit_set[$T]) {…}
incl_elem ¶
incl_elem :: proc(s: ^$S/bit_set[$T], elem: $T) {…}
incl_elems ¶
incl_elems :: proc(s: ^$S/bit_set[$T], elems: ..$T) {…}
init_global_temporary_allocator ¶
init_global_temporary_allocator :: proc(size: int, backup_allocator := context.allocator) {…}
inject_at_elem ¶
inject_at_elem :: proc(array: ^$T/[dynamic]$T, index: int, arg: $T, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}
inject_at_elem_string ¶
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}
inject_at_elems ¶
inject_at_elems :: proc(array: ^$T/[dynamic]$T, index: int, args: ..$T, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}
is_power_of_two_int ¶
is_power_of_two_int :: proc(x: int) -> bool {…}
is_power_of_two_uintptr ¶
is_power_of_two_uintptr :: proc(x: uintptr) -> bool {…}
make_aligned ¶
make_aligned :: proc($T: typeid/[]T, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_ok {…}
make_dynamic_array ¶
make_dynamic_array :: proc($T: typeid/[dynamic]T, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_ok {…}
make_dynamic_array
allocates and initializes a dynamic array. Like new
, the first argument is a type, not a value.
Unlike new
, make
's return value is the same as the type of its argument, not a pointer to it.
Note: Prefer using the procedure group make
.
make_dynamic_array_error_loc ¶
make_dynamic_array_error_loc :: proc "contextless" ( using loc := #caller_location, len, cap: int) {…}
make_dynamic_array_len ¶
make_dynamic_array_len :: proc($T: typeid/[dynamic]T, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_ok {…}
make_dynamic_array_len
allocates and initializes a dynamic array. Like new
, the first argument is a type, not a value.
Unlike new
, make
's return value is the same as the type of its argument, not a pointer to it.
Note: Prefer using the procedure group make
.
make_dynamic_array_len_cap ¶
make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]T, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_ok {…}
make_dynamic_array_len_cap
allocates and initializes a dynamic array. Like new
, the first argument is a type, not a value.
Unlike new
, make
's return value is the same as the type of its argument, not a pointer to it.
Note: Prefer using the procedure group make
.
make_map ¶
make_map :: proc($T: typeid/map[T]T, #any_int capacity: int = 1 << MAP_MIN_LOG2_CAPACITY, allocator := context.allocator, loc := #caller_location) -> (m: T, err: Allocator_Error) #optional_ok {…}
make_map
allocates and initializes a dynamic array. Like new
, the first argument is a type, not a value.
Unlike new
, make
's return value is the same as the type of its argument, not a pointer to it.
Note: Prefer using the procedure group make
.
make_map_expr_error_loc ¶
make_map_expr_error_loc :: proc "contextless" (loc := #caller_location, cap: int) {…}
make_multi_pointer ¶
make_multi_pointer :: proc($T: typeid/[^]T, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: $/[^]T, err: Allocator_Error) #optional_ok {…}
make_multi_pointer
allocates and initializes a dynamic array. Like new
, the first argument is a type, not a value.
Unlike new
, make
's return value is the same as the type of its argument, not a pointer to it.
This is "similar" to doing raw_data(make([]E, len, allocator))
.
Note: Prefer using the procedure group make
.
make_slice ¶
make_slice :: proc($T: typeid/[]T, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_ok {…}
make_slice
allocates and initializes a slice. Like new
, the first argument is a type, not a value.
Unlike new
, make
's return value is the same as the type of its argument, not a pointer to it.
Note: Prefer using the procedure group make
.
make_slice_error_loc ¶
make_slice_error_loc :: proc "contextless" (loc := #caller_location, len: int) {…}
make_soa_aligned ¶
make_soa_aligned :: proc($T: typeid/#soa[]T, length: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_ok {…}
make_soa_dynamic_array ¶
make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]T, allocator := context.allocator, loc := #caller_location) -> (array: T) {…}
make_soa_dynamic_array_len ¶
make_soa_dynamic_array_len :: proc($T: typeid/#soa[dynamic]T, #any_int length: int, allocator := context.allocator, loc := #caller_location) -> (array: T) {…}
make_soa_dynamic_array_len_cap ¶
make_soa_dynamic_array_len_cap :: proc($T: typeid/#soa[dynamic]T, #any_int length, #any_int capacity: int, allocator := context.allocator, loc := #caller_location) -> (array: T) {…}
make_soa_slice ¶
make_soa_slice :: proc($T: typeid/#soa[]T, length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_ok {…}
map_alloc_dynamic ¶
map_alloc_dynamic :: proc(info: ^Map_Info, log2_capacity: uintptr, allocator := context.allocator, loc := #caller_location) -> (result: Raw_Map, err: Allocator_Error) {…}
The only procedure which needs access to the context is the one which allocates the map.
map_cell_index_dynamic ¶
map_cell_index_dynamic :: proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, index: uintptr) -> uintptr {…}
Same as the above procedure but at runtime with the cell Map_Cell_Info value.
map_cell_index_dynamic_const ¶
map_cell_index_dynamic_const :: proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, $INDEX: uintptr = ) -> uintptr {…}
Same as above procedure but with compile-time constant index.
map_cell_index_static ¶
map_cell_index_static :: proc "contextless" (cells: [^]Map_Cell($T), index: uintptr) -> ^$T {…}
We always round the capacity to a power of two so this becomes [16]Foo, which works out to [4]Cell(Foo).
The following compile-time procedure indexes such a [N]Cell(T) structure as if it were a flat array accounting for the internal padding introduced by the Cell structure.
map_cell_info ¶
map_cell_info :: intrinsics.type_map_cell_info
map_cell_info :: proc "contextless" ($T: typeid) -> ^Map_Cell_Info {...}
map_data ¶
map_data :: proc "contextless" (m: Raw_Map) -> uintptr {…}
Canonicalize the data by removing the tagged capacity stored in the lower six bits of the data uintptr.
map_desired_position ¶
map_desired_position :: proc "contextless" (m: Raw_Map, hash: uintptr) -> uintptr {…}
Computes the desired position in the array. This is just index % capacity, but a procedure as there's some math involved here to recover the capacity.
map_free_dynamic ¶
map_free_dynamic :: proc(m: Raw_Map, info: ^Map_Info, loc := #caller_location) -> Allocator_Error {…}
map_get ¶
map_get :: proc "contextless" (m: $T/map[$T]$T, key: $T) -> (stored_key: $T, stored_value: $T, ok: bool) {…}
map_grow_dynamic ¶
map_grow_dynamic :: proc( #no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, loc := #caller_location) -> Allocator_Error {…}
map_hash_is_deleted ¶
map_hash_is_deleted :: proc "contextless" (hash: uintptr) -> bool {…}
map_hash_is_empty ¶
map_hash_is_empty :: proc "contextless" (hash: uintptr) -> bool {…}
Procedure to check if a slot is empty for a given hash. This is represented by the zero value to make the zero value useful. This is a procedure just for prose reasons.
map_hash_is_valid ¶
map_hash_is_valid :: proc "contextless" (hash: uintptr) -> bool {…}
map_info ¶
map_info :: intrinsics.type_map_info
The Map_Info structure is basically a pseudo-table of information for a given K and V pair. map_info :: proc "contextless" ($T: typeid/map[$K]$V) -> ^Map_Info {...}
map_insert ¶
map_insert :: proc(m: ^$T/map[$T]$T, key: $T, value: $T, loc := #caller_location) -> (ptr: ^$T) {…}
map_insert_hash_dynamic ¶
map_insert_hash_dynamic :: proc( #no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: uintptr, ik: uintptr, iv: uintptr) -> (result: uintptr) {…}
This procedure has to stack allocate storage to store local keys during the Robin Hood hashing technique where elements are swapped in the backing arrays to reduce variance. This swapping can only be done with memcpy since there is no type information.
This procedure returns the address of the just inserted value.
map_load_factor ¶
map_load_factor :: proc "contextless" (log2_capacity: uintptr) -> uintptr {…}
Query the load factor of the map. This is not actually configurable, but some math is needed to compute it. Compute it as a fixed point percentage to avoid floating point operations. This division can be optimized out by multiplying by the multiplicative inverse of 100.
map_log2_cap ¶
map_log2_cap :: proc "contextless" (m: Raw_Map) -> uintptr {…}
The data stores the log2 capacity in the lower six bits. This is primarily used in the implementation rather than map_cap since the check for data = 0 isn't necessary in the implementation. cap() on the otherhand needs to work when called on an empty map.
map_probe_distance ¶
map_probe_distance :: proc "contextless" (m: Raw_Map, hash: uintptr, slot: uintptr) -> uintptr {…}
map_reserve_dynamic ¶
map_reserve_dynamic :: proc( #no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, new_capacity: uintptr, loc := #caller_location) -> Allocator_Error {…}
map_resize_threshold ¶
map_resize_threshold :: proc "contextless" (m: Raw_Map) -> int {…}
map_seed ¶
map_seed :: proc "contextless" (m: Raw_Map) -> uintptr {…}
map_seed_from_map_data ¶
map_seed_from_map_data :: proc "contextless" (data: uintptr) -> uintptr {…}
splitmix for uintptr
map_shrink_dynamic ¶
map_shrink_dynamic :: proc( #no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, loc := #caller_location) -> Allocator_Error {…}
matrix1x1_adjugate ¶
matrix1x1_adjugate :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: $M/matrix[1, 1]$T) {…}
matrix1x1_determinant ¶
matrix1x1_determinant :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: $T) {…}
matrix1x1_inverse ¶
matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: $M/matrix[1, 1]$T) {…}
matrix1x1_inverse_transpose ¶
matrix1x1_inverse_transpose :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: $M/matrix[1, 1]$T) {…}
matrix2x2_adjugate ¶
matrix2x2_adjugate :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: $M/matrix[2, 2]$T) {…}
matrix2x2_determinant ¶
matrix2x2_determinant :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: $T) {…}
matrix2x2_inverse ¶
matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: $M/matrix[2, 2]$T) {…}
matrix2x2_inverse_transpose ¶
matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: $M/matrix[2, 2]$T) {…}
matrix3x3_adjugate ¶
matrix3x3_adjugate :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: $M/matrix[3, 3]$T) {…}
matrix3x3_determinant ¶
matrix3x3_determinant :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: $T) {…}
matrix3x3_inverse ¶
matrix3x3_inverse :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: $M/matrix[3, 3]$T) {…}
matrix3x3_inverse_transpose ¶
matrix3x3_inverse_transpose :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: $M/matrix[3, 3]$T) {…}
matrix4x4_adjugate ¶
matrix4x4_adjugate :: proc "contextless" (x: $A/matrix[4, 4]$T) -> (y: $A/matrix[4, 4]$T) {…}
matrix4x4_determinant ¶
matrix4x4_determinant :: proc "contextless" (m: $A/matrix[4, 4]$T) -> (det: $T) {…}
matrix4x4_inverse ¶
matrix4x4_inverse :: proc "contextless" (x: $A/matrix[4, 4]$T) -> (y: $A/matrix[4, 4]$T) {…}
matrix4x4_inverse_transpose ¶
matrix4x4_inverse_transpose :: proc "contextless" (x: $A/matrix[4, 4]$T) -> (y: $A/matrix[4, 4]$T) {…}
matrix_bounds_check_error ¶
matrix_bounds_check_error :: proc "contextless" ( file: string, line, column: i32, row_index, column_index, row_count, column_count: int, ) {…}
matrix_minor ¶
matrix_minor :: proc "contextless" (m: $M/matrix[0, 0]$T, row, column: int) -> (minor: $T) {…}
matrix_trace ¶
matrix_trace :: proc "contextless" (m: $M/matrix[0, 0]$T) -> (trace: $T) {…}
mem_alloc ¶
mem_alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}
mem_alloc_bytes ¶
mem_alloc_bytes :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}
mem_alloc_non_zeroed ¶
mem_alloc_non_zeroed :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}
mem_copy ¶
mem_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {…}
mem_copy_non_overlapping ¶
mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {…}
mem_free ¶
mem_free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}
mem_free_all ¶
mem_free_all :: proc(allocator := context.allocator, loc := #caller_location) -> (err: Allocator_Error) {…}
mem_free_bytes ¶
mem_free_bytes :: proc(bytes: []u8, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}
mem_free_with_size ¶
mem_free_with_size :: proc(ptr: rawptr, byte_count: int, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}
mem_resize ¶
mem_resize :: proc( ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location, ) -> (data: []u8, err: Allocator_Error) {…}
mem_zero ¶
mem_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr {…}
memory_block_alloc ¶
memory_block_alloc :: proc(allocator: Allocator, capacity: uint, loc := #caller_location) -> (block: ^Memory_Block, err: Allocator_Error) {…}
memory_block_dealloc ¶
memory_block_dealloc :: proc(block_to_free: ^Memory_Block, loc := #caller_location) {…}
memory_compare ¶
memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int {…}
memory_compare_zero ¶
memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int {…}
memory_equal ¶
memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool {…}
mul_quaternion128 ¶
mul_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 {…}
mul_quaternion256 ¶
mul_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 {…}
mul_quaternion64 ¶
mul_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 {…}
multi_pointer_slice_expr_error ¶
multi_pointer_slice_expr_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) {…}
multi_pointer_slice_handle_error ¶
multi_pointer_slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! {…}
new ¶
new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> (^typeid, Allocator_Error) #optional_ok {…}
The new built-in procedure allocates memory. The first argument is a type, not a value, and the value return is a pointer to a newly allocated value of that type using the specified allocator, default is context.allocator
new_aligned ¶
new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> (t: ^typeid, err: Allocator_Error) {…}
new_clone ¶
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: ^$T, err: Allocator_Error) #optional_ok {…}
nil_allocator ¶
nil_allocator :: proc() -> Allocator {…}
nil_allocator_proc ¶
nil_allocator_proc :: proc( allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location, ) -> ([]u8, Allocator_Error) {…}
ordered_remove ¶
ordered_remove :: proc(array: ^$T/[dynamic]$T, index: int, loc := #caller_location) {…}
ordered_remove
removed the element at the specified index
whilst keeping the order of the other elements.
Note: This is an O(N) operation.
Note: If you the elements do not have to remain in their order, prefer unordered_remove
.
Note: If the index is out of bounds, this procedure will panic.
os_write ¶
os_write :: proc "contextless" (data: []u8) -> (int, _OS_Errno) {…}
panic ¶
panic :: proc(message: string, loc := #caller_location) -> ! {…}
pop ¶
pop :: proc(array: ^$T/[dynamic]$T, loc := #caller_location) -> (res: $T) {…}
pop
will remove and return the end value of dynamic array array
and reduces the length of array
by 1.
Note: If the dynamic array as no elements (len(array) == 0
), this procedure will panic.
pop_front ¶
pop_front :: proc(array: ^$T/[dynamic]$T, loc := #caller_location) -> (res: $T) {…}
pop_front
will remove and return the first value of dynamic array array
and reduces the length of array
by 1.
Note: If the dynamic array as no elements (len(array) == 0
), this procedure will panic.
pop_front_safe ¶
pop_front_safe :: proc(array: ^$T/[dynamic]$T) -> (res: $T, ok: bool) {…}
pop_front_safe
trys to return and remove the first value of dynamic array array
and reduces the length of array
by 1.
If the operation is not possible, it will return false.
pop_safe ¶
pop_safe :: proc(array: ^$T/[dynamic]$T) -> (res: $T, ok: bool) {…}
pop_safe
trys to remove and return the end value of dynamic array array
and reduces the length of array
by 1.
If the operation is not possible, it will return false.
print_any_single ¶
print_any_single :: proc "contextless" (arg: any) {…}
print_byte ¶
print_byte :: proc "contextless" (b: u8) -> (n: int) {…}
print_caller_location ¶
print_caller_location :: proc "contextless" ( using loc: Source_Code_Location) {…}
print_encoded_rune ¶
print_encoded_rune :: proc "contextless" (r: rune) {…}
print_i64 ¶
print_i64 :: proc "contextless" (x: i64) {…}
print_int ¶
print_int :: proc "contextless" (x: int) {…}
print_rune ¶
print_rune :: proc "contextless" (r: rune) -> int {…}
print_string ¶
print_string :: proc "contextless" (str: string) -> (n: int) {…}
print_strings ¶
print_strings :: proc "contextless" (args: ..string) -> (n: int) {…}
print_type ¶
print_type :: proc "contextless" (ti: ^Type_Info) {…}
print_typeid ¶
print_typeid :: proc "contextless" (id: typeid) {…}
print_u64 ¶
print_u64 :: proc "contextless" (x: u64) {…}
print_uint ¶
print_uint :: proc "contextless" (x: uint) {…}
print_uintptr ¶
print_uintptr :: proc "contextless" (x: uintptr) {…}
println_any ¶
println_any :: proc "contextless" (args: ..any) {…}
quaternion128_eq ¶
quaternion128_eq :: proc "contextless" (a, b: quaternion128) -> bool {…}
quaternion128_ne ¶
quaternion128_ne :: proc "contextless" (a, b: quaternion128) -> bool {…}
quaternion256_eq ¶
quaternion256_eq :: proc "contextless" (a, b: quaternion256) -> bool {…}
quaternion256_ne ¶
quaternion256_ne :: proc "contextless" (a, b: quaternion256) -> bool {…}
quaternion64_eq ¶
quaternion64_eq :: proc "contextless" (a, b: quaternion64) -> bool {…}
quaternion64_ne ¶
quaternion64_ne :: proc "contextless" (a, b: quaternion64) -> bool {…}
quo_complex128 ¶
quo_complex128 :: proc "contextless" (n, m: complex128) -> complex128 {…}
quo_complex32 ¶
quo_complex32 :: proc "contextless" (n, m: complex32) -> complex32 {…}
quo_complex64 ¶
quo_complex64 :: proc "contextless" (n, m: complex64) -> complex64 {…}
quo_quaternion128 ¶
quo_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 {…}
quo_quaternion256 ¶
quo_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 {…}
quo_quaternion64 ¶
quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 {…}
raw_soa_footer_dynamic_array ¶
raw_soa_footer_dynamic_array :: proc(array: ^$T/#soa[dynamic]$T) -> (footer: ^Raw_SOA_Footer_Dynamic_Array) {…}
raw_soa_footer_slice ¶
raw_soa_footer_slice :: proc(array: ^$T/#soa[]$T) -> (footer: ^Raw_SOA_Footer_Slice) {…}
read_cycle_counter ¶
read_cycle_counter :: intrinsics.read_cycle_counter
remove_range ¶
remove_range :: proc(array: ^$T/[dynamic]$T, lo, hi: int, loc := #caller_location) {…}
remove_range
removes a range of elements specified by the range lo
and hi
, whilst keeping the order of the other elements.
Note: This is an O(N) operation. Note: If the range is out of bounds, this procedure will panic.
reserve_dynamic_array ¶
reserve_dynamic_array :: proc(array: ^$T/[dynamic]$T, capacity: int, loc := #caller_location) -> Allocator_Error {…}
reserve_dynamic_array
will try to reserve memory of a passed dynamic array or map to the requested element count (setting the cap
).
Note: Prefer the procedure group reserve
.
reserve_map ¶
reserve_map :: proc(m: ^$T/map[$T]$T, capacity: int, loc := #caller_location) -> Allocator_Error {…}
reserve_map
will try to reserve memory of a passed map to the requested element count (setting the cap
).
Note: Prefer the procedure group reserve
reserve_soa ¶
reserve_soa :: proc(array: ^$T/#soa[dynamic]$T, capacity: int, loc := #caller_location) -> bool {…}
resize_dynamic_array ¶
resize_dynamic_array :: proc(array: ^$T/[dynamic]$T, length: int, loc := #caller_location) -> Allocator_Error {…}
resize_dynamic_array
will try to resize memory of a passed dynamic array or map to the requested element count (setting the len
, and possibly cap
).
Note: Prefer the procedure group resize
resize_soa ¶
resize_soa :: proc(array: ^$T/#soa[dynamic]$T, length: int, loc := #caller_location) -> bool {…}
shrink_dynamic_array ¶
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$T, new_cap: int = -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {…}
Shrinks the capacity of a dynamic array down to the current length, or the given capacity.
If `new_cap` is negative, then `len(array)` is used. Returns false if `cap(array) < new_cap`, or the allocator report failure. If `len(array) < new_cap`, then `len(array)` will be left unchanged. Note: Prefer the procedure group `shrink`
shrink_map ¶
shrink_map :: proc(m: ^$T/map[$T]$T, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {…}
Shrinks the capacity of a map down to the current length.
Note: Prefer the procedure group shrink
slice_expr_error_hi ¶
slice_expr_error_hi :: proc "contextless" (file: string, line, column: i32, hi: int, len: int) {…}
slice_expr_error_hi_loc ¶
slice_expr_error_hi_loc :: proc "contextless" ( using loc := #caller_location, hi: int, len: int) {…}
slice_expr_error_lo_hi ¶
slice_expr_error_lo_hi :: proc "contextless" ( file: string, line, column: i32, lo, hi: int, len: int, ) {…}
slice_expr_error_lo_hi_loc ¶
slice_expr_error_lo_hi_loc :: proc "contextless" ( using loc := #caller_location, lo, hi: int, len: int) {…}
slice_handle_error ¶
slice_handle_error :: proc "contextless" ( file: string, line, column: i32, lo, hi: int, len: int, ) -> ! {…}
string_cmp ¶
string_cmp :: proc "contextless" (a, b: string) -> int {…}
string_decode_last_rune ¶
string_decode_last_rune :: proc "contextless" (s: string) -> (rune, int) {…}
string_decode_rune ¶
string_decode_rune :: proc "contextless" (s: string) -> (rune, int) {…}
string_eq ¶
string_eq :: proc "contextless" (lhs, rhs: string) -> bool {…}
string_ge ¶
string_ge :: proc "contextless" (a, b: string) -> bool {…}
string_gt ¶
string_gt :: proc "contextless" (a, b: string) -> bool {…}
string_le ¶
string_le :: proc "contextless" (a, b: string) -> bool {…}
string_lt ¶
string_lt :: proc "contextless" (a, b: string) -> bool {…}
string_ne ¶
string_ne :: proc "contextless" (a, b: string) -> bool {…}
trap ¶
trap :: intrinsics.trap
truncdfhf2 ¶
truncdfhf2 :: proc "c" (value: f64) -> u16 {…}
truncsfhf2 ¶
truncsfhf2 :: proc "c" (value: f32) -> u16 {…}
type_assertion_check ¶
type_assertion_check :: proc "contextless" ( ok: bool, file: string, line, column: i32, from, to: typeid, ) {…}
type_assertion_check2 ¶
type_assertion_check2 :: proc "contextless" ( ok: bool, file: string, line, column: i32, from, to: typeid, from_data: rawptr, ) {…}
type_assertion_trap ¶
type_assertion_trap :: proc "contextless" () -> ! {…}
type_info_base_without_enum ¶
type_info_base_without_enum :: type_info_core
typeid_base ¶
typeid_base :: proc "contextless" (id: typeid) -> typeid {…}
typeid_base_without_enum ¶
typeid_base_without_enum :: typeid_core
typeid_core ¶
typeid_core :: proc "contextless" (id: typeid) -> typeid {…}
udivmod128 ¶
udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {…}
udivmodti4 ¶
udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {…}
unimplemented ¶
unimplemented :: proc(message: string, loc := #caller_location) -> ! {…}
unordered_remove ¶
unordered_remove :: proc(array: ^$T/[dynamic]$T, index: int, loc := #caller_location) {…}
unordered_remove
removed the element at the specified index
. It does so by replacing the current end value
with the old value, and reducing the length of the dynamic array by 1.
Note: This is an O(1) operation.
Note: If you the elements to remain in their order, use ordered_remove
.
Note: If the index is out of bounds, this procedure will panic.
Procedure Groups
adjugate ¶
adjugate :: proc{ matrix1x1_adjugate, matrix2x2_adjugate, matrix3x3_adjugate, matrix4x4_adjugate, }
append ¶
append :: proc{ append_elem, append_elems, append_elem_string, }
The append built-in procedure appends elements to the end of a dynamic array
append_soa ¶
append_soa :: proc{ append_soa_elem, append_soa_elems, }
The append_soa built-in procedure appends elements to the end of an #soa dynamic array
assign_at ¶
assign_at :: proc{ assign_at_elem, assign_at_elems, assign_at_elem_string, }
clear ¶
clear :: proc{ clear_dynamic_array, clear_map, }
clear
will set the length of a passed dynamic array or map to 0
copy ¶
copy :: proc{ copy_slice, copy_from_string, }
copy
is a built-in procedure that copies elements from a source slice src
to a destination slice/string dst
.
The source and destination may overlap. Copy returns the number of elements copied, which will be the minimum
of len(src) and len(dst).
delete ¶
delete :: proc{ delete_string, delete_cstring, delete_dynamic_array, delete_slice, delete_map, }
delete
will try to free the underlying data of the passed built-in data structure (string, cstring, dynamic array, slice, or map), with the given allocator
if the allocator supports this operation.
Note: Prefer delete
over the specific delete_*
procedures where possible.
delete_soa ¶
delete_soa :: proc{ delete_soa_slice, delete_soa_dynamic_array, }
determinant ¶
determinant :: proc{ matrix1x1_determinant, matrix2x2_determinant, matrix3x3_determinant, matrix4x4_determinant, }
excl ¶
excl :: proc{ excl_elem, excl_elems, excl_bit_set, }
free ¶
free :: proc{ mem_free, }
free
will try to free the passed pointer, with the given allocator
if the allocator supports this operation.
free_all ¶
free_all :: proc{ mem_free_all, }
free_all
will try to free/reset all of the memory of the given allocator
if the allocator supports this operation.
incl ¶
incl :: proc{ incl_elem, incl_elems, incl_bit_set, }
inject_at ¶
inject_at :: proc{ inject_at_elem, inject_at_elems, inject_at_elem_string, }
inverse ¶
inverse :: proc{ matrix1x1_inverse, matrix2x2_inverse, matrix3x3_inverse, matrix4x4_inverse, }
inverse_transpose ¶
inverse_transpose :: proc{ matrix1x1_inverse_transpose, matrix2x2_inverse_transpose, matrix3x3_inverse_transpose, matrix4x4_inverse_transpose, }
make ¶
make :: proc{ make_slice, make_dynamic_array, make_dynamic_array_len, make_dynamic_array_len_cap, make_map, make_multi_pointer, }
make
built-in procedure allocates and initializes a value of type slice, dynamic array, map, or multi-pointer (only).
Similar to new
, the first argument is a type, not a value. Unlike new, make's return type is the same as the
type of its argument, not a pointer to it.
Make uses the specified allocator, default is context.allocator, default is context.allocator
make_soa ¶
make_soa :: proc{ make_soa_slice, make_soa_dynamic_array, make_soa_dynamic_array_len, make_soa_dynamic_array_len_cap, }
raw_soa_footer ¶
raw_soa_footer :: proc{ raw_soa_footer_slice, raw_soa_footer_dynamic_array, }
reserve ¶
reserve :: proc{ reserve_dynamic_array, reserve_map, }
reserve
will try to reserve memory of a passed dynamic array or map to the requested element count (setting the cap
).
resize ¶
resize :: proc{ resize_dynamic_array, }
resize
will try to resize memory of a passed dynamic array or map to the requested element count (setting the len
, and possibly cap
).
shrink ¶
shrink :: proc{ shrink_dynamic_array, shrink_map, }
Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity.
Source Files
- core.odin
- core_builtin.odin
- core_builtin_matrix.odin
- core_builtin_soa.odin
- default_allocators_arena.odin
- default_allocators_nil.odin
- default_temporary_allocator.odin
- dynamic_array_internal.odin
- dynamic_map_internal.odin
- error_checks.odin
- internal.odin
- os_specific.odin
- print.odin
- procs.odin
- udivmod128.odin
- (hidden platform specific files)
Generation Information
Generated with odin version dev-2023-06 (vendor "odin") Windows_amd64 @ 2023-06-02 21:08:32.578922900 +0000 UTC