Compare commits

...

5 Commits

9 changed files with 67 additions and 45 deletions

View File

@ -281,7 +281,20 @@ constexpr Error MetalClawReaderTemplate<HandlerMaker>::field(const char *name, T
return field(name, val->data(), val->size()); return field(name, val->data(), val->size());
} }
++m_field; ++m_field;
return OxError(0); return {};
} else if constexpr(isArray_v<T>) {
if (m_unionIdx == -1 || m_unionIdx == m_field) {
// set size of val if the field is present, don't worry about it if not
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
oxRequire(len, arrayLength(name, false));
if (len > val->size()) {
return OxError(1, "Input array is too long");
}
}
return field(name, val->data(), val->size());
}
++m_field;
return {};
} else { } else {
if ((m_unionIdx == -1 || m_unionIdx == m_field) && val) { if ((m_unionIdx == -1 || m_unionIdx == m_field) && val) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
@ -291,7 +304,7 @@ constexpr Error MetalClawReaderTemplate<HandlerMaker>::field(const char *name, T
} }
} }
++m_field; ++m_field;
return OxError(0); return {};
} }
} }

View File

@ -290,7 +290,7 @@ constexpr Error MetalClawWriter::fieldCString(const char*, const char *val, std:
template<typename T> template<typename T>
constexpr Error MetalClawWriter::field(const char*, T *val) noexcept { constexpr Error MetalClawWriter::field(const char*, T *val) noexcept {
if constexpr(isVector_v<T>) { if constexpr(isVector_v<T> || isArray_v<T>) {
return field(nullptr, val->data(), val->size()); return field(nullptr, val->data(), val->size());
} else { } else {
bool fieldSet = false; bool fieldSet = false;

View File

@ -147,6 +147,14 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
const auto srcSize = srcVal.size(); const auto srcSize = srcVal.size();
val->resize(srcSize); val->resize(srcSize);
err = field(key, val->data(), val->size()); err = field(key, val->data(), val->size());
} else if constexpr(isArray_v<T>) {
const auto &srcVal = value(key);
const auto srcSize = srcVal.size();
if (srcSize > val->size()) {
err = OxError(1, "Input array is too long");
} else {
err = field(key, val->data(), val->size());
}
} else if (targetValid()) { } else if (targetValid()) {
const auto &jv = value(key); const auto &jv = value(key);
if (jv.empty() || jv.isObject()) { if (jv.empty() || jv.isObject()) {

View File

@ -214,7 +214,7 @@ Error OrganicClawWriter::field(const char *key, T *val, std::size_t len) noexcep
template<typename T> template<typename T>
Error OrganicClawWriter::field(const char *key, T *val) noexcept { Error OrganicClawWriter::field(const char *key, T *val) noexcept {
if constexpr(isVector_v<T>) { if constexpr(isVector_v<T> || isArray_v<T>) {
return field(key, val->data(), val->size()); return field(key, val->data(), val->size());
} else if (val && targetValid()) { } else if (val && targetValid()) {
OrganicClawWriter w; OrganicClawWriter w;

View File

@ -15,7 +15,7 @@ namespace ox {
template<typename PlatSpec, typename T> template<typename PlatSpec, typename T>
[[nodiscard]] [[nodiscard]]
constexpr std::size_t alignOf(const T &t) noexcept; constexpr std::size_t alignOf(const T &v) noexcept;
template<typename PlatSpec, typename T> template<typename PlatSpec, typename T>
[[nodiscard]] [[nodiscard]]
@ -36,7 +36,7 @@ struct AlignmentCatcher: public ModelHandlerBase<AlignmentCatcher<PlatSpec>> {
template<typename T> template<typename T>
constexpr ox::Error field(CRStringView, const T *val) noexcept { constexpr ox::Error field(CRStringView, const T *val) noexcept {
if constexpr(ox::is_integer_v<T>) { if constexpr(ox::is_pointer_v<T> || ox::is_integer_v<T>) {
biggestAlignment = ox::max(biggestAlignment, PlatSpec::alignOf(*val)); biggestAlignment = ox::max(biggestAlignment, PlatSpec::alignOf(*val));
} else { } else {
biggestAlignment = ox::max(biggestAlignment, alignOf<PlatSpec>(*val)); biggestAlignment = ox::max(biggestAlignment, alignOf<PlatSpec>(*val));

View File

@ -21,11 +21,12 @@ struct NativePlatSpec {
template<typename T> template<typename T>
[[nodiscard]] [[nodiscard]]
static constexpr auto alignOf(const T &v) noexcept { static constexpr std::size_t alignOf(const T &v) noexcept {
if constexpr(ox::is_integral_v<T>) { if constexpr(ox::is_integral_v<T>) {
return alignof(T); return alignof(T);
} else if constexpr(ox::is_pointer_v<T>) { } else if constexpr(ox::is_pointer_v<T>) {
return PtrAlign; PtrType p = 0;
return alignOf(p);
} else { } else {
AlignmentCatcher<NativePlatSpec> c; AlignmentCatcher<NativePlatSpec> c;
oxAssert(model(c.interface(), &v), "Could not get alignment for type"); oxAssert(model(c.interface(), &v), "Could not get alignment for type");
@ -41,11 +42,17 @@ struct NativePlatSpec {
template<typename PlatSpec, typename T> template<typename PlatSpec, typename T>
[[nodiscard]] [[nodiscard]]
constexpr std::size_t alignOf(const T &t) noexcept { constexpr std::size_t alignOf(const T &v) noexcept {
return PlatSpec::alignOf(t); if constexpr(ox::is_integral_v<T>) {
return alignof(T);
} else if constexpr(ox::is_pointer_v<T>) {
typename PlatSpec::PtrType p = 0;
return PlatSpec::alignOf(p);
} else {
AlignmentCatcher<NativePlatSpec> c;
oxAssert(model(c.interface(), &v), "Could not get alignment for type");
return c.biggestAlignment;
}
} }
template<typename PlatSpec, typename T>
constexpr auto alignOf_v = alignOf<PlatSpec>(static_cast<T*>(nullptr));
} }

View File

@ -33,6 +33,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
private: private:
using PtrType = typename PlatSpec::PtrType; using PtrType = typename PlatSpec::PtrType;
static constexpr auto PtrSize = sizeof(PtrType);
class UnionIdxTracker { class UnionIdxTracker {
private: private:
int m_unionIdx = -1; int m_unionIdx = -1;
@ -165,6 +166,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
} }
oxReturnError(pad(val)); oxReturnError(pad(val));
if constexpr(ox::is_integral_v<T>) { if constexpr(ox::is_integral_v<T>) {
//oxDebugf("Preloader::field(name, val): {}", name);
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val)); return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) { } else if constexpr(ox::is_pointer_v<T>) {
const PtrType a = startAlloc(sizeOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart; const PtrType a = startAlloc(sizeOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
@ -336,7 +338,7 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView, const auto *v
} }
// serialize the Vector // serialize the Vector
oxReturnError(serialize(&m_writer, vecVal)); oxReturnError(serialize(&m_writer, vecVal));
m_ptrs.emplace_back(m_writer.tellp() - PlatSpec::PtrSize, vecVal.items); m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items);
return {}; return {};
} }

View File

@ -32,16 +32,13 @@ class Optional {
constexpr Optional(const Optional &other) { constexpr Optional(const Optional &other) {
if (other.m_ptr) { if (other.m_ptr) {
m_ptr = new(m_data.data()) T(*other.m_ptr); m_ptr = std::construct_at<T>(m_data.data(), *other.m_ptr);
} }
} }
constexpr Optional(const Optional &&other) noexcept { constexpr Optional(Optional &&other) noexcept {
if (m_ptr) {
m_ptr->~T();
}
if (other.m_ptr) { if (other.m_ptr) {
m_ptr = new(m_data.data()) T(std::move(*other.m_ptr)); m_ptr = std::construct_at<T>(m_data.data(), std::move(*other.m_ptr));
} }
} }
@ -51,14 +48,20 @@ class Optional {
} }
} }
template<typename U = T> constexpr T &value() & noexcept {
constexpr U *get() noexcept { return *m_ptr;
return m_ptr;
} }
template<typename U = T> constexpr const T &value() const & noexcept {
constexpr const U *get() const noexcept { return *m_ptr;
return m_ptr; }
constexpr T &&value() && noexcept {
return *m_ptr;
}
constexpr const T &&value() const && noexcept {
return *m_ptr;
} }
constexpr T &operator*() & noexcept { constexpr T &operator*() & noexcept {
@ -94,7 +97,7 @@ class Optional {
emplace(); emplace();
} }
*m_ptr = *other.m_ptr; *m_ptr = *other.m_ptr;
} else if (m_ptr) { } else {
reset(); reset();
} }
return *this; return *this;
@ -109,7 +112,7 @@ class Optional {
emplace(); emplace();
} }
*m_ptr = std::move(*other.m_ptr); *m_ptr = std::move(*other.m_ptr);
} else if (m_ptr) { } else {
reset(); reset();
} }
return *this; return *this;
@ -117,6 +120,7 @@ class Optional {
template<class... Args> template<class... Args>
constexpr T &emplace(Args &&...args) { constexpr T &emplace(Args &&...args) {
reset();
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_ptr = new T(ox::forward<Args>(args)...); m_ptr = new T(ox::forward<Args>(args)...);
} else { } else {
@ -128,6 +132,7 @@ class Optional {
template<typename U, class... Args> template<typename U, class... Args>
constexpr T &emplace_subclass(Args &&...args) { constexpr T &emplace_subclass(Args &&...args) {
static_assert(sizeof(U) <= buffSize, "Subclass is too large for this Optional"); static_assert(sizeof(U) <= buffSize, "Subclass is too large for this Optional");
reset();
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_ptr = new U(ox::forward<Args>(args)...); m_ptr = new U(ox::forward<Args>(args)...);
} else { } else {
@ -145,11 +150,11 @@ class Optional {
return m_ptr; return m_ptr;
} }
constexpr void reset() noexcept { constexpr void reset() {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_ptr); ox::safeDelete(m_ptr);
} else { } else if (has_value()) {
get()->~T(); value().~T();
} }
m_ptr = nullptr; m_ptr = nullptr;
} }

View File

@ -15,8 +15,6 @@ struct GbaPlatSpec {
using PtrType = uint32_t; using PtrType = uint32_t;
using size_t = uint32_t; using size_t = uint32_t;
static constexpr auto PtrSize = 4;
static constexpr auto PtrAlign = 4;
static constexpr PtrType RomStart = 0x08000000; static constexpr PtrType RomStart = 0x08000000;
[[nodiscard]] [[nodiscard]]
@ -64,27 +62,16 @@ struct GbaPlatSpec {
return 8; return 8;
} }
[[nodiscard]]
static constexpr std::size_t alignOf(auto*) noexcept {
return 4;
}
[[nodiscard]] [[nodiscard]]
static constexpr std::size_t alignOf(const auto*) noexcept { static constexpr std::size_t alignOf(const auto*) noexcept {
return 4; return 4;
} }
[[nodiscard]]
static constexpr std::size_t alignOf(const auto &v) noexcept {
ox::AlignmentCatcher<GbaPlatSpec> c;
oxAssert(model(c.interface(), &v), "Could not get alignment for type");
return c.biggestAlignment;
}
[[nodiscard]] [[nodiscard]]
static constexpr auto correctEndianness(auto v) noexcept { static constexpr auto correctEndianness(auto v) noexcept {
return ox::toLittleEndian(v); return ox::toLittleEndian(v);
} }
}; };
using GbaPreloader = ox::Preloader<GbaPlatSpec>; using GbaPreloader = ox::Preloader<GbaPlatSpec>;