From 75aeedb7b539344029aa30da2f898261a9b57f59 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 11 Feb 2019 05:59:33 +0000 Subject: [PATCH] [ox/mc] Add def writer --- deps/ox/src/ox/fs/CMakeLists.txt | 8 ++ deps/ox/src/ox/mc/CMakeLists.txt | 8 ++ deps/ox/src/ox/mc/definition-language.txt | 7 ++ deps/ox/src/ox/mc/deftypes.hpp | 91 ++++++++++++++++ deps/ox/src/ox/mc/defwriter.cpp | 116 ++++++++++++++++++++ deps/ox/src/ox/mc/defwriter.hpp | 126 ++++++++++++++++++++++ deps/ox/src/ox/mc/mc.hpp | 2 + deps/ox/src/ox/mc/optype.hpp | 5 +- deps/ox/src/ox/mc/read.cpp | 8 +- deps/ox/src/ox/mc/read.hpp | 8 +- deps/ox/src/ox/mc/test/tests.cpp | 4 +- deps/ox/src/ox/mc/write.cpp | 8 +- deps/ox/src/ox/mc/write.hpp | 17 +-- deps/ox/src/ox/std/CMakeLists.txt | 2 + deps/ox/src/ox/std/hashmap.hpp | 17 +++ deps/ox/src/ox/std/std.hpp | 1 + deps/ox/src/ox/std/typeinfo.hpp | 34 ++++++ deps/ox/src/ox/std/typetraits.hpp | 19 ++++ deps/ox/src/ox/std/vector.hpp | 2 +- deps/ox/src/ox/trace/trace.hpp | 2 +- 20 files changed, 468 insertions(+), 17 deletions(-) create mode 100644 deps/ox/src/ox/mc/definition-language.txt create mode 100644 deps/ox/src/ox/mc/deftypes.hpp create mode 100644 deps/ox/src/ox/mc/defwriter.cpp create mode 100644 deps/ox/src/ox/mc/defwriter.hpp create mode 100644 deps/ox/src/ox/std/typeinfo.hpp diff --git a/deps/ox/src/ox/fs/CMakeLists.txt b/deps/ox/src/ox/fs/CMakeLists.txt index 1efe83c3..dd51dd6f 100644 --- a/deps/ox/src/ox/fs/CMakeLists.txt +++ b/deps/ox/src/ox/fs/CMakeLists.txt @@ -9,6 +9,14 @@ add_library( filesystem/passthroughfs.cpp ) +target_link_libraries( + OxFS PUBLIC + c++fs + OxMetalClaw + OxStd + OxTrace +) + set_property( TARGET OxFS diff --git a/deps/ox/src/ox/mc/CMakeLists.txt b/deps/ox/src/ox/mc/CMakeLists.txt index 0312e35f..d4fdfe8e 100644 --- a/deps/ox/src/ox/mc/CMakeLists.txt +++ b/deps/ox/src/ox/mc/CMakeLists.txt @@ -2,11 +2,18 @@ cmake_minimum_required(VERSION 2.8) add_library( OxMetalClaw + defwriter.cpp presencemask.cpp read.cpp write.cpp ) +target_link_libraries( + OxMetalClaw PUBLIC + OxStd + OxTrace +) + set_property( TARGET OxMetalClaw @@ -16,6 +23,7 @@ set_property( install( FILES + defwriter.hpp err.hpp presencemask.hpp read.hpp diff --git a/deps/ox/src/ox/mc/definition-language.txt b/deps/ox/src/ox/mc/definition-language.txt new file mode 100644 index 00000000..70a40807 --- /dev/null +++ b/deps/ox/src/ox/mc/definition-language.txt @@ -0,0 +1,7 @@ + : + : | + : + : | + : + : <0: single> | <1: list> + : diff --git a/deps/ox/src/ox/mc/deftypes.hpp b/deps/ox/src/ox/mc/deftypes.hpp new file mode 100644 index 00000000..d0ede925 --- /dev/null +++ b/deps/ox/src/ox/mc/deftypes.hpp @@ -0,0 +1,91 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include +#include + +namespace ox::mc { + +using String = const char*; + +enum class PrimitiveType: uint8_t { + UnsignedInteger = 0, + SignedInteger = 1, + Bool = 2, + Float = 3, + String = 4, + List = 5, + Struct = 6, +}; + +using FieldName = String; + +struct Field { + // only serialize type name if type has already been serialized + const struct Type *type = nullptr; + FieldName fieldName; + int subscriptLevels = 0; +}; + +using TypeName = String; +using FieldList = Vector; + +struct Type { + TypeName typeName; + PrimitiveType primitiveType; + // fieldList only applies to structs + FieldList fieldList; + // - number of bytes for integer and float types + // - number of fields for structs and lists + int64_t length = 0; + + Type() = default; + + Type(TypeName tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) { + } + + Type(TypeName tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) { + } +}; + + +template +int ioOp(T *io, Field *field) { + int32_t err = 0; + io->setTypeInfo("ox::mc::Field", 5); + if (field->type) { + err |= io->op("typeName", &field->type->typeName); + err |= io->op("type", &field->type); + } else { + // TODO: lookup type + err |= io->op("typeName", &field->type->typeName); + err |= io->op("type", static_casttype)>(nullptr)); + } + err |= io->op("fieldName", &field->fieldName); + // defaultValue is unused now, but placeholder for backwards compatibility + err |= io->op("defaultValue", nullptr); + return err; +} + +template +int ioOp(T *io, Type *type) { + int32_t err = 0; + io->setTypeInfo("ox::mc::Type", 4); + err |= io->op("typeName", &type->typeName); + err |= io->op("primitiveType", &type->primitiveType); + err |= io->op("fieldList", &type->fieldList); + err |= io->op("length", &type->length); + return err; +} + +using TypeStore = ox::HashMap; + +} diff --git a/deps/ox/src/ox/mc/defwriter.cpp b/deps/ox/src/ox/mc/defwriter.cpp new file mode 100644 index 00000000..8e26b049 --- /dev/null +++ b/deps/ox/src/ox/mc/defwriter.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2015 - 2019 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include "defwriter.hpp" + +namespace ox { + +MetalClawDefWriter::MetalClawDefWriter(mc::TypeStore *typeStore) { + if (!typeStore) { + m_typeStoreOwnerRef = new mc::TypeStore; + typeStore = m_typeStoreOwnerRef; + } + m_typeStore = typeStore; +} + +MetalClawDefWriter::~MetalClawDefWriter() { + if (m_typeStoreOwnerRef) { + delete m_typeStoreOwnerRef; + } +} + +constexpr mc::Type *MetalClawDefWriter::type(int8_t*) { + constexpr auto TypeName = "B:int8_t"; + constexpr auto PT = mc::PrimitiveType::SignedInteger; + constexpr auto Bytes = 8; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(int16_t*) { + constexpr auto TypeName = "B:int16_t"; + constexpr auto PT = mc::PrimitiveType::SignedInteger; + constexpr auto Bytes = 16; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(int32_t*) { + constexpr auto TypeName = "B:int32_t"; + constexpr auto PT = mc::PrimitiveType::SignedInteger; + constexpr auto Bytes = 32; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(int64_t*) { + constexpr auto TypeName = "B:int64_t"; + constexpr auto PT = mc::PrimitiveType::SignedInteger; + constexpr auto Bytes = 64; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(uint8_t*) { + constexpr auto TypeName = "B:uint8_t"; + constexpr auto PT = mc::PrimitiveType::UnsignedInteger; + constexpr auto Bytes = 8; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(uint16_t*) { + constexpr auto TypeName = "B:uint16_t"; + constexpr auto PT = mc::PrimitiveType::UnsignedInteger; + constexpr auto Bytes = 16; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(uint32_t*) { + constexpr auto TypeName = "B:uint32_t"; + constexpr auto PT = mc::PrimitiveType::UnsignedInteger; + constexpr auto Bytes = 32; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(uint64_t*) { + constexpr auto TypeName = "B:uint64_t"; + constexpr auto PT = mc::PrimitiveType::UnsignedInteger; + constexpr auto Bytes = 64; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr mc::Type *MetalClawDefWriter::type(bool*) { + constexpr auto TypeName = "B:bool"; + constexpr auto PT = mc::PrimitiveType::Bool; + constexpr auto Bytes = 0; + return getPrimitive(TypeName, PT, Bytes); +} + +constexpr void MetalClawDefWriter::setTypeInfo(const char *name, int) { + m_type = &m_typeStore->at(name); + m_type->typeName = name; + m_type->primitiveType = mc::PrimitiveType::Struct; +} + +constexpr mc::Type *MetalClawDefWriter::type(const char*) { + constexpr auto TypeName = "B:string"; + constexpr auto PT = mc::PrimitiveType::String; + return getPrimitive(TypeName, PT); +} + +constexpr mc::Type *MetalClawDefWriter::getPrimitive(mc::TypeName tn, mc::PrimitiveType pt, int b) { + if (m_typeStore->contains(tn)) { + return &m_typeStore->at(tn); + } else { + auto t = &m_typeStore->at(tn); + t->typeName = tn; + t->primitiveType = pt; + t->length = b; + return t; + } +} + +} diff --git a/deps/ox/src/ox/mc/defwriter.hpp b/deps/ox/src/ox/mc/defwriter.hpp new file mode 100644 index 00000000..47b9a8f0 --- /dev/null +++ b/deps/ox/src/ox/mc/defwriter.hpp @@ -0,0 +1,126 @@ +/* + * Copyright 2015 - 2019 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "deftypes.hpp" +#include "err.hpp" +#include "optype.hpp" + +namespace ox { + +template +static constexpr int indirectionLevels(T) { + return 0; +} + +template +static constexpr int indirectionLevels(T *t) { + return 1 + indirectionLevels(*t); +} + +class MetalClawDefWriter { + + private: + mc::TypeStore *m_typeStoreOwnerRef = nullptr; + mc::TypeStore *m_typeStore = nullptr; + mc::Type *m_type = nullptr; + + public: + explicit MetalClawDefWriter(mc::TypeStore *typeStore = nullptr); + + ~MetalClawDefWriter(); + + template + int op(const char *name, T *val, std::size_t valLen); + + template + int op(const char *name, const char *val); + + template + int op(const char *name, ox::BString *val); + + template + constexpr int op(const char *name, T *val); + + constexpr void setTypeInfo(const char *name, int fields); + + constexpr OpType opType() { + return OpType::Write; + } + + private: + constexpr mc::Type *type(int8_t *val); + constexpr mc::Type *type(int16_t *val); + constexpr mc::Type *type(int32_t *val); + constexpr mc::Type *type(int64_t *val); + + constexpr mc::Type *type(uint8_t *val); + constexpr mc::Type *type(uint16_t *val); + constexpr mc::Type *type(uint32_t *val); + constexpr mc::Type *type(uint64_t *val); + + constexpr mc::Type *type(bool *val); + + constexpr mc::Type *type(const char *val); + + template + constexpr mc::Type *type(ox::BString *val); + + template + mc::Type *type(T *val); + + constexpr mc::Type *getPrimitive(mc::TypeName tn, mc::PrimitiveType t, int b = 0); +}; + +// array handler +template +int MetalClawDefWriter::op(const char *name, T *val, std::size_t) { + if (m_type) { + constexpr typename RemoveIndirection::type *p = nullptr; + const auto t = type(p); + m_type->fieldList.push_back(mc::Field{t, name, subscriptLevels(val)}); + } + return 0; +} + +template +int MetalClawDefWriter::op(const char *name, ox::BString *val) { + return op(name, val->c_str()); +} + +template +constexpr int MetalClawDefWriter::op(const char *name, T *val) { + if (m_type) { + const auto t = type(val); + m_type->fieldList.push_back(mc::Field{t, name}); + return 0; + } + return OxError(1); +} + +template +mc::Type *MetalClawDefWriter::type(T *val) { + MetalClawDefWriter dw(m_typeStore); + oxLogError(ioOp(&dw, val)); + return dw.m_type; +} + +template +constexpr mc::Type *MetalClawDefWriter::type(ox::BString *val) { + return type(val->c_str()); +} + +} diff --git a/deps/ox/src/ox/mc/mc.hpp b/deps/ox/src/ox/mc/mc.hpp index 3578d6a3..d3453cab 100644 --- a/deps/ox/src/ox/mc/mc.hpp +++ b/deps/ox/src/ox/mc/mc.hpp @@ -8,5 +8,7 @@ #pragma once +#include "deftypes.hpp" +#include "defwriter.hpp" #include "read.hpp" #include "write.hpp" diff --git a/deps/ox/src/ox/mc/optype.hpp b/deps/ox/src/ox/mc/optype.hpp index 00490626..f6cac4c5 100644 --- a/deps/ox/src/ox/mc/optype.hpp +++ b/deps/ox/src/ox/mc/optype.hpp @@ -13,8 +13,9 @@ namespace ox { enum class OpType { - Read = 0, - Write = 1 + Read = 1, + Write = 2, + WriteDefinition = 3, }; template diff --git a/deps/ox/src/ox/mc/read.cpp b/deps/ox/src/ox/mc/read.cpp index 4336362a..537c68fa 100644 --- a/deps/ox/src/ox/mc/read.cpp +++ b/deps/ox/src/ox/mc/read.cpp @@ -6,8 +6,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include #include + #include "read.hpp" namespace ox { @@ -17,6 +19,10 @@ MetalClawReader::MetalClawReader(uint8_t *buff, std::size_t buffLen): m_fieldPre m_buffLen = buffLen; } +MetalClawReader::~MetalClawReader() { + oxAssert(m_field == m_fields, "MetalClawReader: incorrect fields number given"); +} + int MetalClawReader::op(const char*, int8_t *val) { return readInteger(val); } @@ -77,7 +83,7 @@ std::size_t MetalClawReader::stringLength(const char*) { return len; } -void MetalClawReader::setFields(int fields) { +void MetalClawReader::setTypeInfo(const char*, int fields) { m_fields = fields; m_buffIt = (fields / 8 + 1) - (fields % 8 == 0); m_fieldPresence.setMaxLen(m_buffIt); diff --git a/deps/ox/src/ox/mc/read.hpp b/deps/ox/src/ox/mc/read.hpp index e970e661..d2259d13 100644 --- a/deps/ox/src/ox/mc/read.hpp +++ b/deps/ox/src/ox/mc/read.hpp @@ -32,6 +32,8 @@ class MetalClawReader { public: MetalClawReader(uint8_t *buff, std::size_t buffLen); + ~MetalClawReader(); + int op(const char*, int8_t *val); int op(const char*, int16_t *val); int op(const char*, int32_t *val); @@ -58,7 +60,7 @@ class MetalClawReader { // stringLength returns the length of the string, including the null terminator. std::size_t stringLength(const char*); - void setFields(int fields); + void setTypeInfo(const char *name, int fields); OpType opType() { return OpType::Read; @@ -72,7 +74,7 @@ class MetalClawReader { template int MetalClawReader::op(const char*, T *val) { int err = 0; - if (m_fieldPresence.get(m_field)) { + if (val && m_fieldPresence.get(m_field)) { MetalClawReader reader(m_buff + m_buffIt, m_buffLen - m_buffIt); err |= ioOp(&reader, val); m_buffIt += reader.m_buffIt; @@ -145,7 +147,7 @@ int MetalClawReader::op(const char*, T *val, std::size_t valLen) { // read the list if (valLen >= len) { MetalClawReader reader(m_buff + m_buffIt, m_buffLen - m_buffIt); - reader.setFields(len); + reader.setTypeInfo("List", len); for (std::size_t i = 0; i < len; i++) { err |= reader.op("", &val[i]); } diff --git a/deps/ox/src/ox/mc/test/tests.cpp b/deps/ox/src/ox/mc/test/tests.cpp index 8873ebf2..e5b563a4 100644 --- a/deps/ox/src/ox/mc/test/tests.cpp +++ b/deps/ox/src/ox/mc/test/tests.cpp @@ -43,7 +43,7 @@ struct TestStruct { template int ioOp(T *io, TestStructNest *obj) { int32_t err = 0; - io->setFields(3); + io->setTypeInfo("common::TestStructNest", 3); err |= io->op("Bool", &obj->Bool); err |= io->op("Int", &obj->Int); err |= io->op("String", &obj->String); @@ -53,7 +53,7 @@ int ioOp(T *io, TestStructNest *obj) { template int ioOp(T *io, TestStruct *obj) { int err = 0; - io->setFields(14); + io->setTypeInfo("common::TestStruct", 14); err |= io->op("Bool", &obj->Bool); err |= io->op("Int", &obj->Int); err |= io->op("Int1", &obj->Int1); diff --git a/deps/ox/src/ox/mc/write.cpp b/deps/ox/src/ox/mc/write.cpp index a9858478..2050b12f 100644 --- a/deps/ox/src/ox/mc/write.cpp +++ b/deps/ox/src/ox/mc/write.cpp @@ -6,8 +6,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include #include + #include "write.hpp" namespace ox { @@ -17,6 +19,10 @@ MetalClawWriter::MetalClawWriter(uint8_t *buff, std::size_t buffLen): m_fieldPre m_buffLen = buffLen; } +MetalClawWriter::~MetalClawWriter() noexcept { + oxAssert(m_field == m_fields, "MetalClawWriter: incorrect fields number given"); +} + int MetalClawWriter::op(const char*, int8_t *val) { return appendInteger(*val); } @@ -54,7 +60,7 @@ int MetalClawWriter::op(const char*, bool *val) { return m_fieldPresence.set(m_field++, *val); } -void MetalClawWriter::setFields(int fields) { +void MetalClawWriter::setTypeInfo(const char*, int fields) { m_fields = fields; m_buffIt = (fields / 8 + 1) - (fields % 8 == 0); m_fieldPresence.setMaxLen(m_buffIt); diff --git a/deps/ox/src/ox/mc/write.hpp b/deps/ox/src/ox/mc/write.hpp index 6f709539..162f31ea 100644 --- a/deps/ox/src/ox/mc/write.hpp +++ b/deps/ox/src/ox/mc/write.hpp @@ -21,6 +21,7 @@ class MetalClawWriter { private: FieldPresenseMask m_fieldPresence; + const char *m_typeName = nullptr; int m_fields = 0; int m_field = 0; std::size_t m_buffIt = 0; @@ -30,6 +31,8 @@ class MetalClawWriter { public: MetalClawWriter(uint8_t *buff, std::size_t buffLen); + ~MetalClawWriter() noexcept; + int op(const char*, int8_t *val); int op(const char*, int16_t *val); int op(const char*, int32_t *val); @@ -54,7 +57,7 @@ class MetalClawWriter { template int op(const char*, T *val); - void setFields(int fields); + void setTypeInfo(const char *name, int fields); std::size_t size(); @@ -96,10 +99,12 @@ int MetalClawWriter::op(const char*, T *val) { int err = 0; bool fieldSet = false; MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); - err |= ioOp(&writer, val); - if (static_cast(writer.m_fieldPresence.getMaxLen()) < writer.m_buffIt) { - m_buffIt += writer.m_buffIt; - fieldSet = true; + if (val) { + err |= ioOp(&writer, val); + if (static_cast(writer.m_fieldPresence.getMaxLen()) < writer.m_buffIt) { + m_buffIt += writer.m_buffIt; + fieldSet = true; + } } err |= m_fieldPresence.set(m_field, fieldSet); m_field++; @@ -140,7 +145,7 @@ int MetalClawWriter::op(const char*, T *val, std::size_t len) { } MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); - writer.setFields(len); + writer.setTypeInfo("List", len); // write the array for (std::size_t i = 0; i < len; i++) { diff --git a/deps/ox/src/ox/std/CMakeLists.txt b/deps/ox/src/ox/std/CMakeLists.txt index b0c3140b..b65c1405 100644 --- a/deps/ox/src/ox/std/CMakeLists.txt +++ b/deps/ox/src/ox/std/CMakeLists.txt @@ -17,6 +17,8 @@ set_property( POSITION_INDEPENDENT_CODE ON ) +target_link_libraries(OxStd PUBLIC OxTrace) + install( FILES assert.hpp diff --git a/deps/ox/src/ox/std/hashmap.hpp b/deps/ox/src/ox/std/hashmap.hpp index e7393aa4..48d0db8f 100644 --- a/deps/ox/src/ox/std/hashmap.hpp +++ b/deps/ox/src/ox/std/hashmap.hpp @@ -38,6 +38,13 @@ class HashMap { */ T &operator[](K key) noexcept; + /** + * K is assumed to be a null terminated string. + */ + T &at(K key) noexcept; + + bool contains(K key) noexcept; + std::size_t size() const noexcept; private: @@ -93,6 +100,16 @@ T &HashMap::operator[](K k) noexcept { return p->value; } +template +T &HashMap::at(K k) noexcept { + return operator[](k); +} + +template +bool HashMap::contains(K k) noexcept { + return access(m_pairs, k) != nullptr; +} + template std::size_t HashMap::size() const noexcept { return m_keys.size(); diff --git a/deps/ox/src/ox/std/std.hpp b/deps/ox/src/ox/std/std.hpp index 1c17dfff..99a1f060 100644 --- a/deps/ox/src/ox/std/std.hpp +++ b/deps/ox/src/ox/std/std.hpp @@ -21,6 +21,7 @@ #include "stddef.hpp" #include "strops.hpp" #include "string.hpp" +#include "typeinfo.hpp" #include "types.hpp" #include "typetraits.hpp" #include "vector.hpp" diff --git a/deps/ox/src/ox/std/typeinfo.hpp b/deps/ox/src/ox/std/typeinfo.hpp new file mode 100644 index 00000000..8208a40f --- /dev/null +++ b/deps/ox/src/ox/std/typeinfo.hpp @@ -0,0 +1,34 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#if __has_include() +#include +#else + +namespace std { + +// this is not at all guaranteed to work, and does not even fully comply with +// what little the standard does define +struct type_info { + private: + const char *m_name = ""; + + protected: + explicit type_info(const char *name): m_name(name) { + } + + const char *name() { + return m_name; + } +}; + +} + +#endif diff --git a/deps/ox/src/ox/std/typetraits.hpp b/deps/ox/src/ox/std/typetraits.hpp index 414df464..910fff4e 100644 --- a/deps/ox/src/ox/std/typetraits.hpp +++ b/deps/ox/src/ox/std/typetraits.hpp @@ -60,4 +60,23 @@ struct enable_if { using type = T; }; +template +struct RemoveIndirection { + + private: + template + static constexpr ST decay(ST t) { + return t; + } + + template + static constexpr ST decay(ST *t) { + return decay(*t); + } + + public: + using type = decltype(decay(static_cast(nullptr))); + }; + +} diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index e6b5f0d1..75ed5601 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -197,7 +197,7 @@ void Vector::expandCap(std::size_t cap) noexcept { m_items[i] = oldItems[i]; } for (std::size_t i = itRange; i < m_cap; i++) { - m_items[i] = {}; + m_items[i] = T(); } delete[] oldItems; } diff --git a/deps/ox/src/ox/trace/trace.hpp b/deps/ox/src/ox/trace/trace.hpp index ae1dfaca..0f927324 100644 --- a/deps/ox/src/ox/trace/trace.hpp +++ b/deps/ox/src/ox/trace/trace.hpp @@ -23,7 +23,7 @@ struct TraceMsg { template int ioOp(T *io, ox::trace::TraceMsg *obj) { int32_t err = 0; - io->setFields(5); + io->setTypeInfo("ox::trace::TraceMsg", 5); err |= io->op("file", &obj->file); err |= io->op("line", &obj->line); err |= io->op("time", &obj->time);