Compare commits
6 Commits
540ed9b3f9
...
15bc41dd35
Author | SHA1 | Date | |
---|---|---|---|
15bc41dd35 | |||
85e7375f6f | |||
da98aa864c | |||
3a62650d62 | |||
7008ebfb40 | |||
709dc36d0b |
1
deps/buildcore/scripts/pybb.py
vendored
1
deps/buildcore/scripts/pybb.py
vendored
@ -14,7 +14,6 @@
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
1
deps/ox/src/ox/mc/test/tests.cpp
vendored
1
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -98,6 +98,7 @@ constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexce
|
|||||||
oxReturnError(io->field("BString", &obj->BString));
|
oxReturnError(io->field("BString", &obj->BString));
|
||||||
oxReturnError(io->field("List", obj->List, 4));
|
oxReturnError(io->field("List", obj->List, 4));
|
||||||
oxReturnError(io->field("Vector", &obj->Vector));
|
oxReturnError(io->field("Vector", &obj->Vector));
|
||||||
|
oxReturnError(io->field("Vector2", &obj->Vector2));
|
||||||
oxReturnError(io->field("Map", &obj->Map));
|
oxReturnError(io->field("Map", &obj->Map));
|
||||||
oxReturnError(io->field("Struct", &obj->Struct));
|
oxReturnError(io->field("Struct", &obj->Struct));
|
||||||
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
||||||
|
3
deps/ox/src/ox/model/types.hpp
vendored
3
deps/ox/src/ox/model/types.hpp
vendored
@ -79,9 +79,6 @@ static_assert(isBasicString_v<ox::BasicString<0ul>>);
|
|||||||
static_assert(isBasicString_v<ox::BasicString<8ul>>);
|
static_assert(isBasicString_v<ox::BasicString<8ul>>);
|
||||||
static_assert(isBasicString_v<ox::String>);
|
static_assert(isBasicString_v<ox::String>);
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool isOxString_v = isBString_v<T> || isBasicString_v<T>;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
consteval bool isOxVector(const T*) noexcept {
|
consteval bool isOxVector(const T*) noexcept {
|
||||||
return false;
|
return false;
|
||||||
|
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -118,6 +118,7 @@ install(
|
|||||||
std.hpp
|
std.hpp
|
||||||
stddef.hpp
|
stddef.hpp
|
||||||
string.hpp
|
string.hpp
|
||||||
|
stringliteral.hpp
|
||||||
stringview.hpp
|
stringview.hpp
|
||||||
strongint.hpp
|
strongint.hpp
|
||||||
strops.hpp
|
strops.hpp
|
||||||
|
31
deps/ox/src/ox/std/concepts.hpp
vendored
31
deps/ox/src/ox/std/concepts.hpp
vendored
@ -23,35 +23,10 @@ concept CommonRefWith = ox::is_same_v<typename ox::remove_reference_t<const T&>,
|
|||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
concept same_as = ox::is_same_v<T, T>;
|
concept same_as = ox::is_same_v<T, T>;
|
||||||
|
|
||||||
template<std::size_t SmallStringSize>
|
template<typename T>
|
||||||
class BasicString;
|
concept OxString_c = isOxString_v<T>;
|
||||||
template<std::size_t sz>
|
|
||||||
class BString;
|
|
||||||
class StringView;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
constexpr auto isOxString(const auto*) noexcept {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t sz>
|
|
||||||
constexpr auto isOxString(const BasicString<sz>*) noexcept {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t sz>
|
|
||||||
constexpr auto isOxString(const BString<sz>*) noexcept {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto isOxString(const StringView*) noexcept {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept OxString_c = detail::isOxString(static_cast<T*>(nullptr));
|
concept Integral_c = ox::is_integral_v<T>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
110
deps/ox/src/ox/std/hashmap.hpp
vendored
110
deps/ox/src/ox/std/hashmap.hpp
vendored
@ -9,6 +9,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "algorithm.hpp"
|
#include "algorithm.hpp"
|
||||||
|
#include "stringview.hpp"
|
||||||
#include "strops.hpp"
|
#include "strops.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
|
|
||||||
@ -21,6 +22,21 @@ class HashMap {
|
|||||||
using value_t = T;
|
using value_t = T;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Maybe StringView. If K (or KK for MaybeSV) is a string type,
|
||||||
|
// MaybeSV::type/MaybeSV_t is a StringView.
|
||||||
|
// This avoids creating unnecessary Strings when taking a StringView or C
|
||||||
|
// string in lookups.
|
||||||
|
template<typename KK, bool isStr = isOxString_v<KK>>
|
||||||
|
struct MaybeSV {
|
||||||
|
using type = KK;
|
||||||
|
};
|
||||||
|
template<typename KK>
|
||||||
|
struct MaybeSV<KK, true> {
|
||||||
|
using type = ox::StringView;
|
||||||
|
};
|
||||||
|
template<typename KK>
|
||||||
|
using MaybeSV_t = MaybeSV<KK>::type;
|
||||||
|
|
||||||
struct Pair {
|
struct Pair {
|
||||||
K key = {};
|
K key = {};
|
||||||
T value{};
|
T value{};
|
||||||
@ -31,62 +47,55 @@ class HashMap {
|
|||||||
public:
|
public:
|
||||||
explicit constexpr HashMap(std::size_t size = 100);
|
explicit constexpr HashMap(std::size_t size = 100);
|
||||||
|
|
||||||
constexpr HashMap(const HashMap &other);
|
constexpr HashMap(HashMap const&other);
|
||||||
|
|
||||||
constexpr HashMap(HashMap &&other) noexcept;
|
constexpr HashMap(HashMap &&other) noexcept;
|
||||||
|
|
||||||
constexpr ~HashMap();
|
constexpr ~HashMap();
|
||||||
|
|
||||||
constexpr bool operator==(const HashMap &other) const;
|
constexpr bool operator==(HashMap const&other) const;
|
||||||
|
|
||||||
constexpr HashMap &operator=(const HashMap &other);
|
constexpr HashMap &operator=(HashMap const&other);
|
||||||
|
|
||||||
constexpr HashMap &operator=(HashMap &&other) noexcept;
|
constexpr HashMap &operator=(HashMap &&other) noexcept;
|
||||||
|
|
||||||
/**
|
constexpr T &operator[](MaybeSV_t<K> const&key);
|
||||||
* K is assumed to be a null terminated string.
|
|
||||||
*/
|
|
||||||
constexpr T &operator[](const K &key);
|
|
||||||
|
|
||||||
/**
|
constexpr Result<T*> at(MaybeSV_t<K> const&key) noexcept;
|
||||||
* K is assumed to be a null terminated string.
|
|
||||||
*/
|
|
||||||
constexpr Result<T*> at(const K &key) noexcept;
|
|
||||||
|
|
||||||
/**
|
constexpr Result<const T*> at(MaybeSV_t<K> const&key) const noexcept;
|
||||||
* K is assumed to be a null terminated string.
|
|
||||||
*/
|
|
||||||
constexpr Result<const T*> at(const K &key) const noexcept;
|
|
||||||
|
|
||||||
constexpr void erase(const K &key);
|
constexpr void erase(MaybeSV_t<K> const&key);
|
||||||
|
|
||||||
constexpr bool contains(const K &key) const noexcept;
|
[[nodiscard]]
|
||||||
|
constexpr bool contains(MaybeSV_t<K> const&key) const noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr std::size_t size() const noexcept;
|
constexpr std::size_t size() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr const Vector<K> &keys() const noexcept;
|
constexpr Vector<K> const&keys() const noexcept;
|
||||||
|
|
||||||
constexpr void clear();
|
constexpr void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr void expand();
|
constexpr void expand();
|
||||||
|
|
||||||
/**
|
constexpr static uint64_t hash(Integral_c auto) noexcept;
|
||||||
* K is assumed to be a null terminated string.
|
|
||||||
*/
|
constexpr static uint64_t hash(StringView const&) noexcept;
|
||||||
constexpr static uint64_t hash(auto) noexcept;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* K is assumed to be a null terminated string.
|
* K is assumed to be a null terminated string.
|
||||||
*/
|
*/
|
||||||
constexpr Pair *const&access(const Vector<Pair*> &pairs, const K &key) const;
|
template<typename KK>
|
||||||
|
constexpr Pair *const&access(Vector<Pair*> const&pairs, KK const&key) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* K is assumed to be a null terminated string.
|
* K is assumed to be a null terminated string.
|
||||||
*/
|
*/
|
||||||
constexpr Pair *&access(Vector<Pair*> &pairs, const K &key);
|
template<typename KK>
|
||||||
|
constexpr Pair *&access(Vector<Pair*> &pairs, KK const&key);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,7 +104,7 @@ constexpr HashMap<K, T>::HashMap(std::size_t size): m_pairs(size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr HashMap<K, T>::HashMap(const HashMap<K, T> &other) {
|
constexpr HashMap<K, T>::HashMap(HashMap<K, T> const&other) {
|
||||||
m_pairs = other.m_pairs;
|
m_pairs = other.m_pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +120,7 @@ constexpr HashMap<K, T>::~HashMap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr bool HashMap<K, T>::operator==(const HashMap &other) const {
|
constexpr bool HashMap<K, T>::operator==(HashMap const&other) const {
|
||||||
if (m_keys != other.m_keys) {
|
if (m_keys != other.m_keys) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -125,7 +134,7 @@ constexpr bool HashMap<K, T>::operator==(const HashMap &other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr HashMap<K, T> &HashMap<K, T>::operator=(const HashMap<K, T> &other) {
|
constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> const&other) {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
clear();
|
clear();
|
||||||
m_keys = other.m_keys;
|
m_keys = other.m_keys;
|
||||||
@ -145,7 +154,7 @@ constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> &&other) noexcep
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr T &HashMap<K, T>::operator[](const K &k) {
|
constexpr T &HashMap<K, T>::operator[](MaybeSV_t<K> const&k) {
|
||||||
auto &p = access(m_pairs, k);
|
auto &p = access(m_pairs, k);
|
||||||
if (p == nullptr) {
|
if (p == nullptr) {
|
||||||
if (static_cast<double>(m_pairs.size()) * 0.7 <
|
if (static_cast<double>(m_pairs.size()) * 0.7 <
|
||||||
@ -154,13 +163,13 @@ constexpr T &HashMap<K, T>::operator[](const K &k) {
|
|||||||
}
|
}
|
||||||
p = new Pair;
|
p = new Pair;
|
||||||
p->key = k;
|
p->key = k;
|
||||||
m_keys.push_back(k);
|
m_keys.emplace_back(k);
|
||||||
}
|
}
|
||||||
return p->value;
|
return p->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr Result<T*> HashMap<K, T>::at(const K &k) noexcept {
|
constexpr Result<T*> HashMap<K, T>::at(MaybeSV_t<K> const&k) noexcept {
|
||||||
auto p = access(m_pairs, k);
|
auto p = access(m_pairs, k);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return {nullptr, OxError(1, "value not found for given key")};
|
return {nullptr, OxError(1, "value not found for given key")};
|
||||||
@ -169,7 +178,7 @@ constexpr Result<T*> HashMap<K, T>::at(const K &k) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr Result<const T*> HashMap<K, T>::at(const K &k) const noexcept {
|
constexpr Result<const T*> HashMap<K, T>::at(MaybeSV_t<K> const&k) const noexcept {
|
||||||
auto p = access(m_pairs, k);
|
auto p = access(m_pairs, k);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return {nullptr, OxError(1, "value not found for given key")};
|
return {nullptr, OxError(1, "value not found for given key")};
|
||||||
@ -178,7 +187,7 @@ constexpr Result<const T*> HashMap<K, T>::at(const K &k) const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr void HashMap<K, T>::erase(const K &k) {
|
constexpr void HashMap<K, T>::erase(MaybeSV_t<K> const&k) {
|
||||||
if (!contains(k)) {
|
if (!contains(k)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -196,7 +205,7 @@ constexpr void HashMap<K, T>::erase(const K &k) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr bool HashMap<K, T>::contains(const K &k) const noexcept {
|
constexpr bool HashMap<K, T>::contains(MaybeSV_t<K> const&k) const noexcept {
|
||||||
return access(m_pairs, k) != nullptr;
|
return access(m_pairs, k) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +215,7 @@ constexpr std::size_t HashMap<K, T>::size() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr const Vector<K> &HashMap<K, T>::keys() const noexcept {
|
constexpr Vector<K> const&HashMap<K, T>::keys() const noexcept {
|
||||||
return m_keys;
|
return m_keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,24 +239,28 @@ constexpr void HashMap<K, T>::expand() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr uint64_t HashMap<K, T>::hash(auto k) noexcept {
|
constexpr uint64_t HashMap<K, T>::hash(Integral_c auto k) noexcept {
|
||||||
uint64_t sum = 1;
|
uint64_t sum = 1;
|
||||||
if constexpr(is_integral_v<decltype(k)>) {
|
for (auto i = 0u; i < sizeof(K); ++i) {
|
||||||
for (auto i = 0u; i < sizeof(K); ++i) {
|
const auto shift = i * 8;
|
||||||
const auto shift = i * 8;
|
const auto v = static_cast<uint64_t>(k >> shift & 0xff);
|
||||||
const auto v = static_cast<uint64_t>(k >> shift & 0xff);
|
sum += (sum + v) * 7 * sum;
|
||||||
sum += (sum + v) * 7 * sum;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (auto i = 0u; k[i]; ++i) {
|
|
||||||
sum += ((sum + static_cast<uint64_t>(k[i])) * 7) * sum;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(const Vector<Pair*> &pairs, const K &k) const {
|
constexpr uint64_t HashMap<K, T>::hash(StringView const&k) noexcept {
|
||||||
|
uint64_t sum = 1;
|
||||||
|
for (auto i = 0u; i < k.len(); ++i) {
|
||||||
|
sum += ((sum + static_cast<uint64_t>(k[i])) * 7) * sum;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename K, typename T>
|
||||||
|
template<typename KK>
|
||||||
|
constexpr typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(Vector<Pair*> const&pairs, KK const&k) const {
|
||||||
auto h = static_cast<std::size_t>(hash(k) % pairs.size());
|
auto h = static_cast<std::size_t>(hash(k) % pairs.size());
|
||||||
while (true) {
|
while (true) {
|
||||||
const auto &p = pairs[h];
|
const auto &p = pairs[h];
|
||||||
@ -260,12 +273,13 @@ constexpr typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(const Vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, const K &k) {
|
template<typename KK>
|
||||||
|
constexpr typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, KK const&k) {
|
||||||
auto h = static_cast<std::size_t>(hash(k) % pairs.size());
|
auto h = static_cast<std::size_t>(hash(k) % pairs.size());
|
||||||
while (true) {
|
while (true) {
|
||||||
auto &p = pairs[h];
|
auto &p = pairs[h];
|
||||||
bool matches = [&] {
|
bool matches = [&] {
|
||||||
if constexpr (is_integral_v<K>) {
|
if constexpr (is_integral_v<KK>) {
|
||||||
return p == nullptr || k == p->key;
|
return p == nullptr || k == p->key;
|
||||||
} else {
|
} else {
|
||||||
return p == nullptr || ox_strcmp(p->key, k) == 0;
|
return p == nullptr || ox_strcmp(p->key, k) == 0;
|
||||||
|
4
deps/ox/src/ox/std/memory.hpp
vendored
4
deps/ox/src/ox/std/memory.hpp
vendored
@ -282,10 +282,10 @@ constexpr bool operator!=(std::nullptr_t, const UniquePtr<T> &p2) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename ...Args>
|
template<typename T, typename U = T, typename ...Args>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr auto make_unique(Args&&... args) {
|
constexpr auto make_unique(Args&&... args) {
|
||||||
return UniquePtr(new T(ox::forward<Args>(args)...));
|
return UniquePtr<U>(new T(ox::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
4
deps/ox/src/ox/std/new.hpp
vendored
4
deps/ox/src/ox/std/new.hpp
vendored
@ -35,9 +35,9 @@ constexpr void *operator new[](std::size_t, void *addr) noexcept {
|
|||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
template<typename T, typename ...Args>
|
template<typename T, typename U = T, typename ...Args>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr T *make(Args &&...args) noexcept {
|
constexpr U *make(Args &&...args) noexcept {
|
||||||
#ifdef __cpp_exceptions
|
#ifdef __cpp_exceptions
|
||||||
try {
|
try {
|
||||||
return new T(ox::forward<Args>(args)...);
|
return new T(ox::forward<Args>(args)...);
|
||||||
|
12
deps/ox/src/ox/std/string.hpp
vendored
12
deps/ox/src/ox/std/string.hpp
vendored
@ -118,6 +118,8 @@ class BasicString {
|
|||||||
|
|
||||||
constexpr BasicString &operator=(BasicString &&src) noexcept;
|
constexpr BasicString &operator=(BasicString &&src) noexcept;
|
||||||
|
|
||||||
|
constexpr BasicString &operator=(CRStringView src) noexcept;
|
||||||
|
|
||||||
constexpr BasicString &operator+=(const char *str) noexcept;
|
constexpr BasicString &operator+=(const char *str) noexcept;
|
||||||
|
|
||||||
constexpr BasicString &operator+=(char *str) noexcept;
|
constexpr BasicString &operator+=(char *str) noexcept;
|
||||||
@ -341,7 +343,15 @@ 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=(BasicString &&src) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(BasicString &&src) noexcept {
|
||||||
m_buff = std::move(src.m_buff);
|
if (this != &src) {
|
||||||
|
m_buff = std::move(src.m_buff);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t SmallStringSize_v>
|
||||||
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(CRStringView src) noexcept {
|
||||||
|
set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
deps/ox/src/ox/std/stringliteral.hpp
vendored
Normal file
47
deps/ox/src/ox/std/stringliteral.hpp
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2022 gary@drinkingtea.net
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "basestringview.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StringLiteral is used for functions that want to ensure that they are taking
|
||||||
|
* string literals, and not strings outside of the data section of the program
|
||||||
|
* that might get deleted.
|
||||||
|
* This type cannot force you to use it correctly, so don't give it something
|
||||||
|
* that is not a literal.
|
||||||
|
* If you do this:
|
||||||
|
* StringLiteral(str.c_str())
|
||||||
|
* the resulting segfault is on you.
|
||||||
|
*/
|
||||||
|
class StringLiteral: public detail::BaseStringView {
|
||||||
|
public:
|
||||||
|
constexpr StringLiteral() noexcept = default;
|
||||||
|
|
||||||
|
constexpr StringLiteral(StringLiteral const&sv) noexcept = default;
|
||||||
|
|
||||||
|
constexpr explicit StringLiteral(std::nullptr_t) noexcept {}
|
||||||
|
|
||||||
|
constexpr explicit StringLiteral(const char *str) noexcept: BaseStringView(str) {}
|
||||||
|
|
||||||
|
constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
|
||||||
|
|
||||||
|
constexpr auto &operator=(StringLiteral const&other) noexcept {
|
||||||
|
if (&other != this) {
|
||||||
|
set(other.data(), other.len());
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
286
deps/ox/src/ox/std/stringview.hpp
vendored
286
deps/ox/src/ox/std/stringview.hpp
vendored
@ -13,11 +13,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "bit.hpp"
|
#include "bit.hpp"
|
||||||
|
#include "concepts.hpp"
|
||||||
#include "iterator.hpp"
|
#include "iterator.hpp"
|
||||||
|
#include "stringliteral.hpp"
|
||||||
#include "strops.hpp"
|
#include "strops.hpp"
|
||||||
#include "types.hpp"
|
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "writer.hpp"
|
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -27,256 +27,68 @@ class BString;
|
|||||||
template<std::size_t buffLen>
|
template<std::size_t buffLen>
|
||||||
class BasicString;
|
class BasicString;
|
||||||
|
|
||||||
class StringView {
|
class StringView: public detail::BaseStringView {
|
||||||
public:
|
|
||||||
template<typename RefType = char&, typename PtrType = char*, bool reverse = false>
|
|
||||||
struct iterator: public Iterator<std::bidirectional_iterator_tag, char> {
|
|
||||||
private:
|
|
||||||
PtrType m_t = nullptr;
|
|
||||||
std::size_t m_offset = 0;
|
|
||||||
std::size_t m_max = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
constexpr iterator() noexcept = default;
|
|
||||||
|
|
||||||
constexpr iterator(PtrType t, std::size_t offset, std::size_t max) noexcept {
|
|
||||||
m_t = t;
|
|
||||||
m_offset = offset;
|
|
||||||
m_max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto offset() const noexcept {
|
|
||||||
return m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator operator+(std::size_t s) const noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
return iterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
|
||||||
} else {
|
|
||||||
return iterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto operator-(const iterator &other) const noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
return m_offset + other.m_offset;
|
|
||||||
} else {
|
|
||||||
return m_offset - other.m_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator operator-(std::size_t s) const noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
return iterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
|
||||||
} else {
|
|
||||||
return iterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator &operator+=(std::size_t s) noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
m_offset = max<std::size_t>(m_offset - s, 0);
|
|
||||||
} else {
|
|
||||||
m_offset = min(m_offset + s, m_max);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator &operator-=(std::size_t s) noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
m_offset = min(m_offset + s, m_max);
|
|
||||||
} else {
|
|
||||||
m_offset = max<std::size_t>(m_offset - s, 0);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator &operator++() noexcept {
|
|
||||||
return operator+=(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator &operator--() noexcept {
|
|
||||||
return operator-=(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr RefType operator*() const noexcept {
|
|
||||||
return m_t[m_offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr RefType operator[](std::size_t s) const noexcept {
|
|
||||||
return m_t[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool operator<(const iterator &other) const noexcept {
|
|
||||||
return m_offset < other.m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool operator>(const iterator &other) const noexcept {
|
|
||||||
return m_offset > other.m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool operator<=(const iterator &other) const noexcept {
|
|
||||||
return m_offset <= other.m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool operator>=(const iterator &other) const noexcept {
|
|
||||||
return m_offset >= other.m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool operator==(const iterator &other) const noexcept {
|
|
||||||
return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool operator!=(const iterator &other) const noexcept {
|
|
||||||
return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char *m_str = nullptr;
|
|
||||||
std::size_t m_len = 0;
|
|
||||||
public:
|
public:
|
||||||
constexpr StringView() noexcept = default;
|
constexpr StringView() noexcept = default;
|
||||||
|
|
||||||
constexpr StringView(const StringView &sv) noexcept = default;
|
constexpr StringView(const StringView &sv) noexcept = default;
|
||||||
|
|
||||||
#ifdef OX_USE_STDLIB
|
#ifdef OX_USE_STDLIB
|
||||||
constexpr StringView(const std::string_view &sv) noexcept: m_str(sv.data()), m_len(sv.size()) {}
|
constexpr StringView(const std::string_view &sv) noexcept: BaseStringView(sv.data(), sv.size()) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<std::size_t SmallStrSz>
|
constexpr StringView(BaseStringView const&str) noexcept: BaseStringView(str.data(), str.bytes()) {}
|
||||||
constexpr StringView(const BasicString<SmallStrSz> &str) noexcept: m_str(str.c_str()), m_len(str.len()) {}
|
|
||||||
|
|
||||||
template<std::size_t SmallStrSz>
|
template<std::size_t SmallStrSz>
|
||||||
constexpr StringView(const BString<SmallStrSz> &str) noexcept: m_str(str.c_str()), m_len(str.len()) {}
|
constexpr StringView(const BasicString<SmallStrSz> &str) noexcept: BaseStringView(str.data(), str.len()) {}
|
||||||
|
|
||||||
|
template<std::size_t SmallStrSz>
|
||||||
|
constexpr StringView(const BString<SmallStrSz> &str) noexcept: BaseStringView(str.data(), str.len()) {}
|
||||||
|
|
||||||
constexpr StringView(std::nullptr_t) noexcept {}
|
constexpr StringView(std::nullptr_t) noexcept {}
|
||||||
|
|
||||||
constexpr StringView(const char *str) noexcept: m_str(str), m_len(str ? ox_strlen(str) : 0) {}
|
constexpr StringView(const char *str) noexcept: BaseStringView(str) {}
|
||||||
|
|
||||||
constexpr StringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {}
|
constexpr StringView(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
|
||||||
|
|
||||||
[[nodiscard]]
|
constexpr auto &operator=(StringView const&other) noexcept {
|
||||||
constexpr iterator<const char&, const char*> begin() const noexcept {
|
if (&other != this) {
|
||||||
return {m_str, 0, m_len};
|
set(other.data(), other.len());
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*> end() const noexcept {
|
|
||||||
return {m_str, m_len, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*> cbegin() const noexcept {
|
|
||||||
return {m_str, 0, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*> cend() const noexcept {
|
|
||||||
return {m_str, m_len, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*, true> crbegin() const noexcept {
|
|
||||||
return {m_str, m_len - 1, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*, true> crend() const noexcept {
|
|
||||||
return {m_str, MaxValue<std::size_t>, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*, true> rbegin() const noexcept {
|
|
||||||
return {m_str, m_len - 1, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr iterator<const char&, const char*, true> rend() const noexcept {
|
|
||||||
return {m_str, MaxValue<std::size_t>, m_len};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto bytes() const noexcept {
|
|
||||||
return m_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto len() const noexcept {
|
|
||||||
return m_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto *data() const noexcept {
|
|
||||||
return &m_str[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto &front() const noexcept {
|
|
||||||
return m_str[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto &back() const noexcept {
|
|
||||||
return m_str[m_len - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto substr(std::size_t pos) const noexcept {
|
|
||||||
if (m_len >= pos) {
|
|
||||||
return StringView(m_str + pos, m_len - pos);
|
|
||||||
}
|
|
||||||
return StringView();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr auto substr(std::size_t start, std::size_t end) const noexcept {
|
|
||||||
if (m_len >= start && end >= start) {
|
|
||||||
return StringView(m_str + start, end - start);
|
|
||||||
}
|
|
||||||
return StringView();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto operator[](std::size_t i) const noexcept {
|
|
||||||
return m_str[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr ox::StringView &operator=(const StringView &other) noexcept = default;
|
|
||||||
|
|
||||||
constexpr auto operator==(const StringView &other) const noexcept {
|
|
||||||
if (other.len() != len()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ox_strncmp(m_str, other.m_str, len()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto operator<=>(const StringView &str2) const noexcept {
|
|
||||||
const StringView &str1 = *this;
|
|
||||||
const auto maxLen = ox::min(str1.len(), str2.len());
|
|
||||||
const auto a = &str1.front();
|
|
||||||
const auto b = &str2.front();
|
|
||||||
for (std::size_t i = 0; i < maxLen && (a[i] || b[i]); ++i) {
|
|
||||||
if (a[i] < b[i]) {
|
|
||||||
return -1;
|
|
||||||
} else if (a[i] > b[i]) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (str1.len() > str2.len()) {
|
|
||||||
return 1;
|
|
||||||
} else if (str1.len() < str2.len()) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using CRStringView = const StringView&;
|
using CRStringView = const StringView&;
|
||||||
|
|
||||||
|
constexpr auto operator==(CRStringView s1, CRStringView s2) noexcept {
|
||||||
|
if (s2.len() != s1.len()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ox_strncmp(s1.data(), s2.data(), s1.len()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto operator<=>(CRStringView s1, CRStringView s2) noexcept {
|
||||||
|
const auto maxLen = ox::min(s1.len(), s2.len());
|
||||||
|
const auto a = &s1.front();
|
||||||
|
const auto b = &s2.front();
|
||||||
|
for (std::size_t i = 0; i < maxLen && (a[i] || b[i]); ++i) {
|
||||||
|
if (a[i] < b[i]) {
|
||||||
|
return -1;
|
||||||
|
} else if (a[i] > b[i]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s1.len() > s2.len()) {
|
||||||
|
return 1;
|
||||||
|
} else if (s1.len() < s2.len()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr bool beginsWith(CRStringView base, CRStringView beginning) noexcept {
|
constexpr bool beginsWith(CRStringView base, CRStringView beginning) noexcept {
|
||||||
const auto beginningLen = ox::min(beginning.len(), base.len());
|
const auto beginningLen = ox::min(beginning.len(), base.len());
|
||||||
@ -302,7 +114,7 @@ constexpr std::size_t find(CRStringView str, char search) noexcept {
|
|||||||
constexpr std::size_t find(CRStringView str, CRStringView search) noexcept {
|
constexpr std::size_t find(CRStringView str, CRStringView search) noexcept {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (; i < str.len(); ++i) {
|
for (; i < str.len(); ++i) {
|
||||||
if (beginsWith(str.substr(i), search)) {
|
if (beginsWith(substr(str, i), search)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,14 +125,14 @@ template<std::size_t smallSz = 0>
|
|||||||
constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, char del) noexcept {
|
constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, char del) noexcept {
|
||||||
ox::Vector<ox::StringView, smallSz> out;
|
ox::Vector<ox::StringView, smallSz> out;
|
||||||
constexpr auto nextSeg = [](CRStringView current, char del) {
|
constexpr auto nextSeg = [](CRStringView current, char del) {
|
||||||
return current.substr(find(current, del) + 1);
|
return substr(current, find(current, del) + 1);
|
||||||
};
|
};
|
||||||
for (auto current = str; current.len(); current = nextSeg(current, del)) {
|
for (auto current = str; current.len(); current = nextSeg(current, del)) {
|
||||||
const auto next = find(current, del);
|
const auto next = find(current, del);
|
||||||
if (const auto s = current.substr(0, next); s.len()) {
|
if (const auto s = substr(current, 0, next); s.len()) {
|
||||||
out.emplace_back(s);
|
out.emplace_back(s);
|
||||||
}
|
}
|
||||||
current = current.substr(next);
|
current = substr(current, next);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -329,14 +141,14 @@ template<std::size_t smallSz = 0>
|
|||||||
constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, CRStringView del) noexcept {
|
constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, CRStringView del) noexcept {
|
||||||
ox::Vector<ox::StringView, smallSz> out;
|
ox::Vector<ox::StringView, smallSz> out;
|
||||||
constexpr auto nextSeg = [](CRStringView current, CRStringView del) {
|
constexpr auto nextSeg = [](CRStringView current, CRStringView del) {
|
||||||
return current.substr(find(current, del) + del.len());
|
return substr(current, find(current, del) + del.len());
|
||||||
};
|
};
|
||||||
for (auto current = str; current.len(); current = nextSeg(current, del)) {
|
for (auto current = str; current.len(); current = nextSeg(current, del)) {
|
||||||
const auto next = find(current, del);
|
const auto next = find(current, del);
|
||||||
if (const auto s = current.substr(0, next); s.len()) {
|
if (const auto s = substr(current, 0, next); s.len()) {
|
||||||
out.emplace_back(s);
|
out.emplace_back(s);
|
||||||
}
|
}
|
||||||
current = current.substr(next);
|
current = substr(current, next);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
19
deps/ox/src/ox/std/strops.hpp
vendored
19
deps/ox/src/ox/std/strops.hpp
vendored
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "concepts.hpp"
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
@ -128,6 +129,24 @@ constexpr int ox_lastIndexOf(const auto &str, int character, std::size_t maxLen
|
|||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
|
template<OxString_c Str>
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr Str substr(Str const&str, std::size_t pos) noexcept {
|
||||||
|
if (str.len() >= pos) {
|
||||||
|
return Str(str.data() + pos, str.len() - pos);
|
||||||
|
}
|
||||||
|
return Str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<OxString_c Str>
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr Str substr(Str const&str, std::size_t start, std::size_t end) noexcept {
|
||||||
|
if (str.len() >= start && end >= start) {
|
||||||
|
return Str(str.data() + start, end - start);
|
||||||
|
}
|
||||||
|
return Str();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Integer>
|
template<typename Integer>
|
||||||
constexpr ox::Error itoa(Integer v, ox::Writer_c auto &writer) noexcept {
|
constexpr ox::Error itoa(Integer v, ox::Writer_c auto &writer) noexcept {
|
||||||
if (v) {
|
if (v) {
|
||||||
|
4
deps/ox/src/ox/std/test/tests.cpp
vendored
4
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -105,6 +105,10 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
|||||||
oxAssert(endsWith(str, "df"), "String endsWith is broken");
|
oxAssert(endsWith(str, "df"), "String endsWith is broken");
|
||||||
oxAssert(!endsWith(str, "awefawe"), "String endsWith is broken");
|
oxAssert(!endsWith(str, "awefawe"), "String endsWith is broken");
|
||||||
oxAssert(!endsWith(str, "eu"), "String endsWith is broken");
|
oxAssert(!endsWith(str, "eu"), "String endsWith is broken");
|
||||||
|
oxAssert(ox::StringView("Write") != ox::String(""), "String / StringView comparison broken");
|
||||||
|
oxAssert(ox::String("Write") != ox::StringView(""), "String / StringView comparison broken");
|
||||||
|
oxAssert(ox::String("Write") == ox::StringView("Write"), "String / StringView comparison broken");
|
||||||
|
oxAssert(ox::String(ox::StringView("Write")) == ox::StringView("Write"), "String / StringView comparison broken");
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
39
deps/ox/src/ox/std/typetraits.hpp
vendored
39
deps/ox/src/ox/std/typetraits.hpp
vendored
@ -266,4 +266,43 @@ constexpr bool is_move_constructible(bool) {
|
|||||||
template<class T>
|
template<class T>
|
||||||
constexpr bool is_move_constructible_v = detail::is_move_constructible<T>(0);
|
constexpr bool is_move_constructible_v = detail::is_move_constructible<T>(0);
|
||||||
|
|
||||||
|
|
||||||
|
// is String?
|
||||||
|
|
||||||
|
template<std::size_t SmallStringSize>
|
||||||
|
class BasicString;
|
||||||
|
template<std::size_t sz>
|
||||||
|
class BString;
|
||||||
|
class StringLiteral;
|
||||||
|
class StringView;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
constexpr auto isOxString(const auto*) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t sz>
|
||||||
|
constexpr auto isOxString(const BasicString<sz>*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t sz>
|
||||||
|
constexpr auto isOxString(const BString<sz>*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto isOxString(const StringLiteral*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto isOxString(const StringView*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr auto isOxString_v = detail::isOxString(static_cast<T*>(nullptr));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
2
deps/ox/src/ox/std/uuid.hpp
vendored
2
deps/ox/src/ox/std/uuid.hpp
vendored
@ -132,7 +132,7 @@ class UUID {
|
|||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto seg = s.substr(i, i + 2);
|
const auto seg = substr(s, i, i + 2);
|
||||||
if (seg.len() != 2) {
|
if (seg.len() != 2) {
|
||||||
return OxError(1, "Invalid UUID");
|
return OxError(1, "Invalid UUID");
|
||||||
}
|
}
|
||||||
|
2
deps/ox/src/ox/std/vector.hpp
vendored
2
deps/ox/src/ox/std/vector.hpp
vendored
@ -324,7 +324,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexce
|
|||||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
|
||||||
for (auto &item : list) {
|
for (auto &item : list) {
|
||||||
emplace_back(item);
|
emplace_back(std::move(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,13 +194,13 @@ class AssetManager {
|
|||||||
ox::HashMap<ox::String, ox::UniquePtr<AssetContainer<T>>> m_cache;
|
ox::HashMap<ox::String, ox::UniquePtr<AssetContainer<T>>> m_cache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ox::Result<AssetRef<T>> getAsset(const ox::String &assetId) const noexcept {
|
ox::Result<AssetRef<T>> getAsset(const ox::StringView &assetId) const noexcept {
|
||||||
auto out = m_cache.at(assetId);
|
auto out = m_cache.at(assetId);
|
||||||
oxReturnError(out);
|
oxReturnError(out);
|
||||||
return AssetRef<T>(out.value->get());
|
return AssetRef<T>(out.value->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Result<AssetRef<T>> setAsset(const ox::String &assetId, const T &obj) noexcept {
|
ox::Result<AssetRef<T>> setAsset(const ox::StringView &assetId, const T &obj) noexcept {
|
||||||
auto &p = m_cache[assetId];
|
auto &p = m_cache[assetId];
|
||||||
if (!p) {
|
if (!p) {
|
||||||
p = ox::make_unique<AssetContainer<T>>(obj);
|
p = ox::make_unique<AssetContainer<T>>(obj);
|
||||||
@ -211,7 +211,7 @@ class AssetManager {
|
|||||||
return AssetRef<T>(p.get());
|
return AssetRef<T>(p.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Result<AssetRef<T>> setAsset(const ox::String &assetId, T &&obj) noexcept {
|
ox::Result<AssetRef<T>> setAsset(const ox::StringView &assetId, T &&obj) noexcept {
|
||||||
auto &p = m_cache[assetId];
|
auto &p = m_cache[assetId];
|
||||||
if (!p) {
|
if (!p) {
|
||||||
p = ox::make_unique<AssetContainer<T>>(obj);
|
p = ox::make_unique<AssetContainer<T>>(obj);
|
||||||
@ -247,13 +247,13 @@ class AssetManager {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Result<AssetRef<T>> getAsset(const ox::String &assetId) noexcept {
|
ox::Result<AssetRef<T>> getAsset(ox::CRStringView assetId) noexcept {
|
||||||
auto m = getTypeManager<T>();
|
auto m = getTypeManager<T>();
|
||||||
return m->getAsset(assetId);
|
return m->getAsset(assetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Result<AssetRef<T>> setAsset(const ox::String &assetId, const T &obj) noexcept {
|
ox::Result<AssetRef<T>> setAsset(ox::CRStringView assetId, const T &obj) noexcept {
|
||||||
auto m = getTypeManager<T>();
|
auto m = getTypeManager<T>();
|
||||||
return m->setAsset(assetId, obj);
|
return m->setAsset(assetId, obj);
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,11 @@ ox::Result<char*> loadRom(ox::CRStringView path) noexcept {
|
|||||||
file.read(buff, size);
|
file.read(buff, size);
|
||||||
return buff;
|
return buff;
|
||||||
} catch (const std::ios_base::failure &e) {
|
} catch (const std::ios_base::failure &e) {
|
||||||
oxErrorf("Could not read ROM file: {}", e.what());
|
oxErrorf("Could not read ROM file due to file IO failure: {}", e.what());
|
||||||
return OxError(2, "Could not read ROM file");
|
return OxError(2, "Could not read ROM file");
|
||||||
|
} catch (const std::bad_alloc &e) {
|
||||||
|
oxErrorf("Could not read ROM file due to new failure: {}", e.what());
|
||||||
|
return OxError(2, "Could not allocate memory for ROM file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +145,7 @@ ox::Error setRomFs(Context *ctx, ox::UPtr<ox::FileSystem> fs) noexcept {
|
|||||||
|
|
||||||
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::CRStringView path) noexcept {
|
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::CRStringView path) noexcept {
|
||||||
const auto lastDot = ox_lastIndexOf(path, '.');
|
const auto lastDot = ox_lastIndexOf(path, '.');
|
||||||
const auto fsExt = lastDot != -1 ? path.substr(static_cast<std::size_t>(lastDot)) : "";
|
const auto fsExt = lastDot != -1 ? substr(path, static_cast<std::size_t>(lastDot)) : "";
|
||||||
if (ox_strcmp(fsExt, ".oxfs") == 0) {
|
if (ox_strcmp(fsExt, ".oxfs") == 0) {
|
||||||
oxRequire(rom, loadRom(path));
|
oxRequire(rom, loadRom(path));
|
||||||
return {ox::make_unique<ox::FileSystem32>(rom, 32 * ox::units::MB, unloadRom)};
|
return {ox::make_unique<ox::FileSystem32>(rom, 32 * ox::units::MB, unloadRom)};
|
||||||
|
@ -52,28 +52,24 @@ ox::Result<keel::AssetRef<T>> readObjFile(
|
|||||||
ox::StringView path;
|
ox::StringView path;
|
||||||
ox::UUIDStr uuidStr;
|
ox::UUIDStr uuidStr;
|
||||||
if (beginsWith(assetId, "uuid://")) {
|
if (beginsWith(assetId, "uuid://")) {
|
||||||
assetId = assetId.substr(7);
|
assetId = substr(assetId, 7);
|
||||||
path = ctx->uuidToPath[assetId];
|
path = ctx->uuidToPath[assetId];
|
||||||
} else {
|
} else {
|
||||||
path = assetId;
|
path = assetId;
|
||||||
// Warning: StringView to String
|
uuidStr = ctx->pathToUuid[path].toString();
|
||||||
uuidStr = ctx->pathToUuid[ox::String(path)].toString();
|
|
||||||
assetId = uuidStr;
|
assetId = uuidStr;
|
||||||
}
|
}
|
||||||
if (forceLoad) {
|
if (forceLoad) {
|
||||||
oxRequire(buff, ctx->rom->read(path));
|
oxRequire(buff, ctx->rom->read(path));
|
||||||
oxRequire(obj, readConvert(ctx, buff));
|
oxRequire(obj, readConvert(ctx, buff));
|
||||||
// Warning: StringView to String
|
oxRequire(cached, ctx->assetManager.setAsset(assetId, obj));
|
||||||
oxRequire(cached, ctx->assetManager.setAsset(ox::String(assetId), obj));
|
|
||||||
return cached;
|
return cached;
|
||||||
} else {
|
} else {
|
||||||
// Warning: StringView to String
|
auto [cached, err] = ctx->assetManager.getAsset<T>(assetId);
|
||||||
auto [cached, err] = ctx->assetManager.getAsset<T>(ox::String(assetId));
|
|
||||||
if (err) {
|
if (err) {
|
||||||
oxRequire(buff, ctx->rom->read(path));
|
oxRequire(buff, ctx->rom->read(path));
|
||||||
oxRequire(obj, readConvert(ctx, buff));
|
oxRequire(obj, readConvert(ctx, buff));
|
||||||
// Warning: StringView to String
|
oxReturnError(ctx->assetManager.setAsset(assetId, obj).moveTo(&cached));
|
||||||
oxReturnError(ctx->assetManager.setAsset(ox::String(assetId), obj).moveTo(&cached));
|
|
||||||
}
|
}
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
@ -107,14 +103,12 @@ ox::Result<AssetRef<T>> setAsset(keel::Context *ctx, ox::StringView assetId, T c
|
|||||||
}
|
}
|
||||||
ox::UUIDStr idStr;
|
ox::UUIDStr idStr;
|
||||||
if (assetId[0] == '/') {
|
if (assetId[0] == '/') {
|
||||||
// Warning: StringView to String
|
const auto [id, err] = ctx->pathToUuid.at(assetId);
|
||||||
const auto [id, err] = ctx->pathToUuid.at(ox::String(assetId));
|
|
||||||
oxReturnError(err);
|
oxReturnError(err);
|
||||||
idStr = id->toString();
|
idStr = id->toString();
|
||||||
assetId = idStr;
|
assetId = idStr;
|
||||||
}
|
}
|
||||||
// Warning: StringView to String
|
return ctx->assetManager.setAsset(assetId, asset);
|
||||||
return ctx->assetManager.setAsset(ox::String(assetId), asset);
|
|
||||||
#else
|
#else
|
||||||
return OxError(1, "Not supported on this platform");
|
return OxError(1, "Not supported on this platform");
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,7 +31,7 @@ static ox::Error pathToInode(
|
|||||||
}
|
}
|
||||||
if (beginsWith(path, "uuid://")) {
|
if (beginsWith(path, "uuid://")) {
|
||||||
#ifndef OX_BARE_METAL
|
#ifndef OX_BARE_METAL
|
||||||
const auto uuid = ox::StringView(path).substr(7);
|
const auto uuid = substr(ox::StringView(path), 7);
|
||||||
path = ctx->uuidToPath[uuid];
|
path = ctx->uuidToPath[uuid];
|
||||||
#else
|
#else
|
||||||
return OxError(1, "UUID to path conversion not supported on this platform");
|
return OxError(1, "UUID to path conversion not supported on this platform");
|
||||||
|
@ -29,10 +29,10 @@ class StudioModule: public studio::Module {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Vector<ox::UniquePtr<studio::ItemMaker>> itemMakers(turbine::Context*) const noexcept final {
|
ox::Vector<ox::UPtr<studio::ItemMaker>> itemMakers(turbine::Context*) const noexcept final {
|
||||||
ox::Vector<ox::UniquePtr<studio::ItemMaker>> out;
|
ox::Vector<ox::UniquePtr<studio::ItemMaker>> out;
|
||||||
out.emplace_back(ox::make<studio::ItemMakerT<core::TileSheet>>("Tile Sheet", "TileSheets", "ng"));
|
out.emplace_back(ox::make<studio::ItemMakerT<core::TileSheet>>("Tile Sheet", "TileSheets", FileExt_ng));
|
||||||
out.emplace_back(ox::make<studio::ItemMakerT<core::Palette>>("Palette", "Palettes", "npal"));
|
out.emplace_back(ox::make<studio::ItemMakerT<core::Palette>>("Palette", "Palettes", FileExt_npal));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -632,7 +632,7 @@ ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
|||||||
}
|
}
|
||||||
constexpr ox::StringView uuidPrefix = "uuid://";
|
constexpr ox::StringView uuidPrefix = "uuid://";
|
||||||
if (ox::beginsWith(path, uuidPrefix)) {
|
if (ox::beginsWith(path, uuidPrefix)) {
|
||||||
auto uuid = ox::StringView(path + uuidPrefix.bytes(), ox_strlen(path) - uuidPrefix.bytes());
|
auto uuid = ox::StringView(path.data() + uuidPrefix.bytes(), path.bytes() - uuidPrefix.bytes());
|
||||||
auto out = m_ctx->keelCtx.uuidToPath.at(uuid);
|
auto out = m_ctx->keelCtx.uuidToPath.at(uuid);
|
||||||
if (out.error) {
|
if (out.error) {
|
||||||
return {};
|
return {};
|
||||||
|
@ -35,17 +35,7 @@ int main(int argc, const char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
OX_INIT_DEBUG_LOGGER(loggerConn, "Nostalgia Player")
|
OX_INIT_DEBUG_LOGGER(loggerConn, "Nostalgia Player")
|
||||||
ox::Error err;
|
ox::Error err;
|
||||||
#ifdef __cpp_exceptions
|
|
||||||
try {
|
|
||||||
err = run(argc, argv);
|
|
||||||
} catch (ox::Exception const&ex) {
|
|
||||||
err = ex.toError();
|
|
||||||
} catch (...) {
|
|
||||||
err = OxError(1, "Non-Ox exception");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
err = run(argc, argv);
|
err = run(argc, argv);
|
||||||
#endif
|
|
||||||
oxAssert(err, "Something went wrong...");
|
oxAssert(err, "Something went wrong...");
|
||||||
return static_cast<int>(err);
|
return static_cast<int>(err);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ constexpr ox::Result<ox::StringView> fileExt(ox::CRStringView path) noexcept {
|
|||||||
if (!extStart) {
|
if (!extStart) {
|
||||||
return OxError(1, "Cannot open a file without valid extension.");
|
return OxError(1, "Cannot open a file without valid extension.");
|
||||||
}
|
}
|
||||||
return path.substr(extStart + 1);
|
return substr(path, extStart + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Project {
|
class Project {
|
||||||
|
@ -104,7 +104,7 @@ ox::Error BaseEditor::saveItem() noexcept {
|
|||||||
|
|
||||||
ox::StringView BaseEditor::pathToItemName(ox::CRStringView path) noexcept {
|
ox::StringView BaseEditor::pathToItemName(ox::CRStringView path) noexcept {
|
||||||
const auto lastSlash = std::find(path.rbegin(), path.rend(), '/').offset();
|
const auto lastSlash = std::find(path.rbegin(), path.rend(), '/').offset();
|
||||||
return path.substr(lastSlash + 1);
|
return substr(path, lastSlash + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseEditor::setRequiresConstantRefresh(bool value) noexcept {
|
void BaseEditor::setRequiresConstantRefresh(bool value) noexcept {
|
||||||
|
@ -23,7 +23,7 @@ static void generateTypes(ox::TypeStore *ts) noexcept {
|
|||||||
|
|
||||||
Project::Project(keel::Context *ctx, ox::String path, ox::CRStringView projectDataDir) noexcept:
|
Project::Project(keel::Context *ctx, ox::String path, ox::CRStringView projectDataDir) noexcept:
|
||||||
m_ctx(ctx),
|
m_ctx(ctx),
|
||||||
m_path(path),
|
m_path(std::move(path)),
|
||||||
m_projectDataDir(projectDataDir),
|
m_projectDataDir(projectDataDir),
|
||||||
m_typeStore(ctx->rom.get(), ox::sfmt("/.{}/type_descriptors", projectDataDir)),
|
m_typeStore(ctx->rom.get(), ox::sfmt("/.{}/type_descriptors", projectDataDir)),
|
||||||
m_fs(ctx->rom.get()) {
|
m_fs(ctx->rom.get()) {
|
||||||
@ -57,8 +57,7 @@ bool Project::exists(ox::CRStringView path) const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ox::Vector<ox::String> &Project::fileList(ox::CRStringView ext) noexcept {
|
const ox::Vector<ox::String> &Project::fileList(ox::CRStringView ext) noexcept {
|
||||||
// Warning: StringView to String
|
return m_fileExtFileMap[ext];
|
||||||
return m_fileExtFileMap[ox::String(ext)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::buildFileIndex() noexcept {
|
void Project::buildFileIndex() noexcept {
|
||||||
@ -81,8 +80,7 @@ void Project::indexFile(ox::CRStringView path) noexcept {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Warning: StringView to String
|
m_fileExtFileMap[ext].emplace_back(path);
|
||||||
m_fileExtFileMap[ox::String(ext)].emplace_back(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error Project::writeBuff(const ox::StringView &path, const ox::Buffer &buff) noexcept {
|
ox::Error Project::writeBuff(const ox::StringView &path, const ox::Buffer &buff) noexcept {
|
||||||
@ -90,8 +88,7 @@ ox::Error Project::writeBuff(const ox::StringView &path, const ox::Buffer &buff)
|
|||||||
ox::Buffer outBuff;
|
ox::Buffer outBuff;
|
||||||
outBuff.reserve(buff.size() + HdrSz);
|
outBuff.reserve(buff.size() + HdrSz);
|
||||||
ox::BufferWriter writer(&outBuff);
|
ox::BufferWriter writer(&outBuff);
|
||||||
// Warning: StringView to String
|
const auto [uuid, err] = m_ctx->pathToUuid.at(path);
|
||||||
const auto [uuid, err] = m_ctx->pathToUuid.at(ox::String(path));
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
oxReturnError(keel::writeUuidHeader(writer, *uuid));
|
oxReturnError(keel::writeUuidHeader(writer, *uuid));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user