Merge commit 'ace68f7c1d870ed53e69c55ba53709a9425388be'

This commit is contained in:
Gary Talent 2024-02-04 10:21:12 -06:00
commit 9c0acf1b8f
3 changed files with 259 additions and 38 deletions

@ -131,6 +131,8 @@ class ModelHandlerInterface {
} }
case ModelValue::Type::Vector: case ModelValue::Type::Vector:
return m_handler->field(name, &v->template get<ModelValueVector>()); return m_handler->field(name, &v->template get<ModelValueVector>());
case ModelValue::Type::InlineArray:
return m_handler->field(name, &v->template get<ModelValueArray>());
} }
oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type())); oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type()));
oxPanic(OxError(1), "invalid type"); oxPanic(OxError(1), "invalid type");

@ -31,6 +31,7 @@ namespace ox {
class ModelObject; class ModelObject;
class ModelUnion; class ModelUnion;
class ModelValue; class ModelValue;
class ModelValueArray;
class ModelValueVector; class ModelValueVector;
class ModelValue { class ModelValue {
@ -50,6 +51,7 @@ class ModelValue {
Object, Object,
Union, Union,
Vector, Vector,
InlineArray,
}; };
private: private:
@ -68,6 +70,7 @@ class ModelValue {
ModelObject *obj; ModelObject *obj;
ModelUnion *uni; ModelUnion *uni;
ModelValueVector *vec; ModelValueVector *vec;
ModelValueArray *array;
} m_data; } m_data;
template<typename T> template<typename T>
@ -101,6 +104,8 @@ class ModelValue {
return Type::String; return Type::String;
} else if constexpr(is_same_v<U, ModelValueVector>) { } else if constexpr(is_same_v<U, ModelValueVector>) {
return Type::Vector; return Type::Vector;
} else if constexpr(is_same_v<U, ModelValueArray>) {
return Type::InlineArray;
} else { } else {
return Type::Undefined; return Type::Undefined;
} }
@ -134,6 +139,8 @@ class ModelValue {
return *t.m_data.obj; return *t.m_data.obj;
} else if constexpr(type == Type::Vector) { } else if constexpr(type == Type::Vector) {
return *t.m_data.vec; return *t.m_data.vec;
} else if constexpr(type == Type::InlineArray) {
return *t.m_data.array;
} else { } else {
return t.m_data.i32; return t.m_data.i32;
} }
@ -147,10 +154,12 @@ class ModelValue {
constexpr ModelValue(ModelValue &&other) noexcept; constexpr ModelValue(ModelValue &&other) noexcept;
template<typename T> template<typename T>
explicit constexpr ModelValue(const T &val) noexcept; explicit constexpr ModelValue(const T &val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>);
template<typename T> template<typename T>
explicit constexpr ModelValue(T &&val) noexcept; explicit constexpr ModelValue(T &&val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>);
constexpr ~ModelValue() noexcept; constexpr ~ModelValue() noexcept;
@ -177,7 +186,10 @@ class ModelValue {
[[nodiscard]] [[nodiscard]]
constexpr Type type() const noexcept; 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<typename T> template<typename T>
constexpr Error setType() noexcept; constexpr Error setType() noexcept;
@ -199,11 +211,160 @@ class ModelValue {
}; };
class ModelValueArray {
private:
Vector<ModelValue> 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<ModelValueArray> make(size_t sz) noexcept {
ox::Result<ModelValueArray> 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 { class ModelValueVector {
private: private:
Vector<ModelValue> m_vec; Vector<ModelValue> m_vec;
const DescriptorType *m_type = nullptr; const DescriptorType *m_type = nullptr;
int m_typeSubscriptLevels = 0; int m_typeSubscriptLevels = 0;
SubscriptStack m_subscriptStack;
String m_typeName; String m_typeName;
int m_typeVersion = 0; int m_typeVersion = 0;
@ -233,7 +394,7 @@ class ModelValueVector {
m_vec.resize(sz); m_vec.resize(sz);
if (sz > oldSz) { if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) { 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 {}; return {};
@ -249,9 +410,13 @@ class ModelValueVector {
return m_vec; 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_type = type;
m_typeSubscriptLevels = subscriptLevels; m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
return {}; return {};
} }
@ -506,7 +671,7 @@ class ModelObject {
for (const auto &f : type->fieldList) { for (const auto &f : type->fieldList) {
auto field = make_unique<Field>(); auto field = make_unique<Field>();
field->name = f.fieldName; 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_fields[field->name] = &field->value;
m_fieldsOrder.emplace_back(std::move(field)); m_fieldsOrder.emplace_back(std::move(field));
} }
@ -713,6 +878,12 @@ constexpr std::size_t sizeOf(const ModelValue *t) noexcept {
case ModelValue::Type::Vector: case ModelValue::Type::Vector:
size = sizeOf<PlatSpec>(&t->get<ox::ModelValueVector>()); size = sizeOf<PlatSpec>(&t->get<ox::ModelValueVector>());
break; break;
case ModelValue::Type::InlineArray:
{
auto &list = t->get<ox::ModelValueArray>();
size = sizeOf<PlatSpec>(&list[0]) * list.size();
break;
}
} }
return size; return size;
} }
@ -727,56 +898,63 @@ constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
template<typename PlatSpec> template<typename PlatSpec>
[[nodiscard]] [[nodiscard]]
constexpr std::size_t alignOf(const ModelValue &t) noexcept { constexpr std::size_t alignOf(const ModelValue &t) noexcept {
std::size_t size = 0; std::size_t alignment = 0;
switch (t.type()) { switch (t.type()) {
case ModelValue::Type::Bool: case ModelValue::Type::Bool:
size = PlatSpec::alignOf(t.get<bool>()); alignment = PlatSpec::alignOf(t.get<bool>());
break; break;
case ModelValue::Type::Undefined: case ModelValue::Type::Undefined:
size = 1; alignment = 1;
break; break;
case ModelValue::Type::UnsignedInteger8: case ModelValue::Type::UnsignedInteger8:
size = PlatSpec::alignOf(t.get<uint8_t>()); alignment = PlatSpec::alignOf(t.get<uint8_t>());
break; break;
case ModelValue::Type::UnsignedInteger16: case ModelValue::Type::UnsignedInteger16:
size = PlatSpec::alignOf(t.get<uint16_t>()); alignment = PlatSpec::alignOf(t.get<uint16_t>());
break; break;
case ModelValue::Type::UnsignedInteger32: case ModelValue::Type::UnsignedInteger32:
size = PlatSpec::alignOf(t.get<uint32_t>()); alignment = PlatSpec::alignOf(t.get<uint32_t>());
break; break;
case ModelValue::Type::UnsignedInteger64: case ModelValue::Type::UnsignedInteger64:
size = PlatSpec::alignOf(t.get<uint64_t>()); alignment = PlatSpec::alignOf(t.get<uint64_t>());
break; break;
case ModelValue::Type::SignedInteger8: case ModelValue::Type::SignedInteger8:
size = PlatSpec::alignOf(t.get<int8_t>()); alignment = PlatSpec::alignOf(t.get<int8_t>());
break; break;
case ModelValue::Type::SignedInteger16: case ModelValue::Type::SignedInteger16:
size = PlatSpec::alignOf(t.get<int16_t>()); alignment = PlatSpec::alignOf(t.get<int16_t>());
break; break;
case ModelValue::Type::SignedInteger32: case ModelValue::Type::SignedInteger32:
size = PlatSpec::alignOf(t.get<int32_t>()); alignment = PlatSpec::alignOf(t.get<int32_t>());
break; break;
case ModelValue::Type::SignedInteger64: case ModelValue::Type::SignedInteger64:
size = PlatSpec::alignOf(t.get<int64_t>()); alignment = PlatSpec::alignOf(t.get<int64_t>());
break; break;
case ModelValue::Type::String: case ModelValue::Type::String:
size = alignOf<PlatSpec>(t.get<ox::String>()); alignment = alignOf<PlatSpec>(t.get<ox::String>());
break; break;
case ModelValue::Type::Object: case ModelValue::Type::Object:
size = alignOf<PlatSpec>(t.get<ox::ModelObject>()); alignment = alignOf<PlatSpec>(t.get<ox::ModelObject>());
break; break;
case ModelValue::Type::Union: case ModelValue::Type::Union:
size = alignOf<PlatSpec>(t.get<ox::ModelUnion>()); alignment = alignOf<PlatSpec>(t.get<ox::ModelUnion>());
break; break;
case ModelValue::Type::Vector: case ModelValue::Type::Vector:
size = alignOf<PlatSpec>(t.get<ox::ModelValueVector>()); alignment = alignOf<PlatSpec>(t.get<ox::ModelValueVector>());
break;
case ModelValue::Type::InlineArray:
{
auto &list = t.get<ox::ModelValueArray>();
alignment = alignOf<PlatSpec>(list[0]);
break; break;
} }
return size; }
return alignment;
} }
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept { constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelObject>(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); oxReturnError(h->template setTypeInfo<ModelObject>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) { for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value)); oxReturnError(h->field(f->name.c_str(), &f->value));
} }
@ -784,7 +962,8 @@ constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
} }
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept { constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelUnion>(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); oxReturnError(h->template setTypeInfo<ModelUnion>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) { for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value)); oxReturnError(h->field(f->name.c_str(), &f->value));
} }
@ -818,6 +997,9 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
case Type::Vector: case Type::Vector:
m_data.vec = new ModelValueVector(*other.m_data.vec); m_data.vec = new ModelValueVector(*other.m_data.vec);
break; 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; m_data.vec = other.m_data.vec;
other.m_data.vec = new ModelValueVector; other.m_data.vec = new ModelValueVector;
break; break;
case Type::InlineArray:
m_data.array = other.m_data.array;
other.m_data.array = new ModelValueArray();
break;
} }
} }
template<typename T> template<typename T>
constexpr ModelValue::ModelValue(const T &val) noexcept { constexpr ModelValue::ModelValue(const T &val) noexcept
set(val); requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
oxIgnoreError(set(val));
} }
template<typename T> template<typename T>
constexpr ModelValue::ModelValue(T &&val) noexcept { constexpr ModelValue::ModelValue(T &&val) noexcept
set(ox::forward(val)); requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
oxIgnoreError(set(ox::forward<T>(val)));
} }
constexpr ModelValue::~ModelValue() noexcept { constexpr ModelValue::~ModelValue() noexcept {
@ -874,12 +1062,22 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
return m_type; 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(); freeResources();
if (subscriptLevels) { if (subscriptLevels) {
auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
m_type = Type::InlineArray;
m_data.array = new ModelValueArray;
oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
} else {
m_type = Type::Vector; m_type = Type::Vector;
m_data.vec = new ModelValueVector; m_data.vec = new ModelValueVector;
return m_data.vec->setType(type, subscriptLevels - 1); }
return m_data.vec->setType(type, subscriptLevels - 1, subscriptStack);
} else if (type->typeName == types::Bool) { } else if (type->typeName == types::Bool) {
m_type = Type::Bool; m_type = Type::Bool;
} else if (type->typeName == types::BasicString || } else if (type->typeName == types::BasicString ||
@ -922,7 +1120,8 @@ constexpr Error ModelValue::setType() noexcept {
constexpr auto type = getType<T>(); constexpr auto type = getType<T>();
freeResources(); freeResources();
m_type = type; m_type = type;
// 2022.09.04: Clang retardedly requires initializing the union values directly, rather than using getValue<type>() // 2022.09.04: Clang retardedly requires initializing the union values directly,
// rather than using getValue<type>()
if constexpr(type == Type::Object) { if constexpr(type == Type::Object) {
m_data.obj = new ModelObject; m_data.obj = new ModelObject;
oxReturnError(m_data.obj->setType(type)); oxReturnError(m_data.obj->setType(type));
@ -964,7 +1163,7 @@ constexpr Error ModelValue::set(const T &v) noexcept {
} }
auto &value = getValue<type>(*this); auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object || 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); safeDelete(&value);
} }
value = v; value = v;
@ -979,10 +1178,10 @@ constexpr Error ModelValue::set(T &&v) noexcept {
} }
auto &value = getValue<type>(*this); auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object || 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); safeDelete(&value);
} }
value = ox::forward<T>(v); value = std::move(v);
return OxError(0); return OxError(0);
} }
@ -1021,6 +1220,9 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
case Type::Vector: case Type::Vector:
m_data.vec = new ModelValueVector(*other.m_data.vec); m_data.vec = new ModelValueVector(*other.m_data.vec);
break; break;
case Type::InlineArray:
m_data.array = new ModelValueArray(*other.m_data.array);
break;
} }
return *this; return *this;
} }
@ -1061,6 +1263,10 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
m_data.vec = other.m_data.vec; m_data.vec = other.m_data.vec;
other.m_data.vec = new ModelValueVector; other.m_data.vec = new ModelValueVector;
break; break;
case Type::InlineArray:
m_data.array = other.m_data.array;
other.m_data.array = new ModelValueArray;
break;
} }
return *this; return *this;
} }
@ -1090,6 +1296,9 @@ constexpr void ModelValue::freeResources() noexcept {
case Type::Vector: case Type::Vector:
safeDelete(m_data.vec); safeDelete(m_data.vec);
break; break;
case Type::InlineArray:
safeDelete(m_data.array);
break;
} }
m_type = Type::Undefined; m_type = Type::Undefined;
} }

@ -131,6 +131,8 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept; constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept;
constexpr bool unionCheckAndIt() noexcept; constexpr bool unionCheckAndIt() noexcept;
}; };
@ -368,6 +370,14 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
return {}; return {};
} }
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept {
for (auto const&v : *val) {
oxReturnError(this->interface()->field({}, &v));
}
return {};
}
template<typename PlatSpec> template<typename PlatSpec>
constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept { constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
auto &u = *m_unionIdx.back().unwrap(); auto &u = *m_unionIdx.back().unwrap();