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

View File

@ -131,6 +131,8 @@ class ModelHandlerInterface {
}
case ModelValue::Type::Vector:
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()));
oxPanic(OxError(1), "invalid type");

View File

@ -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<typename T>
@ -101,6 +104,8 @@ class ModelValue {
return Type::String;
} else if constexpr(is_same_v<U, ModelValueVector>) {
return Type::Vector;
} else if constexpr(is_same_v<U, ModelValueArray>) {
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<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>
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;
@ -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<typename T>
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 {
private:
Vector<ModelValue> 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>();
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<PlatSpec>(&t->get<ox::ModelValueVector>());
break;
case ModelValue::Type::InlineArray:
{
auto &list = t->get<ox::ModelValueArray>();
size = sizeOf<PlatSpec>(&list[0]) * list.size();
break;
}
}
return size;
}
@ -727,56 +898,63 @@ constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
template<typename PlatSpec>
[[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<bool>());
alignment = PlatSpec::alignOf(t.get<bool>());
break;
case ModelValue::Type::Undefined:
size = 1;
alignment = 1;
break;
case ModelValue::Type::UnsignedInteger8:
size = PlatSpec::alignOf(t.get<uint8_t>());
alignment = PlatSpec::alignOf(t.get<uint8_t>());
break;
case ModelValue::Type::UnsignedInteger16:
size = PlatSpec::alignOf(t.get<uint16_t>());
alignment = PlatSpec::alignOf(t.get<uint16_t>());
break;
case ModelValue::Type::UnsignedInteger32:
size = PlatSpec::alignOf(t.get<uint32_t>());
alignment = PlatSpec::alignOf(t.get<uint32_t>());
break;
case ModelValue::Type::UnsignedInteger64:
size = PlatSpec::alignOf(t.get<uint64_t>());
alignment = PlatSpec::alignOf(t.get<uint64_t>());
break;
case ModelValue::Type::SignedInteger8:
size = PlatSpec::alignOf(t.get<int8_t>());
alignment = PlatSpec::alignOf(t.get<int8_t>());
break;
case ModelValue::Type::SignedInteger16:
size = PlatSpec::alignOf(t.get<int16_t>());
alignment = PlatSpec::alignOf(t.get<int16_t>());
break;
case ModelValue::Type::SignedInteger32:
size = PlatSpec::alignOf(t.get<int32_t>());
alignment = PlatSpec::alignOf(t.get<int32_t>());
break;
case ModelValue::Type::SignedInteger64:
size = PlatSpec::alignOf(t.get<int64_t>());
alignment = PlatSpec::alignOf(t.get<int64_t>());
break;
case ModelValue::Type::String:
size = alignOf<PlatSpec>(t.get<ox::String>());
alignment = alignOf<PlatSpec>(t.get<ox::String>());
break;
case ModelValue::Type::Object:
size = alignOf<PlatSpec>(t.get<ox::ModelObject>());
alignment = alignOf<PlatSpec>(t.get<ox::ModelObject>());
break;
case ModelValue::Type::Union:
size = alignOf<PlatSpec>(t.get<ox::ModelUnion>());
alignment = alignOf<PlatSpec>(t.get<ox::ModelUnion>());
break;
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;
}
}
return size;
return alignment;
}
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) {
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 {
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) {
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<typename T>
constexpr ModelValue::ModelValue(const T &val) noexcept {
set(val);
constexpr ModelValue::ModelValue(const T &val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
oxIgnoreError(set(val));
}
template<typename T>
constexpr ModelValue::ModelValue(T &&val) noexcept {
set(ox::forward(val));
constexpr ModelValue::ModelValue(T &&val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
oxIgnoreError(set(ox::forward<T>(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<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_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<T>();
freeResources();
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) {
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<type>(*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<type>(*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<T>(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;
}

View File

@ -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 fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept;
constexpr bool unionCheckAndIt() noexcept;
};
@ -316,8 +318,8 @@ template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept {
// serialize the Vector
ox::VectorMemMap<PlatSpec> vecVal{
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
};
return fieldVector(name, val, vecVal);
}
@ -368,6 +370,14 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
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>
constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
auto &u = *m_unionIdx.back().unwrap();