[..] Module – jc
Module jc contains procedures for working with memory, arrays, and strings; as well as helpful macros and constants. Additionally, it provides a platform-independant interface for interacting with the target operating system.
#import "jc";
Index
Constants (29)
Procedures (55)
- AlignBackward
- AlignForward
- Aligned
- ArenaPush
- ArenaPushSize
- ArenaRelease
- ArenaReset
- ArenaRestore
- ArenaSave
- ArenaToAllocator
- ArrayAppend
- ArrayClear
- ArrayContains
- ArrayEquals
- ArrayFind
- ArrayGrow
- ArrayReset
- ArraySlice
- ArrayTrim
- BumpArena
- MapGet
- MapHas
- MapRemove
- MapReset
- MapSet
- MemAcquirePage
- MemAlignBackward
- MemAlignForward
- MemAligned
- MemCopy
- MemEqual
- MemOverwrite
- MemReleasePage
- MemReset
- MemZero
- MemZero
- Murmur32
- Murmur32
- Murmur32
- NextPowerOfTwo
- PagingArena
- PanicArena
- PowerOfTwo
- Test
- TypeIsArray
- TypeIsEnum
- TypeIsFloat
- TypeIsInteger
- TypeIsPointer
- TypeIsScalar
- TypeIsStruct
- TypeTagIs
- XXHash64
- XXHash64
- XXHash64
Macros (20)
Types (16)
Imports (4)
Constants
JcMajor ¶
JcMajor :: 0;
JcMajor is the current major version of this library. Major versions are guaranteed to have stable apis for their duration.
JcMinor ¶
JcMinor :: 1;
JcMinor is the current minor version of this library. Minor versions denote bug fixes, additions, or improvements that do not affect api stability.
MurmurSeed ¶
MurmurSeed :: 2747864353;
XXHashSeed ¶
XXHashSeed :: 0;
Procedures
AlignBackward ¶
AlignBackward :: (a: int, align: int = DefaultAlign) -> int
AlignForward ¶
AlignForward :: (a: int, align: int = DefaultAlign) -> int
ArenaPush ¶
ArenaPush :: ($T: Type, loc := #caller_location) -> *T
ArenaPush pushes a value of type T to the current context.arena.
ArenaPushSize ¶
ArenaPushSize :: (size: int, align := DefaultAlign, loc := #caller_location) -> *void
ArenaPushSize pushes size bytes to the current context.arena.
ArenaRelease ¶
ArenaRelease :: (loc := #caller_location)
ArenaRelease frees the current context.arena's memory.
ArenaReset ¶
ArenaReset :: (loc := #caller_location)
ArenaReset resets arena's state, allowing its memory to be reused.
ArenaRestore ¶
ArenaRestore :: (savepoint: ArenaSaveResult, loc := #caller_location)
ArenaToAllocator ¶
ArenaToAllocator :: (arena: *Arena) -> Allocator
ArenaToAllocator wraps the given arena, allowing it to be used with Jai's builtin Allocator system.
ArrayAppend ¶
ArrayAppend :: (arr: *[..]$T, values: ..T) -> *T
ArrayAppend pushes values to the end of an array, resizing if necessary.
A pointer to the first value appended will be returned.
Note: If no allocator has been set, ArrayAppend will use the current context allocator.
Note: Calls to Append may invalidate pre-existing pointers.
ArrayClear ¶
ArrayClear :: (arr: *[]$T)
ArrayClear zeroes an array's memory and sets its length to 0.
Note: To leave the associated memory intact, see ArrayReset.
ArrayContains ¶
ArrayContains :: (view: []$T, value: T) -> bool
ArrayContains checks if the given value exists in an array.
ArrayEquals ¶
ArrayEquals :: (lhs: []$T, rhs: []T) -> bool
ArrayEquals checks equality between two arrays.
ArrayFind ¶
ArrayFind :: (view: []$T, value: T, $flags: ArrayFindFlags = 0) -> (bool, ArrayIndex(T))
ArrayFind searches through an array, returning the first element that matches the given value.
ArrayGrow ¶
ArrayGrow :: (arr: *[..]$T, new_count: int)
ArrayGrow resizes the memory associated with an array to hold new_count values.
Note: If the array has enough allocated memory to accomodate new_count, ArrayGrow does nothing.
Note: ArrayGrow does not guarantee pointer stability.
ArrayReset ¶
ArrayReset :: (arr: *[]$T)
ArrayReset sets an array's length to 0, but leaves its memory intact.
Note: To reset the associated memory as well, see ArrayClear.
ArraySlice ¶
ArraySlice :: (arr: []$T, start_idx: int, count := -1, loc := #caller_location) -> []T
ArraySlice returns a subsection of an array.
ArrayTrim ¶
ArrayTrim :: (view: []$T, cutset: []T, $flags: ArrayTrimFlags = .FromStart) -> []T
ArrayTrim returns a subsection of an array with all leading/trailing values from cutset removed.
MemAcquirePage ¶
MemAcquirePage :: (flags: MemAcquirePageFlags = 0, previous: *void = null) -> *void
MemAlignBackward ¶
MemAlignBackward :: (p: *void, align: int = DefaultAlign) -> *void
MemAlignForward ¶
MemAlignForward :: (p: *void, align: int = DefaultAlign) -> *void
MemAligned ¶
MemAligned :: (p: *void, align: int = DefaultAlign) -> bool
MemCopy ¶
MemCopy :: (dst: *void, src: *void, size_in_bytes: int)
MemCopy copies the memory of src to dst.
Note: MemCopy will panic if size_in_bytes is negative.
MemEqual ¶
MemEqual :: (p1: *void, p2: *void, size_in_bytes: int) -> bool
MemEqual checks the equality of two pieces of memory.
Note: MemEqual will panic if size_in_bytes is negative.
MemOverwrite ¶
MemOverwrite :: (p: *void, size_in_bytes: int, value: u8 = 0)
MemOverwrite overwites the memory of p with value.
Note: MemOverwrite will panic if size_in_bytes is negative.
MemReleasePage ¶
MemReleasePage :: (page: *void, size: int)
MemReset ¶
MemReset :: (p: *$T)
MemReset resets the memory of p, as if it was just instantiated.
Note: MemReset will call the initializer for aggregate types, so you
may want MemZero instead.
MemZero ¶
MemZero :: (p: *$T)
MemZero zeroes the memory of p.
Note: MemZero will not call the initializer for aggregate types,
so you may want MemReset instead.
MemZero ¶
MemZero :: (p: *void, size_in_bytes: int)
MemZero zeroes the memory of p.
Note: MemZero will panic if size_in_bytes is negative.
NextPowerOfTwo ¶
NextPowerOfTwo :: (x: int) -> int
PagingArena ¶
PagingArena :: () -> Arena
PowerOfTwo ¶
PowerOfTwo :: (x: int) -> bool
Test ¶
Test :: (name: string, proc: (t: *void) -> (), loc := #caller_location)
Test defines a new suite to be executed by the test runner.
See: Expect for more information.
Example
Test("my_proc does what it should", t => {
value1 := my_proc(/* ... */);
Expect(value1 != 0, "my_proc returned zero!");
value2 := my_proc(/* .... */);
Expect(value2 > 0, "my_proc returned a negative number!");
});
TypeIsArray ¶
TypeIsArray :: ($$T: Type) -> (bool, *Type_Info_Array)
TypeIsEnum ¶
TypeIsEnum :: ($$T: Type) -> (bool, *Type_Info_Enum)
TypeIsFloat ¶
TypeIsFloat :: ($$T: Type) -> (bool, *Type_Info_Float)
TypeIsInteger ¶
TypeIsInteger :: ($$T: Type) -> (bool, *Type_Info_Integer)
TypeIsPointer ¶
TypeIsPointer :: ($$T: Type) -> (bool, *Type_Info_Pointer)
TypeIsScalar ¶
TypeIsScalar :: ($$T: Type) -> bool
TypeIsStruct ¶
TypeIsStruct :: ($$T: Type) -> (bool, *Type_Info_Struct)
Macros
ArenaAutoRestore ¶
ArenaAutoRestore :: () #expand
Assert ¶
Assert :: (cond: bool, message := "jc: condition was false", loc := #caller_location) #expand
Assert causes a debug break if the given condition is false.
AssertCallsite ¶
AssertCallsite :: (cond: bool, message := "jc: condition was false") #expand
AssertCallsite works identically to Assert, except that it expects a Source_Code_Location (called 'loc') to exist in the calling scope.
Example
MyProc :: (loc := #caller_location) {
AssertCallsite(false); // 'loc' is passed implicitly
Assert(false, loc = loc); // equivalent
}
CheckBounds ¶
CheckBounds :: ($$index: $T, $$count: T, loc := #caller_location) #expand
CompileError ¶
CompileError :: (message: string, loc := #caller_location) #expand #compile_time
CompileError displays the given message and stops compilation.
Note: By default, the error is reported at the callsite.
DebugTrap ¶
DebugTrap :: () #expand
DebugTrap causes an execution trap that grabs the attention of a debugger.
Expect ¶
Expect :: (cond: bool, message := "", args: ..Any, loc := #caller_location) #expand
Expect checks the given condition, failing the current test if it is false.
Note: Expect must be called within a test. Additionally, it expects the test
parameter to be called 't'.
Panic ¶
Panic :: (message := "jc: runtime panic", loc := #caller_location) #expand
Panic displays the given message and crashes the program.
Note: Defers will not run when Panic is called.
Unreachable ¶
Unreachable :: (message := "jc: unreachable code hit", loc := #caller_location) #expand
Unreachable displays the given message and causes an execution trap.
Note: Defers will not run when Unreachable is called.
default_of ¶
default_of :: ($T: Type) -> T #expand
default_of returns a value of type T as if it was just instantiated.
Note: default_of will call the initializer for aggregate types, so you
may want zero_of instead.
for_expansion ¶
for_expansion :: (r: *Map, body: Code, flags: For_Flags) #expand
max_of ¶
max_of :: ($T: Type, loc := #caller_location) -> T #expand
max_of returns the maximum value T can represent.
Note: T must be an integer, float, or enum type.
min_of ¶
min_of :: ($T: Type, loc := #caller_location) -> T #expand
min_of returns the minimum value T can represent.
Note: T must be an integer, float, or enum type.
offset_of ¶
offset_of :: (#discard value: $T, ident: Code, loc := #caller_location) -> int #expand
offset_of returns the byte offset of a field within the type of value.
Note: If offset_of is given a pointer value, it will use the type pointed to.
Example
value := struct{ x: int; y: int; z: int; }.{};
offset_of(value, #code y); // 8
offset_of ¶
offset_of :: ($T: Type, ident: Code, loc := #caller_location) -> int #expand
offset_of returns the byte offset of a field within the type T.
Note: T must be a struct type.
Example
MyType :: struct { x: int; y: int; z: int; };
offset_of(MyType, #code y); // 8
range_of ¶
range_of :: ($T: Type, loc := #caller_location) -> (T, T) #expand
range_of returns the minimum and maximum values T can represent.
Note: T must be an integer, float, or enum type.
undefined_of ¶
undefined_of :: ($T: Type) -> T #expand
undefined_of returns a value of type T that has not been initialized.
Types
Arena ¶
Arena :: struct {
proc: ArenaProc;
data: *void;
}Arena is an interface for an arena-based memory allocation.
ArenaEvent ¶
ArenaEvent :: enum {
Setup;
Teardown;
Acquire;
Reset;
Save;
Restore;
}ArenaSaveResult ¶
ArenaSaveResult :: #type,distinct *void;
ArenaSaveResult is an arena-specific value used for saving/restoring. see: ArenaSave
ArrayFindFlags ¶
ArrayFindFlags :: enum_flags {
Last; // Return the last matching element.
FromEnd; // Search in reverse.
}ArrayIndex ¶
ArrayIndex :: struct(T: Type) {
value: T = ---;
index: int;
}ArrayTrimFlags ¶
ArrayTrimFlags :: enum_flags {
FromStart; // ArrayTrim the start of the array.
FromEnd; // ArrayTrim the end of the array.
MatchInFull; // Only trim when the cutset matches exactly.
}Map ¶
Map :: struct(Key: Type, Value: Type) {
allocator: Allocator;
slots: [..]Slot;
free_slots: [..]int;
count: int;
Slot :: struct {
hash: u32 = InvalidHash;
key: Key = ---;
value: Value = ---;
}
HashProc :: Murmur32;
InvalidHash :: (0x8000_dead).(u32); // @note(judah): I'm curious what values would hit this hash on accident
AllocatedItemsAtStart :: 16;
}MemAcquirePageFlags ¶
MemAcquirePageFlags :: enum_flags {
CommitImmediately;
}b16 ¶
b16 :: enum u16 { false_ :: (0 != 0).(u16); true_ :: (0 == 0).(u16); };b16 is a 16-bit boolean.
b32 ¶
b32 :: enum u32 { false_ :: (0 != 0).(u32); true_ :: (0 == 0).(u32); };b32 is a 32-bit boolean.
b64 ¶
b64 :: enum u64 { false_ :: (0 != 0).(u64); true_ :: (0 == 0).(u64); };b64 is a 64-bit boolean.
m0 ¶
m0 :: #type void;
m0 is a 0-size marker type. It allows specific offsets within a type to be marked which is useful for (de)serialization.
Example
MyType :: struct {
do_not_serialize_1: *void;
_start: m0; // Has the same offset as serialize_1
serialize_1: [32]u8;
serialize_2: u64;
serialize_3: bool;
serialize_4: float32;
_end: m0; // Has the same offset as serialize_4
do_not_serialize_2: [..]int;
}
value := MyType.{};
start := *value + offset_of(value, #code _start);
end := *value + offset_of(value, #code _end);
WriteToDisk(data = start, count = end - start);