package base:runtime

⌘K
Ctrl+K
or
/

    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 (80)
    Procedures (273)

    Types

    Allocator_Error ¶

    Allocator_Error :: enum u8 {
    	None                 = 0, 
    	Out_Of_Memory        = 1, 
    	Invalid_Pointer      = 2, 
    	Invalid_Argument     = 3, 
    	Mode_Not_Implemented = 4, 
    }
    Related Procedures With Returns

    Allocator_Mode ¶

    Allocator_Mode :: enum u8 {
    	Alloc, 
    	Free, 
    	Free_All, 
    	Resize, 
    	Query_Features, 
    	Query_Info, 
    	Alloc_Non_Zeroed, 
    	Resize_Non_Zeroed, 
    }
     

    Allocation Stuff

    Related Procedures With Parameters

    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)

    Allocator_Query_Info ¶

    Allocator_Query_Info :: struct {
    	pointer:   rawptr,
    	size:      Maybe($T=int),
    	alignment: Maybe($T=int),
    }

    Arena ¶

    Arena :: struct {
    	backing_allocator:  Allocator,
    	curr_block:         ^Memory_Block,
    	total_used:         uint,
    	total_capacity:     uint,
    	minimum_block_size: uint,
    	temp_count:         uint,
    }
    Related Procedures With Parameters

    Arena_Temp ¶

    Arena_Temp :: struct {
    	arena: ^Arena,
    	block: ^Memory_Block,
    	used:  uint,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    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,
    }
    Related Procedures With Returns

    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,
    }
    Related Procedures With Parameters

    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

    Load_Directory_File ¶

    Load_Directory_File :: struct {
    	name: string,
    	data: []u8,
    }
     

    Used by the built-in directory #load_directory(path: string) -> []Load_Directory_File

    Logger ¶

    Logger :: struct {
    	procedure:    Logger_Proc,
    	data:         rawptr,
    	lowest_level: Logger_Level,
    	options:      bit_set[Logger_Option],
    }
    Related Procedures With Returns

    Logger_Level ¶

    Logger_Level :: enum uint {
    	Debug   = 0, 
    	Info    = 10, 
    	Warning = 20, 
    	Error   = 30, 
    	Fatal   = 40, 
    }
    Related Procedures With Parameters

    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

    Related Procedures With Parameters

    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

    Related Procedures With Parameters

    Maybe ¶

    Maybe :: union($T: typeid) {}

    Memory_Block ¶

    Memory_Block :: struct {
    	prev:      ^Memory_Block,
    	allocator: Allocator,
    	base:      [^]u8,
    	used:      uint,
    	capacity:  uint,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    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,
    	wasm64p32,
    }
    

    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,
    }
    

    Odin_Platform_Subtarget_Type ¶

    Odin_Platform_Subtarget_Type :: .Odin_Platform_Subtarget_Type
     

    // Defined internally by the compiler

    Odin_Platform_Subtarget_Type :: enum int {
    	Default,
    	iOS,
    }
    

    Odin_Sanitizer_Flags ¶

    Odin_Sanitizer_Flags :: .Odin_Sanitizer_Flags
     

    // Defined internally by the compiler

    Odin_Sanitizer_Flag :: enum u32 {
    	Address = 0,
    	Memory  = 1,
    	Thread  = 2,
    }
    Odin_Sanitizer_Flags :: distinct bitset[Odin_Sanitizer_Flag; u32]
    
    ODIN_SANITIZER_FLAGS // is a constant
    

    Platform_Endianness ¶

    Platform_Endianness :: enum u8 {
    	Platform = 0, 
    	Little   = 1, 
    	Big      = 2, 
    }

    Raw_Any ¶

    Raw_Any :: struct {
    	data: rawptr,
    	id:   typeid,
    }

    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:       uintptr,
    	// 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

    Related Procedures With Parameters
    Related Procedures With Returns
    Raw_SOA_Footer_Dynamic_Array :: struct {
    	len:       int,
    	cap:       int,
    	allocator: Allocator,
    }
    Related Procedures With Returns
    Raw_SOA_Footer_Slice :: struct {
    	len: int,
    }
    Related Procedures With Returns

    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:      i32,
    	column:    i32,
    	procedure: string,
    }
    Related Procedures With Parameters

    Type_Info_Any ¶

    Type_Info_Any :: struct {}

    Type_Info_Array ¶

    Type_Info_Array :: struct {
    	elem:      ^Type_Info,
    	elem_size: int,
    	count:     int,
    }

    Type_Info_Bit_Field ¶

    Type_Info_Bit_Field :: struct {
    	backing_type: ^Type_Info,
    	names:        []string,
    	types:        []^Type_Info,
    	bit_sizes:    []uintptr,
    	bit_offsets:  []uintptr,
    	tags:         []string,
    }

    Type_Info_Bit_Set ¶

    Type_Info_Bit_Set :: struct {
    	elem:       ^Type_Info,
    	underlying: ^Type_Info,
    	// Possibly nil
    	lower:      i64,
    	upper:      i64,
    }

    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_Map ¶

    Type_Info_Map :: struct {
    	key:      ^Type_Info,
    	value:    ^Type_Info,
    	map_info: ^Map_Info,
    }

    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,
    	// Total element count = column_count * elem_stride
    	layout:       enum u8 {
    		Column_Major, // array of column vectors
    		Row_Major,    // array of row vectors
    	},
    }

    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_Relative_Multi_Pointer ¶

    Type_Info_Relative_Multi_Pointer :: struct {
    	pointer:      ^Type_Info,
    	// ^T
    	base_integer: ^Type_Info,
    }

    Type_Info_Relative_Pointer ¶

    Type_Info_Relative_Pointer :: struct {
    	pointer:      ^Type_Info,
    	// ^T
    	base_integer: ^Type_Info,
    }

    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_Tuple ¶

    Type_Info_Tuple :: Type_Info_Parameters
     

    Will be removed eventually

    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_Multi_Pointer, 
    	Matrix, 
    	Soa_Pointer, 
    	Bit_Field, 
    }
     

    NOTE(bill): This must match the compiler's

    Constants

    Byte ¶

    Byte :: 1

    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)

    Exabyte ¶

    Exabyte :: 1024 * Petabyte

    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_CACHE_LINE_SIZE ¶

    MAP_CACHE_LINE_SIZE :: 1 << MAP_CACHE_LINE_LOG2
     

    The size of a cache-line.

    MAP_LOAD_FACTOR ¶

    MAP_LOAD_FACTOR :: 75
     

    With Robin Hood hashing a maximum load factor of 75% is ideal.

    MAP_MIN_LOG2_CAPACITY ¶

    MAP_MIN_LOG2_CAPACITY :: 3
     

    Minimum log2 capacity.

    Megabyte ¶

    Megabyte :: 1024 * Kilobyte

    NO_DEFAULT_TEMP_ALLOCATOR ¶

    NO_DEFAULT_TEMP_ALLOCATOR: bool : ODIN_OS == .Freestanding || ODIN_OS == .JS || ODIN_DEFAULT_TO_NIL_ALLOCATOR

    Petabyte ¶

    Petabyte :: 1024 * Terabyte

    RUNTIME_REQUIRE ¶

    RUNTIME_REQUIRE :: false
     

    !ODIN_TILDE

    TOMBSTONE_MASK ¶

    TOMBSTONE_MASK :: 1 << (size_of(Map_Hash) * 8 - 1)

    Terabyte ¶

    Terabyte :: 1024 * Gigabyte

    Variables

    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, #no_broadcast 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 {…}

    append_elems ¶

    append_elems :: proc(array: ^$T/[dynamic]$T, .. #no_broadcast 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) -> (n: int, err: Allocator_Error) #optional_ok {…}

    append_soa_elems ¶

    append_soa_elems :: proc(array: ^$T/#soa[dynamic]$T, .. args: ..$T, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

    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 ¶

    arena_allocator :: proc(arena: ^Arena) -> Allocator {…}

    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, #no_broadcast 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, .. #no_broadcast 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" (loc := #caller_location, index, count: int) {…}

    bounds_trap ¶

    bounds_trap :: proc "contextless" () -> ! {…}

    card ¶

    card :: proc "contextless" (s: $S/bit_set[$T]) -> int {…}

    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

    clear_soa_dynamic_array ¶

    clear_soa_dynamic_array :: proc(array: ^$T/#soa[dynamic]$T) {…}

    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 string 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.

    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_cmp ¶

    cstring_cmp :: proc "contextless" (lhs, rhs: cstring) -> int {…}

    cstring_eq ¶

    cstring_eq :: proc "contextless" (lhs, rhs: cstring) -> bool {…}

    cstring_ge ¶

    cstring_ge :: proc "contextless" (a, b: cstring) -> bool {…}

    cstring_gt ¶

    cstring_gt :: proc "contextless" (a, b: cstring) -> bool {…}

    cstring_le ¶

    cstring_le :: proc "contextless" (a, b: cstring) -> bool {…}

    cstring_len ¶

    cstring_len :: proc "contextless" (s: cstring) -> int {…}

    cstring_lt ¶

    cstring_lt :: proc "contextless" (a, b: cstring) -> bool {…}

    cstring_ne ¶

    cstring_ne :: proc "contextless" (a, b: cstring) -> bool {…}

    cstring_to_string ¶

    cstring_to_string :: proc "contextless" (s: cstring) -> string {…}

    debug_trap ¶

    debug_trap :: intrinsics.debug_trap

    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(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) -> Allocator_Error {…}

    delete_soa_slice ¶

    delete_soa_slice :: proc(array: $T/#soa[]$T, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

    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 {…}

    divti3 ¶

    divti3 :: proc "c" (a, b: 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" (loc := #caller_location, low, high, max: int) {…}

    encode_rune ¶

    encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {…}

    extendhfsf2 ¶

    extendhfsf2 :: proc "c" (value: f16) -> f32 {…}

    fixdfti ¶

    fixdfti :: proc(a: u64) -> i128 {…}

    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) -> f16 {…}

    gnu_h2f_ieee ¶

    gnu_h2f_ieee :: proc "c" (value_: f16) -> f32 {…}

    heap_alloc ¶

    heap_alloc :: proc(size: int, zero_memory: bool = true) -> rawptr {…}

    heap_allocator ¶

    heap_allocator :: proc() -> Allocator {…}

    heap_allocator_proc ¶

    heap_allocator_proc :: proc(
    	allocator_data:  rawptr, 
    	mode:            Allocator_Mode, 
    	size, alignment: int, 
    	old_memory:      rawptr, 
    	old_size:        int, 
    	loc := #caller_location, 
    ) -> ([]u8, Allocator_Error) {…}

    heap_free ¶

    heap_free :: proc(ptr: rawptr) {…}

    heap_resize ¶

    heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {…}

    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, #no_broadcast 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, .. #no_broadcast args: ..$T, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #optional_ok {…}

    into_dynamic_soa ¶

    into_dynamic_soa :: proc(array: $T/#soa[]$T) -> #soa[dynamic]$T {…}
     

    Converts soa slice into a soa dynamic array without cloning or allocating memory

    is_power_of_two_int ¶

    is_power_of_two_int :: proc "contextless" (x: int) -> bool {…}

    is_power_of_two_uintptr ¶

    is_power_of_two_uintptr :: proc "contextless" (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" (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, err: Allocator_Error) #optional_ok {…}

    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, err: Allocator_Error) #optional_ok {…}

    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, err: Allocator_Error) #optional_ok {…}

    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_cap ¶

    map_cap :: proc "contextless" (m: Raw_Map) -> int {…}
     

    cap() for 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_clear_dynamic ¶

    map_clear_dynamic :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_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_erase_dynamic ¶

    map_erase_dynamic :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, k: uintptr) -> (old_k, old_v: uintptr, ok: bool) {…}

    map_exists_dynamic ¶

    map_exists_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, k: uintptr) -> (ok: bool) {…}

    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, and will return 'nil' if there was no room to insert the entry

    map_kvh_data_dynamic ¶

    map_kvh_data_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info) -> (ks: uintptr, vs: uintptr, hs: [^]uintptr, sk: uintptr, sv: uintptr) {…}

    map_kvh_data_static ¶

    map_kvh_data_static :: proc "contextless" (m: $T/map[$T]$T) -> (ks: [^]Map_Cell($T), vs: [^]Map_Cell($T), hs: [^]uintptr) {…}

    map_kvh_data_values_dynamic ¶

    map_kvh_data_values_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info) -> (vs: uintptr) {…}

    map_len ¶

    map_len :: proc "contextless" (m: Raw_Map) -> int {…}
     

    len() for map

    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_lookup_dynamic ¶

    map_lookup_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, k: uintptr) -> (index: uintptr, ok: bool) {…}

    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) -> uintptr {…}

    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) -> (did_shrink: bool, err: Allocator_Error) {…}

    map_total_allocation_size ¶

    map_total_allocation_size :: proc "contextless" (capacity: uintptr, info: ^Map_Info) -> uintptr {…}

    map_total_allocation_size_from_value ¶

    map_total_allocation_size_from_value :: proc "contextless" (m: $T/map[$T]$T) -> uintptr {…}

    map_upsert ¶

    map_upsert :: proc(m: ^$T/map[$T]$T, key: $T, value: $T, loc := #caller_location) -> (prev_key: $T, value_ptr: ^$T, found_previous: bool) {…}
     

    Explicitly inserts a key and value into a map m, the same as map_insert, but the return values differ. prev_key will return the previous pointer of a key if it exists, check found_previous if was previously found value_ptr will return the pointer of the memory where the insertion happens, and nil if the map failed to resize found_previous will be true a previous key was found

    matrix_bounds_check_error ¶

    matrix_bounds_check_error :: proc "contextless" (
    	file:                               string, 
    	line, column:                       i32, 
    	row_index, column_index, row_count, 
    	column_count:                       int, 
    ) {…}

    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, alignment: 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 {…}

    memset ¶

    memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {…}

    modti3 ¶

    modti3 :: proc "c" (a, b: i128) -> i128 {…}

    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) {…}

    non_zero_append_elem ¶

    non_zero_append_elem :: proc(array: ^$T/[dynamic]$T, #no_broadcast arg: $T, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

    non_zero_append_elem_string ¶

    non_zero_append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $S/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

    non_zero_append_elems ¶

    non_zero_append_elems :: proc(array: ^$T/[dynamic]$T, .. #no_broadcast args: ..$T, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_ok {…}

    non_zero_mem_resize ¶

    non_zero_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) {…}

    non_zero_reserve_dynamic_array ¶

    non_zero_reserve_dynamic_array :: proc(array: ^$T/[dynamic]$T, capacity: int, loc := #caller_location) -> Allocator_Error {…}

    non_zero_resize_dynamic_array ¶

    non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$T, length: int, loc := #caller_location) -> 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.

    ordered_remove_soa ¶

    ordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$T, index: int, loc := #caller_location) {…}
     

    ordered_remove_soa 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_soa. Note: If the index is out of bounds, this procedure will panic.

    panic ¶

    panic :: proc(message: string, loc := #caller_location) -> ! {…}

    panic_allocator ¶

    panic_allocator :: proc() -> Allocator {…}

    panic_allocator_proc ¶

    panic_allocator_proc :: proc(
    	allocator_data:  rawptr, 
    	mode:            Allocator_Mode, 
    	size, alignment: int, 
    	old_memory:      rawptr, 
    	old_size:        int, 
    	loc := #caller_location, 
    ) -> ([]u8, Allocator_Error) {…}

    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 has 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 "contextless" (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 "contextless" (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 :: proc "contextless" (arg: any) {…}
    print_byte :: proc "contextless" (b: u8) -> (n: int) {…}
    print_caller_location :: proc "contextless" (loc: Source_Code_Location) {…}
    print_encoded_rune :: proc "contextless" (r: rune) {…}
    print_i64 :: proc "contextless" (x: i64) {…}
    print_int :: proc "contextless" (x: int) {…}
    print_rune :: proc "contextless" (r: rune) -> int {…}
    print_string :: proc "contextless" (str: string) -> (n: int) {…}
    print_strings :: proc "contextless" (.. args: ..string) -> (n: int) {…}
    print_type :: proc "contextless" (ti: ^Type_Info) {…}
    print_typeid :: proc "contextless" (id: typeid) {…}
    print_u64 :: proc "contextless" (x: u64) {…}
    print_uint :: proc "contextless" (x: uint) {…}
    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 :: proc(array: ^$T/#soa[dynamic]$T) -> (footer: ^Raw_SOA_Footer_Dynamic_Array) {…}
    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_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) -> Allocator_Error {…}

    resize_dynamic_array ¶

    resize_dynamic_array :: proc(array: ^$T/[dynamic]$T, length: int, loc := #caller_location) -> Allocator_Error {…}

    resize_soa ¶

    resize_soa :: proc(array: ^$T/#soa[dynamic]$T, length: int, loc := #caller_location) -> Allocator_Error {…}

    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" (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" (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, 
    ) -> ! {…}

    stderr_write ¶

    stderr_write :: proc "contextless" (data: []u8) -> (int, _OS_Errno) {…}

    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) -> f16 {…}

    truncsfhf2 ¶

    truncsfhf2 :: proc "c" (value: f32) -> f16 {…}

    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 ¶

    type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {…}

    type_info_base_without_enum ¶

    type_info_base_without_enum :: type_info_core

    type_info_core ¶

    type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {…}

    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 {…}

    udivti3 ¶

    udivti3 :: proc "c" (a, b: u128) -> u128 {…}

    umodti3 ¶

    umodti3 :: proc "c" (a, b: 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.

    unordered_remove_soa ¶

    unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$T, index: int, loc := #caller_location) {…}
     

    unordered_remove_soa 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_soa. Note: If the index is out of bounds, this procedure will panic.

    Procedure Groups

    append ¶

     

    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

    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/string 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).

    delete ¶

     

    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.

    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.

    make ¶

     

    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.

    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 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

    Generation Information

    Generated with odin version dev-2024-04 (vendor "odin") Windows_amd64 @ 2024-04-23 21:09:29.928723900 +0000 UTC