Squashed 'deps/nostalgia/' changes from 0c0ccd1a..227f3cd9
227f3cd9 [nostalgia/core/studio] Update itoa usages 20ff0f89 [ox/std] Rework itoa 4061b831 [ox/model] Remove broken global var 18bb5062 [ox/std] Add String::append(StringView), cleanup 6a4b4822 [nostalgia,studio] Fixes for Ox changes d2a3cfa7 [ox/std] Remove append operators from IString 7c4e2a65 [ox/std] Cleanup IString e30ebce4 [nostalgia] Add pyenv to .gitignore 7163947e [ox/std] Cleanup 0a0a6e30 [studio] Move UndoCommand implementation to its own file 97bc9332 [nostalgia/core] Fix TileSheetV1 to use PaletteV1 9caf7099 [keel] Fix for Ox change fda1280d [ox/std] Make substr always take and return a StringView 59aa4ad2 [cityhash] Cleanup 1a8afa1a [nostalgia/sample_project] Add missing type descriptor cdbc2d6c [olympic/studio] Move UndoCommand to its own file acd93337 [ox/std] Fix Integer assignment operator return cebd3b0a [ox/std] Fix Integer assignment operator return 43e2e215 [ox/std] Cleanup be1f9095 [ox/std] Make safeDelete constexpr 0f2c18d5 [ox/std] Add std::string(_view) variant of MaybeView git-subtree-dir: deps/nostalgia git-subtree-split: 227f3cd9f584039cfddad75f1fe1275ad6cac000
This commit is contained in:
parent
22e6299e90
commit
df22a1e51b
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@
|
|||||||
.stfolder
|
.stfolder
|
||||||
.stignore
|
.stignore
|
||||||
scripts/__pycache__
|
scripts/__pycache__
|
||||||
|
pyenv
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
ROM.oxfs
|
ROM.oxfs
|
||||||
Session.vim
|
Session.vim
|
||||||
|
54
deps/ox/deps/cityhash/include/cityhash/city.h
vendored
54
deps/ox/deps/cityhash/include/cityhash/city.h
vendored
@ -100,27 +100,52 @@ typedef uint32_t uintptr_t;
|
|||||||
#error intptr_t, and uintptr_t undefined
|
#error intptr_t, and uintptr_t undefined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
using size_t = decltype(alignof(int));
|
using size_t = decltype(alignof(int));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if __has_include(<utility>)
|
|
||||||
#include <utility>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace cityhash::detail {
|
namespace cityhash::detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct remove_reference {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct remove_reference<T&> {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct remove_reference<T&&> {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using remove_reference_t = typename remove_reference<T>::type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr remove_reference_t<T> &&move(T &&t) noexcept {
|
||||||
|
return static_cast<remove_reference_t<T>&&>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using remove_reference_t = typename remove_reference<T>::type;
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct pair {
|
struct pair {
|
||||||
T1 first{};
|
T1 first{};
|
||||||
T2 second{};
|
T2 second{};
|
||||||
constexpr pair() noexcept = default;
|
constexpr pair() noexcept = default;
|
||||||
constexpr pair(T1 a, T2 b) noexcept: first(std::move(a)), second(std::move(b)) {}
|
constexpr pair(T1 a, T2 b) noexcept: first(detail::move(a)), second(detail::move(b)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr void swap(T &a, T &b) noexcept {
|
||||||
|
auto temp = detail::move(a);
|
||||||
|
a = detail::move(b);
|
||||||
|
b = detail::move(temp);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace cityhash {
|
namespace cityhash {
|
||||||
@ -129,13 +154,6 @@ using uint128 = cityhash::detail::pair<uint64_t, uint64_t>;
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr void swap(T &a, T &b) noexcept {
|
|
||||||
auto temp = std::move(a);
|
|
||||||
a = std::move(b);
|
|
||||||
b = std::move(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr T byteSwap(T i) noexcept {
|
constexpr T byteSwap(T i) noexcept {
|
||||||
@ -290,7 +308,7 @@ constexpr uint32_t Hash32Len0to4(const char *s, size_t len) noexcept {
|
|||||||
uint32_t b = 0;
|
uint32_t b = 0;
|
||||||
uint32_t c = 9;
|
uint32_t c = 9;
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
signed char v = static_cast<signed char>(s[i]);
|
auto const v = static_cast<signed char>(s[i]);
|
||||||
b = b * detail::c1 + static_cast<uint32_t>(v);
|
b = b * detail::c1 + static_cast<uint32_t>(v);
|
||||||
c ^= b;
|
c ^= b;
|
||||||
}
|
}
|
||||||
|
7
deps/ox/src/ox/model/typenamecatcher.hpp
vendored
7
deps/ox/src/ox/model/typenamecatcher.hpp
vendored
@ -147,13 +147,6 @@ constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
|
|||||||
template<typename T, typename Str = const char*>
|
template<typename T, typename Str = const char*>
|
||||||
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
|
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
|
||||||
|
|
||||||
template<typename T, typename Str = const char*>
|
|
||||||
constexpr auto ModelTypeVersionStr_v = [] {
|
|
||||||
constexpr auto version = ModelTypeVersion_v<T>;
|
|
||||||
constexpr auto versionStr = ox::sfmt("{}", version);
|
|
||||||
return ox::IString<versionStr.len()>{versionStr};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr auto ModelTypeId_v = [] {
|
constexpr auto ModelTypeId_v = [] {
|
||||||
constexpr auto name = ModelTypeName_v<T, ox::StringView>;
|
constexpr auto name = ModelTypeName_v<T, ox::StringView>;
|
||||||
|
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -124,6 +124,7 @@ install(
|
|||||||
stringliteral.hpp
|
stringliteral.hpp
|
||||||
stringview.hpp
|
stringview.hpp
|
||||||
strongint.hpp
|
strongint.hpp
|
||||||
|
strconv.hpp
|
||||||
strops.hpp
|
strops.hpp
|
||||||
trace.hpp
|
trace.hpp
|
||||||
typeinfo.hpp
|
typeinfo.hpp
|
||||||
|
34
deps/ox/src/ox/std/cstrops.hpp
vendored
34
deps/ox/src/ox/std/cstrops.hpp
vendored
@ -112,38 +112,4 @@ constexpr int lastIndexOf(const auto &str, int character, std::size_t maxLen = 0
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Integer, typename T>
|
|
||||||
constexpr T itoa(Integer v, T str) noexcept {
|
|
||||||
if (v) {
|
|
||||||
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
|
|
||||||
ox::ResizedInt_t<Integer, 64> val = v;
|
|
||||||
constexpr auto base = 10;
|
|
||||||
auto it = 0;
|
|
||||||
if (val < 0) {
|
|
||||||
str[static_cast<std::size_t>(it)] = '-';
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
while (mod) {
|
|
||||||
auto digit = val / mod;
|
|
||||||
val %= mod;
|
|
||||||
mod /= base;
|
|
||||||
if (it || digit) {
|
|
||||||
ox::ResizedInt_t<Integer, 64> start = '0';
|
|
||||||
if (digit >= 10) {
|
|
||||||
start = 'a';
|
|
||||||
digit -= 10;
|
|
||||||
}
|
|
||||||
str[static_cast<std::size_t>(it)] = static_cast<typename ox::remove_reference<decltype(str[0])>::type>(start + digit);
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str[static_cast<std::size_t>(it)] = 0;
|
|
||||||
} else {
|
|
||||||
// 0 is a special case
|
|
||||||
str[0] = '0';
|
|
||||||
str[1] = 0;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
11
deps/ox/src/ox/std/fmt.hpp
vendored
11
deps/ox/src/ox/std/fmt.hpp
vendored
@ -75,14 +75,17 @@ constexpr StringView toStringView(const auto&) noexcept requires(force) {
|
|||||||
class FmtArg {
|
class FmtArg {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char dataStr[10] = {};
|
static constexpr auto DataSz = 23;
|
||||||
|
char dataStr[DataSz] = {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr StringView sv(const T &v, char *dataStr) noexcept {
|
constexpr StringView sv(const T &v, char *dataStr) noexcept {
|
||||||
if constexpr(is_bool_v<T>) {
|
if constexpr(is_bool_v<T>) {
|
||||||
return v ? "true" : "false";
|
return v ? "true" : "false";
|
||||||
} else if constexpr(is_integer_v<T>) {
|
} else if constexpr(is_integer_v<T>) {
|
||||||
return ox::itoa(v, dataStr);
|
ox::CharBuffWriter w(dataStr, DataSz);
|
||||||
|
std::ignore = ox::writeItoa(v, w);
|
||||||
|
return dataStr;
|
||||||
} else {
|
} else {
|
||||||
return toStringView(v);
|
return toStringView(v);
|
||||||
}
|
}
|
||||||
@ -195,7 +198,7 @@ constexpr StringType sfmt(StringView fmt, Args&&... args) noexcept {
|
|||||||
std::ignore = out.append(firstSegment.str, firstSegment.length);
|
std::ignore = out.append(firstSegment.str, firstSegment.length);
|
||||||
const detail::FmtArg elements[sizeof...(args)] = {args...};
|
const detail::FmtArg elements[sizeof...(args)] = {args...};
|
||||||
for (size_t i = 0; i < fmtSegments.size - 1; ++i) {
|
for (size_t i = 0; i < fmtSegments.size - 1; ++i) {
|
||||||
out += elements[i].out;
|
std::ignore = out.append(elements[i].out);
|
||||||
const auto &s = fmtSegments.segments[i + 1];
|
const auto &s = fmtSegments.segments[i + 1];
|
||||||
std::ignore = out.append(s.str, s.length);
|
std::ignore = out.append(s.str, s.length);
|
||||||
}
|
}
|
||||||
@ -203,7 +206,7 @@ constexpr StringType sfmt(StringView fmt, Args&&... args) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T = String>
|
template<typename T = String>
|
||||||
constexpr Result<T> join(auto d, const auto &list) {
|
constexpr Result<T> join(auto const&d, auto const&list) {
|
||||||
if (!list.size()) {
|
if (!list.size()) {
|
||||||
return T("");
|
return T("");
|
||||||
}
|
}
|
||||||
|
218
deps/ox/src/ox/std/istring.hpp
vendored
218
deps/ox/src/ox/std/istring.hpp
vendored
@ -8,20 +8,25 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ignore.hpp"
|
#include "array.hpp"
|
||||||
|
#include "concepts.hpp"
|
||||||
|
#include "cstrops.hpp"
|
||||||
#include "memops.hpp"
|
#include "memops.hpp"
|
||||||
|
#include "error.hpp"
|
||||||
|
#include "buffer.hpp"
|
||||||
|
#include "ignore.hpp"
|
||||||
#include "stringview.hpp"
|
#include "stringview.hpp"
|
||||||
#include "strops.hpp"
|
|
||||||
#include "typetraits.hpp"
|
#include "typetraits.hpp"
|
||||||
|
#include "strconv.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
// Inline String
|
// Inline String
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
class IString {
|
class IString {
|
||||||
private:
|
private:
|
||||||
char m_buff[buffLen + 1];
|
|
||||||
size_t m_size{};
|
size_t m_size{};
|
||||||
|
ox::Array<char, StrCap + 1> m_buff;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr IString() noexcept;
|
constexpr IString() noexcept;
|
||||||
@ -34,23 +39,8 @@ class IString {
|
|||||||
|
|
||||||
constexpr IString &operator=(const char *str) noexcept;
|
constexpr IString &operator=(const char *str) noexcept;
|
||||||
|
|
||||||
constexpr IString &operator=(char *str) noexcept;
|
|
||||||
|
|
||||||
constexpr IString &operator=(Integer_c auto i) noexcept;
|
constexpr IString &operator=(Integer_c auto i) noexcept;
|
||||||
|
|
||||||
constexpr IString &operator+=(const char *str) noexcept;
|
|
||||||
|
|
||||||
constexpr IString &operator+=(char *str) noexcept;
|
|
||||||
|
|
||||||
constexpr IString &operator+=(Integer_c auto i) noexcept;
|
|
||||||
|
|
||||||
constexpr IString &operator+=(StringView s) noexcept;
|
|
||||||
|
|
||||||
constexpr IString operator+(const char *str) const noexcept;
|
|
||||||
|
|
||||||
constexpr IString operator+(char *str) const noexcept;
|
|
||||||
|
|
||||||
constexpr IString operator+(Integer_c auto i) const noexcept;
|
|
||||||
|
|
||||||
constexpr bool operator==(const char *other) const noexcept;
|
constexpr bool operator==(const char *other) const noexcept;
|
||||||
|
|
||||||
@ -66,6 +56,8 @@ class IString {
|
|||||||
|
|
||||||
constexpr Error append(const char *str, std::size_t strLen) noexcept;
|
constexpr Error append(const char *str, std::size_t strLen) noexcept;
|
||||||
|
|
||||||
|
constexpr Error append(ox::StringView str) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr const char *data() const noexcept;
|
constexpr const char *data() const noexcept;
|
||||||
|
|
||||||
@ -87,6 +79,8 @@ class IString {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr std::size_t bytes() const noexcept;
|
constexpr std::size_t bytes() const noexcept;
|
||||||
|
|
||||||
|
constexpr ox::Error resize(size_t sz) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the capacity of bytes for this string.
|
* Returns the capacity of bytes for this string.
|
||||||
*/
|
*/
|
||||||
@ -110,9 +104,11 @@ constexpr IString<size>::IString(const char *str) noexcept: m_buff{{0}} {
|
|||||||
|
|
||||||
template<std::size_t size>
|
template<std::size_t size>
|
||||||
constexpr IString<size> &IString<size>::operator=(Integer_c auto i) noexcept {
|
constexpr IString<size> &IString<size>::operator=(Integer_c auto i) noexcept {
|
||||||
char str[65] = {};
|
ox::Array<char, 22> s;
|
||||||
ox::itoa(i, str);
|
ox::CharBuffWriter w(s);
|
||||||
return this->operator=(str);
|
std::ignore = ox::writeItoa(i, w);
|
||||||
|
this->operator=({s.data(), w.tellp()});
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t size>
|
template<std::size_t size>
|
||||||
@ -122,7 +118,7 @@ constexpr IString<size> &IString<size>::operator=(ox::CRStringView str) noexcept
|
|||||||
strLen = cap();
|
strLen = cap();
|
||||||
}
|
}
|
||||||
m_size = strLen;
|
m_size = strLen;
|
||||||
ox::listcpy(m_buff, str.data(), strLen);
|
ox::listcpy(m_buff.data(), str.data(), strLen);
|
||||||
// make sure last element is a null terminator
|
// make sure last element is a null terminator
|
||||||
m_buff[strLen] = 0;
|
m_buff[strLen] = 0;
|
||||||
return *this;
|
return *this;
|
||||||
@ -135,128 +131,92 @@ constexpr IString<size> &IString<size>::operator=(const char *str) noexcept {
|
|||||||
strLen = cap();
|
strLen = cap();
|
||||||
}
|
}
|
||||||
m_size = strLen;
|
m_size = strLen;
|
||||||
ox::listcpy(m_buff, str, strLen);
|
ox::listcpy(m_buff.data(), str, strLen);
|
||||||
// make sure last element is a null terminator
|
// make sure last element is a null terminator
|
||||||
m_buff[cap()] = 0;
|
m_buff[cap()] = 0;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t size>
|
template<std::size_t StrCap>
|
||||||
constexpr IString<size> &IString<size>::operator=(char *str) noexcept {
|
constexpr bool IString<StrCap>::operator==(const char *other) const noexcept {
|
||||||
return *this = static_cast<const char*>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> &IString<size>::operator+=(const char *str) noexcept {
|
|
||||||
std::size_t strLen = ox::strlen(str) + 1;
|
|
||||||
std::ignore = append(str, strLen);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> &IString<size>::operator+=(char *str) noexcept {
|
|
||||||
return *this += static_cast<const char*>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> &IString<size>::operator+=(Integer_c auto i) noexcept {
|
|
||||||
char str[65] = {};
|
|
||||||
ox::itoa(i, str);
|
|
||||||
return this->operator+=(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> &IString<size>::operator+=(StringView s) noexcept {
|
|
||||||
std::size_t strLen = s.bytes();
|
|
||||||
std::ignore = append(s.data(), strLen);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> IString<size>::operator+(const char *str) const noexcept {
|
|
||||||
auto out = *this;
|
|
||||||
std::size_t strLen = ox::strlen(str) + 1;
|
|
||||||
std::ignore = out.append(str, strLen);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> IString<size>::operator+(char *str) const noexcept {
|
|
||||||
return *this + static_cast<const char*>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t size>
|
|
||||||
constexpr IString<size> IString<size>::operator+(Integer_c auto i) const noexcept {
|
|
||||||
char str[65] = {};
|
|
||||||
ox::itoa(i, str);
|
|
||||||
return this->operator+(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
|
||||||
constexpr bool IString<buffLen>::operator==(const char *other) const noexcept {
|
|
||||||
return ox::StringView(*this) == other;
|
return ox::StringView(*this) == other;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr bool IString<buffLen>::operator==(const OxString_c auto &other) const noexcept {
|
constexpr bool IString<StrCap>::operator==(const OxString_c auto &other) const noexcept {
|
||||||
return ox::StringView(*this) == ox::StringView(other);
|
return ox::StringView(*this) == ox::StringView(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr bool IString<buffLen>::operator!=(const char *other) const noexcept {
|
constexpr bool IString<StrCap>::operator!=(const char *other) const noexcept {
|
||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr bool IString<buffLen>::operator!=(const OxString_c auto &other) noexcept {
|
constexpr bool IString<StrCap>::operator!=(const OxString_c auto &other) noexcept {
|
||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr char IString<buffLen>::operator[](std::size_t i) const noexcept {
|
constexpr char IString<StrCap>::operator[](std::size_t i) const noexcept {
|
||||||
return m_buff[i];
|
return m_buff[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr char &IString<buffLen>::operator[](std::size_t i) noexcept {
|
constexpr char &IString<StrCap>::operator[](std::size_t i) noexcept {
|
||||||
return m_buff[i];
|
return m_buff[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr Error IString<buffLen>::append(const char *str, std::size_t strLen) noexcept {
|
constexpr Error IString<StrCap>::append(const char *str, std::size_t strLen) noexcept {
|
||||||
Error err;
|
Error err{};
|
||||||
auto currentLen = len();
|
auto currentLen = len();
|
||||||
if (cap() < currentLen + strLen + 1) {
|
if (cap() < currentLen + strLen + 1) {
|
||||||
strLen = cap() - currentLen;
|
strLen = cap() - currentLen;
|
||||||
err = OxError(1, "Insufficient space for full string");
|
err = OxError(1, "Insufficient space for full string");
|
||||||
}
|
}
|
||||||
ox::strncpy(m_buff + currentLen, str, strLen);
|
ox::strncpy(m_buff.data() + currentLen, str, strLen);
|
||||||
// make sure last element is a null terminator
|
// make sure last element is a null terminator
|
||||||
m_buff[currentLen + strLen] = 0;
|
m_buff[currentLen + strLen] = 0;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr const char *IString<buffLen>::data() const noexcept {
|
constexpr Error IString<StrCap>::append(ox::StringView str) noexcept {
|
||||||
return static_cast<const char*>(m_buff);
|
auto strLen = str.len();
|
||||||
|
Error err{};
|
||||||
|
auto currentLen = len();
|
||||||
|
if (cap() < currentLen + strLen + 1) {
|
||||||
|
strLen = cap() - currentLen;
|
||||||
|
err = OxError(1, "Insufficient space for full string");
|
||||||
|
}
|
||||||
|
ox::strncpy(m_buff.data() + currentLen, str, strLen);
|
||||||
|
// make sure last element is a null terminator
|
||||||
|
m_buff[currentLen + strLen] = 0;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr char *IString<buffLen>::data() noexcept {
|
constexpr const char *IString<StrCap>::data() const noexcept {
|
||||||
return static_cast<char*>(m_buff);
|
return static_cast<const char*>(m_buff.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr const char *IString<buffLen>::c_str() const noexcept {
|
constexpr char *IString<StrCap>::data() noexcept {
|
||||||
return static_cast<const char*>(m_buff);
|
return static_cast<char*>(m_buff.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t StrCap>
|
||||||
|
constexpr const char *IString<StrCap>::c_str() const noexcept {
|
||||||
|
return static_cast<const char*>(m_buff.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr std::size_t IString<buffLen>::len() const noexcept {
|
constexpr std::size_t IString<StrCap>::len() const noexcept {
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
for (std::size_t i = 0; i < buffLen; i++) {
|
for (std::size_t i = 0; i < StrCap; i++) {
|
||||||
uint8_t b = static_cast<uint8_t>(m_buff[i]);
|
auto const b = static_cast<uint8_t>(m_buff[i]);
|
||||||
if (b) {
|
if (b) {
|
||||||
const auto asciiChar = (b & 128) == 0;
|
const auto asciiChar = (b & 128) == 0;
|
||||||
const auto utf8Char = (b & (256 << 6)) == (256 << 6);
|
const auto utf8Char = (b & (256 << 6)) == (256 << 6);
|
||||||
@ -270,16 +230,28 @@ constexpr std::size_t IString<buffLen>::len() const noexcept {
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr std::size_t IString<buffLen>::bytes() const noexcept {
|
constexpr std::size_t IString<StrCap>::bytes() const noexcept {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (i = 0; i < buffLen && m_buff[i]; i++);
|
for (i = 0; i < StrCap && m_buff[i]; i++);
|
||||||
return i + 1; // add one for null terminator
|
return i + 1; // add one for null terminator
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t buffLen>
|
template<std::size_t StrCap>
|
||||||
constexpr std::size_t IString<buffLen>::cap() const noexcept {
|
constexpr ox::Error IString<StrCap>::resize(size_t sz) noexcept {
|
||||||
return buffLen;
|
if (sz > StrCap) [[unlikely]] {
|
||||||
|
return OxError(1, "Trying to extend IString beyond its cap");
|
||||||
|
}
|
||||||
|
for (auto i = m_size; i < sz; ++i) {
|
||||||
|
m_buff[i] = 0;
|
||||||
|
}
|
||||||
|
m_size = sz;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t StrCap>
|
||||||
|
constexpr std::size_t IString<StrCap>::cap() const noexcept {
|
||||||
|
return StrCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t sz>
|
template<size_t sz>
|
||||||
@ -287,4 +259,30 @@ struct MaybeView<ox::IString<sz>> {
|
|||||||
using type = ox::StringView;
|
using type = ox::StringView;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<Integer_c Integer>
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto itoa(Integer v) noexcept {
|
||||||
|
constexpr auto Cap = [] {
|
||||||
|
auto out = 0;
|
||||||
|
switch (sizeof(Integer)) {
|
||||||
|
case 1:
|
||||||
|
out = 3;
|
||||||
|
case 2:
|
||||||
|
out = 5;
|
||||||
|
case 4:
|
||||||
|
out = 10;
|
||||||
|
case 8:
|
||||||
|
out = 21;
|
||||||
|
}
|
||||||
|
return out + ox::is_signed_v<Integer>;
|
||||||
|
}();
|
||||||
|
ox::IString<Cap> out;
|
||||||
|
std::ignore = out.resize(out.cap());
|
||||||
|
ox::CharBuffWriter w(out.data(), out.cap());
|
||||||
|
std::ignore = writeItoa(v, w);
|
||||||
|
std::ignore = out.resize(w.tellp());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
6
deps/ox/src/ox/std/math.hpp
vendored
6
deps/ox/src/ox/std/math.hpp
vendored
@ -48,11 +48,11 @@ constexpr const T &clamp(const T &v, const T &lo, const T &hi) noexcept requires
|
|||||||
return min(ox::max(v, lo), hi);
|
return min(ox::max(v, lo), hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I>
|
template<typename I, typename E>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr I pow(I v, int e) noexcept {
|
constexpr I pow(I v, E e) noexcept {
|
||||||
I out = 1;
|
I out = 1;
|
||||||
for (I i = 0; i < e; i++) {
|
for (E i = 0; i < e; ++i) {
|
||||||
out *= v;
|
out *= v;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
12
deps/ox/src/ox/std/maybeview.hpp
vendored
12
deps/ox/src/ox/std/maybeview.hpp
vendored
@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "typetraits.hpp"
|
#if __has_include(<string>)
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -23,4 +26,11 @@ struct MaybeView {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
using MaybeView_t = typename MaybeView<T>::type;
|
using MaybeView_t = typename MaybeView<T>::type;
|
||||||
|
|
||||||
|
#if __has_include(<string>)
|
||||||
|
template<typename CharT, typename Traits, typename Allocator>
|
||||||
|
struct MaybeView<std::basic_string<CharT, Traits, Allocator>> {
|
||||||
|
using type = std::basic_string_view<CharT, Traits>;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
4
deps/ox/src/ox/std/memory.hpp
vendored
4
deps/ox/src/ox/std/memory.hpp
vendored
@ -51,12 +51,12 @@ namespace ox {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void safeDelete(T *val) requires(sizeof(T) >= 1) {
|
constexpr void safeDelete(T *val) requires(sizeof(T) >= 1) {
|
||||||
delete val;
|
delete val;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void safeDeleteArray(T *val) requires(sizeof(T) >= 1) {
|
constexpr void safeDeleteArray(T *val) requires(sizeof(T) >= 1) {
|
||||||
delete[] val;
|
delete[] val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
deps/ox/src/ox/std/strconv.hpp
vendored
Normal file
44
deps/ox/src/ox/std/strconv.hpp
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "error.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
#include "writer.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
template<Integer_c Integer>
|
||||||
|
constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept {
|
||||||
|
if (v) {
|
||||||
|
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
|
||||||
|
ox::ResizedInt_t<Integer, 64> val = v;
|
||||||
|
constexpr auto base = 10;
|
||||||
|
auto it = 0;
|
||||||
|
if (val < 0) {
|
||||||
|
oxReturnError(writer.put('-'));
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
while (mod) {
|
||||||
|
auto digit = val / mod;
|
||||||
|
val %= mod;
|
||||||
|
mod /= base;
|
||||||
|
if (it || digit) {
|
||||||
|
ox::ResizedInt_t<Integer, 64> start = '0';
|
||||||
|
if (digit >= 10) {
|
||||||
|
start = 'a';
|
||||||
|
digit -= 10;
|
||||||
|
}
|
||||||
|
oxReturnError(writer.put(static_cast<char>(start + digit)));
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 0 is a special case
|
||||||
|
oxReturnError(writer.put('0'));
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "istring.hpp"
|
24
deps/ox/src/ox/std/string.hpp
vendored
24
deps/ox/src/ox/std/string.hpp
vendored
@ -16,6 +16,7 @@
|
|||||||
#include "ignore.hpp"
|
#include "ignore.hpp"
|
||||||
#include "memops.hpp"
|
#include "memops.hpp"
|
||||||
#include "serialize.hpp"
|
#include "serialize.hpp"
|
||||||
|
#include "strconv.hpp"
|
||||||
#include "stringliteral.hpp"
|
#include "stringliteral.hpp"
|
||||||
#include "stringview.hpp"
|
#include "stringview.hpp"
|
||||||
#include "strops.hpp"
|
#include "strops.hpp"
|
||||||
@ -23,6 +24,9 @@
|
|||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
|
template<typename Integer>
|
||||||
|
constexpr ox::IString<21> itoa(Integer v) noexcept;
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
class BasicString {
|
class BasicString {
|
||||||
private:
|
private:
|
||||||
@ -178,6 +182,10 @@ class BasicString {
|
|||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr Error append(ox::StringView sv) noexcept {
|
||||||
|
return append(sv.data(), sv.len());
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr BasicString substr(std::size_t pos) const noexcept;
|
constexpr BasicString substr(std::size_t pos) const noexcept;
|
||||||
|
|
||||||
@ -323,17 +331,13 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
|
|||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(int64_t i) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(int64_t i) noexcept {
|
||||||
ox::Array<char, 65> str{};
|
set(ox::itoa(i));
|
||||||
ox::itoa(i, str.data());
|
|
||||||
set(str.data());
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(uint64_t i) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(uint64_t i) noexcept {
|
||||||
ox::Array<char, 65> str{};
|
set(ox::itoa(i));
|
||||||
ox::itoa(i, str.data());
|
|
||||||
set(str.data());
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,9 +383,8 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
|
|||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator+=(Integer_c auto i) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator+=(Integer_c auto i) noexcept {
|
||||||
char str[65] = {};
|
auto const str = ox::itoa(i);
|
||||||
ox::itoa(i, str);
|
return this->operator+=(str.c_str());
|
||||||
return this->operator+=(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
@ -423,8 +426,7 @@ constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operato
|
|||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operator+(Integer_c auto i) const noexcept {
|
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operator+(Integer_c auto i) const noexcept {
|
||||||
char str[65] = {};
|
auto const str = ox::itoa(i);
|
||||||
ox::itoa(i, str);
|
|
||||||
return *this + str;
|
return *this + str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
deps/ox/src/ox/std/stringliteral.hpp
vendored
5
deps/ox/src/ox/std/stringliteral.hpp
vendored
@ -32,10 +32,9 @@ class StringLiteral: public detail::BaseStringView {
|
|||||||
|
|
||||||
constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
|
constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
|
||||||
|
|
||||||
constexpr explicit StringLiteral(char const *str) noexcept: StringLiteral(str, ox::strlen(str)) {
|
constexpr explicit StringLiteral(char const *str) noexcept: StringLiteral(str, ox::strlen(str)) {}
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto &operator=(StringLiteral const&other) noexcept {
|
constexpr StringLiteral &operator=(StringLiteral const&other) noexcept {
|
||||||
if (&other != this) {
|
if (&other != this) {
|
||||||
set(other.data(), other.len());
|
set(other.data(), other.len());
|
||||||
}
|
}
|
||||||
|
7
deps/ox/src/ox/std/strongint.hpp
vendored
7
deps/ox/src/ox/std/strongint.hpp
vendored
@ -34,7 +34,7 @@ class Integer: public Base {
|
|||||||
|
|
||||||
constexpr Integer(const Integer<T, Base> &i) noexcept;
|
constexpr Integer(const Integer<T, Base> &i) noexcept;
|
||||||
|
|
||||||
constexpr Integer<T, Base> operator=(Integer<T, Base> i) noexcept;
|
constexpr Integer<T, Base> &operator=(Integer<T, Base> i) noexcept;
|
||||||
|
|
||||||
constexpr Integer<T, Base> operator==(Integer<T, Base> i) const noexcept;
|
constexpr Integer<T, Base> operator==(Integer<T, Base> i) const noexcept;
|
||||||
|
|
||||||
@ -118,10 +118,9 @@ constexpr Integer<T, Base>::Integer(const Integer<T, Base> &i) noexcept: Base(i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, class Base>
|
template<typename T, class Base>
|
||||||
constexpr Integer<T, Base> Integer<T, Base>::operator=(Integer<T, Base> i) noexcept {
|
constexpr Integer<T, Base> &Integer<T, Base>::operator=(Integer<T, Base> i) noexcept {
|
||||||
// needed in case T has nodiscard
|
// needed in case T has nodiscard
|
||||||
constexpr auto ignore = [](Base) {};
|
Base::operator=(i);
|
||||||
ignore(Base::operator=(i));
|
|
||||||
m_i = i.m_i;
|
m_i = i.m_i;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
45
deps/ox/src/ox/std/strops.hpp
vendored
45
deps/ox/src/ox/std/strops.hpp
vendored
@ -14,56 +14,21 @@
|
|||||||
#include "stringview.hpp"
|
#include "stringview.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "writer.hpp"
|
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
template<OxString_c Str>
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Str substr(Str const&str, std::size_t pos) noexcept {
|
constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexcept {
|
||||||
if (str.len() >= pos) {
|
if (str.len() >= pos) {
|
||||||
return Str(str.data() + pos, str.len() - pos);
|
return {str.data() + pos, str.len() - pos};
|
||||||
}
|
}
|
||||||
return Str();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<OxString_c Str>
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr ox::StringView substr(Str const&str, std::size_t start, std::size_t end) noexcept {
|
constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std::size_t end) noexcept {
|
||||||
if (str.len() >= start && end >= start) {
|
if (str.len() >= start && end >= start) {
|
||||||
return Str(str.data() + start, end - start);
|
return {str.data() + start, end - start};
|
||||||
}
|
|
||||||
return Str();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Integer>
|
|
||||||
constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept {
|
|
||||||
if (v) {
|
|
||||||
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
|
|
||||||
ox::ResizedInt_t<Integer, 64> val = v;
|
|
||||||
constexpr auto base = 10;
|
|
||||||
auto it = 0;
|
|
||||||
if (val < 0) {
|
|
||||||
oxReturnError(writer.put('-'));
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
while (mod) {
|
|
||||||
auto digit = val / mod;
|
|
||||||
val %= mod;
|
|
||||||
mod /= base;
|
|
||||||
if (it || digit) {
|
|
||||||
ox::ResizedInt_t<Integer, 64> start = '0';
|
|
||||||
if (digit >= 10) {
|
|
||||||
start = 'a';
|
|
||||||
digit -= 10;
|
|
||||||
}
|
|
||||||
oxReturnError(writer.put(static_cast<char>(start + digit)));
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 0 is a special case
|
|
||||||
oxReturnError(writer.put('0'));
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
9
deps/ox/src/ox/std/test/tests.cpp
vendored
9
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -6,6 +6,7 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ox/std/def.hpp"
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -69,10 +70,10 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
|||||||
"BString",
|
"BString",
|
||||||
[]() {
|
[]() {
|
||||||
ox::IString<5> s;
|
ox::IString<5> s;
|
||||||
s += "A";
|
oxReturnError(s.append("A"));
|
||||||
s += "B";
|
oxReturnError(s.append("B"));
|
||||||
s += 9;
|
oxReturnError(s.append("9"));
|
||||||
s += "C";
|
oxReturnError(s.append("C"));
|
||||||
oxAssert(s == "AB9C", "BString append broken");
|
oxAssert(s == "AB9C", "BString append broken");
|
||||||
s = "asdf";
|
s = "asdf";
|
||||||
oxAssert(s == "asdf", "String assign broken");
|
oxAssert(s == "asdf", "String assign broken");
|
||||||
|
4
deps/ox/src/ox/std/utility.hpp
vendored
4
deps/ox/src/ox/std/utility.hpp
vendored
@ -16,8 +16,8 @@
|
|||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr typename ox::remove_reference<T>::type &&move(T &&t) noexcept {
|
constexpr ox::remove_reference_t<T> &&move(T &&t) noexcept {
|
||||||
return static_cast<typename ox::remove_reference<T>::type&&>(t);
|
return static_cast<ox::remove_reference_t<T>&&>(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
6
deps/ox/src/ox/std/uuid.hpp
vendored
6
deps/ox/src/ox/std/uuid.hpp
vendored
@ -8,12 +8,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "array.hpp"
|
#include "ignore.hpp"
|
||||||
#include "istring.hpp"
|
#include "istring.hpp"
|
||||||
#include "buffer.hpp"
|
#include "buffer.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
#include "ranges.hpp"
|
#include "ranges.hpp"
|
||||||
#include "stringview.hpp"
|
#include "stringview.hpp"
|
||||||
|
#include "strops.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -80,7 +81,8 @@ constexpr ox::IString<2> toHex(uint8_t v) noexcept {
|
|||||||
'e',
|
'e',
|
||||||
'f',
|
'f',
|
||||||
};
|
};
|
||||||
ox::Array<char, 3> out;
|
ox::IString<2> out;
|
||||||
|
std::ignore = out.resize(2);
|
||||||
out[0] = valMap[static_cast<unsigned>((v & 0xf0) / 16)];
|
out[0] = valMap[static_cast<unsigned>((v & 0xf0) / 16)];
|
||||||
out[1] = valMap[static_cast<unsigned>(v & 0x0f)];
|
out[1] = valMap[static_cast<unsigned>(v & 0x0f)];
|
||||||
out[2] = 0;
|
out[2] = 0;
|
||||||
|
11
deps/ox/src/ox/std/vector.hpp
vendored
11
deps/ox/src/ox/std/vector.hpp
vendored
@ -30,7 +30,6 @@ struct VectorAllocator {
|
|||||||
static_assert(alignof(AllocAlias<T>) == alignof(T));
|
static_assert(alignof(AllocAlias<T>) == alignof(T));
|
||||||
private:
|
private:
|
||||||
ox::Array<AllocAlias<T>, Size> m_data = {};
|
ox::Array<AllocAlias<T>, Size> m_data = {};
|
||||||
Allocator m_allocator;
|
|
||||||
protected:
|
protected:
|
||||||
constexpr VectorAllocator() noexcept = default;
|
constexpr VectorAllocator() noexcept = default;
|
||||||
constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
|
constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
|
||||||
@ -39,7 +38,7 @@ struct VectorAllocator {
|
|||||||
constexpr void allocate(T **items, std::size_t cap) noexcept {
|
constexpr void allocate(T **items, std::size_t cap) noexcept {
|
||||||
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
||||||
if (std::is_constant_evaluated() || cap > Size) {
|
if (std::is_constant_evaluated() || cap > Size) {
|
||||||
*items = m_allocator.allocate(cap);
|
*items = Allocator{}.allocate(cap);
|
||||||
} else {
|
} else {
|
||||||
*items = reinterpret_cast<T*>(m_data.data());
|
*items = reinterpret_cast<T*>(m_data.data());
|
||||||
}
|
}
|
||||||
@ -87,7 +86,7 @@ struct VectorAllocator {
|
|||||||
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
||||||
if (std::is_constant_evaluated()) {
|
if (std::is_constant_evaluated()) {
|
||||||
if (items && static_cast<void*>(items) != static_cast<void*>(m_data.data())) {
|
if (items && static_cast<void*>(items) != static_cast<void*>(m_data.data())) {
|
||||||
m_allocator.deallocate(items, cap);
|
Allocator{}.deallocate(items, cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,15 +95,13 @@ struct VectorAllocator {
|
|||||||
|
|
||||||
template<typename T, typename Allocator>
|
template<typename T, typename Allocator>
|
||||||
struct VectorAllocator<T, Allocator, 0> {
|
struct VectorAllocator<T, Allocator, 0> {
|
||||||
private:
|
|
||||||
Allocator m_allocator;
|
|
||||||
protected:
|
protected:
|
||||||
constexpr VectorAllocator() noexcept = default;
|
constexpr VectorAllocator() noexcept = default;
|
||||||
constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
|
constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
|
||||||
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
|
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
|
||||||
|
|
||||||
constexpr void allocate(T **items, std::size_t cap) noexcept {
|
constexpr void allocate(T **items, std::size_t cap) noexcept {
|
||||||
*items = m_allocator.allocate(cap);
|
*items = Allocator{}.allocate(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
@ -121,7 +118,7 @@ struct VectorAllocator<T, Allocator, 0> {
|
|||||||
|
|
||||||
constexpr void deallocate(T *items, std::size_t cap) noexcept {
|
constexpr void deallocate(T *items, std::size_t cap) noexcept {
|
||||||
if (items) {
|
if (items) {
|
||||||
m_allocator.deallocate(items, cap);
|
Allocator{}.deallocate(items, cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "pages",
|
||||||
|
"subscriptLevels" : 2,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "B.uint16;0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preloadable" : true,
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.core.Palette",
|
||||||
|
"typeVersion" : 2
|
||||||
|
}
|
@ -27,7 +27,7 @@ struct TileSheetV1 {
|
|||||||
int rows = 1;
|
int rows = 1;
|
||||||
int columns = 1;
|
int columns = 1;
|
||||||
ox::FileAddress defaultPalette;
|
ox::FileAddress defaultPalette;
|
||||||
Palette pal;
|
PaletteV1 pal;
|
||||||
ox::Vector<uint8_t> pixels = {};
|
ox::Vector<uint8_t> pixels = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,8 +32,7 @@ void panic(const char *file, int line, const char *panicMsg, ox::Error const&err
|
|||||||
std::ignore = initConsole(*ctx);
|
std::ignore = initConsole(*ctx);
|
||||||
setBgStatus(*ctx, 0, true);
|
setBgStatus(*ctx, 0, true);
|
||||||
clearBg(*ctx, 0);
|
clearBg(*ctx, 0);
|
||||||
ox::IString<23> serr = "Error code: ";
|
auto const serr = ox::sfmt<ox::IString<23>>("Error code: {}", static_cast<int64_t>(err));
|
||||||
serr += static_cast<int64_t>(err);
|
|
||||||
puts(*ctx, 32 + 1, 1, "SADNESS...");
|
puts(*ctx, 32 + 1, 1, "SADNESS...");
|
||||||
puts(*ctx, 32 + 1, 4, "UNEXPECTED STATE:");
|
puts(*ctx, 32 + 1, 4, "UNEXPECTED STATE:");
|
||||||
puts(*ctx, 32 + 2, 6, panicMsg);
|
puts(*ctx, 32 + 2, 6, panicMsg);
|
||||||
|
@ -68,12 +68,6 @@ void PaletteEditorImGui::drawColumn(ox::CStringView txt) noexcept {
|
|||||||
ImGui::Text("%s", txt.c_str());
|
ImGui::Text("%s", txt.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaletteEditorImGui::drawColumn(uint64_t i) noexcept {
|
|
||||||
ox::Array<char, 10> numStr;
|
|
||||||
ox::itoa(i, numStr.data());
|
|
||||||
drawColumn(numStr.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaletteEditorImGui::drawColorsEditor() noexcept {
|
void PaletteEditorImGui::drawColorsEditor() noexcept {
|
||||||
constexpr auto tableFlags = ImGuiTableFlags_RowBg;
|
constexpr auto tableFlags = ImGuiTableFlags_RowBg;
|
||||||
auto const colorsSz = ImGui::GetContentRegionAvail();
|
auto const colorsSz = ImGui::GetContentRegionAvail();
|
||||||
|
@ -33,7 +33,9 @@ class PaletteEditorImGui: public studio::Editor {
|
|||||||
private:
|
private:
|
||||||
static void drawColumn(ox::CStringView txt) noexcept;
|
static void drawColumn(ox::CStringView txt) noexcept;
|
||||||
|
|
||||||
static void drawColumn(uint64_t i) noexcept;
|
static void drawColumn(ox::Integer_c auto i) noexcept {
|
||||||
|
drawColumn(ox::itoa(i));
|
||||||
|
}
|
||||||
|
|
||||||
void drawColorsEditor() noexcept;
|
void drawColorsEditor() noexcept;
|
||||||
|
|
||||||
|
@ -410,14 +410,13 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
|||||||
auto const pages = m_model.pal().pages.size();
|
auto const pages = m_model.pal().pages.size();
|
||||||
if (pages > 1) {
|
if (pages > 1) {
|
||||||
ImGui::Indent(20);
|
ImGui::Indent(20);
|
||||||
ox::Array<char, 10> numStr;
|
auto numStr = ox::itoa(m_model.palettePage() + 1);
|
||||||
ox::itoa(m_model.palettePage() + 1, numStr.data());
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub);
|
||||||
if (ImGui::BeginCombo("Page", numStr.data(), 0)) {
|
if (ImGui::BeginCombo("Page", numStr.c_str(), 0)) {
|
||||||
for (auto n = 0u; n < pages; ++n) {
|
for (auto n = 0u; n < pages; ++n) {
|
||||||
auto const selected = (m_model.palettePage() == n);
|
auto const selected = (m_model.palettePage() == n);
|
||||||
ox::itoa(n + 1, numStr.data());
|
numStr = ox::itoa(n + 1);
|
||||||
if (ImGui::Selectable(numStr.data(), selected) && m_model.palettePage() != n) {
|
if (ImGui::Selectable(numStr.c_str(), selected) && m_model.palettePage() != n) {
|
||||||
m_model.setPalettePage(n);
|
m_model.setPalettePage(n);
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
@ -440,7 +439,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
|
|||||||
ImGui::PushID(static_cast<int>(i));
|
ImGui::PushID(static_cast<int>(i));
|
||||||
// Column: color idx
|
// Column: color idx
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
auto const label = ox::IString<8>() + (i + 1);
|
auto const label = ox::itoa(i + 1);
|
||||||
auto const rowSelected = i == m_view.palIdx();
|
auto const rowSelected = i == m_view.palIdx();
|
||||||
if (ImGui::Selectable(label.c_str(), rowSelected, ImGuiSelectableFlags_SpanAllColumns)) {
|
if (ImGui::Selectable(label.c_str(), rowSelected, ImGuiSelectableFlags_SpanAllColumns)) {
|
||||||
m_view.setPalIdx(i);
|
m_view.setPalIdx(i);
|
||||||
|
@ -29,7 +29,7 @@ static ox::Error pathToInode(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (beginsWith(path, "uuid://")) {
|
if (beginsWith(path, "uuid://")) {
|
||||||
auto const uuid = substr<ox::StringView>(path, 7);
|
auto const uuid = ox::substr(path, 7);
|
||||||
oxReturnError(keel::uuidToPath(ctx, uuid).moveTo(path));
|
oxReturnError(keel::uuidToPath(ctx, uuid).moveTo(path));
|
||||||
}
|
}
|
||||||
oxRequire(s, dest.stat(path));
|
oxRequire(s, dest.stat(path));
|
||||||
|
@ -13,5 +13,6 @@
|
|||||||
#include <studio/popup.hpp>
|
#include <studio/popup.hpp>
|
||||||
#include <studio/project.hpp>
|
#include <studio/project.hpp>
|
||||||
#include <studio/task.hpp>
|
#include <studio/task.hpp>
|
||||||
|
#include <studio/undocommand.hpp>
|
||||||
#include <studio/undostack.hpp>
|
#include <studio/undostack.hpp>
|
||||||
#include <studio/widget.hpp>
|
#include <studio/widget.hpp>
|
||||||
|
19
src/olympic/studio/modlib/include/studio/undocommand.hpp
Normal file
19
src/olympic/studio/modlib/include/studio/undocommand.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace studio {
|
||||||
|
|
||||||
|
class UndoCommand {
|
||||||
|
public:
|
||||||
|
virtual ~UndoCommand() noexcept = default;
|
||||||
|
virtual void redo() noexcept = 0;
|
||||||
|
virtual void undo() noexcept = 0;
|
||||||
|
[[nodiscard]]
|
||||||
|
virtual int commandId() const noexcept = 0;
|
||||||
|
virtual bool mergeWith(UndoCommand const*cmd) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -9,17 +9,9 @@
|
|||||||
#include <ox/std/memory.hpp>
|
#include <ox/std/memory.hpp>
|
||||||
#include <ox/std/vector.hpp>
|
#include <ox/std/vector.hpp>
|
||||||
|
|
||||||
namespace studio {
|
#include "undocommand.hpp"
|
||||||
|
|
||||||
class UndoCommand {
|
namespace studio {
|
||||||
public:
|
|
||||||
virtual ~UndoCommand() noexcept = default;
|
|
||||||
virtual void redo() noexcept = 0;
|
|
||||||
virtual void undo() noexcept = 0;
|
|
||||||
[[nodiscard]]
|
|
||||||
virtual int commandId() const noexcept = 0;
|
|
||||||
virtual bool mergeWith(UndoCommand const*cmd) noexcept;
|
|
||||||
};
|
|
||||||
|
|
||||||
class UndoStack {
|
class UndoStack {
|
||||||
private:
|
private:
|
||||||
|
@ -7,6 +7,7 @@ add_library(
|
|||||||
popup.cpp
|
popup.cpp
|
||||||
project.cpp
|
project.cpp
|
||||||
task.cpp
|
task.cpp
|
||||||
|
undocommand.cpp
|
||||||
undostack.cpp
|
undostack.cpp
|
||||||
filedialog_nfd.cpp
|
filedialog_nfd.cpp
|
||||||
)
|
)
|
||||||
|
10
src/olympic/studio/modlib/src/undocommand.cpp
Normal file
10
src/olympic/studio/modlib/src/undocommand.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#include <studio/undocommand.hpp>
|
||||||
|
|
||||||
|
namespace studio {
|
||||||
|
|
||||||
|
bool UndoCommand::mergeWith(UndoCommand const*) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,10 +6,6 @@
|
|||||||
|
|
||||||
namespace studio {
|
namespace studio {
|
||||||
|
|
||||||
bool UndoCommand::mergeWith(UndoCommand const*) noexcept {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept {
|
void UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept {
|
||||||
for (auto const i = m_stackIdx; i < m_stack.size();) {
|
for (auto const i = m_stackIdx; i < m_stack.size();) {
|
||||||
std::ignore = m_stack.erase(i);
|
std::ignore = m_stack.erase(i);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user