[ox/std] Add a form of small string and small vector optimization
This commit is contained in:
parent
b36cd1694b
commit
1df1e3809f
3
deps/ox/src/ox/clargs/clargs.hpp
vendored
3
deps/ox/src/ox/clargs/clargs.hpp
vendored
@ -9,11 +9,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
class String;
|
||||
|
||||
class ClArgs {
|
||||
private:
|
||||
HashMap<String, bool> m_bools;
|
||||
|
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -12,6 +12,7 @@ endif()
|
||||
|
||||
target_compile_definitions(
|
||||
OxTraceHook PUBLIC
|
||||
$<$<BOOL:${OX_BARE_METAL}>:OX_BARE_METAL>
|
||||
$<$<BOOL:${OX_USE_STDLIB}>:OX_USE_STDLIB>
|
||||
$<$<BOOL:${OX_NODEBUG}>:OX_NODEBUG>
|
||||
)
|
||||
|
4
deps/ox/src/ox/std/error.hpp
vendored
4
deps/ox/src/ox/std/error.hpp
vendored
@ -126,8 +126,8 @@ constexpr void oxIgnoreError(ox::Error) noexcept {}
|
||||
#define oxReturnError(x) if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] return _ox_error
|
||||
#define oxThrowError(x) if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] throw _ox_error
|
||||
#else
|
||||
#define oxReturnError(x) if (const auto _ox_error = ox::detail::toError(x)) return _ox_error
|
||||
#define oxThrowError(x) if (const auto _ox_error = ox::detail::toError(x)) throw _ox_error
|
||||
#define oxReturnError(err) if (const auto _ox_error = ox::detail::toError(err)) return _ox_error
|
||||
#define oxThrowError(err) if (const auto _ox_error = ox::detail::toError(err)) throw _ox_error
|
||||
#endif
|
||||
#define oxConcatImpl(a, b) a##b
|
||||
#define oxConcat(a, b) oxConcatImpl(a, b)
|
||||
|
3
deps/ox/src/ox/std/stacktrace.cpp
vendored
3
deps/ox/src/ox/std/stacktrace.cpp
vendored
@ -11,17 +11,14 @@
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if __has_include(<cxxabi.h>)
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "error.hpp"
|
||||
#include "string.hpp"
|
||||
#include "trace.hpp"
|
||||
#include "units.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
|
166
deps/ox/src/ox/std/string.cpp
vendored
166
deps/ox/src/ox/std/string.cpp
vendored
@ -7,172 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "string.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
String &String::operator=(const char *str) noexcept {
|
||||
std::size_t strLen = ox_strlen(str) + 1;
|
||||
m_buff.resize(strLen + 1);
|
||||
memcpy(m_buff.data(), str, strLen);
|
||||
// make sure last element is a null terminator
|
||||
m_buff[m_buff.size() - 1] = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(char *str) noexcept {
|
||||
return *this = static_cast<const char*>(str);
|
||||
}
|
||||
|
||||
String &String::operator=(char c) noexcept {
|
||||
char str[] = {c, 0};
|
||||
return this->operator=(str);
|
||||
}
|
||||
|
||||
String &String::operator=(int i) noexcept {
|
||||
return this->operator=(static_cast<int64_t>(i));
|
||||
}
|
||||
|
||||
String &String::operator=(int64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator=(str);
|
||||
}
|
||||
|
||||
String &String::operator=(uint64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator=(str);
|
||||
}
|
||||
|
||||
String &String::operator=(const String &src) noexcept {
|
||||
return *this = src.c_str();
|
||||
}
|
||||
|
||||
String &String::operator=(String &&src) noexcept {
|
||||
m_buff = move(src.m_buff);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(const char *str) noexcept {
|
||||
std::size_t strLen = ox_strlen(str);
|
||||
oxIgnoreError(append(str, strLen));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(char *str) noexcept {
|
||||
return *this += static_cast<const char*>(str);
|
||||
}
|
||||
|
||||
String &String::operator+=(char c) noexcept {
|
||||
const char str[] = {c, 0};
|
||||
return this->operator+=(str);
|
||||
}
|
||||
|
||||
String &String::operator+=(int i) noexcept {
|
||||
return this->operator+=(static_cast<int64_t>(i));
|
||||
}
|
||||
|
||||
String &String::operator+=(int64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator+=(str);
|
||||
}
|
||||
|
||||
String &String::operator+=(uint64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator+=(str);
|
||||
}
|
||||
|
||||
String &String::operator+=(const String &src) noexcept {
|
||||
return *this += src.c_str();
|
||||
}
|
||||
|
||||
String String::operator+(const char *str) const noexcept {
|
||||
const std::size_t strLen = ox_strlen(str);
|
||||
const auto currentLen = len();
|
||||
String cpy(currentLen + strLen);
|
||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
||||
memcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||
memcpy(&cpy.m_buff[currentLen], str, strLen);
|
||||
// make sure last element is a null terminator
|
||||
cpy.m_buff[currentLen + strLen] = 0;
|
||||
return move(cpy);
|
||||
}
|
||||
|
||||
String String::operator+(char *str) const noexcept {
|
||||
return *this + static_cast<const char*>(str);
|
||||
}
|
||||
|
||||
String String::operator+(char c) const noexcept {
|
||||
const char str[] = {c, 0};
|
||||
return *this + str;
|
||||
}
|
||||
|
||||
String String::operator+(int i) const noexcept {
|
||||
return this->operator+(static_cast<int64_t>(i));
|
||||
}
|
||||
|
||||
String String::operator+(int64_t i) const noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return *this + str;
|
||||
}
|
||||
|
||||
String String::operator+(uint64_t i) const noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return *this + str;
|
||||
}
|
||||
|
||||
String String::operator+(const String &src) const noexcept {
|
||||
return *this + src.c_str();
|
||||
}
|
||||
|
||||
bool String::operator==(const String &other) const noexcept {
|
||||
bool retval = true;
|
||||
std::size_t i = 0;
|
||||
while (i < m_buff.size() && (m_buff[i] || other.m_buff[i])) {
|
||||
if (m_buff[i] != other.m_buff[i]) {
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool String::operator!=(const String &other) const noexcept {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
char String::operator[](std::size_t i) const noexcept {
|
||||
return m_buff[i];
|
||||
}
|
||||
|
||||
char &String::operator[](std::size_t i) noexcept {
|
||||
return m_buff[i];
|
||||
}
|
||||
|
||||
String String::substr(std::size_t pos) const noexcept {
|
||||
return m_buff.data() + pos;
|
||||
}
|
||||
|
||||
bool String::endsWith(const char *ending) const noexcept {
|
||||
const auto endingLen = ox_strlen(ending);
|
||||
return len() >= endingLen && ox_strcmp(data() + (len() - endingLen), ending) == 0;
|
||||
}
|
||||
|
||||
bool String::endsWith(const String &ending) const noexcept {
|
||||
const auto endingLen = ending.len();
|
||||
return len() >= endingLen && ox_strcmp(data() + (len() - endingLen), ending.c_str()) == 0;
|
||||
}
|
||||
|
||||
std::size_t String::bytes() const noexcept {
|
||||
std::size_t i;
|
||||
for (i = 0; i < m_buff.size() && m_buff[i]; i++);
|
||||
return i + 1; // add one for null terminator
|
||||
}
|
||||
|
||||
}
|
||||
|
294
deps/ox/src/ox/std/string.hpp
vendored
294
deps/ox/src/ox/std/string.hpp
vendored
@ -20,70 +20,71 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
class String {
|
||||
template<std::size_t SmallStringSize = 0>
|
||||
class BasicString {
|
||||
private:
|
||||
Buffer m_buff;
|
||||
Vector<char, SmallStringSize> m_buff;
|
||||
|
||||
public:
|
||||
constexpr String() noexcept;
|
||||
constexpr BasicString() noexcept;
|
||||
|
||||
constexpr explicit String(std::size_t cap) noexcept;
|
||||
constexpr explicit BasicString(std::size_t cap) noexcept;
|
||||
|
||||
constexpr String(const char *str) noexcept;
|
||||
constexpr BasicString(const char *str) noexcept;
|
||||
|
||||
constexpr String(const char *str, std::size_t size) noexcept;
|
||||
constexpr BasicString(const char *str, std::size_t size) noexcept;
|
||||
|
||||
constexpr String(const String&) noexcept;
|
||||
constexpr BasicString(const BasicString&) noexcept;
|
||||
|
||||
constexpr String(String&&) noexcept;
|
||||
constexpr BasicString(BasicString&&) noexcept;
|
||||
|
||||
String &operator=(const char *str) noexcept;
|
||||
BasicString &operator=(const char *str) noexcept;
|
||||
|
||||
String &operator=(char *str) noexcept;
|
||||
BasicString &operator=(char *str) noexcept;
|
||||
|
||||
String &operator=(char c) noexcept;
|
||||
BasicString &operator=(char c) noexcept;
|
||||
|
||||
String &operator=(int i) noexcept;
|
||||
BasicString &operator=(int i) noexcept;
|
||||
|
||||
String &operator=(int64_t i) noexcept;
|
||||
BasicString &operator=(int64_t i) noexcept;
|
||||
|
||||
String &operator=(uint64_t i) noexcept;
|
||||
BasicString &operator=(uint64_t i) noexcept;
|
||||
|
||||
String &operator=(const String &src) noexcept;
|
||||
BasicString &operator=(const BasicString &src) noexcept;
|
||||
|
||||
String &operator=(String &&src) noexcept;
|
||||
BasicString &operator=(BasicString &&src) noexcept;
|
||||
|
||||
String &operator+=(const char *str) noexcept;
|
||||
constexpr BasicString &operator+=(const char *str) noexcept;
|
||||
|
||||
String &operator+=(char *str) noexcept;
|
||||
constexpr BasicString &operator+=(char *str) noexcept;
|
||||
|
||||
String &operator+=(char c) noexcept;
|
||||
constexpr BasicString &operator+=(char c) noexcept;
|
||||
|
||||
String &operator+=(int i) noexcept;
|
||||
constexpr BasicString &operator+=(int i) noexcept;
|
||||
|
||||
String &operator+=(int64_t i) noexcept;
|
||||
constexpr BasicString &operator+=(int64_t i) noexcept;
|
||||
|
||||
String &operator+=(uint64_t i) noexcept;
|
||||
constexpr BasicString &operator+=(uint64_t i) noexcept;
|
||||
|
||||
String &operator+=(const String &src) noexcept;
|
||||
constexpr BasicString &operator+=(const BasicString &src) noexcept;
|
||||
|
||||
String operator+(const char *str) const noexcept;
|
||||
BasicString operator+(const char *str) const noexcept;
|
||||
|
||||
String operator+(char *str) const noexcept;
|
||||
BasicString operator+(char *str) const noexcept;
|
||||
|
||||
String operator+(char c) const noexcept;
|
||||
BasicString operator+(char c) const noexcept;
|
||||
|
||||
String operator+(int i) const noexcept;
|
||||
BasicString operator+(int i) const noexcept;
|
||||
|
||||
String operator+(int64_t i) const noexcept;
|
||||
BasicString operator+(int64_t i) const noexcept;
|
||||
|
||||
String operator+(uint64_t i) const noexcept;
|
||||
BasicString operator+(uint64_t i) const noexcept;
|
||||
|
||||
String operator+(const String &src) const noexcept;
|
||||
BasicString operator+(const BasicString &src) const noexcept;
|
||||
|
||||
bool operator==(const String &other) const noexcept;
|
||||
bool operator==(const BasicString &other) const noexcept;
|
||||
|
||||
bool operator!=(const String &other) const noexcept;
|
||||
bool operator!=(const BasicString &other) const noexcept;
|
||||
|
||||
char operator[](std::size_t i) const noexcept;
|
||||
|
||||
@ -100,13 +101,13 @@ class String {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
String substr(std::size_t pos) const noexcept;
|
||||
BasicString substr(std::size_t pos) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
bool endsWith(const char *other) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
bool endsWith(const String &other) const noexcept;
|
||||
bool endsWith(const BasicString &other) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const char *data() const noexcept {
|
||||
@ -144,7 +145,8 @@ class String {
|
||||
|
||||
};
|
||||
|
||||
constexpr String::String() noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize>::BasicString() noexcept {
|
||||
if (m_buff.size()) {
|
||||
m_buff[0] = 0;
|
||||
} else {
|
||||
@ -152,12 +154,14 @@ constexpr String::String() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr String::String(std::size_t cap) noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize>::BasicString(std::size_t cap) noexcept {
|
||||
m_buff.resize(cap + 1);
|
||||
m_buff[0] = 0;
|
||||
}
|
||||
|
||||
constexpr String::String(const char *str) noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize>::BasicString(const char *str) noexcept {
|
||||
if (m_buff.size()) {
|
||||
m_buff[0] = 0;
|
||||
} else {
|
||||
@ -166,29 +170,227 @@ constexpr String::String(const char *str) noexcept {
|
||||
*this = str;
|
||||
}
|
||||
|
||||
constexpr String::String(const char *str, std::size_t size) noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize>::BasicString(const char *str, std::size_t size) noexcept {
|
||||
m_buff.resize(size + 1);
|
||||
memcpy(m_buff.data(), str, size);
|
||||
m_buff[size] = 0;
|
||||
}
|
||||
|
||||
constexpr String::String(const String &other) noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize>::BasicString(const BasicString &other) noexcept {
|
||||
m_buff = other.m_buff;
|
||||
}
|
||||
|
||||
constexpr String::String(String &&other) noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize>::BasicString(BasicString &&other) noexcept {
|
||||
m_buff = move(other.m_buff);
|
||||
}
|
||||
|
||||
constexpr std::size_t String::len() const noexcept {
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(const char *str) noexcept {
|
||||
std::size_t strLen = ox_strlen(str) + 1;
|
||||
m_buff.resize(strLen + 1);
|
||||
memcpy(m_buff.data(), str, strLen);
|
||||
// make sure last element is a null terminator
|
||||
m_buff[m_buff.size() - 1] = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(char *str) noexcept {
|
||||
return *this = static_cast<const char*>(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(char c) noexcept {
|
||||
char str[] = {c, 0};
|
||||
return this->operator=(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(int i) noexcept {
|
||||
return this->operator=(static_cast<int64_t>(i));
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(int64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator=(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(uint64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator=(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(const BasicString &src) noexcept {
|
||||
return *this = src.c_str();
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator=(BasicString &&src) noexcept {
|
||||
m_buff = move(src.m_buff);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(const char *str) noexcept {
|
||||
std::size_t strLen = ox_strlen(str);
|
||||
oxIgnoreError(append(str, strLen));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(char *str) noexcept {
|
||||
return *this += static_cast<const char*>(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(char c) noexcept {
|
||||
const char str[] = {c, 0};
|
||||
return this->operator+=(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(int i) noexcept {
|
||||
return this->operator+=(static_cast<int64_t>(i));
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(int64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator+=(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(uint64_t i) noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return this->operator+=(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr BasicString<SmallStringSize> &BasicString<SmallStringSize>::operator+=(const BasicString &src) noexcept {
|
||||
return *this += src.c_str();
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(const char *str) const noexcept {
|
||||
const std::size_t strLen = ox_strlen(str);
|
||||
const auto currentLen = len();
|
||||
BasicString<SmallStringSize> cpy(currentLen + strLen);
|
||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
||||
memcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||
memcpy(&cpy.m_buff[currentLen], str, strLen);
|
||||
// make sure last element is a null terminator
|
||||
cpy.m_buff[currentLen + strLen] = 0;
|
||||
return move(cpy);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(char *str) const noexcept {
|
||||
return *this + static_cast<const char*>(str);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(char c) const noexcept {
|
||||
const char str[] = {c, 0};
|
||||
return *this + str;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(int i) const noexcept {
|
||||
return this->operator+(static_cast<int64_t>(i));
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(int64_t i) const noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return *this + str;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(uint64_t i) const noexcept {
|
||||
char str[65] = {};
|
||||
ox_itoa(i, str);
|
||||
return *this + str;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::operator+(const BasicString &src) const noexcept {
|
||||
return *this + src.c_str();
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
bool BasicString<SmallStringSize>::operator==(const BasicString &other) const noexcept {
|
||||
bool retval = true;
|
||||
std::size_t i = 0;
|
||||
while (i < m_buff.size() && (m_buff[i] || other.m_buff[i])) {
|
||||
if (m_buff[i] != other.m_buff[i]) {
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
bool BasicString<SmallStringSize>::operator!=(const BasicString &other) const noexcept {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
char BasicString<SmallStringSize>::operator[](std::size_t i) const noexcept {
|
||||
return m_buff[i];
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
char &BasicString<SmallStringSize>::operator[](std::size_t i) noexcept {
|
||||
return m_buff[i];
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
BasicString<SmallStringSize> BasicString<SmallStringSize>::substr(std::size_t pos) const noexcept {
|
||||
return m_buff.data() + pos;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
bool BasicString<SmallStringSize>::endsWith(const char *ending) const noexcept {
|
||||
const auto endingLen = ox_strlen(ending);
|
||||
return len() >= endingLen && ox_strcmp(data() + (len() - endingLen), ending) == 0;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
bool BasicString<SmallStringSize>::endsWith(const BasicString &ending) const noexcept {
|
||||
const auto endingLen = ending.len();
|
||||
return len() >= endingLen && ox_strcmp(data() + (len() - endingLen), ending.c_str()) == 0;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
std::size_t BasicString<SmallStringSize>::bytes() const noexcept {
|
||||
std::size_t i;
|
||||
for (i = 0; i < m_buff.size() && m_buff[i]; i++);
|
||||
return i + 1; // add one for null terminator
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
constexpr std::size_t BasicString<SmallStringSize>::len() const noexcept {
|
||||
std::size_t length = 0;
|
||||
for (std::size_t i = 0; i < m_buff.size(); i++) {
|
||||
uint8_t b = static_cast<uint8_t>(m_buff[i]);
|
||||
for (const auto c : m_buff) {
|
||||
auto b = static_cast<uint8_t>(c);
|
||||
if (b) {
|
||||
if ((b & 128) == 0) { // normal ASCII character
|
||||
length++;
|
||||
++length;
|
||||
} else if ((b & (256 << 6)) == (256 << 6)) { // start of UTF-8 character
|
||||
length++;
|
||||
++length;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
@ -197,4 +399,6 @@ constexpr std::size_t String::len() const noexcept {
|
||||
return length;
|
||||
}
|
||||
|
||||
using String = BasicString<0>;
|
||||
|
||||
}
|
||||
|
53
deps/ox/src/ox/std/trace.hpp
vendored
53
deps/ox/src/ox/std/trace.hpp
vendored
@ -15,6 +15,7 @@
|
||||
#include "bstring.hpp"
|
||||
#include "fmt.hpp"
|
||||
#include "hashmap.hpp"
|
||||
#include "string.hpp"
|
||||
#include "units.hpp"
|
||||
|
||||
extern "C" {
|
||||
@ -35,7 +36,7 @@ struct TraceMsg {
|
||||
int line = 0;
|
||||
uint64_t time = 0;
|
||||
const char *ch = "";
|
||||
BString<units::KB * 10> msg;
|
||||
BasicString<100> msg;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -102,7 +103,53 @@ class OutStream {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr OutStream &operator<<(const T &v) noexcept {
|
||||
constexpr OutStream &operator<<(const typename enable_if<is_integral_v<T>>::type &v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
if constexpr(T(-1) < 0) {
|
||||
m_msg.msg += static_cast<int64_t>(v);
|
||||
} else {
|
||||
m_msg.msg += static_cast<uint64_t>(v);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr OutStream &operator<<(char *v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
m_msg.msg += v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr OutStream &operator<<(const char *v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
m_msg.msg += v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr OutStream &operator<<(const BasicString<sz> &v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
m_msg.msg += v.c_str();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr OutStream &operator<<(const BString<sz> &v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
m_msg.msg += v.c_str();
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr OutStream &operator<<(char v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
@ -156,7 +203,7 @@ class NullStream {
|
||||
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#if defined(DEBUG) && !defined(OX_BARE_METAL)
|
||||
using TraceStream = OutStream;
|
||||
#else
|
||||
using TraceStream = NullStream;
|
||||
|
180
deps/ox/src/ox/std/vector.hpp
vendored
180
deps/ox/src/ox/std/vector.hpp
vendored
@ -17,8 +17,61 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, std::size_t Size = 100>
|
||||
struct SmallVector {
|
||||
private:
|
||||
AllocAlias<T> m_data[Size] = {};
|
||||
|
||||
protected:
|
||||
constexpr void initItems(T **items, std::size_t cap) noexcept {
|
||||
if (cap <= Size) {
|
||||
*items = bit_cast<T*>(m_data);
|
||||
} else {
|
||||
*items = bit_cast<T*>(new AllocAlias<T>[cap]);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void moveItemsFrom(T **items, SmallVector &src, const std::size_t count, const std::size_t cap) noexcept {
|
||||
if (cap <= Size) {
|
||||
const auto dstItems = bit_cast<T*>(m_data);
|
||||
const auto srcItems = bit_cast<T*>(src.m_data);
|
||||
for (auto i = 0u; i < count; ++i) {
|
||||
dstItems[i] = move(srcItems[i]);
|
||||
}
|
||||
*items = bit_cast<T*>(m_data);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void clearItems(AllocAlias<T> *items) noexcept {
|
||||
if (items != m_data) {
|
||||
delete[] items;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Vector {
|
||||
struct SmallVector<T, 0> {
|
||||
protected:
|
||||
constexpr void initItems(T **items, std::size_t cap) noexcept {
|
||||
*items = bit_cast<T*>(new AllocAlias<T>[cap]);
|
||||
}
|
||||
|
||||
constexpr void moveItemsFrom(T**, SmallVector&, const std::size_t, const std::size_t) noexcept {
|
||||
}
|
||||
|
||||
constexpr void clearItems(AllocAlias<T> *items) noexcept {
|
||||
delete[] items;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize = 0>
|
||||
class Vector: detail::SmallVector<T, SmallVectorSize> {
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
@ -232,45 +285,46 @@ class Vector {
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vector<T>::Vector(std::size_t size) noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Vector<T, SmallVectorSize>::Vector(std::size_t size) noexcept {
|
||||
m_size = size;
|
||||
m_cap = m_size;
|
||||
m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
this->initItems(&m_items, m_cap);
|
||||
for (std::size_t i = 0; i < size; ++i) {
|
||||
m_items[i] = {};
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector<T>::Vector(const Vector<T> &other) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Vector<T, SmallVectorSize>::Vector(const Vector &other) {
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
|
||||
for (std::size_t i = 0; i < m_size; i++) {
|
||||
this->initItems(&m_items, other.m_cap);
|
||||
for (std::size_t i = 0; i < m_size; ++i) {
|
||||
m_items[i] = move(other.m_items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector<T>::Vector(Vector<T> &&other) noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Vector<T, SmallVectorSize>::Vector(Vector &&other) noexcept {
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_items = other.m_items;
|
||||
this->moveItemsFrom(&m_items, other, m_size, m_cap);
|
||||
other.m_size = 0;
|
||||
other.m_cap = 0;
|
||||
other.m_items = nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector<T>::~Vector() {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Vector<T, SmallVectorSize>::~Vector() {
|
||||
clear();
|
||||
delete[] bit_cast<AllocAlias<T>*>(m_items);
|
||||
this->clearItems(bit_cast<AllocAlias<T>*>(m_items));
|
||||
m_items = nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Vector<T>::operator==(const Vector<T> &other) const {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
bool Vector<T, SmallVectorSize>::operator==(const Vector &other) const {
|
||||
if (m_size != other.m_size) {
|
||||
return false;
|
||||
}
|
||||
@ -282,14 +336,15 @@ bool Vector<T>::operator==(const Vector<T> &other) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Vector<T> &Vector<T>::operator=(const Vector<T> &other) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
constexpr Vector<T, SmallVectorSize> &Vector<T, SmallVectorSize>::operator=(const Vector &other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
delete[] bit_cast<AllocAlias<T>*>(m_items);
|
||||
this->clearItems(bit_cast<AllocAlias<T>*>(m_items));
|
||||
m_items = nullptr;
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
|
||||
this->initItems(&m_items, other.m_cap);
|
||||
for (std::size_t i = 0; i < m_size; i++) {
|
||||
m_items[i] = other.m_items[i];
|
||||
}
|
||||
@ -297,14 +352,15 @@ constexpr Vector<T> &Vector<T>::operator=(const Vector<T> &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Vector<T> &Vector<T>::operator=(Vector<T> &&other) noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
constexpr Vector<T, SmallVectorSize> &Vector<T, SmallVectorSize>::operator=(Vector &&other) noexcept {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
delete[] bit_cast<AllocAlias<T>*>(m_items);
|
||||
this->clearItems(bit_cast<AllocAlias<T>*>(m_items));
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_items = other.m_items;
|
||||
this->moveItemsFrom(&m_items, other, m_size, m_cap);
|
||||
other.m_size = 0;
|
||||
other.m_cap = 0;
|
||||
other.m_items = nullptr;
|
||||
@ -312,18 +368,18 @@ constexpr Vector<T> &Vector<T>::operator=(Vector<T> &&other) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr T &Vector<T>::operator[](std::size_t i) noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
constexpr T &Vector<T, SmallVectorSize>::operator[](std::size_t i) noexcept {
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr const T &Vector<T>::operator[](std::size_t i) const noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
constexpr const T &Vector<T, SmallVectorSize>::operator[](std::size_t i) const noexcept {
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<T&> Vector<T>::front() noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Result<T&> Vector<T, SmallVectorSize>::front() noexcept {
|
||||
if (!m_size) {
|
||||
AllocAlias<T> v;
|
||||
return {*bit_cast<T*>(&v), OxError(1)};
|
||||
@ -331,8 +387,8 @@ Result<T&> Vector<T>::front() noexcept {
|
||||
return m_items[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<const T&> Vector<T>::front() const noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Result<const T&> Vector<T, SmallVectorSize>::front() const noexcept {
|
||||
if (!m_size) {
|
||||
AllocAlias<T> v;
|
||||
return {*bit_cast<T*>(&v), OxError(1)};
|
||||
@ -340,8 +396,8 @@ Result<const T&> Vector<T>::front() const noexcept {
|
||||
return m_items[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<T&> Vector<T>::back() noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Result<T&> Vector<T, SmallVectorSize>::back() noexcept {
|
||||
if (!m_size) {
|
||||
AllocAlias<T> v;
|
||||
return {*bit_cast<T*>(&v), OxError(1)};
|
||||
@ -349,8 +405,8 @@ Result<T&> Vector<T>::back() noexcept {
|
||||
return m_items[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<const T&> Vector<T>::back() const noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Result<const T&> Vector<T, SmallVectorSize>::back() const noexcept {
|
||||
if (!m_size) {
|
||||
AllocAlias<T> v;
|
||||
return {*bit_cast<T*>(&v), OxError(1)};
|
||||
@ -358,18 +414,18 @@ Result<const T&> Vector<T>::back() const noexcept {
|
||||
return m_items[m_size - 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr std::size_t Vector<T>::size() const noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
constexpr std::size_t Vector<T, SmallVectorSize>::size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Vector<T>::empty() const noexcept {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
bool Vector<T, SmallVectorSize>::empty() const noexcept {
|
||||
return !m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Vector<T>::clear() {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
void Vector<T, SmallVectorSize>::clear() {
|
||||
if constexpr(is_class<T>()) {
|
||||
for (std::size_t i = 0; i < m_size; ++i) {
|
||||
m_items[i].~T();
|
||||
@ -378,8 +434,8 @@ void Vector<T>::clear() {
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr void Vector<T>::resize(std::size_t size) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
constexpr void Vector<T, SmallVectorSize>::resize(std::size_t size) {
|
||||
if (m_cap < size) {
|
||||
expandCap(size);
|
||||
}
|
||||
@ -395,8 +451,8 @@ constexpr void Vector<T>::resize(std::size_t size) {
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Vector<T>::contains(const T &v) const {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
bool Vector<T, SmallVectorSize>::contains(const T &v) const {
|
||||
for (std::size_t i = 0; i < m_size; i++) {
|
||||
if (m_items[i] == v) {
|
||||
return true;
|
||||
@ -405,8 +461,8 @@ bool Vector<T>::contains(const T &v) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Vector<T>::insert(std::size_t pos, const T &val) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
void Vector<T, SmallVectorSize>::insert(std::size_t pos, const T &val) {
|
||||
// TODO: insert should ideally have its own expandCap
|
||||
if (m_size == m_cap) {
|
||||
expandCap(m_cap ? m_cap * 2 : 100);
|
||||
@ -418,9 +474,9 @@ void Vector<T>::insert(std::size_t pos, const T &val) {
|
||||
++m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
template<typename... Args>
|
||||
void Vector<T>::emplace_back(Args&&... args) {
|
||||
void Vector<T, SmallVectorSize>::emplace_back(Args&&... args) {
|
||||
if (m_size == m_cap) {
|
||||
expandCap(m_cap ? m_cap * 2 : 100);
|
||||
}
|
||||
@ -428,8 +484,8 @@ void Vector<T>::emplace_back(Args&&... args) {
|
||||
++m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Vector<T>::push_back(const T &item) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
void Vector<T, SmallVectorSize>::push_back(const T &item) {
|
||||
if (m_size == m_cap) {
|
||||
expandCap(m_cap ? m_cap * 2 : 100);
|
||||
}
|
||||
@ -437,14 +493,14 @@ void Vector<T>::push_back(const T &item) {
|
||||
++m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Vector<T>::pop_back() {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
void Vector<T, SmallVectorSize>::pop_back() {
|
||||
--m_size;
|
||||
m_items[m_size].~T();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error Vector<T>::erase(std::size_t pos) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Error Vector<T, SmallVectorSize>::erase(std::size_t pos) {
|
||||
if (pos >= m_size) {
|
||||
return OxError(1);
|
||||
}
|
||||
@ -455,21 +511,21 @@ Error Vector<T>::erase(std::size_t pos) {
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error Vector<T>::unordered_erase(std::size_t pos) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
Error Vector<T, SmallVectorSize>::unordered_erase(std::size_t pos) {
|
||||
if (pos >= m_size) {
|
||||
return OxError(1);
|
||||
}
|
||||
m_size--;
|
||||
--m_size;
|
||||
m_items[pos] = move(m_items[m_size]);
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Vector<T>::expandCap(std::size_t cap) {
|
||||
template<typename T, std::size_t SmallVectorSize>
|
||||
void Vector<T, SmallVectorSize>::expandCap(std::size_t cap) {
|
||||
auto oldItems = m_items;
|
||||
m_cap = cap;
|
||||
m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
|
||||
this->initItems(&m_items, cap);
|
||||
if (oldItems) { // move over old items
|
||||
const auto itRange = cap > m_size ? m_size : cap;
|
||||
for (std::size_t i = 0; i < itRange; i++) {
|
||||
@ -478,7 +534,7 @@ void Vector<T>::expandCap(std::size_t cap) {
|
||||
for (std::size_t i = itRange; i < m_cap; i++) {
|
||||
new (&m_items[i]) T;
|
||||
}
|
||||
delete[] bit_cast<AllocAlias<T>*>(oldItems);
|
||||
this->clearItems(bit_cast<AllocAlias<T>*>(oldItems));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user