[..] 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)

Macros (20)

Types (16)

Imports (4)

Constants

Float32Max

Float32Max :: #run max_of(float32);

3.40282e+38 (0h7f7fffff)

Float32Min

Float32Min :: #run min_of(float32);

1.17549e-38 (0h0080_0000)

Float64Max

Float64Max :: #run max_of(float64);

1.79769e+308 (0h7fefffff_ffffffff)

Float64Min

Float64Min :: #run min_of(float64);

2.22507e-308 (0h00100000_00000000)

Gigabyte

Gigabyte :: 1024 * Megabyte;

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.

Kilobyte

Kilobyte :: 1024;

Megabyte

Megabyte :: 1024 * Kilobyte;

MurmurSeed

MurmurSeed :: 2747864353;

PageSize

PageSize :: #run -> uint {

S16Max

S16Max :: #run max_of(s16);

32767 (0x7f_ff)

S16Min

S16Min :: #run min_of(s16);

-32768 (-0x8000)

S32Max

S32Max :: #run max_of(s32);

2147483647 (0x7fff_ffff)

S32Min

S32Min :: #run min_of(s32);

-2147483648 (-0x8000_0000)

S64Max

S64Max :: #run max_of(s64);

9223372036854775807 (0x7fffffff_ffffffff)

S64Min

S64Min :: #run min_of(s64);

-9223372036854775808 (-0x80000000_00000000)

S8Max

S8Max :: #run max_of(s8);

127 (0x7f)

S8Min

S8Min :: #run min_of(s8);

-128 (-0x80)

Terabyte

Terabyte :: 1024 * Gigabyte;

U16Max

U16Max :: #run max_of(u16);

65535 (0xff_ff)

U16Min

U16Min :: #run min_of(u16);

0 (0x00_00)

U32Max

U32Max :: #run max_of(u32);

4294967295 (0xffff_ffff)

U32Min

U32Min :: #run min_of(u32);

0 (0x0000_0000)

U64Max

U64Max :: #run max_of(u64);

18446744073709551615 (0xffffffff_ffffffff)

U64Min

U64Min :: #run min_of(u64);

0 (0x00000000_00000000)

U8Max

U8Max :: #run max_of(u8);

255 (0xff)

U8Min

U8Min :: #run min_of(u8);

0 (0x00)

XXHashSeed

XXHashSeed :: 0;

Procedures

AlignBackward

AlignBackward :: (a: int, align: int = DefaultAlign) -> int

AlignForward

AlignForward :: (a: int, align: int = DefaultAlign) -> int

Aligned

Aligned :: (a: int, align: int = DefaultAlign) -> bool

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)

ArenaSave

ArenaSave :: (loc := #caller_location) -> ArenaSaveResult

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.

BumpArena

BumpArena :: (bump: *BumpData) -> Arena

MapGet

MapGet :: (r: *Map, key: r.Key) -> r.Value, bool

MapHas

MapHas :: (r: *Map, key: r.Key) -> bool

MapRemove

MapRemove :: (r: *Map, key: r.Key) -> bool, r.Value

MapReset

MapReset :: (t: *Map)

MapSet

MapSet :: (r: *Map, key: r.Key, value: r.Value)

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.

Murmur32

Murmur32 :: (x: $T, seed: u32 = MurmurSeed) -> u32

Murmur32

Murmur32 :: (key: *void, len: int, seed: u32 = MurmurSeed) -> u32

Murmur32

Murmur32 :: (s: string, seed: u32 = MurmurSeed) -> u32

NextPowerOfTwo

NextPowerOfTwo :: (x: int) -> int

PagingArena

PagingArena :: () -> Arena

PanicArena

PanicArena :: () -> Arena

PanicArena is an Arena that panics when used.

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)

TypeTagIs

TypeTagIs :: ($$T: Type, tag: Type_Info_Tag) -> (bool, *Type_Info)

XXHash64

XXHash64 :: (s: string, seed: u32 = XXHashSeed) -> u64

XXHash64

XXHash64 :: (x: $T, seed: u32 = XXHashSeed) -> u64

XXHash64

XXHash64 :: (key: *void, len: int, seed: u64 = XXHashSeed) -> u64

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.

Trap

Trap :: () #expand

Trap causes an execution trap.

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.

align_of

align_of :: ($T: Type) -> int #expand

align_of returns the alignment of type T.

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.

zero_of

zero_of :: ($T: Type) -> T #expand

zero_of returns a value of type T that has been zero-initialized.
Note: zero_of will not call the initializer for aggregate types, so you may want default_of instead.

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

ArenaProc

ArenaProc :: #type (

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

BumpData

BumpData :: struct {
   memory: []u8;
   offset: int;
}

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.

b8

b8 :: enum u8  { false_ :: (0 != 0).(u8);  true_ :: (0 == 0).(u8);  };

b8 is an 8-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);

uint

uint :: u64;