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());
}
++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 {
if ((m_unionIdx == -1 || m_unionIdx == m_field) && val) {
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;
return OxError(0);
return {};
}
}

View File

@ -290,7 +290,7 @@ constexpr Error MetalClawWriter::fieldCString(const char*, const char *val, std:
template<typename T>
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());
} else {
bool fieldSet = false;

View File

@ -147,6 +147,14 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
const auto srcSize = srcVal.size();
val->resize(srcSize);
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()) {
const auto &jv = value(key);
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>
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());
} else if (val && targetValid()) {
OrganicClawWriter w;

View File

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

View File

@ -21,11 +21,12 @@ struct NativePlatSpec {
template<typename T>
[[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>) {
return alignof(T);
} else if constexpr(ox::is_pointer_v<T>) {
return PtrAlign;
PtrType p = 0;
return alignOf(p);
} else {
AlignmentCatcher<NativePlatSpec> c;
oxAssert(model(c.interface(), &v), "Could not get alignment for type");
@ -41,11 +42,17 @@ struct NativePlatSpec {
template<typename PlatSpec, typename T>
[[nodiscard]]
constexpr std::size_t alignOf(const T &t) noexcept {
return PlatSpec::alignOf(t);
constexpr std::size_t alignOf(const T &v) noexcept {
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:
using PtrType = typename PlatSpec::PtrType;
static constexpr auto PtrSize = sizeof(PtrType);
class UnionIdxTracker {
private:
int m_unionIdx = -1;
@ -165,6 +166,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
}
oxReturnError(pad(val));
if constexpr(ox::is_integral_v<T>) {
//oxDebugf("Preloader::field(name, val): {}", name);
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) {
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
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 {};
}

View File

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

View File

@ -15,8 +15,6 @@ struct GbaPlatSpec {
using PtrType = uint32_t;
using size_t = uint32_t;
static constexpr auto PtrSize = 4;
static constexpr auto PtrAlign = 4;
static constexpr PtrType RomStart = 0x08000000;
[[nodiscard]]
@ -64,27 +62,16 @@ struct GbaPlatSpec {
return 8;
}
[[nodiscard]]
static constexpr std::size_t alignOf(auto*) noexcept {
return 4;
}
[[nodiscard]]
static constexpr std::size_t alignOf(const auto*) noexcept {
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]]
static constexpr auto correctEndianness(auto v) noexcept {
return ox::toLittleEndian(v);
}
};
using GbaPreloader = ox::Preloader<GbaPlatSpec>;