diff --git a/codegen/datatypes.py b/codegen/datatypes.py index 8d69ce4..64e6e13 100644 --- a/codegen/datatypes.py +++ b/codegen/datatypes.py @@ -246,7 +246,10 @@ class CHeader(CFile): name_upper = self.name.upper() header_guard_name = f"{name_upper}_H" header_guard_open = f"#ifndef {header_guard_name}\n#define {header_guard_name}\n\n" - header_guard_close = f"\n#endif // !{header_guard_name}\n" + header_guard_close = f"#endif // !{header_guard_name}\n" + + c_linkage_open = "#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n" + c_linkage_close = "\n#ifdef WAPP_PLATFORM_CPP\nEND_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n" includes = _get_includes_string(self.includes) @@ -274,10 +277,12 @@ class CHeader(CFile): super().__str__() + header_guard_open + includes + + c_linkage_open + macros + forward_declarations + types + funcs + + c_linkage_close + header_guard_close ) diff --git a/src/common/aliases/aliases.h b/src/common/aliases/aliases.h index 6759a0f..9792f80 100644 --- a/src/common/aliases/aliases.h +++ b/src/common/aliases/aliases.h @@ -54,4 +54,10 @@ #define internal static #define persistent static +#ifdef WAPP_PLATFORM_CPP +#define class_mem static +#define BEGIN_C_LINKAGE extern "C" { +#define END_C_LINKAGE } +#endif // WAPP_PLATFORM_CPP + #endif // !ALIASES_H diff --git a/src/common/assert/assert.h b/src/common/assert/assert.h index 92d80dc..ae98975 100644 --- a/src/common/assert/assert.h +++ b/src/common/assert/assert.h @@ -1,10 +1,18 @@ // vim:fileencoding=utf-8:foldmethod=marker +#ifndef WAPP_ASSERT_H +#define WAPP_ASSERT_H + #include "../aliases/aliases.h" +#include "../platform/platform.h" #include #include #include +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define wapp_static_assert(EXPR, MSG) extern char ASSERTION_FAILED[EXPR ? 1 : -1] #define wapp_runtime_assert(EXPR, MSG) __wapp_runtime_assert(EXPR, MSG) @@ -25,3 +33,9 @@ abort(); \ } \ } while(false) + +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + +#endif // !WAPP_ASSERT_H diff --git a/src/common/misc/misc_utils.h b/src/common/misc/misc_utils.h index 07fcd88..e416d2a 100644 --- a/src/common/misc/misc_utils.h +++ b/src/common/misc/misc_utils.h @@ -5,6 +5,10 @@ #include "../aliases/aliases.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define KB(SIZE) (SIZE * 1024ull) #define MB(SIZE) (KB(SIZE) * 1024) #define GB(SIZE) (MB(SIZE) * 1024) @@ -36,4 +40,8 @@ #define wapp_misc_utils_va_args_count(T, ...) (sizeof((T[]){__VA_ARGS__})/sizeof(T)) +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MISC_UTILS_H diff --git a/src/common/platform/platform.h b/src/common/platform/platform.h index c6796a7..9891f86 100644 --- a/src/common/platform/platform.h +++ b/src/common/platform/platform.h @@ -61,7 +61,30 @@ #endif #ifdef __cplusplus - #error "WAPP is a C only library" + #define WAPP_PLATFORM_CPP + #define WAPP_PLATFORM_CPP_VERSION __cplusplus + #define WAPP_PLATFORM_CPP98_VERSION 199711L + #define WAPP_PLATFORM_CPP11_VERSION 201103L + #define WAPP_PLATFORM_CPP14_VERSION 201402L + #define WAPP_PLATFORM_CPP17_VERSION 201703L + #define WAPP_PLATFORM_CPP20_VERSION 202002L + #define WAPP_PLATFORM_CPP23_VERSION 202302L + + #if WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP98_VERSION + #define WAPP_PLATFORM_CPP98 + #elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP11_VERSION + #define WAPP_PLATFORM_CPP11 + #elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP14_VERSION + #define WAPP_PLATFORM_CPP14 + #elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP17_VERSION + #define WAPP_PLATFORM_CPP17 + #elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP20_VERSION + #define WAPP_PLATFORM_CPP20 + #elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP23_VERSION + #define WAPP_PLATFORM_CPP23 + #else + #error "Unrecognised C++ version" + #endif #else #define WAPP_PLATFORM_C diff --git a/src/core/mem/arena/mem_arena.h b/src/core/mem/arena/mem_arena.h index e72a676..ec05f32 100644 --- a/src/core/mem/arena/mem_arena.h +++ b/src/core/mem/arena/mem_arena.h @@ -8,6 +8,10 @@ #include "../../os/mem/mem_os.h" #include +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + typedef struct arena Arena; #define wapp_mem_arena_init(arena_dptr, base_capacity) \ @@ -32,4 +36,8 @@ void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 void wapp_mem_arena_clear(Arena *arena); void wapp_mem_arena_destroy(Arena **arena); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_ARENA_H diff --git a/src/core/mem/arena/mem_arena_allocator.h b/src/core/mem/arena/mem_arena_allocator.h index 7fb84c7..f0bd4c3 100644 --- a/src/core/mem/arena/mem_arena_allocator.h +++ b/src/core/mem/arena/mem_arena_allocator.h @@ -9,6 +9,10 @@ #include "../../os/mem/mem_os.h" #include +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define wapp_mem_arena_allocator_init(base_capacity) \ (wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, false)) #define wapp_mem_arena_allocator_init_commit(base_capacity) \ @@ -33,4 +37,8 @@ Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags void wapp_mem_arena_allocator_clear(Allocator *allocator); void wapp_mem_arena_allocator_destroy(Allocator *allocator); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_ARENA_ALLOCATOR_H diff --git a/src/core/mem/utils/mem_utils.h b/src/core/mem/utils/mem_utils.h index 8bb1e2f..ca7f781 100644 --- a/src/core/mem/utils/mem_utils.h +++ b/src/core/mem/utils/mem_utils.h @@ -6,6 +6,14 @@ #include "../../../common/aliases/aliases.h" #include "../../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + void *wapp_mem_util_align_forward(void *ptr, u64 alignment); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_UTILS_H diff --git a/src/core/os/cpath/cpath.h b/src/core/os/cpath/cpath.h index 68a24ce..f8363d5 100644 --- a/src/core/os/cpath/cpath.h +++ b/src/core/os/cpath/cpath.h @@ -8,6 +8,10 @@ #include "../../../primitives/mem_allocator/mem_allocator.h" #include "../../../primitives/strings/str8/str8.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #ifdef WAPP_PLATFORM_POSIX #define PATH_SEP '/' #elif defined(WAPP_PLATFORM_WINDOWS) @@ -29,4 +33,8 @@ enum { u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts); Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !CPATH_H diff --git a/src/core/os/mem/mem_os.h b/src/core/os/mem/mem_os.h index 77535bc..451485c 100644 --- a/src/core/os/mem/mem_os.h +++ b/src/core/os/mem/mem_os.h @@ -8,6 +8,10 @@ #include "mem_os_ops.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #if defined(WAPP_PLATFORM_WINDOWS) #include "win/mem_os_win.h" #elif defined(WAPP_PLATFORM_POSIX) @@ -22,4 +26,8 @@ void wapp_mem_util_free(void *ptr, u64 size); external void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type); external void mem_util_free(void *ptr, u64 size); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_OS_H diff --git a/src/core/os/mem/mem_os_ops.h b/src/core/os/mem/mem_os_ops.h index 04d8e2c..460c9a8 100644 --- a/src/core/os/mem/mem_os_ops.h +++ b/src/core/os/mem/mem_os_ops.h @@ -5,6 +5,10 @@ #include "../../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + typedef enum mem_access { WAPP_MEM_ACCESS_NONE, WAPP_MEM_ACCESS_READ_ONLY, @@ -19,4 +23,8 @@ typedef enum mem_init_type { WAPP_MEM_INIT_INITIALISED, } MemInitType; +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_OS_OPS_H diff --git a/src/core/os/mem/posix/mem_os_posix.h b/src/core/os/mem/posix/mem_os_posix.h index f93c3e2..1d3c013 100644 --- a/src/core/os/mem/posix/mem_os_posix.h +++ b/src/core/os/mem/posix/mem_os_posix.h @@ -5,6 +5,10 @@ #include "../../../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #ifdef WAPP_PLATFORM_POSIX #include @@ -24,4 +28,8 @@ typedef enum mem_alloc_flags { #endif // !WAPP_PLATFORM_POSIX +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_OS_POSIX_H diff --git a/src/core/os/mem/win/mem_os_win.h b/src/core/os/mem/win/mem_os_win.h index 1af2557..31f826e 100644 --- a/src/core/os/mem/win/mem_os_win.h +++ b/src/core/os/mem/win/mem_os_win.h @@ -5,6 +5,10 @@ #include "../../../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #ifdef WAPP_PLATFORM_WINDOWS #define WIN32_LEAN_AND_MEAN @@ -18,4 +22,8 @@ typedef enum mem_alloc_flags { #endif // !WAPP_PLATFORM_WINDOWS +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_OS_WIN_H diff --git a/src/primitives/array/array.h b/src/primitives/array/array.h index da31ac8..884e3a4 100644 --- a/src/primitives/array/array.h +++ b/src/primitives/array/array.h @@ -11,6 +11,10 @@ #include "../../common/aliases/aliases.h" #include "../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define wapp_str8_array(...) ((Str8Array){ \ .items = (Str8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \ .count = wapp_misc_utils_va_args_count(Str8, __VA_ARGS__), \ @@ -616,4 +620,8 @@ UptrArray *wapp_uptr_array_copy_alloc(const Allocator *allocator, const UptrArra uptr *_uptr_array_pop(UptrArray *array); VoidPArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !ARRAY_H diff --git a/src/primitives/dbl_list/dbl_list.h b/src/primitives/dbl_list/dbl_list.h index 58fb6b7..a08a3e2 100644 --- a/src/primitives/dbl_list/dbl_list.h +++ b/src/primitives/dbl_list/dbl_list.h @@ -9,6 +9,10 @@ #include "../../common/aliases/aliases.h" #include "../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define wapp_str8_list_node(ITEM_PTR) ((Str8Node){.item = ITEM_PTR}) #define wapp_void_ptr_list_node(ITEM_PTR) ((VoidPNode){.item = ITEM_PTR}) #define wapp_b32_list_node(ITEM_PTR) ((B32Node){.item = ITEM_PTR}) @@ -473,4 +477,8 @@ UptrNode *wapp_uptr_list_pop_back(UptrList *list); UptrNode *wapp_uptr_list_remove(UptrList *list, u64 index); void wapp_uptr_list_empty(UptrList *list); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !DBL_LIST_H diff --git a/src/primitives/mem_allocator/mem_allocator.h b/src/primitives/mem_allocator/mem_allocator.h index 6d2828d..41877e3 100644 --- a/src/primitives/mem_allocator/mem_allocator.h +++ b/src/primitives/mem_allocator/mem_allocator.h @@ -7,6 +7,10 @@ #include "../../common/platform/platform.h" #include +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + typedef void *(MemAllocFunc)(u64 size, void *alloc_obj); typedef void *(MemAllocAlignedFunc)(u64 size, u64 alignment, void *alloc_obj); typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); @@ -32,4 +36,8 @@ void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 new_size, u64 alignment); void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !MEM_ALLOCATOR_H diff --git a/src/primitives/strings/str8/str8.h b/src/primitives/strings/str8/str8.h index 26a06dd..d66c337 100644 --- a/src/primitives/strings/str8/str8.h +++ b/src/primitives/strings/str8/str8.h @@ -4,12 +4,17 @@ #define STR8_H #include "../../../common/aliases/aliases.h" +#include "../../../common/assert/assert.h" #include "../../../common/platform/platform.h" #include "../../../primitives/dbl_list/dbl_list.h" #include "../../mem_allocator/mem_allocator.h" #include #include +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + typedef struct str8 Str8; struct str8 { u64 capacity; @@ -28,6 +33,25 @@ typedef const Str8 Str8RO; /** * Str8 stack buffers */ + +#ifdef WAPP_PLATFORM_CPP +// Uses a lambda to achieve the same behaviour achieved by the C macro +#define wapp_str8_buf(CAPACITY) ([](){ \ + persistent c8 buf[CAPACITY] = {}; \ + memset(buf, 0, CAPACITY); \ + return Str8{CAPACITY, 0, buf}; \ +}()) + +// Uses a lambda to achieve the same behaviour achieved by the C macro +#define wapp_str8_lit(STRING) ([]() { \ + persistent c8 buf[sizeof(STRING) * 2] = {}; \ + memcpy(buf, STRING, sizeof(STRING)); \ + return Str8{(sizeof(STRING) - 1) * 2, sizeof(STRING) - 1, buf}; \ +}()) + +#define wapp_str8_lit_ro(STRING) Str8RO{sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING} +#define wapp_str8_lit_ro_initialiser_list(STRING) {sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING} +#else #define wapp_str8_buf(CAPACITY) ((Str8){.capacity = CAPACITY, .size = 0, .buf = (c8[CAPACITY]){0}}) // Utilises the fact that memcpy returns pointer to dest buffer and that getting @@ -44,6 +68,7 @@ typedef const Str8 Str8RO; #define wapp_str8_lit_ro_initialiser_list(STRING) {.capacity = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \ .buf = (c8 *)STRING} +#endif // !WAPP_PLATFORM_CPP /** * Str8 allocated buffers @@ -94,4 +119,8 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8R #define wapp_str8_node_from_str8(STRING) wapp_str8_list_node(&(STRING)) u64 wapp_str8_list_total_size(const Str8List *list); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !STR8_H diff --git a/src/prng/xorshift/xorshift.h b/src/prng/xorshift/xorshift.h index 768d925..20d1aea 100644 --- a/src/prng/xorshift/xorshift.h +++ b/src/prng/xorshift/xorshift.h @@ -6,6 +6,10 @@ #include "../../common/aliases/aliases.h" #include "../../common/platform/platform.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + typedef struct xor_256_state XOR256State; struct xor_256_state { u64 x; @@ -19,4 +23,8 @@ u64 wapp_prng_xorshift_256(XOR256State *state); u64 wapp_prng_xorshift_256ss(XOR256State *state); u64 wapp_prng_xorshift_256p(XOR256State *state); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !XORSHIFT_H diff --git a/src/testing/tester/tester.h b/src/testing/tester/tester.h index 82bf8f8..60d41f3 100644 --- a/src/testing/tester/tester.h +++ b/src/testing/tester/tester.h @@ -8,6 +8,10 @@ #include "../../primitives/strings/str8/str8.h" #include +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED}) #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) @@ -25,4 +29,8 @@ typedef TestFuncResult(TestFunc)(void); void run_tests(TestFunc *func1, ...); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !TESTER_H diff --git a/src/uuid/uuid.h b/src/uuid/uuid.h index ca970a9..290a462 100644 --- a/src/uuid/uuid.h +++ b/src/uuid/uuid.h @@ -7,6 +7,10 @@ #include "../common/platform/platform.h" #include "../primitives/strings/str8/str8.h" +#ifdef WAPP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #define UUID_BUF_LENGTH 48 #define WAPP_UUID_SPEC WAPP_STR8_SPEC #define wapp_uuid_varg(UUID) wapp_str8_varg((UUID).uuid) @@ -26,4 +30,8 @@ struct uuid { // Fails when passed a NULL pointer. UUID *wapp_uuid_init_uuid4(UUID *uuid); +#ifdef WAPP_PLATFORM_CPP +END_C_LINKAGE +#endif // !WAPP_PLATFORM_CPP + #endif // !UUID_H