aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar gingerBill 2016-04-12 21:52:09 +0100
committerGravatar gingerBill 2016-04-12 21:52:09 +0100
commitdc5fe7638c42b59b8c07c0c0529a084bfd68b284 (patch)
tree6af26cc7462b44b5a853286973eaf79796e58ad4
parentNew gb.h!!!! (diff)
Update gb.h
-rw-r--r--gb.h912
1 files changed, 526 insertions, 386 deletions
diff --git a/gb.h b/gb.h
index ed16d80..9a51b0f 100644
--- a/gb.h
+++ b/gb.h
@@ -1,5 +1,5 @@
-/* gb.h - v0.02 - Ginger Bill's C Helper Library - public domain
- - no warranty implied; use at your own risk
+/* gb.h - v0.02a - Ginger Bill's C Helper Library - public domain
+ - no warranty implied; use at your own risk
This is a single header file with a bunch of useful stuff
to replace the C/C++ standard library
@@ -18,8 +18,16 @@
All other files should just #include "gb.h" without #define
===========================================================================
+Conventions used:
+ gbTypes_Are_Like_This (None core types)
+ gb_functions_and_variables_like_this
+ Prefer // Comments
+ Never use _t suffix for types
+ Private "things" will have prefix `gbpriv` (e.g. Things the user shouldn't be touch if they don't know what they are doing)
+
Version History:
+ 0.02a - Bug fixes
0.02 - Change naming convention and gbArray(Type)
0.01 - Initial Version
@@ -62,11 +70,30 @@ CREDITS
extern "C" {
#endif
+
+#ifndef GB_EXTERN
+ #if defined(__cplusplus)
+ #define GB_EXTERN extern "C"
+ #else
+ #define GB_EXTERN extern
+ #endif
+#endif
+
+#ifndef GB_DLL_EXPORT
+#define GB_DLL_EXPORT __declspec(dllexport)
+#endif
+
+#ifndef GB_DLL_IMPORT
+#define GB_DLL_IMPORT __declspec(dllimport)
+#endif
+
+
+// NOTE(bill): Redefine for DLL, etc.
#ifndef GB_DEF
#ifdef GB_STATIC
#define GB_DEF static
#else
- #define GB_DEF extern
+ #define GB_DEF GB_EXTERN
#endif
#endif
@@ -161,6 +188,11 @@ extern "C" {
typedef int64_t i64;
#endif
+GB_STATIC_ASSERT(sizeof(u8) == sizeof(i8));
+GB_STATIC_ASSERT(sizeof(u16) == sizeof(i16));
+GB_STATIC_ASSERT(sizeof(u32) == sizeof(i32));
+GB_STATIC_ASSERT(sizeof(u64) == sizeof(i64));
+
GB_STATIC_ASSERT(sizeof(u8) == 1);
GB_STATIC_ASSERT(sizeof(u16) == 2);
GB_STATIC_ASSERT(sizeof(u32) == 4);
@@ -177,6 +209,7 @@ typedef intptr_t intptr;
typedef float f32;
typedef double f64;
+
GB_STATIC_ASSERT(sizeof(f32) == 4);
GB_STATIC_ASSERT(sizeof(f64) == 8);
@@ -187,7 +220,7 @@ typedef u32 char32;
// NOTE(bill): I think C99 and C++ `bool` is stupid for numerous reasons but there are too many
// to write in this small comment.
typedef i32 b32; // NOTE(bill): Use this in structs if a boolean _is_ needed to be aligned well
-typedef i8 b8;
+typedef i8 b8; // TODO(bill): Do I really want a 8-bit boolean ever?
// NOTE(bill): Get true and false
#if !defined(__cplusplus)
@@ -206,18 +239,18 @@ typedef i8 b8;
#ifndef U8_MIN
#define U8_MIN 0u
#define U8_MAX 0xffu
-#define S8_MIN (-0x7f - 1)
-#define S8_MAX 0x7f
+#define I8_MIN (-0x7f - 1)
+#define I8_MAX 0x7f
#define U16_MIN 0u
#define U16_MAX 0xffffu
-#define S16_MIN (-0x7fff - 1)
-#define S16_MAX 0x7fff
+#define I16_MIN (-0x7fff - 1)
+#define I16_MAX 0x7fff
#define U32_MIN 0u
#define U32_MAX 0xffffffffu
-#define S32_MIN (-0x7fffffff - 1)
-#define S32_MAX 0x7fffffff
+#define I32_MIN (-0x7fffffff - 1)
+#define I32_MAX 0x7fffffff
#define U64_MIN 0ull
#define U64_MAX 0xffffffffffffffffull
@@ -240,6 +273,13 @@ typedef i8 b8;
#error Unknown architecture size
#endif
+#define F32_MIN 1.17549435e-38f
+#define F32_MAX 3.40282347e+38f
+
+#define F64_MIN 2.2250738585072014e-308
+#define F64_MAX 1.7976931348623157e+308
+
+
#endif
@@ -258,8 +298,9 @@ typedef i8 b8;
-#if !defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER <= 1800
- #define inline __inline
+#if !defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER <= 1800
+ #define inline __inline
+ #define restrict __restrict
#endif
@@ -279,16 +320,6 @@ typedef i8 b8;
#endif
#endif
-#ifndef GB_EXTERN
- #if defined(__cplusplus)
- #define GB_EXTERN extern "C"
- #else
- #define GB_EXTERN extern
- #endif
-#endif
-
-
-
// NOTE(bill): Easy to grep
// NOTE(bill): Not needed in macros
#ifndef cast
@@ -296,40 +327,47 @@ typedef i8 b8;
#endif
+// NOTE(bill): Because a signed sizeof is more useful
#ifndef gb_size_of
-#define gb_size_of(x) cast(i64)(sizeof(x))
+#define gb_size_of(x) (isize)(sizeof(x))
#endif
#ifndef gb_count_of
-#define gb_count_of(x) ((gb_size_of(x)/gb_size_of(0[x])) / ((usize)(!(gb_size_of(x) % gb_size_of(0[x])))))
+#define gb_count_of(x) ((gb_size_of(x)/gb_size_of(0[x])) / ((isize)(!(gb_size_of(x) % gb_size_of(0[x])))))
#endif
#ifndef gb_offset_of
-#define gb_offset_of(Type, element) ((usize)&(((Type *)0)->element))
+#define gb_offset_of(Type, element) ((isize)&(((Type *)0)->element))
#endif
#if defined(__cplusplus)
extern "C++" {
- #ifndef gb_align_of
- template <typename T> struct gb_Alignment_Trick { char c; T member; };
- #define gb_align_of(Type) offset_of(gb_Alignment_Trick<Type>, member)
+#ifndef gb_align_of
+ #if __cplusplus >= 201103L
+ #define gb_align_of(Type) (isize)alignof(Type)
+ #else
+ // NOTE(bill): Fucking Templates!
+ template <typename T> struct gbAlignment_Trick { char c; T member; };
+ #define gb_align_of(Type) gb_offset_of(gbAlignment_Trick<Type>, member)
#endif
+#endif
}
#else
#ifndef gb_align_of
- #define gb_align_of(Type) offs(struct { char c; Type member; }, member)
+ #define gb_align_of(Type) gb_offset_of(struct { char c; Type member; }, member)
#endif
#endif
+// NOTE(bill): I do which I had a type_of that was portable
#ifndef gb_swap
#define gb_swap(Type, a, b) do { Type tmp = (a); (a) = (b); (b) = tmp; } while (0)
#endif
// NOTE(bill): Because static means 3/4 different things in C/C++. Great design (!)
#ifndef gb_global
-#define gb_global static
-#define gb_internal static
-#define gb_local_persist static
+#define gb_global static // Global variables
+#define gb_internal static // Internal linkage
+#define gb_local_persist static // Local Persisting variables
#endif
@@ -340,12 +378,14 @@ extern "C++" {
+
+
////////////////////////////////////////////////////////////////
//
// Defer statement
-// - Akin to D's SCOPE_EXIT or similar to Go's defer but scope-based
+// Akin to D's SCOPE_EXIT or
+// similar to Go's defer but scope-based
//
-////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C++" {
// NOTE(bill): Stupid fucking templates
@@ -354,16 +394,17 @@ extern "C++" {
template <typename T> struct gbRemove_Reference<T &&> { typedef T Type; };
// NOTE(bill): "Move" semantics - invented because the C++ committee are idiots (as a collective not as indiviuals (well a least some aren't))
- template <typename T> gb_inline T &&gb_forward_ownership(typename gbRemove_Reference<T>::Type &t) { return static_cast<T &&>(t); }
- template <typename T> gb_inline T &&gb_forward_ownership(typename gbRemove_Reference<T>::Type &&t) { return static_cast<T &&>(t); }
+ template <typename T> inline T &&gb_forward_ownership(typename gbRemove_Reference<T>::Type &t) { return static_cast<T &&>(t); }
+ template <typename T> inline T &&gb_forward_ownership(typename gbRemove_Reference<T>::Type &&t) { return static_cast<T &&>(t); }
+ template <typename T> inline T &&gb_move_ownership(T &&t) { return static<typename gbRemove_Reference<T>::Type &&>(t); }
template <typename F>
- struct gbImpl_Defer {
+ struct gbprivDefer {
F f;
- gbImpl_Defer(F &&f) : f(gb_forward_ownership<F>(f)) {}
- ~gbImpl_Defer() { f(); }
+ gbprivDefer(F &&f) : f(gb_forward_ownership<F>(f)) {}
+ ~gbprivDefer() { f(); }
};
- template <typename F> gbImpl_Defer<F> gb_defer_func(F &&f) { return gbImpl_Defer<F>(gb_forward_ownership<F>(f)); }
+ template <typename F> gbprivDefer<F> gb_defer_func(F &&f) { return gbprivDefer<F>(gb_forward_ownership<F>(f)); }
#ifndef defer
#define GB_DEFER_1(x, y) x##y
@@ -375,6 +416,22 @@ extern "C++" {
#endif
+////////////////////////////////
+//
+// Macro Fun!
+//
+//
+
+#ifndef GB_JOIN_MACROS
+#define GB_JOIN_MACROS
+ #define GB_JOIN2_IND(a, b) a##b
+ #define GB_JOIN3_IND(a, b, c) a##b##c
+
+ #define GB_JOIN2(a, b) GB_JOIN2_IND(a, b)
+ #define GB_JOIN3(a, b, c) GB_JOIN3_IND(a, b, c)
+#endif
+
+
#ifndef gb_min
@@ -389,10 +446,10 @@ extern "C++" {
////////////////////////////////
-// //
-// Debug //
-// //
-////////////////////////////////
+//
+// Debug
+//
+//
#ifndef GB_DEBUG_TRAP
@@ -407,7 +464,7 @@ extern "C++" {
#ifndef GB_ASSERT_MSG
#define GB_ASSERT_MSG(cond, msg, ...) do { \
if (!(cond)) { \
- gb_assert_handler(#cond, __FILE__, (long long)__LINE__, msg, ##__VA_ARGS__); \
+ gb_assert_handler(#cond, __FILE__, cast(i64)__LINE__, msg, ##__VA_ARGS__); \
GB_DEBUG_TRAP(); \
} \
} while (0)
@@ -421,32 +478,42 @@ extern "C++" {
#define GB_PANIC(msg, ...) GB_ASSERT_MSG(0, msg, ##__VA_ARGS__)
#endif
-GB_DEF void gb_assert_handler(char const *condition,
- char const *file, long long line,
- char const *msg, ...);
+GB_DEF void gb_assert_handler(char const *condition, char const *file, i64 line, char const *msg, ...);
////////////////////////////////
-// //
-// Printing //
-// //
-////////////////////////////////
+//
+// Printing
+//
+//
-GB_DEF int gb_sprintf(char const *fmt, ...);
-GB_DEF int gb_snprintf(char *str, usize n, char const *fmt, ...);
-GB_DEF int gb_vsprintf(char const *fmt, va_list v);
-GB_DEF int gb_vsnprintf(char *str, usize n, char const *fmt, va_list v);
+// Some compilers support applying printf-style warnings to user functions.
+#if defined(__clang__) || defined(__GNUC__)
+#define GB_PRINTF_ARGS(FMT) __attribute__((format(printf, FMT, (FMT+1))))
+#else
+#define GB_PRINTF_ARGS(FMT)
+#endif
+GB_DEF int gb_printf(char const *fmt, ...) GB_PRINTF_ARGS(1);
+GB_DEF int gb_printf_var(char const *fmt, va_list v);
+GB_DEF int gb_fprintf(FILE *f, char const *fmt, ...) GB_PRINTF_ARGS(2);
+GB_DEF int gb_fprintf_var(FILE *f, char const *fmt, va_list v);
+GB_DEF int gb_sprintf(char const *fmt, ...) GB_PRINTF_ARGS(1);
+GB_DEF int gb_sprintf_var(char const *fmt, va_list v);
+GB_DEF int gb_snprintf(char *str, isize n, char const *fmt, ...) GB_PRINTF_ARGS(3);
+GB_DEF int gb_snprintf_var(char *str, isize n, char const *fmt, va_list v);
-////////////////////////////////
-// //
-// Memory //
-// //
-////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////
+//
+// Memory
+//
+//
#ifndef gb_align_to
#define gb_align_to(value, alignment) (((value) + ((alignment)-1)) & ~((alignment) - 1))
@@ -456,17 +523,18 @@ GB_DEF int gb_vsnprintf(char *str, usize n, char const *fmt, va_list v);
#define gb_is_power_of_two(x) ((x) != 0) && !((x) & ((x)-1))
#endif
-GB_DEF void *gb_align_forward(void *ptr, usize alignment);
+GB_DEF void *gb_align_forward(void *ptr, isize alignment);
-GB_DEF void gb_zero_size(void *ptr, usize size);
+GB_DEF void gb_zero_size(void *ptr, isize size);
#ifndef gb_zero_struct
#define gb_zero_struct(t) gb_zero_size((t), gb_size_of(*(t))) // NOTE(bill): Pass pointer of struct
#define gb_zero_array(a, count) gb_zero_size((a), gb_size_of((a)[0])*count)
#endif
-GB_DEF void *gb_memcpy(void *dest, void const *source, usize size);
-GB_DEF void *gb_memmove(void *dest, void const *source, usize size);
+GB_DEF void *gb_memcpy(void *dest, void const *source, isize size);
+GB_DEF void *gb_memmove(void *dest, void const *source, isize size);
+GB_DEF void *gb_memset(void *data, u8 byte_value, isize size);
@@ -478,23 +546,26 @@ GB_DEF void *gb_memmove(void *dest, void const *source, usize size);
#endif
+#if 0
+// NOTE(bill): Is it possible in C (easily) to create a mutex where the zero value is
+// an unlocked mutex be default and also does not require make/destroy ever?
// Mutex
typedef struct gbMutex { void *handle; } gbMutex;
-GB_DEF gbMutex gb_make_mutex(void);
-GB_DEF void gb_destroy_mutex(gbMutex *m);
-GB_DEF void gb_lock_mutex(gbMutex *m);
-GB_DEF void gb_try_lock_mutex(gbMutex *m);
-GB_DEF void gb_unlock_mutex(gbMutex *m);
-
+GB_DEF gbMutex gb_mutex_make(void);
+GB_DEF void gb_mutex_destroy(gbMutex *m);
+GB_DEF void gb_mutex_lock(gbMutex *m);
+GB_DEF void gb_mutex_try_lock(gbMutex *m);
+GB_DEF void gb_mutex_unlock(gbMutex *m);
+#endif
-////////////////////////////////
-// //
-// Custom Allocation //
-// //
-////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Custom Allocation
+//
+//
typedef enum gbAllocation_Type {
GB_ALLOCATION_TYPE_ALLOC,
@@ -506,10 +577,10 @@ typedef enum gbAllocation_Type {
// NOTE(bill): This is useful so you can define an allocator of the same type and parameters
#define GB_ALLOCATOR_PROC(name) \
void *name(void *allocator_data, gbAllocation_Type type, \
- usize size, usize alignment, \
- void *old_memory, usize old_size, \
- u32 options)
-typedef GB_ALLOCATOR_PROC(gbAllocator_Proc);
+ isize size, isize alignment, \
+ void *old_memory, isize old_size, \
+ u64 options)
+;typedef GB_ALLOCATOR_PROC(gbAllocator_Proc);
typedef struct gbAllocator {
gbAllocator_Proc *proc;
@@ -520,17 +591,17 @@ typedef struct gbAllocator {
#define GB_DEFAULT_MEMORY_ALIGNMENT 4
#endif
-GB_DEF void *gb_alloc_align(gbAllocator a, usize size, usize alignment);
-GB_DEF void *gb_alloc(gbAllocator a, usize size);
+GB_DEF void *gb_alloc_align(gbAllocator a, isize size, isize alignment);
+GB_DEF void *gb_alloc(gbAllocator a, isize size);
GB_DEF void gb_free(gbAllocator a, void *ptr);
GB_DEF void gb_free_all(gbAllocator a);
-GB_DEF void *gb_resize(gbAllocator a, void *ptr, usize old_size, usize new_size);
-GB_DEF void *gb_resize_align(gbAllocator a, void *ptr, usize old_size, usize new_size, usize alignment);
+GB_DEF void *gb_resize(gbAllocator a, void *ptr, isize old_size, isize new_size);
+GB_DEF void *gb_resize_align(gbAllocator a, void *ptr, isize old_size, isize new_size, isize alignment);
-GB_DEF void *gb_alloc_copy(gbAllocator a, void const *src, usize size);
-GB_DEF void *gb_alloc_align_copy(gbAllocator a, void const *src, usize size, usize alignment);
+GB_DEF void *gb_alloc_copy(gbAllocator a, void const *src, isize size);
+GB_DEF void *gb_alloc_copy_align(gbAllocator a, void const *src, isize size, isize alignment);
-GB_DEF char *gb_alloc_cstring(gbAllocator a, char const *str, usize len);
+GB_DEF char *gb_alloc_cstring(gbAllocator a, char const *str);
// NOTE(bill): These are very useful and the type case has saved me from numerous bugs
@@ -557,19 +628,18 @@ GB_DEF GB_ALLOCATOR_PROC(gb_malloc_allocator_proc);
typedef struct gbArena {
gbAllocator backing;
void *physical_start;
- usize total_size;
- usize total_allocated;
+ isize total_size;
+ isize total_allocated;
u32 temp_count;
- b32 clear_allocations_to_zero;
} gbArena;
-GB_DEF void gb_arena_init_from_memory(gbArena *arena, void *start, usize size);
-GB_DEF void gb_arena_init_from_allocator(gbArena *arena, gbAllocator backing, usize size);
-GB_DEF void gb_arena_init_subarena(gbArena *arena, gbArena *parent_arena, usize size);
+GB_DEF void gb_arena_init_from_memory(gbArena *arena, void *start, isize size);
+GB_DEF void gb_arena_init_from_allocator(gbArena *arena, gbAllocator backing, isize size);
+GB_DEF void gb_arena_init_subarena(gbArena *arena, gbArena *parent_arena, isize size);
GB_DEF void gb_arena_free(gbArena *arena);
-GB_DEF usize gb_arena_alignment_of(gbArena *arena, usize alignment);
-GB_DEF usize gb_arena_size_remaining(gbArena *arena, usize alignment);
+GB_DEF isize gb_arena_alignment_of(gbArena *arena, isize alignment);
+GB_DEF isize gb_arena_size_remaining(gbArena *arena, isize alignment);
GB_DEF void gb_arena_check(gbArena *arena);
@@ -580,11 +650,11 @@ GB_DEF GB_ALLOCATOR_PROC(gb_arena_allocator_proc);
typedef struct gbTemp_Arena_Memory {
gbArena *arena;
- usize original_count;
+ isize original_count;
} gbTemp_Arena_Memory;
-GB_DEF gbTemp_Arena_Memory gb_begin_temp_arena_memory(gbArena *arena);
-GB_DEF void gb_end_temp_arena_memory(gbTemp_Arena_Memory tmp_mem);
+GB_DEF gbTemp_Arena_Memory gb_temp_arena_memory_begin(gbArena *arena);
+GB_DEF void gb_temp_arena_memory_end(gbTemp_Arena_Memory tmp_mem);
@@ -600,13 +670,13 @@ typedef struct gbPool {
void *physical_start;
void *free_list;
- usize block_size;
- usize block_align;
- usize total_size;
+ isize block_size;
+ isize block_align;
+ isize total_size;
} gbPool;
-GB_DEF void gb_pool_init(gbPool *pool, gbAllocator backing, usize num_blocks, usize block_size);
-GB_DEF void gb_pool_init_align(gbPool *pool, gbAllocator backing, usize num_blocks, usize block_size, usize block_align);
+GB_DEF void gb_pool_init(gbPool *pool, gbAllocator backing, isize num_blocks, isize block_size);
+GB_DEF void gb_pool_init_align(gbPool *pool, gbAllocator backing, isize num_blocks, isize block_size, isize block_align);
GB_DEF void gb_pool_free(gbPool *pool);
@@ -614,11 +684,11 @@ GB_DEF gbAllocator gb_pool_allocator(gbPool *pool);
GB_DEF GB_ALLOCATOR_PROC(gb_pool_allocator_proc);
-////////////////////////////////////////
-// //
-// Char Functions //
-// //
-////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Char Functions
+//
+//
GB_DEF char gb_char_to_lower(char c);
GB_DEF char gb_char_to_upper(char c);
@@ -634,71 +704,65 @@ GB_DEF b32 gb_char_is_alphanumeric(char c);
GB_DEF void gb_to_lower(char *str);
GB_DEF void gb_to_upper(char *str);
-GB_DEF usize gb_strlen(char const *str);
-GB_DEF char *gb_strncpy(char *dest, char const *source, usize len);
-GB_DEF int gb_strncmp(char const *s1, char const *s2, usize len);
+GB_DEF isize gb_strlen(char const *str);
+GB_DEF char *gb_strncpy(char *dest, char const *source, isize len);
+GB_DEF int gb_strncmp(char const *s1, char const *s2, isize len);
-////////////////////////////////////////
-// //
-// Windows UTF-8 Handling //
-// //
-////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Windows UTF-8 Handling
+//
+//
// Windows doesn't handle 8 bit filenames well ('cause Micro$hit)
-GB_DEF char16 *gb_from_utf8(char16 *buffer, char *str, usize len);
-GB_DEF char *gb_to_utf8(char *buffer, char16 *str, usize len);
+GB_DEF char16 *gb_from_utf8(char16 *buffer, char *str, isize len);
+GB_DEF char *gb_to_utf8(char *buffer, char16 *str, isize len);
-////////////////////////////////////////
-// //
-// gbString - C Read-Only-Compatible //
-// //
-////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// gbString - C Read-Only-Compatible
+//
+//
// Pascal like strings in C
typedef char *gbString;
-#ifndef GB_STRING_SIZE
-#define GB_STRING_SIZE
-typedef u32 gbString_Size;
-#endif
-
// This is stored at the beginning of the string
-// NOTE(bill): It is (2*gb_size_of(gbString_Size) + 2*gb_size_of(void*)) (default: 16B (32bit), 24B (64bit))
-// NOTE(bill): If you only need a small string, just use a standard c string
+// NOTE(bill): If you only need a small string, just use a standard c string or change the size
typedef struct gbString_Header {
- gbAllocator allocator;
- gbString_Size length;
- gbString_Size capacity;
+ gbAllocator allocator;
+ isize length;
+ isize capacity;
} gbString_Header;
-#define GB_STRING_HEADER(str) (cast(gbString_Header *)str - 1)
+#define GB_STRING_HEADER(str) ((gbString_Header *)str - 1)
GB_DEF gbString gb_string_make(gbAllocator a, char const *str);
-GB_DEF gbString gb_string_make_length(gbAllocator a, void const *str, gbString_Size num_bytes);
+GB_DEF gbString gb_string_make_length(gbAllocator a, void const *str, isize num_bytes);
GB_DEF void gb_string_free(gbString str);
GB_DEF gbString gb_string_duplicate(gbAllocator a, gbString const str);
-GB_DEF gbString_Size gb_string_length(gbString const str);
-GB_DEF gbString_Size gb_string_capacity(gbString const str);
-GB_DEF gbString_Size gb_string_available_space(gbString const str);
+GB_DEF isize gb_string_length(gbString const str);
+GB_DEF isize gb_string_capacity(gbString const str);
+GB_DEF isize gb_string_available_space(gbString const str);
GB_DEF void gb_string_clear(gbString str);
GB_DEF gbString gb_string_append_string(gbString str, gbString const other);
-GB_DEF gbString gb_string_append_string_length(gbString str, void const *other, gbString_Size num_bytes);
+GB_DEF gbString gb_string_append_string_length(gbString str, void const *other, isize num_bytes);
GB_DEF gbString gb_string_append_cstring(gbString str, char const *other);
GB_DEF gbString gb_string_set(gbString str, char const *cstr);
-GB_DEF gbString gb_string_make_space_for(gbString str, gbString_Size add_len);
-GB_DEF gbString_Size gb_string_allocation_size(gbString const str);
+GB_DEF gbString gb_string_make_space_for(gbString str, isize add_len);
+GB_DEF isize gb_string_allocation_size(gbString const str);
GB_DEF b32 gb_strings_are_equal(gbString const lhs, gbString const rhs);
@@ -708,59 +772,56 @@ GB_DEF gbString gb_string_trim_space(gbString str); /* Whitespace ` \t\r\n\v\f`
-////////////////////////////////
-// //
-// //
-// //
-// Dynamic Array (POD Types) //
-// //
-// //
-// //
-////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//
+// Dynamic Array (POD Types)
+//
+//
// NOTE(bill): I know this is a macro hell but C is an old (and shit) language with no proper arrays
-// Also why the fuck not?! It fucking works!
+// Also why the fuck not?! It fucking works! And it has custom allocation, which is already better than C++!
-// NOTE(bill): Typedef every array
-// e.g. typedef gbArray(int) gb_int_array;
-#ifndef gbArray
+// NOTE(bill): Typedef every array or you get anonymous structures everywhere!
+// e.g. typedef gbArray(int) gb_Int_Array;
+#ifndef GB_ARRAY_TYPE
+#define GB_ARRAY_TYPE
#define gbArray(Type) struct { \
gbAllocator allocator; \
- i64 count; \
- i64 capacity; \
- Type *e; \
+ isize count; \
+ isize capacity; \
+ Type *data; \
}
typedef gbArray(void) gbVoid_Array; // NOTE(bill): Used to generic stuff
-/* Available Procedures for gbArray(Type)
- gb_array_init
- gb_array_free
- gb_array_set_capacity
- gb_array_grow
- gb_array_append
- gb_array_appendv
- gb_array_pop
- gb_array_clear
- gb_array_resize
- gb_array_reserve
-*/
+// Available Procedures for gbArray(Type)
+// gb_array_init
+// gb_array_free
+// gb_array_set_capacity
+// gb_array_grow
+// gb_array_append
+// gb_array_appendv
+// gb_array_pop
+// gb_array_clear
+// gb_array_resize
+// gb_array_reserve
+//
#define gb_array_init(x, allocator_) do { gb_zero_struct(x); (x)->allocator = allocator_; } while (0)
#define gb_array_free(x) do { \
if ((x)->allocator.proc) { \
gbAllocator a = (x)->allocator; \
- gb_free(a, (x)->e); \
+ gb_free(a, (x)->data); \
gb_array_init((x), a); \
} \
} while (0)
-#define gb_array_set_capacity(array, capacity) gb__array_set_capacity((array), (capacity), gb_size_of((array)->e[0]))
+#define gb_array_set_capacity(array, capacity) gbprivarray_set_capacity((array), (capacity), gb_size_of((array)->data[0]))
// NOTE(bill): Do not use directly the thing below, use the macro
-GB_DEF void gb__array_set_capacity(void *array, i64 capacity, usize element_size);
+GB_DEF void gbprivarray_set_capacity(void *array, i64 capacity, isize element_size);
// TODO(bill): Decide on a decent growing formula for gbArray
// Is 2*c+8 good enough
@@ -775,15 +836,15 @@ GB_DEF void gb__array_set_capacity(void *array, i64 capacity, usize element_size
#define gb_array_append(x, item) do { \
if ((x)->capacity < (x)->count+1) \
gb_array_grow(x, 0); \
- (x)->e[(x)->count++] = item; \
+ (x)->data[(x)->count++] = item; \
} while (0)
-#define gb_array_appendv(x, items, item_count) do { \
- GB_ASSERT(gb_size_of(items[0]) == gb_size_of((x)->e[0])); \
- if ((x)->capacity < (x)->count+item_count) \
- gb_array_grow(x, (x)->count+item_count); \
- gb_memcpy((x)->e[a->count], items, gb_size_of((x)->e[0])*item_count); \
- (x)->count += item_count; \
+#define gb_array_appendv(x, items, item_count) do { \
+ GB_ASSERT(gb_size_of(items[0]) == gb_size_of((x)->data[0])); \
+ if ((x)->capacity < (x)->count+item_count) \
+ gb_array_grow(x, (x)->count+item_count); \
+ gb_memcpy((x)->data[a->count], items, gb_size_of((x)->data[0])*item_count); \
+ (x)->count += item_count; \
} while (0)
@@ -798,51 +859,83 @@ GB_DEF void gb__array_set_capacity(void *array, i64 capacity, usize element_size
} while (0)
-#define gb_array_reserve(x, capacity) do { \
- if ((x)->capacity < capacity) \
- gb_array_set_capacity(x, capacity); \
+#define gb_array_reserve(x, new_capacity) do { \
+ if ((x)->capacity < new_capacity) \
+ gb_array_set_capacity(x, new_capacity); \
} while (0)
-gb_no_inline void
-gb__array_set_capacity(void *array_, i64 capacity, usize element_size)
-{
- // NOTE(bill): I know this is unsafe so don't call this function directly
- gbVoid_Array *a = cast(gbVoid_Array *)array_;
- void *new_elements = NULL;
+#endif /* GB_ARRAY_TYPE */
- GB_ASSERT(element_size > 0);
- if (capacity == a->capacity)
- return;
- if (capacity < a->count) {
- if (a->capacity < capacity) {
- i64 new_capacity = 2*a->capacity + 8;
- if (new_capacity < capacity)
- new_capacity = capacity;
- gb__array_set_capacity(a, new_capacity, element_size);
- }
- a->count = capacity;
- }
- if (capacity > 0) {
- new_elements = gb_alloc(a->allocator, element_size*capacity);
- gb_memcpy(new_elements, a->e, element_size*a->count);
- }
- gb_free(a->allocator, a->e);
- a->e = new_elements;
- a->capacity = capacity;
+
+
+
+
+////////////////////////////////////////////////////////////////
+//
+//
+// Hash_Table (POD Types)
+//
+//
+
+
+// TODO(bill): Hash Table and make it decent!!!
+
+// NOTE(bill): All keys are u64
+#ifndef GB_HASH_TABLE_TYPE
+#define GB_HASH_TABLE_TYPE
+
+#define gbHash_Table_Entry(Type) struct { \
+ u64 key; \
+ Type value; \
}
-#endif
+#define gbHash_Table(Type) struct { \
+ gbArray(isize) hashes; \
+ gbArray(gbHash_Table_Entry(Type)) entries; \
+}
+
+#define gb_hash_table_init(h, allocator) do { \
+ gb_array_init((h)->hashes, allocator); \
+ gb_array_init((h)->entries, allocator); \
+} while (0)
+
+#define gb_hash_table_free(h) do { \
+ gb_free(&(h)->hashes); \
+ gb_free(&(h)->entries); \
+} while (0)
+
+
+
+/* TODO(bill): Hash_Table Procs
+ gb_hash_table_init(h, allocator)
+ gb_hash_table_free(h)
+
+ gb_hash_table_has(h, key) // Return false/true
+ gb_hash_table_get(h, key) // Return entries index
+ gb_hash_table_set(h, key, value)
+ gb_hash_table_remove(h, key)
+ gb_hash_table_reserve(h, capacity)
+ gb_hash_table_clear(h)
+
+*/
+
-////////////////////////////////
-// //
-// File Handling //
-// //
-////////////////////////////////
+
+
+#endif /* GB_HASH_TABLE_TYPE */
+
+
+
+////////////////////////////////////////////////////////////////
+//
+// File Handling
+//
+//
typedef struct gbFile {
FILE *handle; // File to fread/fwrite
@@ -851,14 +944,14 @@ typedef struct gbFile {
GB_DEF b32 gb_file_create(gbFile *file, char const *filepath); // TODO(bill): Give file permissions
GB_DEF b32 gb_file_open(gbFile *file, char const *filepath);
GB_DEF b32 gb_file_close(gbFile *file);
-GB_DEF b32 gb_file_read_at(gbFile *file, void *buffer, usize size, i64 offset);
-GB_DEF b32 gb_file_write_at(gbFile *file, void const *buffer, usize size, i64 offset);
+GB_DEF b32 gb_file_read_at(gbFile *file, void *buffer, isize size, i64 offset);
+GB_DEF b32 gb_file_write_at(gbFile *file, void const *buffer, isize size, i64 offset);
GB_DEF i64 gb_file_size(gbFile *file);
typedef struct gbFile_Contents {
void *data;
- usize size;
+ isize size;
} gbFile_Contents;
GB_DEF gbFile_Contents gb_read_entire_file_contents(gbAllocator a, char const *filepath, b32 zero_terminate);
@@ -870,31 +963,31 @@ GB_DEF gbFile_Contents gb_read_entire_file_contents(gbAllocator a, char const *f
#endif /* GB_INCLUDE_GB_H */
-////////////////////////////////
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// Implementation //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-// //
-////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+// Implementation
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////
#if defined(GB_IMPLEMENTATION)
@@ -904,54 +997,78 @@ extern "C" {
int
-gb_vsnprintf(char *str, usize n, char const *fmt, va_list v)
+gb_printf(char const *fmt, ...)
{
int res;
- #if defined(_WIN32)
- res = _vsnprintf(str, n, fmt, v);
- #else
- res = vsnprintf(str, n, fmt, v)
- #endif
- if (n) str[n-1] = 0;
- // NOTE(bill): Unix returns length output would require, Windows returns negative when truncated.
- return (res >= cast(int)n || res < 0) ? -1 : res;
+ va_list v;
+ va_start(v, fmt);
+ res = gb_fprintf_var(stdout, fmt, v);
+ va_end(v);
+ return res;
}
int
-gb_snprintf(char *str, usize n, char const *fmt, ...)
+gb_fprintf(FILE *f, char const *fmt, ...)
{
int res;
va_list v;
- va_start(v,fmt);
- res = gb_vsnprintf(str, n, fmt, v);
+ va_start(v, fmt);
+ res = gb_fprintf_var(stdout, fmt, v);
va_end(v);
return res;
}
-
int
-gb_vsprintf(char const *fmt, va_list v)
+gb_sprintf(char const *fmt, ...)
{
gb_local_persist char buffer[1024];
int res;
- res = gb_vsnprintf(buffer, gb_size_of(buffer), fmt, v);
+ va_list v;
+ va_start(v, fmt);
+ res = gb_snprintf_var(buffer, gb_size_of(buffer), fmt, v);
+ va_end(v);
return res;
}
int
-gb_sprintf(char const *fmt, ...)
+gb_snprintf(char *str, isize n, char const *fmt, ...)
{
- gb_local_persist char buffer[1024];
int res;
va_list v;
- va_start(v, fmt);
- res = gb_vsnprintf(buffer, gb_size_of(buffer), fmt, v);
+ va_start(v,fmt);
+ res = gb_snprintf_var(str, n, fmt, v);
va_end(v);
return res;
}
+gb_inline int gb_printf_var(char const *fmt, va_list v) { return gb_fprintf_var(stdout, fmt, v); }
+gb_inline int gb_fprintf_var(FILE *f, char const *fmt, va_list v) { return vfprintf(f, fmt, v); }
+
+gb_inline int
+gb_sprintf_var(char const *fmt, va_list v)
+{
+ gb_local_persist char buffer[1024];
+ int res;
+ res = gb_snprintf_var(buffer, gb_size_of(buffer), fmt, v);
+ return res;
+}
+
+gb_inline int
+gb_snprintf_var(char *str, isize n, char const *fmt, va_list v)
+{
+ int res;
+#if defined(_WIN32)
+ res = _vsnprintf(str, n, fmt, v);
+#else
+ res = vsnprintf(str, n, fmt, v)
+#endif
+ if (n) str[n-1] = 0;
+ // NOTE(bill): Unix returns length output would require, Windows returns negative when truncated.
+ return (res >= n || res < 0) ? -1 : res;
+}
+
@@ -964,31 +1081,29 @@ gb_sprintf(char const *fmt, ...)
void
-gb_assert_handler(char const *condition,
- char const *file, long long line,
- char const *msg, ...)
+gb_assert_handler(char const *condition, char const *file, i64 line, char const *msg, ...)
{
- fprintf(stderr, "%s:%lld: Assert Failure: ", file, line);
+ gb_fprintf(stderr, "%s:%d: Assert Failure: ", file, cast(int)line);
if (condition)
- fprintf(stderr, "`%s` ", condition);
+ gb_fprintf(stderr, "`%s` ", condition);
if (msg) {
va_list args;
va_start(args, msg);
- vfprintf(stderr, msg, args);
+ gb_fprintf(stderr, msg, args);
va_end(args);
}
- fprintf(stderr, "\n");
+ gb_fprintf(stderr, "\n");
}
gb_inline void *
-gb_align_forward(void *ptr, usize align)
+gb_align_forward(void *ptr, isize align)
{
uintptr p;
- usize modulo;
+ isize modulo;
GB_ASSERT(gb_is_power_of_two(align));
@@ -998,35 +1113,32 @@ gb_align_forward(void *ptr, usize align)
return cast(void *)p;
}
-gb_inline void
-gb_zero_size(void *ptr, usize size)
-{
- memset(ptr, 0, size);
-}
+gb_inline void gb_zero_size(void *ptr, isize size) { gb_memset(ptr, 0, size); }
-gb_inline void *gb_memcpy(void *dest, void const *source, usize size) { return memcpy(dest, source, size); }
-gb_inline void *gb_memmove(void *dest, void const *source, usize size) { return memmove(dest, source, size); }
+gb_inline void *gb_memcpy(void *dest, void const *source, isize size) { return memcpy(dest, source, size); }
+gb_inline void *gb_memmove(void *dest, void const *source, isize size) { return memmove(dest, source, size); }
+gb_inline void *gb_memset(void *data, u8 byte_value, isize size) { return memset(data, byte_value, size); }
-gb_inline void *gb_alloc_align(gbAllocator a, usize size, usize alignment) { return a.proc(a.data, GB_ALLOCATION_TYPE_ALLOC, size, alignment, NULL, 0, 0); }
-gb_inline void *gb_alloc(gbAllocator a, usize size) { return gb_alloc_align(a, size, GB_DEFAULT_MEMORY_ALIGNMENT); }
+gb_inline void *gb_alloc_align(gbAllocator a, isize size, isize alignment) { return a.proc(a.data, GB_ALLOCATION_TYPE_ALLOC, size, alignment, NULL, 0, 0); }
+gb_inline void *gb_alloc(gbAllocator a, isize size) { return gb_alloc_align(a, size, GB_DEFAULT_MEMORY_ALIGNMENT); }
gb_inline void gb_free(gbAllocator a, void *ptr) { a.proc(a.data, GB_ALLOCATION_TYPE_FREE, 0, 0, ptr, 0, 0); }
gb_inline void gb_free_all(gbAllocator a) { a.proc(a.data, GB_ALLOCATION_TYPE_FREE_ALL, 0, 0, NULL, 0, 0); }
-gb_inline void *gb_resize(gbAllocator a, void *ptr, usize old_size, usize new_size) { return gb_resize_align(a, ptr, old_size, new_size, GB_DEFAULT_MEMORY_ALIGNMENT); }
-gb_inline void *gb_resize_align(gbAllocator a, void *ptr, usize old_size, usize new_size, usize alignment) { return a.proc(a.data, GB_ALLOCATION_TYPE_RESIZE, new_size, alignment, ptr, old_size, 0); };
+gb_inline void *gb_resize(gbAllocator a, void *ptr, isize old_size, isize new_size) { return gb_resize_align(a, ptr, old_size, new_size, GB_DEFAULT_MEMORY_ALIGNMENT); }
+gb_inline void *gb_resize_align(gbAllocator a, void *ptr, isize old_size, isize new_size, isize alignment) { return a.proc(a.data, GB_ALLOCATION_TYPE_RESIZE, new_size, alignment, ptr, old_size, 0); };
-gb_inline void *gb_alloc_copy(gbAllocator a, void const *src, usize size) { return gb_memcpy(gb_alloc(a, size), src, size); }
-gb_inline void *gb_alloc_align_copy(gbAllocator a, void const *src, usize size, usize alignment) { return gb_memcpy(gb_alloc_align(a, size, alignment), src, size); }
+gb_inline void *gb_alloc_copy(gbAllocator a, void const *src, isize size) { return gb_memcpy(gb_alloc(a, size), src, size); }
+gb_inline void *gb_alloc_copy_align(gbAllocator a, void const *src, isize size, isize alignment) { return gb_memcpy(gb_alloc_align(a, size, alignment), src, size); }
gb_inline char *
-gb_alloc_cstring(gbAllocator a, char const *str, usize len)
+gb_alloc_cstring(gbAllocator a, char const *str)
{
char *result;
- if (len == 0) len = strlen(str);
+ isize len = gb_strlen(str);
result = cast(char *)gb_alloc_copy(a, str, len+1);
result[len] = '\0';
return result;
@@ -1064,7 +1176,7 @@ GB_ALLOCATOR_PROC(gb_malloc_allocator_proc)
void *ptr = NULL;
void *original_block; // Original block
void **aligned_block; // Aligned block
- usize offset = (alignment-1) + sizeof(void *);
+ isize offset = (alignment-1) + sizeof(void *);
original_block = cast(void *)malloc(size + offset);
if (original_block) {
uintptr t = (cast(uintptr)original_block + offset) & ~(alignment-1);
@@ -1090,15 +1202,25 @@ GB_ALLOCATOR_PROC(gb_malloc_allocator_proc)
break;
case GB_ALLOCATION_TYPE_RESIZE: {
- #if defined(_MSC_VER)
+ gbAllocator a = gb_malloc_allocator();
+ if (!old_memory) return gb_alloc_align(a, size, alignment);
+
+ if (size < old_size)
+ size = old_size;
+
+ if (old_size == size) {
+ return old_memory;
+ } else {
+#if defined(_MSC_VER)
return _aligned_realloc(old_memory, size, alignment);
- #else
- gbAllocator a = gb_malloc_allocator();
+#else
void *new_memory = gb_alloc_align(a, size, alignment);
+ if (!new_memory) return NULL;
gb_memmove(new_memory, old_memory, gb_min(size, old_size));
gb_free(a, old_memory);
return new_memory;
- #endif
+#endif
+ }
} break;
}
@@ -1111,7 +1233,7 @@ GB_ALLOCATOR_PROC(gb_malloc_allocator_proc)
gb_inline void
-gb_arena_init_from_memory(gbArena *arena, void *start, usize size)
+gb_arena_init_from_memory(gbArena *arena, void *start, isize size)
{
arena->backing.proc = NULL;
arena->backing.data = NULL;
@@ -1122,7 +1244,7 @@ gb_arena_init_from_memory(gbArena *arena, void *start, usize size)
}
gb_inline void
-gb_arena_init_from_allocator(gbArena *arena, gbAllocator backing, usize size)
+gb_arena_init_from_allocator(gbArena *arena, gbAllocator backing, isize size)
{
arena->backing = backing;
arena->physical_start = gb_alloc(backing, size); // NOTE(bill): Uses default alignment
@@ -1131,7 +1253,7 @@ gb_arena_init_from_allocator(gbArena *arena, gbAllocator backing, usize size)
arena->temp_count = 0;
}
-gb_inline void gb_arena_init_subarena(gbArena *arena, gbArena *parent_arena, usize size) { gb_arena_init_from_allocator(arena, gb_arena_allocator(parent_arena), size); }
+gb_inline void gb_arena_init_subarena(gbArena *arena, gbArena *parent_arena, isize size) { gb_arena_init_from_allocator(arena, gb_arena_allocator(parent_arena), size); }
gb_inline void
@@ -1144,14 +1266,14 @@ gb_arena_free(gbArena *arena)
}
-gb_inline usize
-gb_arena_alignment_of(gbArena *arena, usize alignment)
+gb_inline isize
+gb_arena_alignment_of(gbArena *arena, isize alignment)
{
- usize alignment_offset, result_pointer, mask;
+ isize alignment_offset, result_pointer, mask;
GB_ASSERT(gb_is_power_of_two(alignment));
alignment_offset = 0;
- result_pointer = cast(usize)arena->physical_start + arena->total_allocated;
+ result_pointer = cast(isize)arena->physical_start + arena->total_allocated;
mask = alignment - 1;
if (result_pointer & mask)
alignment_offset = alignment - (result_pointer & mask);
@@ -1159,10 +1281,10 @@ gb_arena_alignment_of(gbArena *arena, usize alignment)
return alignment_offset;
}
-gb_inline usize
-gb_arena_size_remaining(gbArena *arena, usize alignment)
+gb_inline isize
+gb_arena_size_remaining(gbArena *arena, isize alignment)
{
- usize result = arena->total_size - (arena->total_allocated + gb_arena_alignment_of(arena, alignment));
+ isize result = arena->total_size - (arena->total_allocated + gb_arena_alignment_of(arena, alignment));
return result;
}
@@ -1193,22 +1315,21 @@ GB_ALLOCATOR_PROC(gb_arena_allocator_proc)
switch (type) {
case GB_ALLOCATION_TYPE_ALLOC: {
void *ptr;
- usize actual_size = size + alignment;
+ isize actual_size = size + alignment;
// NOTE(bill): Out of memory
- if (arena->total_allocated + actual_size > cast(usize)arena->total_size)
+ if (arena->total_allocated + actual_size > cast(isize)arena->total_size)
return NULL;
ptr = gb_align_forward(cast(u8 *)arena->physical_start + arena->total_allocated, alignment);
arena->total_allocated += actual_size;
- if (arena->clear_allocations_to_zero)
- gb_zero_size(ptr, size);
return ptr;
} break;
case GB_ALLOCATION_TYPE_FREE:
// NOTE(bill): Free all at once
// NOTE(bill): Use Temp_Arena_Memory if you want to free a block
+ // TODO(bill): Free it if it's on top of the stack
break;
case GB_ALLOCATION_TYPE_FREE_ALL:
@@ -1216,11 +1337,22 @@ GB_ALLOCATOR_PROC(gb_arena_allocator_proc)
break;
case GB_ALLOCATION_TYPE_RESIZE: {
+ // TODO(bill): Check if ptr is on top of stack and just extend
gbAllocator a = gb_arena_allocator(arena);
- void *new_memory = gb_alloc_align(a, size, alignment);
- gb_memmove(new_memory, old_memory, gb_min(size, old_size));
- gb_free(a, old_memory);
- return new_memory;
+ if (!old_memory) return gb_alloc_align(a, size, alignment);
+
+ if (size < old_size)
+ size = old_size;
+
+ if (old_size == size) {
+ return old_memory;
+ } else {
+ void *new_memory = gb_alloc_align(a, size, alignment);
+ if (!new_memory) return NULL;
+ gb_memmove(new_memory, old_memory, gb_min(size, old_size));
+ gb_free(a, old_memory);
+ return new_memory;
+ }
} break;
}
@@ -1229,7 +1361,7 @@ GB_ALLOCATOR_PROC(gb_arena_allocator_proc)
gb_inline gbTemp_Arena_Memory
-gb_begin_temp_arena_memory(gbArena *arena)
+gb_temp_arena_memory_begin(gbArena *arena)
{
gbTemp_Arena_Memory tmp;
tmp.arena = arena;
@@ -1239,7 +1371,7 @@ gb_begin_temp_arena_memory(gbArena *arena)
}
gb_inline void
-gb_end_temp_arena_memory(gbTemp_Arena_Memory tmp)
+gb_temp_arena_memory_end(gbTemp_Arena_Memory tmp)
{
GB_ASSERT(tmp.arena->total_allocated >= tmp.original_count);
GB_ASSERT(tmp.arena->temp_count > 0);
@@ -1251,15 +1383,15 @@ gb_end_temp_arena_memory(gbTemp_Arena_Memory tmp)
gb_inline void
-gb_pool_init(gbPool *pool, gbAllocator backing, usize num_blocks, usize block_size)
+gb_pool_init(gbPool *pool, gbAllocator backing, isize num_blocks, isize block_size)
{
gb_pool_init_align(pool, backing, num_blocks, block_size, GB_DEFAULT_MEMORY_ALIGNMENT);
}
void
-gb_pool_init_align(gbPool *pool, gbAllocator backing, usize num_blocks, usize block_size, usize block_align)
+gb_pool_init_align(gbPool *pool, gbAllocator backing, isize num_blocks, isize block_size, isize block_align)
{
- usize actual_block_size, pool_size, block_index;
+ isize actual_block_size, pool_size, block_index;
u8 *data, *curr;
uintptr *end;
@@ -1282,7 +1414,7 @@ gb_pool_init_align(gbPool *pool, gbAllocator backing, usize num_blocks, usize bl
curr += actual_block_size;
}
- end = cast(uintptr*)curr;
+ end = cast(uintptr *)curr;
*end = cast(uintptr)NULL;
pool->physical_start = data;
@@ -1432,21 +1564,21 @@ gb_char_is_alphanumeric(char c)
-gb_inline void gb__string_set_length(gbString str, gbString_Size len) { GB_STRING_HEADER(str)->length = len; }
-gb_inline void gb__string_set_capacity(gbString str, gbString_Size cap) { GB_STRING_HEADER(str)->capacity = cap; }
+gb_inline void gbprivstring_set_length(gbString str, isize len) { GB_STRING_HEADER(str)->length = len; }
+gb_inline void gbprivstring_set_capacity(gbString str, isize cap) { GB_STRING_HEADER(str)->capacity = cap; }
gb_inline gbString
gb_string_make(gbAllocator a, char const *str)
{
- gbString_Size len = cast(gbString_Size)(str ? strlen(str) : 0);
+ isize len = str ? gb_strlen(str) : 0;
return gb_string_make_length(a, str, len);
}
gbString
-gb_string_make_length(gbAllocator a, void const *init_str, gbString_Size num_bytes)
+gb_string_make_length(gbAllocator a, void const *init_str, isize num_bytes)
{
- gbString_Size header_size = gb_size_of(gbString_Header);
+ isize header_size = gb_size_of(gbString_Header);
void *ptr = gb_alloc(a, header_size + num_bytes + 1);
gbString str;
@@ -1480,10 +1612,10 @@ gb_string_free(gbString str)
gb_inline gbString gb_string_duplicate(gbAllocator a, gbString const str) { return gb_string_make_length(a, str, gb_string_length(str)); }
-gb_inline gbString_Size gb_string_length(gbString const str) { return GB_STRING_HEADER(str)->length; }
-gb_inline gbString_Size gb_string_capacity(gbString const str) { return GB_STRING_HEADER(str)->capacity; }
+gb_inline isize gb_string_length(gbString const str) { return GB_STRING_HEADER(str)->length; }
+gb_inline isize gb_string_capacity(gbString const str) { return GB_STRING_HEADER(str)->capacity; }
-gb_inline gbString_Size
+gb_inline isize
gb_string_available_space(gbString const str)
{
gbString_Header *h = GB_STRING_HEADER(str);
@@ -1493,14 +1625,14 @@ gb_string_available_space(gbString const str)
}
-gb_inline void gb_string_clear(gbString str) { gb__string_set_length(str, 0); str[0] = '\0'; }
+gb_inline void gb_string_clear(gbString str) { gbprivstring_set_length(str, 0); str[0] = '\0'; }
gb_inline gbString gb_string_append_string(gbString str, gbString const other) { return gb_string_append_string_length(str, other, gb_string_length(other)); }
gbString
-gb_string_append_string_length(gbString str, void const *other, gbString_Size other_len)
+gb_string_append_string_length(gbString str, void const *other, isize other_len)
{
- gbString_Size curr_len = gb_string_length(str);
+ isize curr_len = gb_string_length(str);
str = gb_string_make_space_for(str, other_len);
if (str == NULL)
@@ -1508,7 +1640,7 @@ gb_string_append_string_length(gbString str, void const *other, gbString_Size ot
gb_memcpy(str + curr_len, other, other_len);
str[curr_len + other_len] = '\0';
- gb__string_set_length(str, curr_len + other_len);
+ gbprivstring_set_length(str, curr_len + other_len);
return str;
}
@@ -1516,14 +1648,14 @@ gb_string_append_string_length(gbString str, void const *other, gbString_Size ot
gb_inline gbString
gb_string_append_cstring(gbString str, char const *other)
{
- return gb_string_append_string_length(str, other, cast(gbString_Size)strlen(other));
+ return gb_string_append_string_length(str, other, cast(isize)strlen(other));
}
gbString
gb_string_set(gbString str, char const *cstr)
{
- gbString_Size len = cast(gbString_Size)strlen(cstr);
+ isize len = gb_strlen(cstr);
if (gb_string_capacity(str) < len) {
str = gb_string_make_space_for(str, len - gb_string_length(str));
if (str == NULL)
@@ -1532,63 +1664,41 @@ gb_string_set(gbString str, char const *cstr)
gb_memcpy(str, cstr, len);
str[len] = '\0';
- gb__string_set_length(str, len);
+ gbprivstring_set_length(str, len);
return str;
}
-gb_internal void *
-gb__string_realloc(gbAllocator a, void *ptr, gbString_Size old_size, gbString_Size new_size)
-{
- if (!ptr) return gb_alloc(a, new_size);
-
- if (new_size < old_size)
- new_size = old_size;
-
- if (old_size == new_size) {
- return ptr;
- } else {
- void *new_ptr = gb_alloc(a, new_size);
- if (!new_ptr)
- return NULL;
-
- gb_memcpy(new_ptr, ptr, old_size);
- gb_free(a, ptr);
- return new_ptr;
- }
-}
-
-
gbString
-gb_string_make_space_for(gbString str, gbString_Size add_len)
+gb_string_make_space_for(gbString str, isize add_len)
{
- gbString_Size available = gb_string_available_space(str);
+ isize available = gb_string_available_space(str);
// Return if there is enough space left
if (available >= add_len) {
return str;
} else {
- gbString_Size new_len = gb_string_length(str) + add_len;
+ isize new_len = gb_string_length(str) + add_len;
void *ptr = GB_STRING_HEADER(str);
- gbString_Size old_size = gb_size_of(gbString_Header) + gb_string_length(str) + 1;
- gbString_Size new_size = gb_size_of(gbString_Header) + new_len + 1;
+ isize old_size = gb_size_of(gbString_Header) + gb_string_length(str) + 1;
+ isize new_size = gb_size_of(gbString_Header) + new_len + 1;
- void *new_ptr = gb__string_realloc(GB_STRING_HEADER(str)->allocator, ptr, old_size, new_size);
+ void *new_ptr = gb_resize(GB_STRING_HEADER(str)->allocator, ptr, old_size, new_size);
if (new_ptr == NULL) return NULL;
str = cast(char *)(GB_STRING_HEADER(new_ptr) + 1);
- gb__string_set_capacity(str, new_len);
+ gbprivstring_set_capacity(str, new_len);
return str;
}
}
-gb_inline gbString_Size
+gb_inline isize
gb_string_allocation_size(gbString const str)
{
- gbString_Size cap = gb_string_capacity(str);
+ isize cap = gb_string_capacity(str);
return gb_size_of(gbString_Header) + cap;
}
@@ -1596,7 +1706,7 @@ gb_string_allocation_size(gbString const str)
gb_inline b32
gb_strings_are_equal(gbString const lhs, gbString const rhs)
{
- gbString_Size lhs_len, rhs_len, i;
+ isize lhs_len, rhs_len, i;
lhs_len = gb_string_length(lhs);
rhs_len = gb_string_length(rhs);
if (lhs_len != rhs_len)
@@ -1615,7 +1725,7 @@ gbString
gb_string_trim(gbString str, char const *cut_set)
{
char *start, *end, *start_pos, *end_pos;
- gbString_Size len;
+ isize len;
start_pos = start = str;
end_pos = end = str + gb_string_length(str) - 1;
@@ -1625,13 +1735,13 @@ gb_string_trim(gbString str, char const *cut_set)
while (end_pos > start_pos && strchr(cut_set, *end_pos))
end_pos--;
- len = cast(gbString_Size)((start_pos > end_pos) ? 0 : ((end_pos - start_pos)+1));
+ len = cast(isize)((start_pos > end_pos) ? 0 : ((end_pos - start_pos)+1));
if (str != start_pos)
gb_memmove(str, start_pos, len);
str[len] = '\0';
- gb__string_set_length(str, len);
+ gbprivstring_set_length(str, len);
return str;
}
@@ -1659,7 +1769,7 @@ gb_to_upper(char *str)
}
-gb_inline usize
+gb_inline isize
gb_strlen(char const *str)
{
char const *end;
@@ -1670,7 +1780,7 @@ gb_strlen(char const *str)
}
gb_inline char *
-gb_strncpy(char *dest, char const *source, usize len)
+gb_strncpy(char *dest, char const *source, isize len)
{
char *str = dest;
while (len > 0 && *source) {
@@ -1685,7 +1795,7 @@ gb_strncpy(char *dest, char const *source, usize len)
}
gb_inline int
-gb_strncmp(char const *s1, char const *s2, usize len)
+gb_strncmp(char const *s1, char const *s2, isize len)
{
for(; len > 0; s1++, s2++, len--) {
if (*s1 != *s2)
@@ -1699,19 +1809,19 @@ gb_strncmp(char const *s1, char const *s2, usize len)
-////////////////////////////////////////
-// //
-// Windows UTF-8 Handling //
-// //
-////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Windows UTF-8 Handling
+//
+//
char16 *
-gb_from_utf8(char16 *buffer, char *s, usize len)
+gb_from_utf8(char16 *buffer, char *s, isize len)
{
u8 *str = cast(u8 *)s;
u32 c;
- usize i = 0;
+ isize i = 0;
len--;
while (*str) {
if (i >= len)
@@ -1774,9 +1884,9 @@ gb_from_utf8(char16 *buffer, char *s, usize len)
}
char *
-gb_to_utf8(char *buffer, char16 *str, usize len)
+gb_to_utf8(char *buffer, char16 *str, isize len)
{
- usize i = 0;
+ isize i = 0;
len--;
while (*str) {
if (*str < 0x80) {
@@ -1823,21 +1933,21 @@ gb_to_utf8(char *buffer, char16 *str, usize len)
////////////////////////////////
gb_inline b32
-gb_create_file(gbFile *file, char const *filepath)
+gb_file_create(gbFile *file, char const *filepath)
{
file->handle = fopen(filepath, "wb");
return (file->handle != NULL); // TODO(bill): Handle fopen errors
}
gb_inline b32
-gb_open_file(gbFile *file, char const *filepath)
+gb_file_open(gbFile *file, char const *filepath)
{
file->handle = fopen(filepath, "rb");
return (file->handle != NULL); // TODO(bill): Handle fopen errors
}
gb_inline b32
-gb_close_file(gbFile *file)
+gb_file_close(gbFile *file)
{
b32 result = true;
if (file && file->handle)
@@ -1846,7 +1956,7 @@ gb_close_file(gbFile *file)
}
gb_inline b32
-gb_read_file_at(gbFile *file, void *buffer, usize size, i64 offset)
+gb_file_read_at(gbFile *file, void *buffer, isize size, i64 offset)
{
i64 prev_cursor_pos = ftell(file->handle);
fseek(file->handle, offset, SEEK_SET);
@@ -1856,9 +1966,9 @@ gb_read_file_at(gbFile *file, void *buffer, usize size, i64 offset)
}
gb_inline b32
-gb_write_file_at(gbFile *file, void const *buffer, usize size, i64 offset)
+gb_file_write_at(gbFile *file, void const *buffer, isize size, i64 offset)
{
- usize written_size;
+ isize written_size;
i64 prev_cursor_pos = ftell(file->handle);
fseek(file->handle, offset, SEEK_SET);
@@ -1876,10 +1986,10 @@ gb_write_file_at(gbFile *file, void const *buffer, usize size, i64 offset)
gb_inline i64
gb_file_size(gbFile *file)
{
- usize result_size;
+ i64 result_size;
fseek(file->handle, 0, SEEK_END);
- result_size = cast(usize)ftell(file->handle);
+ result_size = cast(i64)ftell(file->handle);
fseek(file->handle, 0, SEEK_SET);
return result_size;
}
@@ -1893,16 +2003,16 @@ gb_read_entire_file_contents(gbAllocator a, char const *filepath, b32 zero_termi
{
gbFile_Contents result = {0};
gbFile file = {0};
- if (gb_open_file(&file, filepath)) {
+ if (gb_file_open(&file, filepath)) {
i64 file_size = gb_file_size(&file);
if (file_size > 0) {
result.data = gb_alloc(a, zero_terminate ? file_size+1 : file_size);
result.size = file_size;
- gb_read_file_at(&file, result.data, result.size, 0);
+ gb_file_read_at(&file, result.data, result.size, 0);
if (zero_terminate)
(cast(u8 *)(result.data))[file_size] = '\0';
}
- gb_close_file(&file);
+ gb_file_close(&file);
}
return result;
@@ -1911,6 +2021,36 @@ gb_read_entire_file_contents(gbAllocator a, char const *filepath, b32 zero_termi
+gb_no_inline void
+gbprivarray_set_capacity(void *array_, isize capacity, isize element_size)
+{
+ // NOTE(bill): I know this is unsafe so don't call this function directly
+ gbVoid_Array *a = cast(gbVoid_Array *)array_;
+ void *data = NULL;
+
+ GB_ASSERT(element_size > 0);
+
+ if (capacity == a->capacity)
+ return;
+
+ if (capacity < a->count) {
+ if (a->capacity < capacity) {
+ isize new_capacity = 2*a->capacity + 8;
+ if (new_capacity < capacity)
+ new_capacity = capacity;
+ gbprivarray_set_capacity(a, new_capacity, element_size);
+ }
+ a->count = capacity;
+ }
+
+ if (capacity > 0) {
+ data = gb_alloc(a->allocator, element_size*capacity);
+ gb_memcpy(data, a->data, element_size*a->count);
+ }
+ gb_free(a->allocator, a->data);
+ a->data = data;
+ a->capacity = capacity;
+}