diff --git a/deps/ox/src/ox/model/modelhandleradaptor.hpp b/deps/ox/src/ox/model/modelhandleradaptor.hpp index 39f69d36..7bd43860 100644 --- a/deps/ox/src/ox/model/modelhandleradaptor.hpp +++ b/deps/ox/src/ox/model/modelhandleradaptor.hpp @@ -131,6 +131,8 @@ class ModelHandlerInterface { } case ModelValue::Type::Vector: return m_handler->field(name, &v->template get()); + case ModelValue::Type::InlineArray: + return m_handler->field(name, &v->template get()); } oxErrf("invalid type: {}: {}\n", name, static_cast(v->type())); oxPanic(OxError(1), "invalid type"); diff --git a/deps/ox/src/ox/model/modelvalue.hpp b/deps/ox/src/ox/model/modelvalue.hpp index 67bec3a5..1108e7c8 100644 --- a/deps/ox/src/ox/model/modelvalue.hpp +++ b/deps/ox/src/ox/model/modelvalue.hpp @@ -31,6 +31,7 @@ namespace ox { class ModelObject; class ModelUnion; class ModelValue; +class ModelValueArray; class ModelValueVector; class ModelValue { @@ -50,6 +51,7 @@ class ModelValue { Object, Union, Vector, + InlineArray, }; private: @@ -68,6 +70,7 @@ class ModelValue { ModelObject *obj; ModelUnion *uni; ModelValueVector *vec; + ModelValueArray *array; } m_data; template @@ -101,6 +104,8 @@ class ModelValue { return Type::String; } else if constexpr(is_same_v) { return Type::Vector; + } else if constexpr(is_same_v) { + return Type::InlineArray; } else { return Type::Undefined; } @@ -134,6 +139,8 @@ class ModelValue { return *t.m_data.obj; } else if constexpr(type == Type::Vector) { return *t.m_data.vec; + } else if constexpr(type == Type::InlineArray) { + return *t.m_data.array; } else { return t.m_data.i32; } @@ -147,10 +154,12 @@ class ModelValue { constexpr ModelValue(ModelValue &&other) noexcept; template - explicit constexpr ModelValue(const T &val) noexcept; + explicit constexpr ModelValue(const T &val) noexcept + requires(!ox::is_same_v, ModelValue>); template - explicit constexpr ModelValue(T &&val) noexcept; + explicit constexpr ModelValue(T &&val) noexcept + requires(!ox::is_same_v, ModelValue>); constexpr ~ModelValue() noexcept; @@ -177,7 +186,10 @@ class ModelValue { [[nodiscard]] constexpr Type type() const noexcept; - constexpr Error setType(const DescriptorType *type, int subscriptLevels = 0) noexcept; + constexpr Error setType( + DescriptorType const*type, + int subscriptLevels = 0, + SubscriptStack const& = {}) noexcept; template constexpr Error setType() noexcept; @@ -199,11 +211,160 @@ class ModelValue { }; +class ModelValueArray { + private: + Vector m_vec; + const DescriptorType *m_type = nullptr; + int m_typeSubscriptLevels = 0; + SubscriptStack m_subscriptStack; + String m_typeName; + int m_typeVersion = 0; + + public: + constexpr explicit ModelValueArray() noexcept = default; + + constexpr ModelValueArray(ModelValueArray const&other) noexcept { + for (auto &v : other.m_vec) { + m_vec.emplace_back(v); + } + m_typeName = other.m_typeName; + m_typeVersion = other.m_typeVersion; + } + + constexpr ModelValueArray(ModelValueArray &&other) noexcept { + m_vec = std::move(other.m_vec); + m_typeName = std::move(other.m_typeName); + m_typeVersion = other.m_typeVersion; + } + + constexpr ox::Error setSize(std::size_t sz) noexcept { + const auto oldSz = m_vec.size(); + m_vec.resize(sz); + if (sz > oldSz) { + for (auto i = oldSz; i < sz; ++i) { + oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels)); + } + } + return {}; + } + + [[nodiscard]] + constexpr auto data() const noexcept { + return m_vec.data(); + } + + [[nodiscard]] + constexpr auto data() noexcept { + return m_vec.data(); + } + + constexpr static ox::Result make(size_t sz) noexcept { + ox::Result out; + out.error = out.value.setSize(sz); + return out; + } + + [[nodiscard]] + constexpr auto &get() noexcept { + return m_vec; + } + + [[nodiscard]] + constexpr auto const&get() const noexcept { + return m_vec; + } + + constexpr Error setType( + DescriptorType const*type, + int subscriptLevels, + SubscriptStack subscriptStack) noexcept { + m_type = type; + m_typeSubscriptLevels = subscriptLevels; + m_subscriptStack = std::move(subscriptStack); + return {}; + } + + [[nodiscard]] + constexpr String const&typeName() const noexcept { + return m_typeName; + } + + [[nodiscard]] + constexpr int typeVersion() const noexcept { + return m_typeVersion; + } + + [[nodiscard]] + constexpr std::size_t size() const noexcept { + return m_vec.size(); + } + + constexpr auto &operator[](std::size_t i) noexcept { + return m_vec[i]; + } + + constexpr auto &operator[](std::size_t i) const noexcept { + return m_vec[i]; + } + + [[nodiscard]] + auto begin() noexcept { + return m_vec.begin(); + } + + [[nodiscard]] + auto begin() const noexcept { + return m_vec.cbegin(); + } + + [[nodiscard]] + auto cbegin() const noexcept { + return m_vec.cbegin(); + } + + [[nodiscard]] + auto rbegin() noexcept { + return m_vec.rbegin(); + } + + [[nodiscard]] + auto crbegin() const noexcept { + return m_vec.crbegin(); + } + + [[nodiscard]] + auto end() noexcept { + return m_vec.end(); + } + + [[nodiscard]] + auto end() const noexcept { + return m_vec.cend(); + } + + [[nodiscard]] + auto cend() const noexcept { + return m_vec.cend(); + } + + [[nodiscard]] + auto rend() noexcept { + return m_vec.rend(); + } + + [[nodiscard]] + auto crend() const noexcept { + return m_vec.crend(); + } + +}; + class ModelValueVector { private: Vector m_vec; const DescriptorType *m_type = nullptr; int m_typeSubscriptLevels = 0; + SubscriptStack m_subscriptStack; String m_typeName; int m_typeVersion = 0; @@ -233,7 +394,7 @@ class ModelValueVector { m_vec.resize(sz); if (sz > oldSz) { for (auto i = oldSz; i < sz; ++i) { - oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels)); + oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack)); } } return {}; @@ -249,9 +410,13 @@ class ModelValueVector { return m_vec; } - constexpr Error setType(const DescriptorType *type, int subscriptLevels) noexcept { + constexpr Error setType( + DescriptorType const*type, + int subscriptLevels, + SubscriptStack subscriptStack) noexcept { m_type = type; m_typeSubscriptLevels = subscriptLevels; + m_subscriptStack = std::move(subscriptStack); return {}; } @@ -506,7 +671,7 @@ class ModelObject { for (const auto &f : type->fieldList) { auto field = make_unique(); field->name = f.fieldName; - oxReturnError(field->value.setType(f.type, f.subscriptLevels)); + oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack)); m_fields[field->name] = &field->value; m_fieldsOrder.emplace_back(std::move(field)); } @@ -713,6 +878,12 @@ constexpr std::size_t sizeOf(const ModelValue *t) noexcept { case ModelValue::Type::Vector: size = sizeOf(&t->get()); break; + case ModelValue::Type::InlineArray: + { + auto &list = t->get(); + size = sizeOf(&list[0]) * list.size(); + break; + } } return size; } @@ -727,56 +898,63 @@ constexpr std::size_t alignOf(const ModelValueVector&) noexcept { template [[nodiscard]] constexpr std::size_t alignOf(const ModelValue &t) noexcept { - std::size_t size = 0; + std::size_t alignment = 0; switch (t.type()) { case ModelValue::Type::Bool: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::Undefined: - size = 1; + alignment = 1; break; case ModelValue::Type::UnsignedInteger8: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::UnsignedInteger16: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::UnsignedInteger32: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::UnsignedInteger64: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::SignedInteger8: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::SignedInteger16: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::SignedInteger32: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::SignedInteger64: - size = PlatSpec::alignOf(t.get()); + alignment = PlatSpec::alignOf(t.get()); break; case ModelValue::Type::String: - size = alignOf(t.get()); + alignment = alignOf(t.get()); break; case ModelValue::Type::Object: - size = alignOf(t.get()); + alignment = alignOf(t.get()); break; case ModelValue::Type::Union: - size = alignOf(t.get()); + alignment = alignOf(t.get()); break; case ModelValue::Type::Vector: - size = alignOf(t.get()); + alignment = alignOf(t.get()); break; + case ModelValue::Type::InlineArray: + { + auto &list = t.get(); + alignment = alignOf(list[0]); + break; + } } - return size; + return alignment; } constexpr Error model(auto *h, CommonPtrWith auto *obj) noexcept { - oxReturnError(h->template setTypeInfo(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); + oxReturnError(h->template setTypeInfo( + obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); for (auto &f : obj->m_fieldsOrder) { oxReturnError(h->field(f->name.c_str(), &f->value)); } @@ -784,7 +962,8 @@ constexpr Error model(auto *h, CommonPtrWith auto *obj) noexcept { } constexpr Error model(auto *h, CommonPtrWith auto *obj) noexcept { - oxReturnError(h->template setTypeInfo(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); + oxReturnError(h->template setTypeInfo( + obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); for (auto &f : obj->m_fieldsOrder) { oxReturnError(h->field(f->name.c_str(), &f->value)); } @@ -818,6 +997,9 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept { case Type::Vector: m_data.vec = new ModelValueVector(*other.m_data.vec); break; + case Type::InlineArray: + m_data.array = new ModelValueArray(*other.m_data.array); + break; } } @@ -853,17 +1035,23 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept { m_data.vec = other.m_data.vec; other.m_data.vec = new ModelValueVector; break; + case Type::InlineArray: + m_data.array = other.m_data.array; + other.m_data.array = new ModelValueArray(); + break; } } template -constexpr ModelValue::ModelValue(const T &val) noexcept { - set(val); +constexpr ModelValue::ModelValue(const T &val) noexcept + requires(!ox::is_same_v, ModelValue>) { + oxIgnoreError(set(val)); } template -constexpr ModelValue::ModelValue(T &&val) noexcept { - set(ox::forward(val)); +constexpr ModelValue::ModelValue(T &&val) noexcept + requires(!ox::is_same_v, ModelValue>) { + oxIgnoreError(set(ox::forward(val))); } constexpr ModelValue::~ModelValue() noexcept { @@ -874,12 +1062,22 @@ constexpr ModelValue::Type ModelValue::type() const noexcept { return m_type; } -constexpr Error ModelValue::setType(const DescriptorType *type, int subscriptLevels) noexcept { +constexpr Error ModelValue::setType( + const DescriptorType *type, + int subscriptLevels, + SubscriptStack const&subscriptStack) noexcept { freeResources(); if (subscriptLevels) { - m_type = Type::Vector; - m_data.vec = new ModelValueVector; - return m_data.vec->setType(type, subscriptLevels - 1); + auto const&subscript = subscriptStack[subscriptStack.size() - static_cast(subscriptLevels)]; + if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) { + m_type = Type::InlineArray; + m_data.array = new ModelValueArray; + oxReturnError(m_data.array->setSize(static_cast(subscript.length))); + } else { + m_type = Type::Vector; + m_data.vec = new ModelValueVector; + } + return m_data.vec->setType(type, subscriptLevels - 1, subscriptStack); } else if (type->typeName == types::Bool) { m_type = Type::Bool; } else if (type->typeName == types::BasicString || @@ -922,7 +1120,8 @@ constexpr Error ModelValue::setType() noexcept { constexpr auto type = getType(); freeResources(); m_type = type; - // 2022.09.04: Clang retardedly requires initializing the union values directly, rather than using getValue() + // 2022.09.04: Clang retardedly requires initializing the union values directly, + // rather than using getValue() if constexpr(type == Type::Object) { m_data.obj = new ModelObject; oxReturnError(m_data.obj->setType(type)); @@ -964,7 +1163,7 @@ constexpr Error ModelValue::set(const T &v) noexcept { } auto &value = getValue(*this); if constexpr(type == Type::Vector || type == Type::Object || - type == Type::Union || type == Type::String) { + type == Type::Union || type == Type::String || type == Type::InlineArray) { safeDelete(&value); } value = v; @@ -979,10 +1178,10 @@ constexpr Error ModelValue::set(T &&v) noexcept { } auto &value = getValue(*this); if constexpr(type == Type::Vector || type == Type::Object || - type == Type::Union || type == Type::String) { + type == Type::Union || type == Type::String || type == Type::InlineArray) { safeDelete(&value); } - value = ox::forward(v); + value = std::move(v); return OxError(0); } @@ -1021,6 +1220,9 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept { case Type::Vector: m_data.vec = new ModelValueVector(*other.m_data.vec); break; + case Type::InlineArray: + m_data.array = new ModelValueArray(*other.m_data.array); + break; } return *this; } @@ -1061,6 +1263,10 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept { m_data.vec = other.m_data.vec; other.m_data.vec = new ModelValueVector; break; + case Type::InlineArray: + m_data.array = other.m_data.array; + other.m_data.array = new ModelValueArray; + break; } return *this; } @@ -1090,6 +1296,9 @@ constexpr void ModelValue::freeResources() noexcept { case Type::Vector: safeDelete(m_data.vec); break; + case Type::InlineArray: + safeDelete(m_data.array); + break; } m_type = Type::Undefined; } diff --git a/deps/ox/src/ox/preloader/preloader.hpp b/deps/ox/src/ox/preloader/preloader.hpp index f9fe6e82..23b815f4 100644 --- a/deps/ox/src/ox/preloader/preloader.hpp +++ b/deps/ox/src/ox/preloader/preloader.hpp @@ -131,6 +131,8 @@ class Preloader: public ModelHandlerBase, OpType::Reflect> { constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap vecVal) noexcept; + constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept; + constexpr bool unionCheckAndIt() noexcept; }; @@ -316,8 +318,8 @@ template constexpr ox::Error Preloader::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept { // serialize the Vector ox::VectorMemMap vecVal{ - .size = PlatSpec::correctEndianness(static_cast(val->size())), - .cap = PlatSpec::correctEndianness(static_cast(val->size())), + .size = PlatSpec::correctEndianness(static_cast(val->size())), + .cap = PlatSpec::correctEndianness(static_cast(val->size())), }; return fieldVector(name, val, vecVal); } @@ -368,6 +370,14 @@ constexpr ox::Error Preloader::fieldVector( return {}; } +template +constexpr ox::Error Preloader::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept { + for (auto const&v : *val) { + oxReturnError(this->interface()->field({}, &v)); + } + return {}; +} + template constexpr bool Preloader::unionCheckAndIt() noexcept { auto &u = *m_unionIdx.back().unwrap();