Simplify folder sturcture + String refactor

1) Over time the total amount of files has decreased, and so it made sense to just simplify the folder structure and remove all of the subfolders.
2) Refactor the String class to utilize the existing Vector and StackVector classes instead of managing everything itself.
This commit is contained in:
Noel Berry
2022-10-01 13:29:51 -07:00
parent c94e372e7d
commit dcd3e11b16
47 changed files with 1018 additions and 1091 deletions

View File

@ -1,27 +1,22 @@
#pragma once
#include "blah/common.h"
#include "blah/app.h"
#include "blah/filesystem.h"
#include "blah/time.h"
#include "blah/input.h"
#include "blah/stream.h"
#include "blah/graphics.h"
#include "blah/containers/vector.h"
#include "blah/containers/stackvector.h"
#include "blah/containers/str.h"
#include "blah/drawing/batch.h"
#include "blah/drawing/spritefont.h"
#include "blah/drawing/subtexture.h"
#include "blah/images/aseprite.h"
#include "blah/images/font.h"
#include "blah/images/image.h"
#include "blah/images/packer.h"
#include "blah/math/calc.h"
#include "blah/math/spatial.h"
#include "blah/math/color.h"
#include "blah/math/ease.h"
#include "blah_app.h"
#include "blah_aseprite.h"
#include "blah_batch.h"
#include "blah_calc.h"
#include "blah_color.h"
#include "blah_common.h"
#include "blah_ease.h"
#include "blah_filesystem.h"
#include "blah_font.h"
#include "blah_graphics.h"
#include "blah_image.h"
#include "blah_input.h"
#include "blah_packer.h"
#include "blah_spatial.h"
#include "blah_spritefont.h"
#include "blah_stackvector.h"
#include "blah_string.h"
#include "blah_stream.h"
#include "blah_subtexture.h"
#include "blah_time.h"
#include "blah_vector.h"

View File

@ -1,321 +0,0 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/vector.h>
#include <stdarg.h>
#include <stdio.h>
namespace Blah
{
template<int T> class StrOf;
using String = StrOf<64>;
using FilePath = StrOf<260>;
// A simple String implementation
class Str
{
public:
Str() { m_buffer = empty_buffer; m_length = m_capacity = m_local_size = 0; }
Str(const char* start, const char* end = nullptr) : Str() { set(start, end); }
Str(const Str& str) : Str() { set(str); }
char& operator[](int index) { return data()[index]; }
const char& operator[](int index) const { return data()[index]; }
// equality operators
bool operator==(const Str& rhs) const;
bool operator!=(const Str& rhs) const;
bool operator==(const char* rhs) const;
bool operator!=(const char* rhs) const;
// assignment operator
Str& operator=(const Str& rhs) { set(rhs.cstr(), rhs.cstr() + rhs.m_length); return *this; }
Str& operator=(const char* rhs) { set(rhs, nullptr); return *this; }
// append string
Str& operator+=(const Str& rhs) { return append(rhs); }
// append cstr
Str& operator+=(const char* rhs) { return append(rhs); }
// append char
Str& operator+=(const char& rhs) { return append(rhs); }
// combine string
Str operator+(const Str& rhs) { Str str; str.append(*this).append(rhs); return str; }
// combine cstr
Str operator+(const char* rhs) { Str str; str.append(*this).append(rhs); return str; }
// combine char
Str operator+(const char& rhs) { Str str; str.append(*this).append(rhs); return str; }
// implicit cast to cstr
operator char* () { return cstr(); }
// implicit cast to cstr
operator const char* () const { return cstr(); }
// returns a pointer to the null-terminated string buffer
char* cstr() { return data(); }
// returns a pointer to the null-terminated string buffer
const char* cstr() const { return data(); }
// returns a pointer to the start of the buffer
const char* begin() const { return data(); }
// returns a pointer to the end of the buffer
const char* end() const { return data() + m_length; }
// returns the length of the string
int length() const { return m_length; }
// returns the capacity of the string
int capacity() const { return m_capacity; }
// returns the capacity of the string's stack buffer
int stack_capacity() const { return m_local_size; }
// sets the length of the string.
// this does not set the value of the string!
void set_length(int length);
// ensures the string has the given capacity
void reserve(int capacity);
// Returns the unicode value at the given index.
// Assumes the index is a valid utf8 starting point.
u32 utf8_at(int index) const;
// Returns the byte-length of the utf8 character.
// Assumes the index is a valid utf8 starting point.
int utf8_length(int index) const;
// appends the given character
Str& append(char c);
// appends the given unicode character
Str& append(u32 c);
// appends the given c string
Str& append(const char* start, const char* end = nullptr);
// appends the given string
Str& append(const Str& str, int start = 0, int end = -1);
// appends the given formatted string
Str& append_fmt(const char* fmt, ...);
// appends a utf16 string
Str& append_utf16(const u16* start, const u16* end = nullptr, bool swapEndian = false);
// trims whitespace
Str& trim();
// returns true if the string begins with the given string
bool starts_with(const Str& str, bool ignore_case = false) const { return starts_with(str.cstr(), ignore_case); }
// returns true if the string begins with the given string
bool equals(const Str& str, bool ignore_case = false) const { return str.length() == length() && starts_with(str.cstr(), ignore_case); }
// returns true if the string begins with the given string
bool starts_with(const char* str, bool ignore_case = false) const;
// returns true if the string contains with the given string
bool contains(const Str& str, bool ignore_case = false) const { return contains(str.cstr(), ignore_case); }
// returns true if the string contains with the given string
bool contains(const char* str, bool ignore_case = false) const;
// returns true if the string ends with the given string
bool ends_with(const Str& str, bool ignore_case = false) const { return ends_with(str.cstr(), ignore_case); }
// returns true if the string ends with the given string
bool ends_with(const char* str, bool ignore_case = false) const;
// returns the first index of the given character, or -1 if it isn't found
int first_index_of(char ch) const;
// returns the last index of the given character, or -1 if it isn't found
int last_index_of(char ch) const;
// returns a substring of the string
String substr(int start) const;
// returns a substring of the string
String substr(int start, int end) const;
// Splits the string into a vector of strings
Vector<String> split(char ch) const;
// replaces all occurances of old string with the new string
Str& replace(const Str& old_str, const Str& new_str);
// replaces all occurances of the given character in the string
Str& replace(char c, char r);
// checks if the string has a length of 0
bool empty() const { return m_length <= 0; }
// clears the string length to 0
void clear();
// clears and disposes the internal string buffer
void dispose();
virtual ~Str()
{
if (m_buffer != nullptr && m_buffer != empty_buffer)
delete[] m_buffer;
}
protected:
Str(int local_size)
{
m_buffer = nullptr;
m_length = 0;
m_capacity = local_size;
m_local_size = local_size;
}
// returns a pointer to the heap buffer or to our stack allocation
virtual char* data() { return m_buffer; }
// returns a pointer to the heap buffer or to our stack allocation
virtual const char* data() const { return m_buffer; }
// assigns the contents of the string
void set(const Str& str) { set(str.cstr(), str.cstr() + str.m_length); }
// assigns the contents of the string
void set(const char* start, const char* end = nullptr);
char* m_buffer;
private:
static char empty_buffer[1];
int m_length;
int m_capacity;
int m_local_size;
};
// combine string
inline Str operator+(const Str& lhs, const Str& rhs) { Str str; str.append(lhs).append(rhs); return str; }
// A string with a local stack buffer of size T
template<int T>
class StrOf : public Str
{
private:
char m_local_buffer[T];
public:
StrOf() : Str(T) { m_local_buffer[0] = '\0'; }
StrOf(const char* rhs, const char* end = nullptr) : Str(T) { m_local_buffer[0] = '\0'; set(rhs, end); }
StrOf(const Str& rhs) : Str(T) { m_local_buffer[0] = '\0'; set(rhs); }
StrOf(const StrOf& rhs) : Str(T) { m_local_buffer[0] = '\0'; set(rhs); }
// assignment operators
StrOf& operator=(const char* rhs) { set(rhs); return *this; }
StrOf& operator=(const Str& rhs) { set(rhs); return *this; }
StrOf& operator=(const StrOf& rhs) { set(rhs); return *this; }
// either return stack or heap buffer depending on which is in-use
char* data() override { return m_buffer != nullptr ? m_buffer : m_local_buffer; }
const char* data() const override { return m_buffer != nullptr ? m_buffer : m_local_buffer; }
// creates a string from the format
static StrOf fmt(const char* str, ...);
};
template<int T>
StrOf<T> StrOf<T>::fmt(const char* fmt, ...)
{
StrOf<T> str;
int add, diff;
// determine arg length
va_list args;
va_start(args, fmt);
add = vsnprintf(NULL, 0, fmt, args);
va_end(args);
// reserve
auto len = str.length();
str.set_length(len + add);
diff = str.capacity() - len;
if (diff <= 0) diff = 0;
// print out
va_start(args, fmt);
vsnprintf(str.cstr() + len, (size_t)diff, fmt, args);
va_end(args);
return str;
}
struct CaseInsenstiveStringHash
{
std::size_t operator()(const Blah::Str& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
if (it >= 'A' && it <= 'Z')
result ^= (static_cast<std::size_t>(it) - 'A' + 'a');
else
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
struct CaseInsenstiveStringCompare
{
bool operator() (const Str& lhs, const Str& rhs) const
{
return lhs.length() == rhs.length() && lhs.starts_with(rhs, true);
}
};
}
namespace std
{
template <>
struct hash<Blah::Str>
{
std::size_t operator()(const Blah::Str& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
template <int T>
struct hash<Blah::StrOf<T>>
{
std::size_t operator()(const Blah::StrOf<T>& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
}

View File

@ -1,7 +1,7 @@
#pragma once
#include <blah/common.h>
#include <blah/graphics.h>
#include <blah/math/spatial.h>
#include <blah_common.h>
#include <blah_graphics.h>
#include <blah_spatial.h>
namespace Blah
{

View File

@ -1,9 +1,9 @@
#pragma once
#include <blah/common.h>
#include <blah/math/color.h>
#include <blah/images/image.h>
#include <blah/containers/str.h>
#include <blah/stream.h>
#include <blah_common.h>
#include <blah_color.h>
#include <blah_image.h>
#include <blah_string.h>
#include <blah_stream.h>
namespace Blah
{

View File

@ -1,11 +1,11 @@
#pragma once
#include <blah/containers/vector.h>
#include <blah/containers/str.h>
#include <blah/drawing/spritefont.h>
#include <blah/drawing/subtexture.h>
#include <blah/math/spatial.h>
#include <blah/math/color.h>
#include <blah/graphics.h>
#include <blah_vector.h>
#include <blah_string.h>
#include <blah_spritefont.h>
#include <blah_subtexture.h>
#include <blah_spatial.h>
#include <blah_color.h>
#include <blah_graphics.h>
namespace Blah
{

View File

@ -1,6 +1,5 @@
#pragma once
#include <blah/common.h>
#include <math.h>
#include <blah_common.h>
namespace Blah
{

View File

@ -1,7 +1,7 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/str.h>
#include <blah/math/spatial.h>
#include <blah_common.h>
#include <blah_string.h>
#include <blah_spatial.h>
#define BLAH_HEX_VALUE(n) ((n >= '0' && n <= '9') ? (n - '0') : ((n >= 'A' && n <= 'F') ? (10 + n - 'A') : ((n >= 'a' && n <= 'f') ? (10 + n - 'a') : 0)))

View File

@ -1,10 +1,29 @@
#pragma once
#include <new> // for in-place constructors, for Vector/StackVector
#include <utility> // for std::move, std::forward
#include <stdint.h> // for integer types
#include <stddef.h> // for std::size_t
#include <stdlib.h> // for abort
#include <stdarg.h> // for string format methods
#include <math.h> // for standard lib math functions used in blah_calc.h
#include <new> // for in-place constructors, for Vector/StackVector
#include <utility> // for std::move
// Numeric Types
namespace Blah
{
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using f32 = float;
using f64 = double;
using size_t = std::size_t;
}
// Aborts
#include <stdlib.h> // for abort
#ifdef _WIN32
#define BLAH_ABORT() do { __debugbreak(); ::exit(1); } while(0)
#else
@ -34,24 +53,6 @@
} \
} while(0)
// Numeric Types
#include <stdint.h> // for integer types
#include <stddef.h> // for size_t type
namespace Blah
{
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using f32 = float;
using f64 = double;
using size_t = std::size_t;
}
// Logging
namespace Blah
{

View File

@ -1,6 +1,6 @@
#pragma once
#include <blah/common.h>
#include <blah/math/calc.h>
#include <blah_common.h>
#include <blah_calc.h>
namespace Blah
{

View File

@ -1,7 +1,7 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah_common.h>
#include <blah_string.h>
#include <blah_vector.h>
namespace Blah
{

View File

@ -1,10 +1,10 @@
#pragma once
#include <blah/common.h>
#include <blah/stream.h>
#include <blah/images/image.h>
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah/filesystem.h>
#include <blah_common.h>
#include <blah_stream.h>
#include <blah_image.h>
#include <blah_string.h>
#include <blah_vector.h>
#include <blah_filesystem.h>
namespace Blah
{

View File

@ -1,14 +1,15 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/vector.h>
#include <blah/containers/stackvector.h>
#include <blah/containers/str.h>
#include <blah/math/spatial.h>
#include <blah/images/image.h>
#include <blah/stream.h>
#include <blah_common.h>
#include <blah_vector.h>
#include <blah_stackvector.h>
#include <blah_string.h>
#include <blah_spatial.h>
#include <blah_image.h>
namespace Blah
{
class Stream;
class Shader; using ShaderRef = Ref<Shader>;
class Texture; using TextureRef = Ref<Texture>;
class Target; using TargetRef = Ref<Target>;

View File

@ -1,8 +1,8 @@
#pragma once
#include <blah/math/color.h>
#include <blah/math/spatial.h>
#include <blah/filesystem.h>
#include <blah/stream.h>
#include <blah_color.h>
#include <blah_spatial.h>
#include <blah_filesystem.h>
#include <blah_stream.h>
namespace Blah
{

View File

@ -1,8 +1,8 @@
#pragma once
#include <blah/common.h>
#include <blah/math/spatial.h>
#include <blah/containers/str.h>
#include <blah/containers/stackvector.h>
#include <blah_common.h>
#include <blah_spatial.h>
#include <blah_string.h>
#include <blah_stackvector.h>
// These are generally copied from the SDL2 Scancode Keys,
// which are in turn based on the USB standards:

View File

@ -1,12 +1,12 @@
#pragma once
#include <blah/common.h>
#include <blah/images/image.h>
#include <blah/math/color.h>
#include <blah/math/spatial.h>
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah/stream.h>
#include <blah/filesystem.h>
#include <blah_common.h>
#include <blah_image.h>
#include <blah_color.h>
#include <blah_spatial.h>
#include <blah_string.h>
#include <blah_vector.h>
#include <blah_stream.h>
#include <blah_filesystem.h>
namespace Blah
{

View File

@ -1,6 +1,6 @@
#pragma once
#include <blah/common.h>
#include <blah/math/calc.h>
#include <blah_common.h>
#include <blah_calc.h>
namespace Blah
{

View File

@ -1,9 +1,9 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah/drawing/subtexture.h>
#include <blah/images/font.h>
#include <blah_common.h>
#include <blah_string.h>
#include <blah_vector.h>
#include <blah_subtexture.h>
#include <blah_font.h>
namespace Blah
{

View File

@ -1,5 +1,5 @@
#pragma once
#include <blah/common.h>
#include <blah_common.h>
namespace Blah
{
@ -10,7 +10,7 @@ namespace Blah
class StackVector
{
private:
char m_buffer[sizeof(T) * Capacity];
u8 m_buffer[sizeof(T) * Capacity];
int m_count;
public:

View File

@ -1,9 +1,9 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah/math/calc.h>
#include <blah/filesystem.h>
#include <blah_common.h>
#include <blah_string.h>
#include <blah_vector.h>
#include <blah_calc.h>
#include <blah_filesystem.h>
namespace Blah
{

371
include/blah_string.h Normal file
View File

@ -0,0 +1,371 @@
#pragma once
#include <blah_common.h>
#include <blah_vector.h>
#include <blah_stackvector.h>
namespace Blah
{
class BaseString
{
public:
const char* cstr() const { return s_ptr(); }
char* cstr() { return s_ptr(); }
const char* begin() const { return s_ptr(); }
char* begin() { return s_ptr(); }
const char* end() const { return s_ptr() + length(); }
char* end() { return s_ptr() + length(); }
char& operator[](int index)
{
BLAH_ASSERT(index >= 0 && index < length(), "Index out of range");
return s_ptr()[index];
}
const char& operator[](int index) const
{
BLAH_ASSERT(index >= 0 && index < length(), "Index out of range");
return s_ptr()[index];
}
operator char* () { return cstr(); }
operator const char* () const { return cstr(); }
void assign(const char* cstr, const char* cstr_end = nullptr);
void append(const char* cstr, const char* cstr_end = nullptr);
void append(const u16* u16_cstr, const u16* u16_cstr_end = nullptr, bool swap_endian = false);
void append(char ch, int count = 1);
void append(u32 unicode);
void append_fmt(const char* fmt, ...);
bool starts_with(const char* cstr, bool ignore_case = false) const;
bool ends_with(const char* cstr, bool ignore_case = false) const;
bool contains(const char* cstr, bool ignore_case = false) const;
int first_index_of(char ch) const;
int last_index_of(char ch) const;
int length() const
{
int n = s_len() - 1; // reduce by 1 for null-terminator
return (n > 0 ? n : 0); // safety, although due to how StackString is implemented s_len shouldn't ever be less than 1
}
bool equals(const char* other, bool ignore_case = false) const;
bool empty() const { return length() == 0; }
void clear() { s_clear(); }
bool operator==(const char* rhs) const { return equals(rhs); }
bool operator!=(const char* rhs) const { return !(*this == rhs); }
bool operator==(const BaseString& rhs) const { return s_len() == rhs.s_len() && *this == rhs.cstr(); }
bool operator!=(const BaseString& rhs) const { return !(*this == rhs); }
protected:
virtual void s_clear() = 0;
virtual void s_ensure(int capacity) = 0;
virtual char* s_ptr() = 0;
virtual const char* s_ptr() const = 0;
virtual int s_len() const = 0;
};
template<size_t StackSize>
class StackString final : public BaseString
{
public:
StackString() { assign(""); }
StackString(const char* cstr, const char* cstr_end = nullptr) { assign(cstr, cstr_end); }
StackString(const BaseString& other) { assign(other.cstr()); }
StackString& operator=(const BaseString& rhs)
{
assign(rhs.cstr(), rhs.cstr() + rhs.length());
return *this;
}
StackString& operator=(const char* rhs)
{
assign(rhs, nullptr);
return *this;
}
StackString& operator+=(const BaseString& rhs)
{
append(rhs.cstr());
return *this;
}
StackString& operator+=(const char* rhs)
{
append(rhs);
return *this;
}
StackString& operator+=(const char& rhs)
{
append(rhs);
return *this;
}
StackString operator+(const BaseString& rhs)
{
StackString str(*this);
str += rhs;
return str;
}
StackString operator+(const char* rhs)
{
StackString str(*this);
str += rhs;
return str;
}
StackString operator+(const char& rhs)
{
StackString str(*this);
str += rhs;
return str;
}
StackString substr(int start, int len = 0) const
{
if (len == 0) len = length() - start;
return StackString(cstr() + start, cstr() + start + len);
}
StackString trim() const
{
if (length() > 0)
{
const char* s = begin();
const char* e = end() - 1;
while (s < e && (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' || *s == '\v' || *s == '\f')) s++;
while (e > s && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n' || *e == '\v' || *e == '\f')) e--;
return StackString(s, e + 1);
}
return StackString();
}
Vector<StackString> split(char ch) const
{
Vector<StackString> result;
const char* ptr = s_ptr();
const char* end = ptr + length();
const char* last = ptr;
while (ptr < end)
{
if (*ptr == ch)
{
result.emplace_back(last, ptr);
last = ptr + 1;
}
ptr++;
}
if (last < ptr)
result.emplace_back(last, ptr);
return result;
}
static StackString fmt(const char* fmt, ...)
{
StackString str;
va_list args;
// determine arg m_length
va_start(args, fmt);
auto add = vsnprintf(nullptr, 0, fmt, args);
va_end(args);
if (add <= 0)
return str;
// reserve (+1 for null-terminator)
auto len = str.length();
str.s_ensure(len + add + 1);
// print out
va_start(args, fmt);
vsnprintf(str.s_ptr() + len, add + 1, fmt, args);
va_end(args);
return str;
}
protected:
void s_clear() override
{
m_stack_buffer.clear();
m_heap_buffer.clear();
s_ensure(1);
}
void s_ensure(int capacity) override
{
int count = capacity - s_len();
if (count <= 0)
return;
// expand heap buffer
if (m_heap_buffer.size() > 0)
{
m_heap_buffer.expand(count);
}
// switch from stack to heap
else if (capacity > StackSize)
{
m_heap_buffer.expand(capacity);
char* src = m_stack_buffer.data();
char* len = src + m_stack_buffer.size();
char* dst = m_heap_buffer.data();
while (src < len) *(dst++) = *(src++);
}
// expand stack buffer
else
{
m_stack_buffer.expand(count);
}
*(s_ptr() + s_len() - 1) = '\0';
}
char* s_ptr() override
{
return m_heap_buffer.size() > 0 ? m_heap_buffer.data() : m_stack_buffer.data();
}
const char* s_ptr() const override
{
return m_heap_buffer.size() > 0 ? m_heap_buffer.data() : m_stack_buffer.data();
}
int s_len() const override
{
return m_heap_buffer.size() > 0 ? m_heap_buffer.size() : m_stack_buffer.size();
}
private:
Vector<char> m_heap_buffer;
StackVector<char, StackSize> m_stack_buffer;
};
template<size_t StackSize>
StackString<StackSize> operator+(const StackString<StackSize>& lhs, const BaseString& rhs)
{
StackString str(lhs);
str += rhs;
return str;
}
template<size_t StackSize>
StackString<StackSize> operator+(const StackString<StackSize>& lhs, const char* rhs)
{
StackString str(lhs);
str += rhs;
return str;
}
template<size_t StackSize>
StackString<StackSize> operator+(const StackString<StackSize>& lhs, const char& rhs)
{
StackString str(lhs);
str += rhs;
return str;
}
// Stores enough for an empty string on the stack, and afterwards allocates on the heap
using HeapString = StackString<1>;
// Standard String with a fair amount of stack storage
using String = StackString<64>;
// Large String with enough stack storage to store FilePaths without allocating.
using FilePath = StackString<260>;
// Utf8 Utility, to iterate over a string and read utf-8 characters
struct Utf8
{
const char* str = nullptr;
u32 character = 0;
u32 character_size = 0;
Utf8() = default;
Utf8(const char* cstr);
// moves to the next character, returns false if at end of string or an invalid character
bool next();
};
struct CaseInsenstiveStringHash
{
std::size_t operator()(const Blah::BaseString& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
if (it >= 'A' && it <= 'Z')
result ^= (static_cast<std::size_t>(it) - 'A' + 'a');
else
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
struct CaseInsenstiveStringCompare
{
bool operator() (const BaseString& lhs, const BaseString& rhs) const
{
return lhs.length() == rhs.length() && lhs.starts_with(rhs, true);
}
};
}
// STD Hash Utility, so the String can be used in a set / unordered_map / map
namespace std
{
template <>
struct hash<Blah::BaseString>
{
std::size_t operator()(const Blah::BaseString& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
template <size_t StackSize>
struct hash<Blah::StackString<StackSize>>
{
std::size_t operator()(const Blah::StackString<StackSize>& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
}

View File

@ -1,6 +1,6 @@
#pragma once
#include <blah/graphics.h>
#include <blah/math/spatial.h>
#include <blah_graphics.h>
#include <blah_spatial.h>
namespace Blah
{

View File

@ -1,5 +1,5 @@
#pragma once
#include <blah/common.h>
#include <blah_common.h>
namespace Blah
{

View File

@ -1,6 +1,5 @@
#pragma once
#include <blah/common.h>
#include <string.h>
#include <blah_common.h>
namespace Blah
{
@ -182,7 +181,10 @@ namespace Blah
if constexpr (std::is_trivially_copyable<T>())
{
memcpy(new_buffer, m_buffer, m_count * sizeof(T));
u8* src = (u8*)m_buffer;
u8* len = src + m_count * sizeof(T);
u8* dst = (u8*)new_buffer;
while (src < len) *(dst++) = *(src++);
}
else
{
@ -356,4 +358,4 @@ namespace Blah
m_count--;
return value;
}
}
}