gb.hpp - #ifndef for many macros
This commit is contained in:
parent
9be05386ac
commit
a8f308e2cd
|
@ -6,7 +6,7 @@ library | latest version | category | languages | description
|
||||||
----------------|----------------|----------|-----------|-------------
|
----------------|----------------|----------|-----------|-------------
|
||||||
**gb_string.h** | 0.93 | strings | C, C++ | A better string library for C & C++
|
**gb_string.h** | 0.93 | strings | C, C++ | A better string library for C & C++
|
||||||
**gb_ini.h** | 0.91 | misc | C, C++ | A simple ini file loader library for C & C++
|
**gb_ini.h** | 0.91 | misc | C, C++ | A simple ini file loader library for C & C++
|
||||||
**gb.hpp** | 0.20 | misc | C++11 | (Experimental) A C++11 helper library without STL geared towards game development
|
**gb.hpp** | 0.20a | misc | C++11 | (Experimental) A C++11 helper library without STL geared towards game development
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
|
400
gb.hpp
400
gb.hpp
|
@ -1,8 +1,9 @@
|
||||||
// gb.hpp - v0.20 - public domain C++11 helper library - no warranty implied; use at your own risk
|
// gb.hpp - v0.20a - public domain C++11 helper library - no warranty implied; use at your own risk
|
||||||
// (Experimental) A C++11 helper library without STL geared towards game development
|
// (Experimental) A C++11 helper library without STL geared towards game development
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Version History:
|
Version History:
|
||||||
|
0.20a - #ifndef for many macros
|
||||||
0.20 - Angle
|
0.20 - Angle
|
||||||
0.19 - Cache friendly Transform and String fixes
|
0.19 - Cache friendly Transform and String fixes
|
||||||
0.18 - Hash_Table bug fixes
|
0.18 - Hash_Table bug fixes
|
||||||
|
@ -65,6 +66,7 @@ Context:
|
||||||
- Complex
|
- Complex
|
||||||
- Quaternion
|
- Quaternion
|
||||||
- Matrix(2,3,4)
|
- Matrix(2,3,4)
|
||||||
|
- Angle
|
||||||
- Euler_Angles
|
- Euler_Angles
|
||||||
- Transform
|
- Transform
|
||||||
- Aabb
|
- Aabb
|
||||||
|
@ -74,12 +76,6 @@ Context:
|
||||||
- Functions & Constants
|
- Functions & Constants
|
||||||
- Type Functions
|
- Type Functions
|
||||||
- Random
|
- Random
|
||||||
- Generator_Type
|
|
||||||
- Geneartor Definition (Template/Concept)
|
|
||||||
- Mt19937_32
|
|
||||||
- Mt19937_64
|
|
||||||
- Random_Device
|
|
||||||
- Functions
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GB_INCLUDE_GB_HPP
|
#ifndef GB_INCLUDE_GB_HPP
|
||||||
|
@ -91,17 +87,20 @@ Context:
|
||||||
|
|
||||||
// NOTE(bill): Because static means three different things in C/C++
|
// NOTE(bill): Because static means three different things in C/C++
|
||||||
// Great Design(!)
|
// Great Design(!)
|
||||||
|
#ifndef global
|
||||||
#define global static
|
#define global static
|
||||||
#define internal static
|
#define internal static
|
||||||
#define local_persist static
|
#define local_persist static
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define _ALLOW_KEYWORD_MACROS
|
#define _ALLOW_KEYWORD_MACROS
|
||||||
|
|
||||||
|
#ifndef alignof // Needed for MSVC 2013 'cause Microsoft "loves" standards
|
||||||
|
#define alignof(x) __alignof(x)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(alignof) // Needed for MSVC 2013 'cause Microsoft "loves" standards
|
|
||||||
#define alignof(x) __alignof(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
|
@ -109,16 +108,26 @@ Context:
|
||||||
/// ///
|
/// ///
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#ifndef GB_SYSTEM_WINDOWS
|
||||||
#define GB_SYSTEM_WINDOWS 1
|
#define GB_SYSTEM_WINDOWS 1
|
||||||
|
#endif
|
||||||
#elif defined(__APPLE__) && defined(__MACH__)
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#ifndef GB_SYSTEM_OSX
|
||||||
#define GB_SYSTEM_OSX 1
|
#define GB_SYSTEM_OSX 1
|
||||||
|
#endif
|
||||||
#elif defined(__unix__)
|
#elif defined(__unix__)
|
||||||
|
#ifndef GB_SYSTEM_UNIX
|
||||||
#define GB_SYSTEM_UNIX 1
|
#define GB_SYSTEM_UNIX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
#ifndef GB_SYSTEM_LINUX
|
||||||
#define GB_SYSTEM_LINUX 1
|
#define GB_SYSTEM_LINUX 1
|
||||||
|
#endif
|
||||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
|
#ifndef GB_SYSTEM_FREEBSD
|
||||||
#define GB_SYSTEM_FREEBSD 1
|
#define GB_SYSTEM_FREEBSD 1
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#error This UNIX operating system is not supported by gb.hpp
|
#error This UNIX operating system is not supported by gb.hpp
|
||||||
#endif
|
#endif
|
||||||
|
@ -133,21 +142,30 @@ Context:
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
|
#ifndef GB_ARCH_64_BIT
|
||||||
#define GB_ARCH_64_BIT 1
|
#define GB_ARCH_64_BIT 1
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
|
#ifndef GB_ARCH_32_BIT
|
||||||
#define GB_ARCH_32_BIT 1
|
#define GB_ARCH_32_BIT 1
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO(bill): Check if this KEPLER_ENVIRONMENT works on clang
|
// TODO(bill): Check if this KEPLER_ENVIRONMENT works on clang
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if defined(__x86_64__) || defined(__ppc64__)
|
#if defined(__x86_64__) || defined(__ppc64__)
|
||||||
|
#ifndef GB_ARCH_64_BIT
|
||||||
#define GB_ARCH_64_BIT 1
|
#define GB_ARCH_64_BIT 1
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
|
#ifndef GB_ARCH_32_BIT
|
||||||
#define GB_ARCH_32_BIT 1
|
#define GB_ARCH_32_BIT 1
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO(bill): Get this to work
|
||||||
// #if !defined(GB_LITTLE_EDIAN) && !defined(GB_BIG_EDIAN)
|
// #if !defined(GB_LITTLE_EDIAN) && !defined(GB_BIG_EDIAN)
|
||||||
|
|
||||||
// // Source: http://sourceforge.net/p/predef/wiki/Endianness/
|
// // Source: http://sourceforge.net/p/predef/wiki/Endianness/
|
||||||
|
@ -225,45 +243,50 @@ Context:
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#ifndef GB_ARRAY_BOUND_CHECKING
|
||||||
#define GB_ASSERT(x, ...) ((void)(::gb__assert_handler((x), #x, __FILE__, __LINE__, ##__VA_ARGS__)))
|
|
||||||
#else
|
|
||||||
#define GB_ASSERT(x, ...) ((void)sizeof(x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(GB_ARRAY_BOUND_CHECKING)
|
|
||||||
#define GB_ARRAY_BOUND_CHECKING 1
|
#define GB_ARRAY_BOUND_CHECKING 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GB_DISABLE_COPY
|
||||||
#define GB_DISABLE_COPY(Type) \
|
#define GB_DISABLE_COPY(Type) \
|
||||||
Type(const Type&) = delete; \
|
Type(const Type&) = delete; \
|
||||||
Type& operator=(const Type&) = delete
|
Type& operator=(const Type&) = delete
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Helper function used as a better alternative to assert which allows for
|
#if !defined(GB_ASSERT)
|
||||||
/// optional printf style error messages
|
#if !defined(NDEBUG)
|
||||||
extern "C" inline void
|
#define GB_ASSERT(x, ...) ((void)(::gb__assert_handler((x), #x, __FILE__, __LINE__, ##__VA_ARGS__)))
|
||||||
gb__assert_handler(bool condition, const char* condition_str,
|
|
||||||
const char* filename, size_t line,
|
|
||||||
const char* error_text = nullptr, ...)
|
|
||||||
{
|
|
||||||
if (condition)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fprintf(stderr, "ASSERT! %s(%lu): %s", filename, line, condition_str);
|
/// Helper function used as a better alternative to assert which allows for
|
||||||
if (error_text)
|
/// optional printf style error messages
|
||||||
{
|
extern "C" inline void
|
||||||
fprintf(stderr, " - ");
|
gb__assert_handler(bool condition, const char* condition_str,
|
||||||
|
const char* filename, size_t line,
|
||||||
|
const char* error_text = nullptr, ...)
|
||||||
|
{
|
||||||
|
if (condition)
|
||||||
|
return;
|
||||||
|
|
||||||
va_list args;
|
fprintf(stderr, "ASSERT! %s(%lu): %s", filename, line, condition_str);
|
||||||
va_start(args, error_text);
|
if (error_text)
|
||||||
vfprintf(stderr, error_text, args);
|
{
|
||||||
va_end(args);
|
fprintf(stderr, " - ");
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
va_list args;
|
||||||
// TODO(bill): Get a better way to abort
|
va_start(args, error_text);
|
||||||
*(int*)0 = 0;
|
vfprintf(stderr, error_text, args);
|
||||||
}
|
va_end(args);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
// TODO(bill): Get a better way to abort
|
||||||
|
*(int*)0 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define GB_ASSERT(x, ...) ((void)sizeof(x))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
|
@ -271,34 +294,32 @@ gb__assert_handler(bool condition, const char* condition_str,
|
||||||
/// ///
|
/// ///
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
extern "C" inline int
|
||||||
|
gb__vsnprintf_compatible(char* buffer, size_t size, const char* format, va_list args)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
if (size > 0)
|
||||||
|
result = _vsnprintf_s(buffer, size, _TRUNCATE, format, args);
|
||||||
|
if (result == -1)
|
||||||
|
return _vscprintf(format, args);
|
||||||
|
|
||||||
extern "C" inline int
|
return result;
|
||||||
gb__vsnprintf_compatible(char* buffer, size_t size, const char* format, va_list args)
|
}
|
||||||
{
|
|
||||||
int result = -1;
|
|
||||||
if (size > 0)
|
|
||||||
result = _vsnprintf_s(buffer, size, _TRUNCATE, format, args);
|
|
||||||
if (result == -1)
|
|
||||||
return _vscprintf(format, args);
|
|
||||||
|
|
||||||
return result;
|
extern "C" inline int
|
||||||
}
|
gb__snprintf_compatible(char* buffer, size_t size, const char* format, ...)
|
||||||
|
{
|
||||||
extern "C" inline int
|
va_list args;
|
||||||
gb__snprintf_compatible(char* buffer, size_t size, const char* format, ...)
|
va_start(args, format);
|
||||||
{
|
int result = gb__vsnprintf_compatible(buffer, size, format, args);
|
||||||
va_list args;
|
va_end(args);
|
||||||
va_start(args, format);
|
return result;
|
||||||
int result = gb__vsnprintf_compatible(buffer, size, format, args);
|
}
|
||||||
va_end(args);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(GB_DO_NOT_USE_MSVC_SPRINTF_FIX)
|
|
||||||
#define snprintf gb__snprintf_compatible
|
|
||||||
#define vsnprintf gb__vsnprintf_compatible
|
|
||||||
#endif // GB_DO_NOT_USE_MSVC_SPRINTF_FIX
|
|
||||||
|
|
||||||
|
#if !defined(GB_DO_NOT_USE_MSVC_SPRINTF_FIX)
|
||||||
|
#define snprintf gb__snprintf_compatible
|
||||||
|
#define vsnprintf gb__vsnprintf_compatible
|
||||||
|
#endif // GB_DO_NOT_USE_MSVC_SPRINTF_FIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__GB_NAMESPACE_PREFIX) && !defined(GB_NO_GB_NAMESPACE)
|
#if !defined(__GB_NAMESPACE_PREFIX) && !defined(GB_NO_GB_NAMESPACE)
|
||||||
|
@ -327,96 +348,101 @@ __GB_NAMESPACE_START
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GB_BASIC_TYPES
|
||||||
|
#define GB_BASIC_TYPES
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
using u8 = unsigned __int8;
|
||||||
|
using s8 = signed __int8;
|
||||||
|
using u16 = unsigned __int16;
|
||||||
|
using s16 = signed __int16;
|
||||||
|
using u32 = unsigned __int32;
|
||||||
|
using s32 = signed __int32;
|
||||||
|
using u64 = unsigned __int64;
|
||||||
|
using s64 = signed __int64;
|
||||||
|
#else
|
||||||
|
using u8 = unsigned char;
|
||||||
|
using s8 = signed char;
|
||||||
|
using u16 = unsigned short;
|
||||||
|
using s16 = signed short;
|
||||||
|
using u32 = unsigned int;
|
||||||
|
using s32 = signed int;
|
||||||
|
using u64 = unsigned long long;
|
||||||
|
using s64 = signed long long;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert( sizeof(u8) == 1, "u8 is not 8 bits");
|
||||||
|
static_assert(sizeof(u16) == 2, "u16 is not 16 bits");
|
||||||
|
static_assert(sizeof(u32) == 4, "u32 is not 32 bits");
|
||||||
|
static_assert(sizeof(u64) == 8, "u64 is not 64 bits");
|
||||||
|
|
||||||
|
using f32 = float;
|
||||||
|
using f64 = double;
|
||||||
|
|
||||||
|
#if defined(GB_B8_AS_BOOL)
|
||||||
|
using b8 = bool;
|
||||||
|
#else
|
||||||
|
using b8 = s8;
|
||||||
|
#endif
|
||||||
|
using b32 = s32;
|
||||||
|
|
||||||
|
// NOTE(bill): (std::)size_t is not used not because it's a bad concept but on
|
||||||
|
// the platforms that I will be using:
|
||||||
|
// sizeof(size_t) == sizeof(usize) == sizeof(s64)
|
||||||
|
// NOTE(bill): This also allows for a signed version of size_t which is similar
|
||||||
|
// to ptrdiff_t
|
||||||
|
// NOTE(bill): If (u)intptr is a better fit, please use that.
|
||||||
|
// NOTE(bill): Also, I hate the `_t` suffix
|
||||||
|
#if defined(GB_ARCH_64_BIT)
|
||||||
|
using ssize = s64;
|
||||||
|
using usize = u64;
|
||||||
|
#elif defined(GB_ARCH_32_BIT)
|
||||||
|
using usize = s32;
|
||||||
|
using usize = u32;
|
||||||
|
#else
|
||||||
|
#error Unknown architecture bit size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert(sizeof(usize) == sizeof(size_t),
|
||||||
|
"`usize` is not the same size as `size_t`");
|
||||||
|
static_assert(sizeof(ssize) == sizeof(usize),
|
||||||
|
"`ssize` is not the same size as `usize`");
|
||||||
|
|
||||||
|
using intptr = intptr_t;
|
||||||
|
using uintptr = uintptr_t;
|
||||||
|
|
||||||
|
using ptrdiff = ptrdiff_t;
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
using u8 = unsigned __int8;
|
|
||||||
using s8 = signed __int8;
|
|
||||||
using u16 = unsigned __int16;
|
|
||||||
using s16 = signed __int16;
|
|
||||||
using u32 = unsigned __int32;
|
|
||||||
using s32 = signed __int32;
|
|
||||||
using u64 = unsigned __int64;
|
|
||||||
using s64 = signed __int64;
|
|
||||||
#else
|
|
||||||
using u8 = unsigned char;
|
|
||||||
using s8 = signed char;
|
|
||||||
using u16 = unsigned short;
|
|
||||||
using s16 = signed short;
|
|
||||||
using u32 = unsigned int;
|
|
||||||
using s32 = signed int;
|
|
||||||
using u64 = unsigned long long;
|
|
||||||
using s64 = signed long long;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert( sizeof(u8) == 1, "u8 is not 8 bits");
|
#if !defined(GB_U8_MIN)
|
||||||
static_assert(sizeof(u16) == 2, "u16 is not 16 bits");
|
#define GB_U8_MIN 0u
|
||||||
static_assert(sizeof(u32) == 4, "u32 is not 32 bits");
|
#define GB_U8_MAX 0xffu
|
||||||
static_assert(sizeof(u64) == 8, "u64 is not 64 bits");
|
#define GB_S8_MIN (-0x7f - 1)
|
||||||
|
#define GB_S8_MAX 0x7f
|
||||||
|
|
||||||
using f32 = float;
|
#define GB_U16_MIN 0u
|
||||||
using f64 = double;
|
#define GB_U16_MAX 0xffffu
|
||||||
|
#define GB_S16_MIN (-0x7fff - 1)
|
||||||
|
#define GB_S16_MAX 0x7fff
|
||||||
|
|
||||||
#if defined(GB_B8_AS_BOOL)
|
#define GB_U32_MIN 0u
|
||||||
using b8 = bool;
|
#define GB_U32_MAX 0xffffffffu
|
||||||
#else
|
#define GB_S32_MIN (-0x7fffffff - 1)
|
||||||
using b8 = s8;
|
#define GB_S32_MAX 0x7fffffff
|
||||||
#endif
|
|
||||||
using b32 = s32;
|
|
||||||
|
|
||||||
// NOTE(bill): (std::)size_t is not used not because it's a bad concept but on
|
#define GB_U64_MIN 0ull
|
||||||
// the platforms that I will be using:
|
#define GB_U64_MAX 0xffffffffffffffffull
|
||||||
// sizeof(size_t) == sizeof(usize) == sizeof(s64)
|
#define GB_S64_MIN (-0x7fffffffffffffffll - 1)
|
||||||
// NOTE(bill): This also allows for a signed version of size_t which is similar
|
#define GB_S64_MAX 0x7fffffffffffffffll
|
||||||
// to ptrdiff_t
|
|
||||||
// NOTE(bill): If (u)intptr is a better fit, please use that.
|
|
||||||
// NOTE(bill): Also, I hate the `_t` suffix
|
|
||||||
#if defined(GB_ARCH_64_BIT)
|
|
||||||
using ssize = s64;
|
|
||||||
using usize = u64;
|
|
||||||
#elif defined(GB_ARCH_32_BIT)
|
|
||||||
using usize = s32;
|
|
||||||
using usize = u32;
|
|
||||||
#else
|
|
||||||
#error Unknown architecture bit size
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert(sizeof(usize) == sizeof(size_t),
|
#if defined(GB_ARCH_64_BIT) && !defined(GB_USIZE_MIX)
|
||||||
"`usize` is not the same size as `size_t`");
|
|
||||||
static_assert(sizeof(ssize) == sizeof(usize),
|
|
||||||
"`ssize` is not the same size as `usize`");
|
|
||||||
|
|
||||||
using intptr = intptr_t;
|
|
||||||
using uintptr = uintptr_t;
|
|
||||||
|
|
||||||
using ptrdiff = ptrdiff_t;
|
|
||||||
|
|
||||||
#define GB_U8_MIN 0u
|
|
||||||
#define GB_U8_MAX 0xffu
|
|
||||||
#define GB_S8_MIN (-0x7f - 1)
|
|
||||||
#define GB_S8_MAX 0x7f
|
|
||||||
|
|
||||||
#define GB_U16_MIN 0u
|
|
||||||
#define GB_U16_MAX 0xffffu
|
|
||||||
#define GB_S16_MIN (-0x7fff - 1)
|
|
||||||
#define GB_S16_MAX 0x7fff
|
|
||||||
|
|
||||||
#define GB_U32_MIN 0u
|
|
||||||
#define GB_U32_MAX 0xffffffffu
|
|
||||||
#define GB_S32_MIN (-0x7fffffff - 1)
|
|
||||||
#define GB_S32_MAX 0x7fffffff
|
|
||||||
|
|
||||||
#define GB_U64_MIN 0ull
|
|
||||||
#define GB_U64_MAX 0xffffffffffffffffull
|
|
||||||
#define GB_S64_MIN (-0x7fffffffffffffffll - 1)
|
|
||||||
#define GB_S64_MAX 0x7fffffffffffffffll
|
|
||||||
|
|
||||||
#if defined(GB_ARCH_64_BIT)
|
|
||||||
#define GB_USIZE_MIX GB_U64_MIN
|
#define GB_USIZE_MIX GB_U64_MIN
|
||||||
#define GB_USIZE_MAX GB_U64_MAX
|
#define GB_USIZE_MAX GB_U64_MAX
|
||||||
|
|
||||||
#define GB_SSIZE_MIX GB_S64_MIN
|
#define GB_SSIZE_MIX GB_S64_MIN
|
||||||
#define GB_SSIZE_MAX GB_S64_MAX
|
#define GB_SSIZE_MAX GB_S64_MAX
|
||||||
#elif defined(GB_ARCH_32_BIT)
|
#elif defined(GB_ARCH_32_BIT) && !defined(GB_USIZE_MIX)
|
||||||
#define GB_USIZE_MIX GB_U32_MIN
|
#define GB_USIZE_MIX GB_U32_MIN
|
||||||
#define GB_USIZE_MAX GB_U32_MAX
|
#define GB_USIZE_MAX GB_U32_MAX
|
||||||
|
|
||||||
|
@ -424,7 +450,7 @@ using ptrdiff = ptrdiff_t;
|
||||||
#define GB_SSIZE_MAX GB_S32_MAX
|
#define GB_SSIZE_MAX GB_S32_MAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GB_BASIC_WITHOUT_NAMESPACE)
|
#if defined(GB_BASIC_WITHOUT_NAMESPACE) && !defined(U8_MIN)
|
||||||
#define U8_MIN 0u
|
#define U8_MIN 0u
|
||||||
#define U8_MAX 0xffu
|
#define U8_MAX 0xffu
|
||||||
#define S8_MIN (-0x7f - 1)
|
#define S8_MIN (-0x7f - 1)
|
||||||
|
@ -445,13 +471,13 @@ using ptrdiff = ptrdiff_t;
|
||||||
#define S64_MIN (-0x7fffffffffffffffll - 1)
|
#define S64_MIN (-0x7fffffffffffffffll - 1)
|
||||||
#define S64_MAX 0x7fffffffffffffffll
|
#define S64_MAX 0x7fffffffffffffffll
|
||||||
|
|
||||||
#if defined(GB_ARCH_64_BIT)
|
#if defined(GB_ARCH_64_BIT) && !defined(GB_USIZE_MIX)
|
||||||
#define USIZE_MIX U64_MIN
|
#define USIZE_MIX U64_MIN
|
||||||
#define USIZE_MAX U64_MAX
|
#define USIZE_MAX U64_MAX
|
||||||
|
|
||||||
#define SSIZE_MIX S64_MIN
|
#define SSIZE_MIX S64_MIN
|
||||||
#define SSIZE_MAX S64_MAX
|
#define SSIZE_MAX S64_MAX
|
||||||
#elif defined(GB_ARCH_32_BIT)
|
#elif defined(GB_ARCH_32_BIT) && !defined(GB_USIZE_MIX)
|
||||||
#define USIZE_MIX U32_MIN
|
#define USIZE_MIX U32_MIN
|
||||||
#define USIZE_MAX U32_MAX
|
#define USIZE_MAX U32_MAX
|
||||||
|
|
||||||
|
@ -564,60 +590,68 @@ move(T&& t)
|
||||||
{
|
{
|
||||||
return static_cast<Remove_Reference<T>&&>(t);
|
return static_cast<Remove_Reference<T>&&>(t);
|
||||||
}
|
}
|
||||||
|
__GB_NAMESPACE_END
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
/// Defer ///
|
/// Defer ///
|
||||||
/// ///
|
/// ///
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
namespace impl
|
#ifndef GB_DEFER
|
||||||
{
|
#define GB_DEFER
|
||||||
template <typename Func>
|
__GB_NAMESPACE_START
|
||||||
struct Defer
|
namespace impl
|
||||||
{
|
{
|
||||||
Func f;
|
template <typename Func>
|
||||||
|
struct Defer
|
||||||
|
{
|
||||||
|
Func f;
|
||||||
|
|
||||||
Defer(Func&& f) : f{forward<Func>(f)} {}
|
Defer(Func&& f) : f{forward<Func>(f)} {}
|
||||||
~Defer() { f(); };
|
~Defer() { f(); };
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
inline Defer<Func>
|
inline Defer<Func>
|
||||||
defer_func(Func&& f) { return Defer<Func>(forward<Func>(f)); }
|
defer_func(Func&& f) { return Defer<Func>(forward<Func>(f)); }
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
__GB_NAMESPACE_END
|
__GB_NAMESPACE_END
|
||||||
|
|
||||||
// NOTE(bill): These macros are in the global namespace thus, defer can be treated without a __GB_NAMESPACE_PREFIX:: prefix
|
// NOTE(bill): These macros are in the global namespace thus, defer can be treated without a __GB_NAMESPACE_PREFIX:: prefix
|
||||||
#define GB_DEFER_1(x, y) x##y
|
#define GB_DEFER_1(x, y) x##y
|
||||||
#define GB_DEFER_2(x, y) GB_DEFER_1(x, y)
|
#define GB_DEFER_2(x, y) GB_DEFER_1(x, y)
|
||||||
#define GB_DEFER_3(x) GB_DEFER_2(GB_DEFER_2(GB_DEFER_2(x, __COUNTER__), _), __LINE__)
|
#define GB_DEFER_3(x) GB_DEFER_2(GB_DEFER_2(GB_DEFER_2(x, __COUNTER__), _), __LINE__)
|
||||||
#define defer(code) auto GB_DEFER_3(_defer_) = __GB_NAMESPACE_PREFIX::impl::defer_func([&](){code;})
|
#define defer(code) auto GB_DEFER_3(_defer_) = __GB_NAMESPACE_PREFIX::impl::defer_func([&](){code;})
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(GB_CASTS_WITHOUT_NAMESPACE)
|
#if !defined(GB_CASTS_WITHOUT_NAMESPACE)
|
||||||
__GB_NAMESPACE_START
|
__GB_NAMESPACE_START
|
||||||
#endif // GB_CASTS_WITHOUT_NAMESPACE
|
#endif // GB_CASTS_WITHOUT_NAMESPACE
|
||||||
|
|
||||||
// IMPORTANT NOTE(bill): Very similar to doing `*(T*)(&u)` but easier/clearer to write
|
#ifndef GB_SPECIAL_CASTS
|
||||||
// however, it can be dangerous if sizeof(T) > sizeof(U) e.g. unintialized memory, undefined behavior
|
#define GB_SPECIAL_CASTS
|
||||||
// *(T*)(&u) ~~ pseudo_cast<T>(u)
|
// IMPORTANT NOTE(bill): Very similar to doing `*(T*)(&u)` but easier/clearer to write
|
||||||
template <typename T, typename U>
|
// however, it can be dangerous if sizeof(T) > sizeof(U) e.g. unintialized memory, undefined behavior
|
||||||
inline T
|
// *(T*)(&u) ~~ pseudo_cast<T>(u)
|
||||||
pseudo_cast(const U& u)
|
template <typename T, typename U>
|
||||||
{
|
inline T
|
||||||
return reinterpret_cast<const T&>(u);
|
pseudo_cast(const U& u)
|
||||||
}
|
{
|
||||||
|
return reinterpret_cast<const T&>(u);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(bill): Very similar to doing `*(T*)(&u)`
|
// NOTE(bill): Very similar to doing `*(T*)(&u)`
|
||||||
template <typename Dest, typename Source>
|
template <typename Dest, typename Source>
|
||||||
inline Dest
|
inline Dest
|
||||||
bit_cast(const Source& source)
|
bit_cast(const Source& source)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(Dest) <= sizeof(Source),
|
static_assert(sizeof(Dest) <= sizeof(Source),
|
||||||
"bit_cast<Dest>(const Source&) - sizeof(Dest) <= sizeof(Source)");
|
"bit_cast<Dest>(const Source&) - sizeof(Dest) <= sizeof(Source)");
|
||||||
Dest dest;
|
Dest dest;
|
||||||
::memcpy(&dest, &source, sizeof(Dest));
|
::memcpy(&dest, &source, sizeof(Dest));
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// FORENOTE(bill): There used to be a magic_cast that was equivalent to
|
// FORENOTE(bill): There used to be a magic_cast that was equivalent to
|
||||||
// a C-style cast but I removed it as I could not get it work as intented
|
// a C-style cast but I removed it as I could not get it work as intented
|
||||||
|
|
Loading…
Reference in New Issue