gb.hpp v0.25 - gb_math.hpp v0.03
0.25 - Faster Heap_Allocator for Windows using HeapAlloc 0.03 - Remove templated min/max/clamp
This commit is contained in:
parent
ddcc482418
commit
2159ae399a
|
@ -5,7 +5,7 @@ gb single-file public domain libraries for C & C++
|
||||||
library | latest version | category | languages | description
|
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.hpp** | 0.24b | misc | C++11 | (Experimental) A C++11 helper library without STL geared towards game development
|
**gb.hpp** | 0.25 | misc | C++11 | (Experimental) A C++11 helper library without STL geared towards game development
|
||||||
**gb_math.hpp** | 0.02b | math | C++11 | A C++11 math library geared towards game development
|
**gb_math.hpp** | 0.02b | math | C++11 | A C++11 math library geared towards game development
|
||||||
**gb_ini.h** | 0.91a | misc | C, C++ | A simple ini file loader library for C & C++
|
**gb_ini.h** | 0.91a | misc | C, C++ | A simple ini file loader library for C & C++
|
||||||
|
|
||||||
|
|
143
gb.hpp
143
gb.hpp
|
@ -1,4 +1,4 @@
|
||||||
// gb.hpp - v0.24b - public domain C++11 helper library - no warranty implied; use at your own risk
|
// gb.hpp - v0.25 - 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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -218,11 +218,6 @@ CONTENTS:
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GB_ARRAY_BOUND_CHECKING
|
|
||||||
#define GB_ARRAY_BOUND_CHECKING 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef GB_DISABLE_COPY
|
#ifndef GB_DISABLE_COPY
|
||||||
#define GB_DISABLE_COPY(Type) \
|
#define GB_DISABLE_COPY(Type) \
|
||||||
Type(const Type&) = delete; \
|
Type(const Type&) = delete; \
|
||||||
|
@ -838,7 +833,7 @@ namespace thread
|
||||||
Thread make();
|
Thread make();
|
||||||
void destroy(Thread* t);
|
void destroy(Thread* t);
|
||||||
void start(Thread* t, Thread_Function* func, void* data = nullptr, usize stack_size = 0);
|
void start(Thread* t, Thread_Function* func, void* data = nullptr, usize stack_size = 0);
|
||||||
void stop(Thread* t);
|
void join(Thread* t);
|
||||||
bool is_running(const Thread& t);
|
bool is_running(const Thread& t);
|
||||||
u32 current_id();
|
u32 current_id();
|
||||||
} // namespace thread
|
} // namespace thread
|
||||||
|
@ -948,10 +943,18 @@ struct Allocator
|
||||||
/// Allocations are padded with to align them to the desired alignment
|
/// Allocations are padded with to align them to the desired alignment
|
||||||
struct Heap_Allocator : Allocator
|
struct Heap_Allocator : Allocator
|
||||||
{
|
{
|
||||||
Mutex mutex = mutex::make();
|
struct Header
|
||||||
|
{
|
||||||
|
usize size;
|
||||||
|
};
|
||||||
|
|
||||||
s64 total_allocated_count = 0;
|
s64 total_allocated_count = 0;
|
||||||
s64 allocation_count = 0;
|
s64 allocation_count = 0;
|
||||||
|
|
||||||
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
|
HANDLE heap_handle = HeapCreate(0, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
Heap_Allocator() = default;
|
Heap_Allocator() = default;
|
||||||
virtual ~Heap_Allocator();
|
virtual ~Heap_Allocator();
|
||||||
|
|
||||||
|
@ -1042,6 +1045,7 @@ void* copy(const void* src, usize bytes, void* dest);
|
||||||
void* move(const void* src, usize bytes, void* dest);
|
void* move(const void* src, usize bytes, void* dest);
|
||||||
bool equals(const void* a, const void* b, usize bytes);
|
bool equals(const void* a, const void* b, usize bytes);
|
||||||
|
|
||||||
|
// TODO(bill): Should this be just zero(T*) ???
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* zero_struct(T* ptr);
|
T* zero_struct(T* ptr);
|
||||||
|
|
||||||
|
@ -1049,6 +1053,12 @@ template <typename T>
|
||||||
T* copy_array(const T* src_array, usize count, T* dest_array);
|
T* copy_array(const T* src_array, usize count, T* dest_array);
|
||||||
|
|
||||||
// TODO(bill): Should I implement something like std::copy, std::fill, std::fill_n ???
|
// TODO(bill): Should I implement something like std::copy, std::fill, std::fill_n ???
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void swap(T* a, T* b);
|
||||||
|
|
||||||
|
template <typename T, usize N>
|
||||||
|
void swap(T (& a)[N], T (& b)[N]);
|
||||||
} // namespace memory
|
} // namespace memory
|
||||||
|
|
||||||
void* alloc(Allocator* a, usize size, usize align = GB_DEFAULT_ALIGNMENT);
|
void* alloc(Allocator* a, usize size, usize align = GB_DEFAULT_ALIGNMENT);
|
||||||
|
@ -1148,6 +1158,10 @@ void format_uint(u64 value, char* buffer, usize len);
|
||||||
/// ///
|
/// ///
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef GB_ARRAY_BOUND_CHECKING
|
||||||
|
#define GB_ARRAY_BOUND_CHECKING 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Dynamic resizable array for POD types only
|
/// Dynamic resizable array for POD types only
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Array
|
struct Array
|
||||||
|
@ -1281,7 +1295,6 @@ template <typename T> void remove_entry(Hash_Table<T>* h, typename const Hash_Ta
|
||||||
template <typename T> void remove_all(Hash_Table<T>* h, u64 key);
|
template <typename T> void remove_all(Hash_Table<T>* h, u64 key);
|
||||||
} // namespace multi_hash_table
|
} // namespace multi_hash_table
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
/// Hash ///
|
/// Hash ///
|
||||||
|
@ -1519,9 +1532,9 @@ Array<T>::Array(const Array<T>& other)
|
||||||
, capacity(0)
|
, capacity(0)
|
||||||
, data(nullptr)
|
, data(nullptr)
|
||||||
{
|
{
|
||||||
const auto n = other.count;
|
const auto count = other.count;
|
||||||
array::set_capacity(this, n);
|
array::set_capacity(this, count);
|
||||||
memory::copy(other.data, n * sizeof(T), data);
|
memory::copy_array(other.data, count, data);
|
||||||
count = n;
|
count = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1552,9 +1565,9 @@ Array<T>::operator=(const Array<T>& other)
|
||||||
{
|
{
|
||||||
if (allocator == nullptr)
|
if (allocator == nullptr)
|
||||||
allocator = other.allocator;
|
allocator = other.allocator;
|
||||||
const auto n = other.count;
|
const auto count = other.count;
|
||||||
array::resize(this, n);
|
array::resize(this, count);
|
||||||
memory::copy(other.data, n * sizeof(T), data);
|
memory::copy_count(other.data, count, data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1660,7 +1673,7 @@ append(Array<T>* a, const T* items, usize count)
|
||||||
if (a->capacity <= a->count + static_cast<s64>(count))
|
if (a->capacity <= a->count + static_cast<s64>(count))
|
||||||
array::grow(a, a->count + count);
|
array::grow(a, a->count + count);
|
||||||
|
|
||||||
memory::copy(items, count * sizeof(T), &a->data[a->count]);
|
memory::copy_array(items, count, &a->data[a->count]);
|
||||||
a->count += count;
|
a->count += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1711,7 +1724,7 @@ set_capacity(Array<T>* a, usize capacity)
|
||||||
if (capacity > 0)
|
if (capacity > 0)
|
||||||
{
|
{
|
||||||
data = alloc_array<T>(a->allocator, capacity);
|
data = alloc_array<T>(a->allocator, capacity);
|
||||||
memory::copy(a->data, a->count * sizeof(T), data);
|
memory::copy_array(a->data, a->count, data);
|
||||||
}
|
}
|
||||||
dealloc(a->allocator, a->data);
|
dealloc(a->allocator, a->data);
|
||||||
a->data = data;
|
a->data = data;
|
||||||
|
@ -2200,6 +2213,23 @@ copy_array(const T* src_array, usize count, T* dest_array)
|
||||||
{
|
{
|
||||||
return static_cast<T*>(memory::copy(src_array, count * sizeof(T), dest_array));
|
return static_cast<T*>(memory::copy(src_array, count * sizeof(T), dest_array));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void
|
||||||
|
swap(T* a, T* b)
|
||||||
|
{
|
||||||
|
T c = __GB_NAMESPACE_START::move(*a);
|
||||||
|
*a = __GB_NAMESPACE_START::move(*b);
|
||||||
|
*b = __GB_NAMESPACE_START::move(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, usize N>
|
||||||
|
inline void
|
||||||
|
swap(T (& a)[N], T (& b)[N])
|
||||||
|
{
|
||||||
|
for (usize i = 0; i < N; i++)
|
||||||
|
math::swap(&a[i], &b[i]);
|
||||||
|
}
|
||||||
} // namespace memory
|
} // namespace memory
|
||||||
|
|
||||||
|
|
||||||
|
@ -2607,7 +2637,7 @@ void
|
||||||
destroy(Thread* t)
|
destroy(Thread* t)
|
||||||
{
|
{
|
||||||
if (t->is_running)
|
if (t->is_running)
|
||||||
thread::stop(t);
|
thread::join(t);
|
||||||
|
|
||||||
semaphore::destroy(&t->semaphore);
|
semaphore::destroy(&t->semaphore);
|
||||||
}
|
}
|
||||||
|
@ -2677,7 +2707,7 @@ start(Thread* t, Thread_Function* func, void* data, usize stack_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stop(Thread* t)
|
join(Thread* t)
|
||||||
{
|
{
|
||||||
if (!t->is_running)
|
if (!t->is_running)
|
||||||
return;
|
return;
|
||||||
|
@ -2705,13 +2735,11 @@ current_id()
|
||||||
{
|
{
|
||||||
u32 thread_id;
|
u32 thread_id;
|
||||||
|
|
||||||
|
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
u8* thread_local_storage = reinterpret_cast<u8*>(__readgsqword(0x30));
|
u8* thread_local_storage = reinterpret_cast<u8*>(__readgsqword(0x30));
|
||||||
thread_id = *reinterpret_cast<u32*>(thread_local_storage + 0x48);
|
thread_id = *reinterpret_cast<u32*>(thread_local_storage + 0x48);
|
||||||
|
|
||||||
#elif defined(GB_SYSTEM_OSX) && defined(GB_ARCH_64_BIT)
|
#elif defined(GB_SYSTEM_OSX) && defined(GB_ARCH_64_BIT)
|
||||||
u32 thread_id;
|
|
||||||
asm("mov %%gs:0x00,%0" : "=r"(thread_id));
|
asm("mov %%gs:0x00,%0" : "=r"(thread_id));
|
||||||
#elif defined(GB_ARCH_32_BIT)
|
#elif defined(GB_ARCH_32_BIT)
|
||||||
asm("mov %%gs:0x08,%0" : "=r"(thread_id));
|
asm("mov %%gs:0x08,%0" : "=r"(thread_id));
|
||||||
|
@ -2721,7 +2749,6 @@ current_id()
|
||||||
#error Unsupported architecture for thread::current_id()
|
#error Unsupported architecture for thread::current_id()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return thread_id;
|
return thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2886,24 +2913,32 @@ free(Data* tmp)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
//#define GB_HEAP_ALLOCATOR_HEADER_PAD_VALUE (usize)(-1)
|
|
||||||
Heap_Allocator::~Heap_Allocator()
|
Heap_Allocator::~Heap_Allocator()
|
||||||
{
|
{
|
||||||
#if 0
|
#if defined (GB_SYSTEM_WINDOWS)
|
||||||
GB_ASSERT(allocation_count == 0 && total_allocated() == 0,
|
HeapDestroy(heap_handle);
|
||||||
"Heap Allocator: allocation count = %lld; total allocated = %lld",
|
#else
|
||||||
allocation_count, total_allocated());
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
Heap_Allocator::alloc(usize size, usize align)
|
Heap_Allocator::alloc(usize size, usize align)
|
||||||
{
|
{
|
||||||
mutex::lock(&mutex);
|
|
||||||
defer (mutex::unlock(&mutex));
|
|
||||||
|
|
||||||
usize total = size + align - (size % align);
|
usize total = size + align - (size % align);
|
||||||
|
|
||||||
|
#if defined (GB_SYSTEM_WINDOWS)
|
||||||
|
total += sizeof(Header);
|
||||||
|
|
||||||
|
void* data = HeapAlloc(heap_handle, 0, total);
|
||||||
|
Header* h = static_cast<Header*>(data);
|
||||||
|
h->size = total;
|
||||||
|
data = (h + 1);
|
||||||
|
|
||||||
|
#else
|
||||||
|
// TODO(bill): Find a better malloc alternative for this platform
|
||||||
void* data = malloc(total);
|
void* data = malloc(total);
|
||||||
|
#endif
|
||||||
|
|
||||||
total_allocated_count += total;
|
total_allocated_count += total;
|
||||||
allocation_count++;
|
allocation_count++;
|
||||||
|
@ -2917,27 +2952,34 @@ Heap_Allocator::dealloc(const void* ptr)
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex::lock(&mutex);
|
|
||||||
defer (mutex::unlock(&mutex));
|
|
||||||
|
|
||||||
total_allocated_count -= this->allocated_size(ptr);
|
total_allocated_count -= this->allocated_size(ptr);
|
||||||
allocation_count--;
|
allocation_count--;
|
||||||
|
|
||||||
|
#if defined (GB_SYSTEM_WINDOWS)
|
||||||
|
ptr = static_cast<const Header*>(ptr) + 1;
|
||||||
|
HeapFree(heap_handle, 0, const_cast<void*>(ptr));
|
||||||
|
|
||||||
|
#else
|
||||||
::free(const_cast<void*>(ptr));
|
::free(const_cast<void*>(ptr));
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64
|
inline s64
|
||||||
Heap_Allocator::allocated_size(const void* ptr)
|
Heap_Allocator::allocated_size(const void* ptr)
|
||||||
{
|
{
|
||||||
mutex::lock(&mutex);
|
|
||||||
defer (mutex::unlock(&mutex));
|
|
||||||
|
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
return static_cast<usize>(_msize(const_cast<void*>(ptr)));
|
const Header* h = static_cast<const Header*>(ptr) - 1;
|
||||||
|
return static_cast<usize>(h->size);
|
||||||
|
|
||||||
#elif defined(GB_SYSTEM_OSX)
|
#elif defined(GB_SYSTEM_OSX)
|
||||||
return static_cast<usize>(malloc_size(ptr));
|
return static_cast<usize>(malloc_size(ptr));
|
||||||
#else
|
|
||||||
|
#elif defined(GB_SYSTEM_LINUX)
|
||||||
return static_cast<usize>(malloc_usable_size(const_cast<void*>(ptr)));
|
return static_cast<usize>(malloc_usable_size(const_cast<void*>(ptr)));
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Implement Heap_Allocator::allocated_size
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2971,8 +3013,10 @@ Arena_Allocator::~Arena_Allocator()
|
||||||
if (backing)
|
if (backing)
|
||||||
backing->dealloc(physical_start);
|
backing->dealloc(physical_start);
|
||||||
|
|
||||||
GB_ASSERT(total_allocated_count == 0,
|
GB_ASSERT(temp_count == 0,
|
||||||
"Memory leak of %ld bytes, maybe you forgot to call arena_allocator::clear()?", total_allocated_count);
|
"%ld Temporary_Arena_Memory have not be cleared", temp_count);
|
||||||
|
|
||||||
|
total_allocated_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
|
@ -3035,7 +3079,6 @@ free(Temporary_Arena_Memory* tmp)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
/// Memory ///
|
/// Memory ///
|
||||||
|
@ -3197,17 +3240,19 @@ make(Allocator* a, const void* init_str, Size len)
|
||||||
{
|
{
|
||||||
usize header_size = sizeof(string::Header);
|
usize header_size = sizeof(string::Header);
|
||||||
void* ptr = alloc(a, header_size + len + 1);
|
void* ptr = alloc(a, header_size + len + 1);
|
||||||
|
if (!ptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (!init_str)
|
if (!init_str)
|
||||||
memory::zero(ptr, header_size + len + 1);
|
memory::zero(ptr, header_size + len + 1);
|
||||||
|
|
||||||
if (ptr == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
String str = static_cast<char*>(ptr) + header_size;
|
String str = static_cast<char*>(ptr) + header_size;
|
||||||
|
|
||||||
string::Header* header = string::header(str);
|
string::Header* header = string::header(str);
|
||||||
header->allocator = a;
|
header->allocator = a;
|
||||||
header->len = len;
|
header->len = len;
|
||||||
header->cap = len;
|
header->cap = len;
|
||||||
|
|
||||||
if (len && init_str)
|
if (len && init_str)
|
||||||
memory::copy(init_str, len, str);
|
memory::copy(init_str, len, str);
|
||||||
str[len] = '\0';
|
str[len] = '\0';
|
||||||
|
@ -3220,10 +3265,11 @@ free(String str)
|
||||||
{
|
{
|
||||||
if (str == nullptr)
|
if (str == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string::Header* h = string::header(str);
|
string::Header* h = string::header(str);
|
||||||
Allocator* a = h->allocator;
|
|
||||||
if (a)
|
if (h->allocator)
|
||||||
dealloc(a, h);
|
dealloc(h->allocator, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline String
|
inline String
|
||||||
|
@ -3337,7 +3383,7 @@ make_space_for(String* str, Size add_len)
|
||||||
if (available >= add_len) // Return if there is enough space left
|
if (available >= add_len) // Return if there is enough space left
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void* ptr = reinterpret_cast<string::Header*>(*str) - 1;
|
void* ptr = reinterpret_cast<string::Header*>(str) - 1;
|
||||||
usize old_size = sizeof(string::Header) + string::length(*str) + 1;
|
usize old_size = sizeof(string::Header) + string::length(*str) + 1;
|
||||||
usize new_size = sizeof(string::Header) + new_len + 1;
|
usize new_size = sizeof(string::Header) + new_len + 1;
|
||||||
|
|
||||||
|
@ -4302,6 +4348,7 @@ __GB_NAMESPACE_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Version History:
|
Version History:
|
||||||
|
0.25 - Faster Heap_Allocator for Windows using HeapAlloc
|
||||||
0.24b - Even More Hash_Table Bug Fixes
|
0.24b - Even More Hash_Table Bug Fixes
|
||||||
0.24a - Hash_Table Bug Fixes
|
0.24a - Hash_Table Bug Fixes
|
||||||
0.24 - More documentation and bug fixes
|
0.24 - More documentation and bug fixes
|
||||||
|
|
120
gb_math.hpp
120
gb_math.hpp
|
@ -1,9 +1,10 @@
|
||||||
// gb_math.hpp - v0.02b - public domain C++11 math library - no warranty implied; use at your own risk
|
// gb_math.hpp - v0.03 - public domain C++11 math library - no warranty implied; use at your own risk
|
||||||
// A C++11 math library geared towards game development
|
// A C++11 math library geared towards game development
|
||||||
// This is meant to be used the gb.hpp library but it doesn't have to be
|
// This is meant to be used the gb.hpp library but it doesn't have to be
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Version History:
|
Version History:
|
||||||
|
0.03 - Remove templated min/max/clamp
|
||||||
0.02b - Typo fixes
|
0.02b - Typo fixes
|
||||||
0.02a - Better `static` keywords
|
0.02a - Better `static` keywords
|
||||||
0.02 - More Angle Units and templated min/max/clamp/lerp
|
0.02 - More Angle Units and templated min/max/clamp/lerp
|
||||||
|
@ -95,6 +96,21 @@ CONTENTS:
|
||||||
#error This operating system is not supported by gb.hpp
|
#error This operating system is not supported by gb.hpp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
// Microsoft Visual Studio
|
||||||
|
#define GB_COMPILER_MSVC 1
|
||||||
|
#elif defined(__clang__)
|
||||||
|
// Clang
|
||||||
|
#define GB_COMPILER_CLANG 1
|
||||||
|
#elif defined(__GNUC__) || defined(__GNUG__) && !(defined(__clang__) || defined(__INTEL_COMPILER))
|
||||||
|
// GNU GCC/G++ Compiler
|
||||||
|
#define GB_COMPILER_GNU_GCC 1
|
||||||
|
#elif defined(__INTEL_COMPILER)
|
||||||
|
// Intel C++ Compiler
|
||||||
|
#define GB_COMPILER_INTEL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
/// Environment Bit Size ///
|
/// Environment Bit Size ///
|
||||||
|
@ -125,6 +141,7 @@ CONTENTS:
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// TODO(bill): Get this to work
|
// TODO(bill): Get this to work
|
||||||
// #if !defined(GB_LITTLE_EDIAN) && !defined(GB_BIG_EDIAN)
|
// #if !defined(GB_LITTLE_EDIAN) && !defined(GB_BIG_EDIAN)
|
||||||
|
|
||||||
|
@ -911,26 +928,24 @@ f32 kronecker_delta(f32 i, f32 j);
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
template <typename T>
|
f32 min(f32 x, f32 y);
|
||||||
const T& min(const T& a, const T& b);
|
s32 min(s32 x, s32 y);
|
||||||
|
s64 min(s64 x, s64 y);
|
||||||
|
|
||||||
template <typename T>
|
f32 max(f32 x, f32 y);
|
||||||
const T& max(const T& a, const T& b);
|
s32 max(s32 x, s32 y);
|
||||||
|
s64 max(s64 x, s64 y);
|
||||||
|
|
||||||
template <typename T>
|
f32 clamp(f32 x, f32 min, f32 max);
|
||||||
T clamp(const T& x, const T& min, const T& max);
|
s32 clamp(s32 x, s32 min, s32 max);
|
||||||
|
s64 clamp(s64 x, s64 min, s64 max);
|
||||||
|
|
||||||
|
// TODO(bill): Should this be a template or just normal function overloading?
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T lerp(const T& x, const T& y, f32 t);
|
T lerp(const T& x, const T& y, f32 t);
|
||||||
|
|
||||||
bool equals(f32 a, f32 b, f32 precision = F32_PRECISION);
|
bool equals(f32 a, f32 b, f32 precision = F32_PRECISION);
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void swap(T* a, T* b);
|
|
||||||
|
|
||||||
template <typename T, usize N>
|
|
||||||
void swap(T (& a)[N], T (& b)[N]);
|
|
||||||
|
|
||||||
// Vector2 functions
|
// Vector2 functions
|
||||||
f32 dot(const Vector2& a, const Vector2& b);
|
f32 dot(const Vector2& a, const Vector2& b);
|
||||||
f32 cross(const Vector2& a, const Vector2& b);
|
f32 cross(const Vector2& a, const Vector2& b);
|
||||||
|
@ -1138,9 +1153,6 @@ f32 perlin_3d(f32 x, f32 y, f32 z, s32 x_wrap = 0, s32 y_wrap = 0, s32 z_wrap =
|
||||||
|
|
||||||
namespace math
|
namespace math
|
||||||
{
|
{
|
||||||
template <typename T> inline const T& min(const T& a, const T& b) { return a < b ? a : b; }
|
|
||||||
template <typename T> inline const T& max(const T& a, const T& b) { return a > b ? a : b; }
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T
|
inline T
|
||||||
clamp(const T& x, const T& min, const T& max)
|
clamp(const T& x, const T& min, const T& max)
|
||||||
|
@ -2361,29 +2373,71 @@ kronecker_delta(f32 i, f32 j)
|
||||||
return static_cast<f32>(i == j);
|
return static_cast<f32>(i == j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline f32
|
||||||
|
min(f32 x, f32 y)
|
||||||
|
{
|
||||||
|
// TODO(bill): Check if this is even good
|
||||||
|
return x < y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s32
|
||||||
|
min(s32 x, s32 y)
|
||||||
|
{
|
||||||
|
return y + ((x-y) & (x-y)>>31);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s64
|
||||||
|
min(s64 x, s64 y)
|
||||||
|
{
|
||||||
|
return y + ((x-y) & (x-y)>>63);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline f32
|
||||||
|
max(f32 x, f32 y)
|
||||||
|
{
|
||||||
|
// TODO(bill): Check if this is even good
|
||||||
|
return x > y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s32
|
||||||
|
max(s32 x, s32 y)
|
||||||
|
{
|
||||||
|
return x - ((x-y) & (x-y)>>31);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s64
|
||||||
|
max(s64 x, s64 y)
|
||||||
|
{
|
||||||
|
return x - ((x-y) & (x-y)>>63);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline f32
|
||||||
|
clamp(f32 x, f32 min, f32 max)
|
||||||
|
{
|
||||||
|
const f32 t = x < min ? min : x;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s32
|
||||||
|
clamp(s32 x, s32 min, s32 max)
|
||||||
|
{
|
||||||
|
const s32 t = x < min ? min : x;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s64
|
||||||
|
clamp(s64 x, s64 min, s64 max)
|
||||||
|
{
|
||||||
|
const s64 t = x < min ? min : x;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
equals(f32 a, f32 b, f32 precision)
|
equals(f32 a, f32 b, f32 precision)
|
||||||
{
|
{
|
||||||
return ((b <= (a + precision)) && (b >= (a - precision)));
|
return ((b <= (a + precision)) && (b >= (a - precision)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void
|
|
||||||
swap(T* a, T* b)
|
|
||||||
{
|
|
||||||
T c = __GB_NAMESPACE_PREFIX::move(*a);
|
|
||||||
*a = __GB_NAMESPACE_PREFIX::move(*b);
|
|
||||||
*b = __GB_NAMESPACE_PREFIX::move(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, usize N>
|
|
||||||
inline void
|
|
||||||
swap(T (& a)[N], T (& b)[N])
|
|
||||||
{
|
|
||||||
for (usize i = 0; i < N; i++)
|
|
||||||
math::swap(&a[i], &b[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector2 functions
|
// Vector2 functions
|
||||||
inline f32
|
inline f32
|
||||||
dot(const Vector2& a, const Vector2& b)
|
dot(const Vector2& a, const Vector2& b)
|
||||||
|
|
Loading…
Reference in New Issue