diff --git a/deps/ox/ox-docs.md b/deps/ox/ox-docs.md index 7a29d54..9852709 100644 --- a/deps/ox/ox-docs.md +++ b/deps/ox/ox-docs.md @@ -28,10 +28,7 @@ All components have a platform indicator next to them: Ox provides ```ox::Error``` to report errors. ```ox::Error``` is a struct that has overloaded operators to behave like an integer error code, plus some extra fields to enhance debuggability. -If instantiated through the ```OxError(x)``` macro, it will also include the -file and line of the error. -The ```OxError(x)``` macro should only be used for the initial instantiation of -an ```ox::Error```. +```ox::Error```s will also include the file and line of the error. In addition to ```ox::Error``` there is also the template ```ox::Result```. ```ox::Result``` simply wraps the type T value in a struct that also includes @@ -49,7 +46,7 @@ ox::Result foo(int i) noexcept { if (i < 10) { return i + 1; // implicitly calls ox::Result::Result(T) } - return OxError(1); // implicitly calls ox::Result::Result(ox::Error) + return ox::Error(1); // implicitly calls ox::Result::Result(ox::Error) } int caller1() { @@ -181,6 +178,216 @@ variant for creating a non-const value. * ```OX_REQUIRE_M``` - OX_REQUIRE Mutable +### Ox String Types + +Ox has six different major string types. +These types are divided into two categories: store types and view types. + +String stores maintain a copy of the string data, whereas view types only +maintain a reference to the data. +Views should be used where you otherwise might use a const reference to a +string store type. + +Having all of these different string types may sound like an interoperability +nightmare, but taking string view types extensively where applicable makes the +imagined interoperability issues virtually non-existent. + +#### String Store Types + +##### String / BasicString + +```ox::String```, or really ```ox::BasicString```, is Ox's version of +```std::string```. +Like ```std::string```, ```String``` allocates to store the string data. +Also like ```std::string```, ```String``` allows for small string +optimization for strings under 8 bytes. +Unlike ```std::string```, the template that ```String``` is based on, +```BasicString```, takes a parameter that allows adjusting to different size +small string buffers. +```ox::String``` is an alias to ```ox::BasicString<8>```. + +```cpp +// s can hold up to 100 bytes, plus one for a null terminator before allocating +ox::BasicString<100> s; +``` +Also unlike ```std::string```, ```ox::String``` has an explicit C-string conversion +constructor. +This prevents accidental instantiations of ```String```. + +Consider the following: + +```cpp +void fStd(std::string const&); +void fOx(ox::String const&); + +int main() { + // implicit and silent instantiation of std::string, which includes an + // allocation + fStd("123456789"); + // Will fail to compile: + fOx("123456789"); + // But explicit String instantiation will work: + fOx(ox::String{"123456789"}); +} +``` + +##### IString + +```IString```, or "inline string", is like ```BasicString```, but it will cut +off strings that exceed that limit. + +```cpp +ox::IString<5> s; // s can hold up to 5 characters, plus a null terminator +s = "12345"; // valid +s = "123456"; // will compile and run, but will get cut off at '5' +``` + +This is useful for certain string categories that have fixed lengths, like UUID +strings or for numbers. + +Ox makes use of ```IString``` in the following ways: + +```cpp +using UUIDStr = ox::IString<36>; + +// and + +template +[[nodiscard]] +constexpr auto intToStr(Integer v) noexcept { + constexpr auto Cap = [] { + auto out = 0; + switch (sizeof(Integer)) { + case 1: + out = 3; + break; + case 2: + out = 5; + break; + case 4: + out = 10; + break; + case 8: + out = 21; + break; + } + return out + ox::is_signed_v; + }(); + ox::IString out; + std::ignore = out.resize(out.cap()); + ox::CharBuffWriter w{{out.data(), out.cap()}}; + std::ignore = writeItoa(v, w); + std::ignore = out.resize(w.tellp()); + return out; +} +``` + +##### StringParam + +```StringParam``` is a weird type. +Because ```String::String(const char*)``` is explicit, it becomes a pain for +functions to take ```String```s. + +```cpp +struct Type { + ox::String m_s; + explicit Type(ox::String p): m_s(std::move(p)) { + } +}; + +void f() { + ox::String s{"asdf"}; + Type t1{"asdf"}; // invalid - will not compile + Type t2{s}; // invalid - will not compile + Type t3{std::move(s)}; // valid + Type t4{ox::String{"asdf"}}; // valid +} +``` + +```StringParam``` has implicit conversion constructors, and will appropriately +move from r-value ```String```s or create a ```String``` if not passed +ownership of an existing ```String```. +Think of ```StringParam``` as a way to opt-in to implicit instantiation with +strings. + +```StringParam``` can access the string as a view through the ```view()``` +function, and the ```String``` inside can be accessed by moving from the +```StringParam```. + +```cpp +struct Type { + ox::String m_s; + explicit Type(ox::StringParam p): m_s(std::move(p)) { + } +}; + +void f() { + ox::String s{"asdf"}; + Type t1{"asdf"}; // valid + Type t2{s}; // valid + Type t3{std::move(s)}; // valid + Type t4{ox::String{"asdf"}}; // valid +} +``` + +#### String View Types + +##### StringView + +```ox::StringView``` is Ox's version of ```std::string_view```. +```StringView``` contains a pointer to a string, along with its size. + +This should be the normal type taken when a function needs a string that will +exist until it returns. + +##### CStringView + +```CStringView``` is like ```StringView```, but it comes with the promise that +the string ends with a null terminator. +Accordingly, it has a ```c_str()``` function in addition to the ```data()``` +function that ```StringView``` has. + +```CStringView``` should be used when wrapping a C API that only takes C +strings. + +##### StringLiteral + +```StringLiteral``` is a string view type, but it kind of straddles the line +between view and store types. +Creating a ```StringLiteral``` is a promise that you are passing a string +literal into the constructor. +This means you can treat it like a store, that can be safely used as a copy of +the data. +Functions that take ```StringLiteral```s are allowed to assume that the data +will have no lifetime concerns and hold onto it without any need to make a +copy. +It has a consteval constructor to enforce the promise that it is a compile time +string. + +```cpp +void f(ox::StringLiteral const&); + +int main() { + f("123456789"); // valid + f(ox::String{"123456789"}.c_str()); // invalid - will not compile +} +``` + +#### Other Variants + +There are a few convenience aliases as well. + +* StringCR = String const& +* StringViewCR = StringView const& +* CStringViewCR = CStringView const& +* CString = const char* + +String views do not generally need const references, but it does make debugging +easier, as we can skip the constructor call if a string view already exists. + +These kind of aliases probably should not exist for most types, but strings are +fundamental and ease of use is desirable. + ### Logging and Output Ox provides for logging and debug prints via the ```oxTrace```, ```oxDebug```, and ```oxError``` macros. diff --git a/deps/ox/src/ox/claw/read.cpp b/deps/ox/src/ox/claw/read.cpp index 4d2e7f1..c5284be 100644 --- a/deps/ox/src/ox/claw/read.cpp +++ b/deps/ox/src/ox/claw/read.cpp @@ -106,15 +106,14 @@ Result readClaw(TypeStore &ts, BufferView buff) noexcept { { ox::BufferReader br({header.data, header.dataSize}); MetalClawReader reader(br); - ModelHandlerInterface handler(&reader); - OX_RETURN_ERROR(model(&handler, &obj)); + OX_RETURN_ERROR(model(reader.interface(), &obj)); return obj; } case ClawFormat::Organic: { #ifdef OX_USE_STDLIB OrganicClawReader reader({header.data, header.dataSize}); - ModelHandlerInterface handler(&reader); + ModelHandlerInterface handler(reader); OX_RETURN_ERROR(model(&handler, &obj)); return obj; #else diff --git a/deps/ox/src/ox/claw/read.hpp b/deps/ox/src/ox/claw/read.hpp index b6d69d6..e748814 100644 --- a/deps/ox/src/ox/claw/read.hpp +++ b/deps/ox/src/ox/claw/read.hpp @@ -52,8 +52,7 @@ Error readClaw(ox::BufferView buff, T &val) { { ox::BufferReader br({header.data, header.dataSize}); MetalClawReader reader(br); - ModelHandlerInterface handler(&reader); - return model(&handler, &val); + return model(reader.interface(), &val); } case ClawFormat::Organic: { diff --git a/deps/ox/src/ox/claw/test/tests.cpp b/deps/ox/src/ox/claw/test/tests.cpp index fc6661c..e2357f1 100644 --- a/deps/ox/src/ox/claw/test/tests.cpp +++ b/deps/ox/src/ox/claw/test/tests.cpp @@ -135,7 +135,7 @@ static std::map tests = { constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf"); constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3"); OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.size() + 1})); - oxExpect(actual, expected); + ox::expect(actual, expected); return ox::Error{}; } }, diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index 9c69afe..cd5b038 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -74,9 +74,9 @@ const std::map> tests = ox::PathIterator it(path); ox::StringView buff; oxAssert(it.next(buff), "PathIterator::next returned error"); - oxExpect(buff, "usr"); + ox::expect(buff, "usr"); oxAssert(it.next(buff), "PathIterator::next returned error"); - oxExpect(buff, "share"); + ox::expect(buff, "share"); return ox::Error(0); } }, diff --git a/deps/ox/src/ox/mc/intops.hpp b/deps/ox/src/ox/mc/intops.hpp index 5659311..d4092bb 100644 --- a/deps/ox/src/ox/mc/intops.hpp +++ b/deps/ox/src/ox/mc/intops.hpp @@ -139,19 +139,19 @@ static_assert(countBytes(0b0111'1111) == 8); static_assert(countBytes(0b1111'1111) == 9); template -constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noexcept { +constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t &bytesRead) noexcept { uint8_t firstByte = 0; OX_RETURN_ERROR(rdr.read(&firstByte, 1)); OX_RETURN_ERROR(rdr.seekg(-1, ox::ios_base::cur)); const auto bytes = countBytes(firstByte); if (bytes == 9) { - *bytesRead = bytes; + bytesRead = bytes; I out = 0; OX_RETURN_ERROR(rdr.seekg(1, ox::ios_base::cur)); OX_RETURN_ERROR(rdr.read(&out, sizeof(I))); return fromLittleEndian(out); } - *bytesRead = bytes; + bytesRead = bytes; uint64_t decoded = 0; OX_RETURN_ERROR(rdr.read(&decoded, bytes)); decoded >>= bytes; @@ -196,7 +196,7 @@ template Result decodeInteger(McInt m) noexcept { std::size_t bytesRead{}; BufferReader br({reinterpret_cast(m.data.data()), 9}); - return decodeInteger(br, &bytesRead); + return decodeInteger(br, bytesRead); } } diff --git a/deps/ox/src/ox/mc/read.hpp b/deps/ox/src/ox/mc/read.hpp index bbdfb6d..c5dd5ae 100644 --- a/deps/ox/src/ox/mc/read.hpp +++ b/deps/ox/src/ox/mc/read.hpp @@ -32,58 +32,58 @@ class MetalClawReaderTemplate: public ModelHandlerBase m_fieldPresence; - std::size_t m_fields = 0; - std::size_t m_field = 0; - ox::Optional m_unionIdx; + size_t m_fields{}; + size_t m_field{}; + Optional const m_unionIdx{}; Reader &m_reader; public: explicit constexpr MetalClawReaderTemplate( Reader &reader, - ox::Optional const&unionIdx = {}) noexcept; + Optional const &unionIdx = {}) noexcept; constexpr ~MetalClawReaderTemplate() noexcept; - constexpr Error field(const char*, int8_t *val) noexcept; - constexpr Error field(const char*, int16_t *val) noexcept; - constexpr Error field(const char*, int32_t *val) noexcept; - constexpr Error field(const char*, int64_t *val) noexcept; + constexpr Error field(CString, int8_t *val) noexcept; + constexpr Error field(CString, int16_t *val) noexcept; + constexpr Error field(CString, int32_t *val) noexcept; + constexpr Error field(CString, int64_t *val) noexcept; - constexpr Error field(const char*, uint8_t *val) noexcept; - constexpr Error field(const char*, uint16_t *val) noexcept; - constexpr Error field(const char*, uint32_t *val) noexcept; - constexpr Error field(const char*, uint64_t *val) noexcept; + constexpr Error field(CString, uint8_t *val) noexcept; + constexpr Error field(CString, uint16_t *val) noexcept; + constexpr Error field(CString, uint32_t *val) noexcept; + constexpr Error field(CString, uint64_t *val) noexcept; - constexpr Error field(const char*, bool *val) noexcept; + constexpr Error field(CString, bool *val) noexcept; // array handler - constexpr Error field(const char*, auto *val, std::size_t len) noexcept; + constexpr Error field(CString, auto *val, size_t valLen) noexcept; // map handler template - constexpr Error field(const char*, HashMap *val) noexcept; + constexpr Error field(CString, HashMap *val) noexcept; // array handler, with callback to allow handling individual elements template - constexpr Error field(const char*, CB cb) noexcept; + constexpr Error field(CString, CB cb) noexcept; template - constexpr Error field(const char*, T *val) noexcept; + constexpr Error field(CString, T *val) noexcept; template - constexpr Error field(const char*, UnionView val) noexcept; + constexpr Error field(CString, UnionView val) noexcept; - template - constexpr Error field(const char*, BasicString *val) noexcept; + template + constexpr Error field(CString, BasicString *val) noexcept; - template - constexpr Error field(const char*, IString *val) noexcept; + template + constexpr Error field(CString, IString *val) noexcept; - constexpr Error fieldCString(const char*, char *val, std::size_t buffLen) noexcept; + constexpr Error fieldCString(CString, char *val, size_t buffLen) noexcept; - constexpr Error fieldCString(const char*, char **val) noexcept; + constexpr Error fieldCString(CString, char **val) noexcept; - constexpr Error fieldCString(const char*, char **val, std::size_t buffLen) noexcept; + constexpr Error fieldCString(CString, char **val, size_t buffLen) noexcept; /** * Reads an array length from the current location in the buffer. @@ -101,13 +101,13 @@ class MetalClawReaderTemplate: public ModelHandlerBase& = {}, - std::size_t fields = ModelFieldCount_v) noexcept; + size_t fields = ModelFieldCount_v) noexcept; /** * Returns a MetalClawReader to parse a child object. */ [[nodiscard]] - constexpr MetalClawReaderTemplate child(const char *name, ox::Optional unionIdx = {}) noexcept; + constexpr MetalClawReaderTemplate child(const char *name, Optional unionIdx = {}) noexcept; /** * Indicates whether or not the next field to be read is present. @@ -122,20 +122,20 @@ class MetalClawReaderTemplate: public ModelHandlerBase - constexpr Error readInteger(I *val) noexcept; + constexpr Error readInteger(I &val) noexcept; }; template constexpr MetalClawReaderTemplate::MetalClawReaderTemplate( Reader &reader, - ox::Optional const&unionIdx) noexcept: + Optional const &unionIdx) noexcept: m_fieldPresence(reader), m_unionIdx(unionIdx), m_reader(reader) { @@ -149,50 +149,50 @@ constexpr MetalClawReaderTemplate::~MetalClawReaderTemplate() noexcept { } template -constexpr Error MetalClawReaderTemplate::field(const char*, int8_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, int8_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, int16_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, int16_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, int32_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, int32_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, int64_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, int64_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, uint8_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, uint8_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, uint16_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, uint16_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, uint32_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, uint32_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, uint64_t *val) noexcept { - return readInteger(val); +constexpr Error MetalClawReaderTemplate::field(CString, uint64_t *val) noexcept { + return readInteger(*val); } template -constexpr Error MetalClawReaderTemplate::field(const char*, bool *val) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - auto const result = m_fieldPresence.get(static_cast(m_field)); +constexpr Error MetalClawReaderTemplate::field(CString, bool *val) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + auto const result = m_fieldPresence.get(static_cast(m_field)); *val = result.value; OX_RETURN_ERROR(result); } @@ -202,18 +202,19 @@ constexpr Error MetalClawReaderTemplate::field(const char*, bool *val) n // array handler template -constexpr Error MetalClawReaderTemplate::field(const char *name, auto *val, std::size_t valLen) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::field( + const char *name, auto *val, size_t const valLen) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(len, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(len, mc::decodeInteger(m_reader, bytesRead)); // read the list if (valLen >= len) { auto reader = child({}); auto &handler = *reader.interface(); - OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast(len))); - for (std::size_t i = 0; i < len; ++i) { + OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast(len))); + for (size_t i = 0; i < len; ++i) { OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_RETURN_ERROR(handler.field({}, &val[i])); OX_ALLOW_UNSAFE_BUFFERS_END @@ -230,18 +231,18 @@ OX_ALLOW_UNSAFE_BUFFERS_END template template -constexpr Error MetalClawReaderTemplate::field(const char*, HashMap *val) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::field(CString, HashMap *val) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length OX_REQUIRE(g, m_reader.tellg()); - std::size_t bytesRead = 0; - OX_REQUIRE(len, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(len, mc::decodeInteger(m_reader, bytesRead)); OX_RETURN_ERROR(m_reader.seekg(g)); // read the list auto reader = child(""); auto &handler = *reader.interface(); - OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast(len))); + OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast(len))); // this loop body needs to be in a lambda because of the potential alloca call constexpr auto loopBody = [](auto &handler, auto &val) { OX_REQUIRE(keyLen, handler.stringLength(nullptr)); @@ -250,7 +251,7 @@ constexpr Error MetalClawReaderTemplate::field(const char*, HashMap template constexpr Error MetalClawReaderTemplate::field(const char *name, T *val) noexcept { if constexpr(isVector_v) { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (!m_unionIdx.has_value() || static_cast(*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(m_field))) { + if (m_fieldPresence.get(static_cast(m_field))) { OX_REQUIRE(len, arrayLength(name, false)); OX_RETURN_ERROR(ox::resizeVector(*val, len)); return field(name, val->data(), val->size()); @@ -275,9 +276,9 @@ constexpr Error MetalClawReaderTemplate::field(const char *name, T *val) ++m_field; return {}; } else if constexpr(isArray_v) { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (!m_unionIdx.has_value() || static_cast(*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(m_field))) { + if (m_fieldPresence.get(static_cast(m_field))) { OX_REQUIRE(len, arrayLength(name, false)); if (len > val->size()) { return ox::Error(1, "Input array is too long"); @@ -288,8 +289,8 @@ constexpr Error MetalClawReaderTemplate::field(const char *name, T *val) ++m_field; return {}; } else { - if ((!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) && val) { - if (m_fieldPresence.get(static_cast(m_field))) { + if ((!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) && val) { + if (m_fieldPresence.get(static_cast(m_field))) { auto reader = child(""); OX_RETURN_ERROR(model(reader.interface(), val)); } @@ -301,9 +302,9 @@ constexpr Error MetalClawReaderTemplate::field(const char *name, T *val) template template -constexpr Error MetalClawReaderTemplate::field(const char*, UnionView val) noexcept { - if ((!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) && val.get()) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::field(CString, UnionView val) noexcept { + if ((!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) && val.get()) { + if (m_fieldPresence.get(static_cast(m_field))) { auto reader = child("", ox::Optional(ox::in_place, val.idx())); OX_RETURN_ERROR(model(reader.interface(), val.get())); } @@ -313,13 +314,13 @@ constexpr Error MetalClawReaderTemplate::field(const char*, UnionView -template -constexpr Error MetalClawReaderTemplate::field(const char*, BasicString *val) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +template +constexpr Error MetalClawReaderTemplate::field(CString, BasicString *val) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(size, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(size, mc::decodeInteger(m_reader, bytesRead)); const auto cap = size; *val = BasicString(cap); auto data = val->data(); @@ -334,13 +335,13 @@ constexpr Error MetalClawReaderTemplate::field(const char*, BasicString< } template -template -constexpr Error MetalClawReaderTemplate::field(const char*, IString *val) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +template +constexpr Error MetalClawReaderTemplate::field(CString, IString *val) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(size, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(size, mc::decodeInteger(m_reader, bytesRead)); *val = IString(); OX_RETURN_ERROR(val->resize(size)); auto const data = val->data(); @@ -355,11 +356,12 @@ constexpr Error MetalClawReaderTemplate::field(const char*, IString * } template -constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char *val, std::size_t buffLen) noexcept { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::fieldCString( + CString, char *val, size_t const buffLen) noexcept { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(size, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(size, mc::decodeInteger(m_reader, bytesRead)); if (size > buffLen) { return ox::Error(McOutputBuffEnded); } @@ -374,11 +376,11 @@ constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char } template -constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char **val) noexcept { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::fieldCString(CString, char **val) noexcept { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(size, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(size, mc::decodeInteger(m_reader, bytesRead)); // re-allocate in case too small safeDelete(*val); *val = new char[size + 1]; @@ -392,12 +394,12 @@ constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char } template -constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char **val, std::size_t buffLen) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::fieldCString(CString, char **val, size_t buffLen) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(size, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(size, mc::decodeInteger(m_reader, bytesRead)); // re-allocate if too small if (buffLen < size + 1) { safeDelete(*val); @@ -420,13 +422,13 @@ constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char } template -constexpr Result MetalClawReaderTemplate::arrayLength(const char*, bool pass) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Result MetalClawReaderTemplate::arrayLength(CString, bool const pass) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; + size_t bytesRead = 0; OX_REQUIRE(g, m_reader.tellg()); - OX_REQUIRE(out, mc::decodeInteger(m_reader, &bytesRead)); + OX_REQUIRE(out, mc::decodeInteger(m_reader, bytesRead)); if (!pass) { OX_RETURN_ERROR(m_reader.seekg(g)); } @@ -437,12 +439,12 @@ constexpr Result MetalClawReaderTemplate::arrayLength(const } template -constexpr Result MetalClawReaderTemplate::stringLength(const char*) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Result MetalClawReaderTemplate::stringLength(CString) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - auto len = mc::decodeInteger(m_reader, &bytesRead); + size_t bytesRead = 0; + auto len = mc::decodeInteger(m_reader, bytesRead); OX_RETURN_ERROR(m_reader.seekg(-static_cast(bytesRead), ox::ios_base::cur)); return len; } @@ -452,15 +454,15 @@ constexpr Result MetalClawReaderTemplate::stringLength(con template template -constexpr Error MetalClawReaderTemplate::readInteger(I *val) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { - std::size_t bytesRead = 0; - auto const result = mc::decodeInteger(m_reader, &bytesRead); +constexpr Error MetalClawReaderTemplate::readInteger(I &val) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { + size_t bytesRead = 0; + auto const result = mc::decodeInteger(m_reader, bytesRead); OX_RETURN_ERROR(result); - *val = result.value; + val = result.value; } else { - *val = 0; + val = 0; } } ++m_field; @@ -469,17 +471,17 @@ constexpr Error MetalClawReaderTemplate::readInteger(I *val) noexcept { template template -constexpr Error MetalClawReaderTemplate::field(const char*, CB cb) noexcept { - if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { - if (m_fieldPresence.get(static_cast(m_field))) { +constexpr Error MetalClawReaderTemplate::field(CString, CB cb) noexcept { + if (!m_unionIdx.has_value() || static_cast(*m_unionIdx) == m_field) { + if (m_fieldPresence.get(static_cast(m_field))) { // read the length - std::size_t bytesRead = 0; - OX_REQUIRE(len, mc::decodeInteger(m_reader, &bytesRead)); + size_t bytesRead = 0; + OX_REQUIRE(len, mc::decodeInteger(m_reader, bytesRead)); // read the list auto reader = child(""); auto &handler = *reader.interface(); - OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast(len))); - for (std::size_t i = 0; i < len; ++i) { + OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast(len))); + for (size_t i = 0; i < len; ++i) { T val; OX_RETURN_ERROR(handler.field("", &val)); OX_RETURN_ERROR(cb(i, &val)); @@ -493,7 +495,7 @@ constexpr Error MetalClawReaderTemplate::field(const char*, CB cb) noexc template template constexpr ox::Error MetalClawReaderTemplate::setTypeInfo( - const char*, int, const Vector&, std::size_t fields) noexcept { + CString, int, const Vector&, size_t const fields) noexcept { m_fields = fields; // Warning: narrow-conv return m_reader.seekg( @@ -503,24 +505,24 @@ constexpr ox::Error MetalClawReaderTemplate::setTypeInfo( template constexpr MetalClawReaderTemplate MetalClawReaderTemplate::child( - const char*, - ox::Optional unionIdx) noexcept { + CString, + Optional const unionIdx) noexcept { return MetalClawReaderTemplate(m_reader, unionIdx); } template -constexpr bool MetalClawReaderTemplate::fieldPresent(const char*) const noexcept { - return m_fieldPresence.get(static_cast(m_field)).value; +constexpr bool MetalClawReaderTemplate::fieldPresent(CString) const noexcept { + return m_fieldPresence.get(static_cast(m_field)).value; } template -constexpr bool MetalClawReaderTemplate::fieldPresent(int fieldNo) const noexcept { - return m_fieldPresence.get(static_cast(fieldNo)).value; +constexpr bool MetalClawReaderTemplate::fieldPresent(int const fieldNo) const noexcept { + return m_fieldPresence.get(static_cast(fieldNo)).value; } template [[nodiscard]] -constexpr int MetalClawReaderTemplate::whichFieldPresent(const char*, const ModelUnion &u) const noexcept { +constexpr int MetalClawReaderTemplate::whichFieldPresent(CString, ModelUnion const &u) const noexcept { FieldBitmapReader p(m_reader); for (auto i = 0u; i < u.fieldCount(); ++i) { if (p.get(i)) { @@ -538,11 +540,10 @@ constexpr void MetalClawReaderTemplate::nextField() noexcept { using MetalClawReader = MetalClawReaderTemplate; template -Error readMC(ox::BufferView buff, T &val) noexcept { +Error readMC(ox::BufferView const buff, T &val) noexcept { BufferReader br(buff); MetalClawReader reader(br); - ModelHandlerInterface handler(&reader); - return model(&handler, &val); + return model(reader.interface(), &val); } template diff --git a/deps/ox/src/ox/mc/test/tests.cpp b/deps/ox/src/ox/mc/test/tests.cpp index e6929c6..0f975a9 100644 --- a/deps/ox/src/ox/mc/test/tests.cpp +++ b/deps/ox/src/ox/mc/test/tests.cpp @@ -157,7 +157,7 @@ std::map tests = { oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch"); oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch"); oxAssert(testIn.String == testOut.String, "String value mismatch"); - oxExpect(testIn.IString, testOut.IString); + ox::expect(testIn.IString, testOut.IString); oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch"); oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch"); oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch"); diff --git a/deps/ox/src/ox/mc/write.hpp b/deps/ox/src/ox/mc/write.hpp index 4c836ff..0e03b7f 100644 --- a/deps/ox/src/ox/mc/write.hpp +++ b/deps/ox/src/ox/mc/write.hpp @@ -268,7 +268,7 @@ constexpr Error MetalClawWriter::field(const char*, const T *val) noexce if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { auto const writeIdx = m_writer.tellp(); MetalClawWriter writer(m_writer); - ModelHandlerInterface> handler{&writer}; + ModelHandlerInterface> handler{writer}; OX_RETURN_ERROR(model(&handler, val)); OX_RETURN_ERROR(writer.finalize()); fieldSet = writeIdx != m_writer.tellp(); @@ -286,7 +286,7 @@ constexpr Error MetalClawWriter::field(const char*, UnionView if (val.get() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { auto const writeIdx = m_writer.tellp(); MetalClawWriter writer(m_writer, ox::Optional(ox::in_place, val.idx())); - ModelHandlerInterface handler{&writer}; + ModelHandlerInterface handler{writer}; OX_RETURN_ERROR(model(&handler, val.get())); OX_RETURN_ERROR(writer.finalize()); fieldSet = writeIdx != m_writer.tellp(); @@ -306,7 +306,7 @@ constexpr Error MetalClawWriter::field(const char*, const T *val, std::s OX_RETURN_ERROR(m_writer.write(reinterpret_cast(arrLen.data.data()), arrLen.length)); auto const writeIdx = m_writer.tellp(); MetalClawWriter writer(m_writer); - ModelHandlerInterface handler{&writer}; + ModelHandlerInterface handler{writer}; OX_RETURN_ERROR(handler.template setTypeInfo("List", 0, {}, static_cast(len))); // write the array for (std::size_t i = 0; i < len; ++i) { @@ -334,7 +334,7 @@ constexpr Error MetalClawWriter::field(const char*, const HashMap(arrLen.data.data()), arrLen.length)); // write map MetalClawWriter writer(m_writer); - ModelHandlerInterface handler{&writer}; + ModelHandlerInterface handler{writer}; // double len for both key and value OX_RETURN_ERROR(handler.setTypeInfo("Map", 0, {}, len * 2)); // this loop body needs to be in a lambda because of the potential alloca call @@ -387,7 +387,7 @@ ox::Error MetalClawWriter::finalize() noexcept { Result writeMC(Writer_c auto &writer, const auto &val) noexcept { MetalClawWriter mcWriter(writer); - ModelHandlerInterface handler{&mcWriter}; + ModelHandlerInterface handler{mcWriter}; OX_RETURN_ERROR(model(&handler, &val)); OX_RETURN_ERROR(mcWriter.finalize()); return {}; diff --git a/deps/ox/src/ox/model/descwrite.hpp b/deps/ox/src/ox/model/descwrite.hpp index c07d494..1bd5c09 100644 --- a/deps/ox/src/ox/model/descwrite.hpp +++ b/deps/ox/src/ox/model/descwrite.hpp @@ -187,7 +187,7 @@ constexpr ox::Error TypeDescWriter::setTypeInfo( PrimitiveType pt; if constexpr(is_union_v) { pt = PrimitiveType::Union; - } else if constexpr(isBasicString_v || isBString_v) { + } else if constexpr(isBasicString_v || isIString_v) { pt = PrimitiveType::String; } else { pt = PrimitiveType::Struct; @@ -357,7 +357,7 @@ constexpr const DescriptorType *TypeDescWriter::type(const char*) const noexcept template constexpr const DescriptorType *TypeDescWriter::type(const IString*) const noexcept { constexpr auto PT = PrimitiveType::String; - return getType(types::BString, 0, PT, 0); + return getType(types::IString, 0, PT, 0); } constexpr const DescriptorType *TypeDescWriter::getType(StringViewCR tn, int typeVersion, PrimitiveType pt, int b, @@ -380,7 +380,7 @@ constexpr const DescriptorType *TypeDescWriter::getType(StringViewCR tn, int typ template constexpr Result buildTypeDef(TypeStore &typeStore) noexcept { TypeDescWriter writer(&typeStore); - ModelHandlerInterface handler(&writer); + ModelHandlerInterface handler(writer); if (std::is_constant_evaluated()) { std::allocator a; T *t = a.allocate(1); @@ -396,7 +396,7 @@ constexpr Result buildTypeDef(TypeStore &typeStore) noexcept { template constexpr Result buildTypeDef(TypeStore &typeStore, T &val) noexcept { TypeDescWriter writer(&typeStore); - ModelHandlerInterface handler(&writer); + ModelHandlerInterface handler(writer); OX_RETURN_ERROR(model(&handler, &val)); return writer.definition(); } diff --git a/deps/ox/src/ox/model/modelhandleradaptor.hpp b/deps/ox/src/ox/model/modelhandleradaptor.hpp index 28b6785..4589f5b 100644 --- a/deps/ox/src/ox/model/modelhandleradaptor.hpp +++ b/deps/ox/src/ox/model/modelhandleradaptor.hpp @@ -17,10 +17,10 @@ namespace ox { template class ModelHandlerInterface { private: - Handler *m_handler = nullptr; + Handler &m_handler; public: - constexpr explicit ModelHandlerInterface(Handler *handler) noexcept: m_handler(handler) { + constexpr explicit ModelHandlerInterface(Handler &handler) noexcept: m_handler(handler) { } template @@ -28,7 +28,7 @@ class ModelHandlerInterface { const char* name = T::TypeName, int version = T::TypeVersion, const Vector& typeParams = {}) noexcept { - return m_handler->template setTypeInfo(name, version, typeParams, ModelFieldCount_v); + return m_handler.template setTypeInfo(name, version, typeParams, ModelFieldCount_v); } template @@ -37,31 +37,31 @@ class ModelHandlerInterface { int version, const Vector& typeParams, std::size_t fields) noexcept { - return m_handler->template setTypeInfo(name, version, typeParams, fields); + return m_handler.template setTypeInfo(name, version, typeParams, fields); } template constexpr Error fieldCString(const char *name, char val[len]) noexcept { - return m_handler->fieldCString(name, &val[0], len); + return m_handler.fieldCString(name, &val[0], len); } template constexpr Error fieldCString(const char *name, const char val[len]) noexcept requires(opType_v != OpType::Read) { if constexpr(opType_v != OpType::Read) { - return m_handler->fieldCString(name, &val[0], len); + return m_handler.fieldCString(name, &val[0], len); } else { return {}; } } constexpr Error fieldCString(const char *name, char **val) noexcept { - return m_handler->fieldCString(name, val); + return m_handler.fieldCString(name, val); } constexpr Error fieldCString(const char *name, const char *const*val) noexcept requires(opType_v != OpType::Read) { // this check looks pointless, but it's to address a Clang bug if constexpr(opType_v != OpType::Read) { - return m_handler->fieldCString(name, val); + return m_handler.fieldCString(name, val); } else { return {}; } @@ -70,27 +70,27 @@ class ModelHandlerInterface { constexpr Error fieldCString(const char *name, const char **val) noexcept requires(opType_v != OpType::Read) { // this check looks pointless, but it's to address a Clang bug if constexpr(opType_v != OpType::Read) { - return m_handler->fieldCString(name, val); + return m_handler.fieldCString(name, val); } else { return {}; } } constexpr Error fieldCString(const char *name, char **val, std::size_t buffLen) noexcept { - return m_handler->fieldCString(name, val, buffLen); + return m_handler.fieldCString(name, val, buffLen); } constexpr Error fieldCString(const char *name, const char **val, std::size_t buffLen) noexcept requires(opType_v != OpType::Read) { // this check looks pointless, but it's to address a Clang bug if constexpr(opType_v != OpType::Read) { - return m_handler->fieldCString(name, val, buffLen); + return m_handler.fieldCString(name, val, buffLen); } else { return {}; } } constexpr Error fieldCString(const char *name, char *val, std::size_t buffLen) noexcept { - return m_handler->fieldCString(name, val, buffLen); + return m_handler.fieldCString(name, val, buffLen); } constexpr Error fieldModelValue(const char *name, CommonPtrWith auto *v) noexcept { @@ -98,51 +98,51 @@ class ModelHandlerInterface { case ModelValue::Type::Undefined: break; case ModelValue::Type::Bool: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::UnsignedInteger8: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::UnsignedInteger16: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::UnsignedInteger32: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::UnsignedInteger64: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::SignedInteger8: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::SignedInteger16: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::SignedInteger32: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::SignedInteger64: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::String: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::Object: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::Union: { auto &u = v->template get(); if constexpr(opType_v == OpType::Read) { - u.setActiveField(m_handler->whichFieldPresent(name, u)); - return m_handler->field(name, UnionView(&u, u.unionIdx())); + u.setActiveField(m_handler.whichFieldPresent(name, u)); + return m_handler.field(name, UnionView(&u, u.unionIdx())); } else { - return m_handler->field(name, UnionView(&u, u.unionIdx())); + return m_handler.field(name, UnionView(&u, u.unionIdx())); } } case ModelValue::Type::Vector: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); case ModelValue::Type::InlineArray: - return m_handler->field(name, &v->template get()); + return m_handler.field(name, &v->template get()); } oxErrf("invalid type: {}: {}\n", name, static_cast(v->type())); - oxPanic(ox::Error(1), "invalid type"); + ox::panic("invalid type"); return ox::Error(1, "invalid type"); } // array handler, with callback to allow handling individual elements template constexpr Error field(const char *name, Callback cb) noexcept { - return m_handler->template field(name, cb); + return m_handler.template field(name, cb); } template @@ -150,7 +150,7 @@ class ModelHandlerInterface { if constexpr(ox::is_same_v) { return fieldModelValue(name, v); } else { - return m_handler->field(name, v); + return m_handler.field(name, v); } } @@ -159,26 +159,27 @@ class ModelHandlerInterface { if constexpr(ox::is_same_v) { return fieldModelValue(name, v); } else { - return m_handler->field(name, v); + return m_handler.field(name, v); } } template constexpr Error field(const char *name, UnionView val) noexcept { - return m_handler->field(name, val); + return m_handler.field(name, val); } constexpr Error field(const char *name, auto *val, std::size_t len) noexcept { - return m_handler->field(name, val, len); + return m_handler.field(name, val, len); } /** * Reads an array length from the current location in the buffer. + * @param name * @param pass indicates that the parsing should iterate past the array length */ [[nodiscard]] constexpr auto arrayLength(const char *name, bool pass = true) noexcept { - return m_handler->arrayLength(name, pass); + return m_handler.arrayLength(name, pass); } /** @@ -186,7 +187,7 @@ class ModelHandlerInterface { */ [[nodiscard]] constexpr auto stringLength(const char *name) noexcept { - return m_handler->stringLength(name); + return m_handler.stringLength(name); } [[nodiscard]] @@ -200,20 +201,17 @@ class ModelHandlerInterface { } }; -template +template class ModelHandlerBase { private: - ModelHandlerInterface m_interface; + ModelHandlerInterface m_interface{*static_cast(this)}; public: - constexpr ModelHandlerBase() noexcept: m_interface(static_cast(this)) {} - constexpr ModelHandlerBase(const ModelHandlerBase&) noexcept: m_interface(static_cast(this)) {} - constexpr ModelHandlerBase(ModelHandlerBase&&) noexcept: m_interface(static_cast(this)) {} [[nodiscard]] constexpr auto interface() noexcept { return &m_interface; } [[nodiscard]] - static constexpr ox::OpType opType() noexcept { + static constexpr OpType opType() noexcept { return opType_v; } }; diff --git a/deps/ox/src/ox/model/modelvalue.cpp b/deps/ox/src/ox/model/modelvalue.cpp index f735717..97829e5 100644 --- a/deps/ox/src/ox/model/modelvalue.cpp +++ b/deps/ox/src/ox/model/modelvalue.cpp @@ -20,4 +20,7 @@ static_assert([]() -> ox::Error { return {}; }() == ox::Error{}); +// a dummy function to prevent linker errors in a library that has no other symbols +void modelDummyFunc() noexcept {} + } diff --git a/deps/ox/src/ox/model/modelvalue.hpp b/deps/ox/src/ox/model/modelvalue.hpp index 28585c9..251ac40 100644 --- a/deps/ox/src/ox/model/modelvalue.hpp +++ b/deps/ox/src/ox/model/modelvalue.hpp @@ -100,7 +100,7 @@ class ModelValue { return Type::Union; } else if constexpr(is_same_v) { return Type::Object; - } else if constexpr(isBasicString_v || isBString_v) { + } else if constexpr(isBasicString_v || isIString_v) { return Type::String; } else if constexpr(is_same_v) { return Type::Vector; @@ -168,7 +168,7 @@ class ModelValue { constexpr const auto &get() const noexcept { constexpr auto type = getType(); if (m_type != type) [[unlikely]] { - oxPanic(ox::Error(1), "invalid cast"); + ox::panic("invalid cast"); } return getValue(*this); } @@ -178,7 +178,7 @@ class ModelValue { constexpr auto &get() noexcept { constexpr auto type = getType(); if (m_type != type) [[unlikely]] { - oxPanic(ox::Error(1), "invalid cast"); + ox::panic("invalid cast"); } return getValue(*this); } @@ -187,7 +187,7 @@ class ModelValue { constexpr Type type() const noexcept; constexpr Error setType( - DescriptorType const*type, + DescriptorType const *type, SubscriptStack const& = {}, int subscriptLevels = 0) noexcept; @@ -275,7 +275,7 @@ class ModelValueArray { } constexpr Error setType( - DescriptorType const*type, + DescriptorType const *type, SubscriptStack subscriptStack, int subscriptLevels) noexcept { oxAssert(subscriptLevels <= static_cast(subscriptStack.size()), "subscript level mismatch"); @@ -418,7 +418,7 @@ class ModelValueVector { } constexpr Error setType( - DescriptorType const*type, + DescriptorType const *type, SubscriptStack subscriptStack, int subscriptLevels) noexcept { oxAssert(subscriptLevels <= static_cast(subscriptStack.size()), "subscript level mismatch"); @@ -821,7 +821,7 @@ class ModelUnion { template [[nodiscard]] -constexpr std::size_t sizeOf(ModelValueArray const*v) noexcept { +constexpr std::size_t sizeOf(ModelValueArray const *v) noexcept { return sizeOf(&(*v)[0]) * v->size(); } @@ -1098,7 +1098,7 @@ constexpr Error ModelValue::setType( } else if (type->typeName == types::Bool) { m_type = Type::Bool; } else if (type->typeName == types::BasicString || - type->typeName == types::BString || + type->typeName == types::IString || type->typeName == types::String) { m_type = Type::String; m_data.str = new String; diff --git a/deps/ox/src/ox/model/types.hpp b/deps/ox/src/ox/model/types.hpp index fd8927c..2256930 100644 --- a/deps/ox/src/ox/model/types.hpp +++ b/deps/ox/src/ox/model/types.hpp @@ -31,18 +31,18 @@ namespace ox { namespace types { -constexpr StringView BasicString = "net.drinkingtea.ox.BasicString"; -constexpr StringView BString = "net.drinkingtea.ox.BString"; -constexpr StringView String = "B.string"; -constexpr StringView Bool = "B.bool"; -constexpr StringView Uint8 = "B.uint8"; -constexpr StringView Uint16 = "B.uint16"; -constexpr StringView Uint32 = "B.uint32"; -constexpr StringView Uint64 = "B.uint64"; -constexpr StringView Int8 = "B.int8"; -constexpr StringView Int16 = "B.int16"; -constexpr StringView Int32 = "B.int32"; -constexpr StringView Int64 = "B.int64"; +constexpr StringLiteral BasicString = "net.drinkingtea.ox.BasicString"; +constexpr StringLiteral IString = "net.drinkingtea.ox.IString"; +constexpr StringLiteral String = "B.string"; +constexpr StringLiteral Bool = "B.bool"; +constexpr StringLiteral Uint8 = "B.uint8"; +constexpr StringLiteral Uint16 = "B.uint16"; +constexpr StringLiteral Uint32 = "B.uint32"; +constexpr StringLiteral Uint64 = "B.uint64"; +constexpr StringLiteral Int8 = "B.int8"; +constexpr StringLiteral Int16 = "B.int16"; +constexpr StringLiteral Int32 = "B.int32"; +constexpr StringLiteral Int64 = "B.int64"; } template @@ -63,17 +63,17 @@ static_assert(isBasicString_v>); static_assert(isBasicString_v); template -consteval bool isBString(const T*) noexcept { +consteval bool isIString(const T*) noexcept { return false; } template -consteval bool isBString(const BasicString*) noexcept { +consteval bool isIString(const BasicString*) noexcept { return true; } template -constexpr bool isBString_v = isBasicString(static_cast(nullptr)); +constexpr bool isIString_v = isIString(static_cast(nullptr)); static_assert(isBasicString_v>); static_assert(isBasicString_v>); @@ -169,12 +169,12 @@ constexpr bool isSmartPtr_v<::std::unique_ptr> = true; #endif -template +template requires(force || is_union_v) class UnionView { protected: int m_idx = -1; - typename enable_if || force, Union>::type *m_union = nullptr; + Union *m_union = nullptr; public: constexpr UnionView(Union *u, int idx) noexcept: m_idx(idx), m_union(u) { diff --git a/deps/ox/src/ox/oc/read.cpp b/deps/ox/src/ox/oc/read.cpp index 38eb1a7..d20749f 100644 --- a/deps/ox/src/ox/oc/read.cpp +++ b/deps/ox/src/ox/oc/read.cpp @@ -13,31 +13,31 @@ namespace ox { -OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) { +OrganicClawReader::OrganicClawReader(const uint8_t *buff, size_t const buffSize) { auto json = reinterpret_cast(buff); auto jsonLen = ox::strnlen_s(json, buffSize); Json::CharReaderBuilder parserBuilder; auto parser = std::unique_ptr(parserBuilder.newCharReader()); if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) { - throw ox::Exception(1, "Could not parse JSON"); + throw Exception(1, "Could not parse JSON"); } } -OrganicClawReader::OrganicClawReader(const char *json, std::size_t jsonLen) { +OrganicClawReader::OrganicClawReader(CString const json, size_t const jsonLen) { Json::CharReaderBuilder parserBuilder; auto parser = std::unique_ptr(parserBuilder.newCharReader()); if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) { - throw ox::Exception(1, "Could not parse JSON"); + throw Exception(1, "Could not parse JSON"); } } -OrganicClawReader::OrganicClawReader(Json::Value json, int unionIdx) noexcept: +OrganicClawReader::OrganicClawReader(Json::Value json, int const unionIdx) noexcept: m_json(std::move(json)), m_unionIdx(unionIdx) { } -Error OrganicClawReader::field(const char *key, bool *val) noexcept { - ox::Error err{}; +Error OrganicClawReader::field(CString const key, bool *val) noexcept { + Error err{}; if (targetValid()) { const auto &jv = value(key); if (jv.empty()) { @@ -45,16 +45,16 @@ Error OrganicClawReader::field(const char *key, bool *val) noexcept { } else if (jv.isBool()) { *val = jv.asBool(); } else { - err = ox::Error(1, "Type mismatch"); + err = Error(1, "Type mismatch"); } } ++m_fieldIt; return err; } -Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept { - ox::Error err{}; - const char *begin = nullptr, *end = nullptr; +Error OrganicClawReader::fieldCString(CString const key, char *val, size_t const buffLen) noexcept { + Error err{}; + CString begin = nullptr, end = nullptr; const auto &jv = value(key); if (targetValid()) { if (jv.empty()) { @@ -64,25 +64,25 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu } } else if (jv.isString()) { jv.getString(&begin, &end); - const auto strSize = static_cast(end - begin); + const auto strSize = static_cast(end - begin); auto data = val; if (strSize >= buffLen) { - err = ox::Error(2, "String size exceeds capacity of destination"); + err = Error(2, "String size exceeds capacity of destination"); } else { - ox::memcpy(data, begin, static_cast(strSize)); + memcpy(data, begin, static_cast(strSize)); data[strSize] = 0; } } else { - err = ox::Error(1, "Type mismatch"); + err = Error(1, "Type mismatch"); } } ++m_fieldIt; return err; } -Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept { - ox::Error err{}; - const char *begin = nullptr, *end = nullptr; +Error OrganicClawReader::fieldCString(CString const key, char **val) noexcept { + Error err{}; + CString begin = nullptr, end = nullptr; const auto &jv = value(key); auto &data = *val; if (targetValid()) { @@ -92,22 +92,22 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept { } } else if (jv.isString()) { jv.getString(&begin, &end); - const auto strSize = static_cast(end - begin); + const auto strSize = static_cast(end - begin); safeDelete(*val); *val = new char[strSize + 1]; - ox::memcpy(data, begin, static_cast(strSize)); + memcpy(data, begin, static_cast(strSize)); data[strSize] = 0; } else { - err = ox::Error(1, "Type mismatch"); + err = Error(1, "Type mismatch"); } } ++m_fieldIt; return err; } -Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t buffLen) noexcept { - ox::Error err{}; - const char *begin = nullptr, *end = nullptr; +Error OrganicClawReader::fieldCString(CString const key, char **val, size_t const buffLen) noexcept { + Error err{}; + CString begin = nullptr, end = nullptr; const auto &jv = value(key); if (targetValid()) { if (jv.empty()) { @@ -117,29 +117,29 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b } } else if (jv.isString()) { jv.getString(&begin, &end); - const auto strSize = static_cast(end - begin); + const auto strSize = static_cast(end - begin); auto data = val; if (strSize >= buffLen) { safeDelete(*val); *val = new char[strSize + 1]; } - ox::memcpy(data, begin, static_cast(strSize)); + memcpy(data, begin, static_cast(strSize)); data[strSize] = nullptr; } else { - err = ox::Error(1, "Type mismatch"); + err = Error(1, "Type mismatch"); } } ++m_fieldIt; return err; } -Error OrganicClawReader::field(const char *key, UUID *val) noexcept { +Error OrganicClawReader::field(CString const key, UUID *val) noexcept { UUIDStr str; OX_RETURN_ERROR(field(key, &str)); return UUID::fromString(str).moveTo(*val); } -Result OrganicClawReader::arrayLength(const char *key, bool) noexcept { +Result OrganicClawReader::arrayLength(CString const key, bool) noexcept { const auto &jv = value(key); if (jv.empty()) { return 0; @@ -147,32 +147,32 @@ Result OrganicClawReader::arrayLength(const char *key, bool) noexce if (jv.isArray()) { return jv.size(); } - return ox::Error(1, "Type mismatch"); + return Error(1, "Type mismatch"); } [[nodiscard]] -std::size_t OrganicClawReader::stringLength(const char *key) noexcept { - const char *begin = nullptr, *end = nullptr; +size_t OrganicClawReader::stringLength(CString const key) noexcept { + CString begin = nullptr, end = nullptr; const auto &jv = value(key); if (jv.empty()) { return 0; } if (jv.isString()) { jv.getString(&begin, &end); - return static_cast(end - begin); + return static_cast(end - begin); } - return ox::Error(1, "Type mismatch"); + return Error(1, "Type mismatch"); } -OrganicClawReader OrganicClawReader::child(const char *key, int unionIdx) noexcept { +OrganicClawReader OrganicClawReader::child(CString const key, int const unionIdx) noexcept { return OrganicClawReader(value(key), unionIdx); } -bool OrganicClawReader::fieldPresent(const char *key) noexcept { +bool OrganicClawReader::fieldPresent(CString const key) noexcept { return !m_json[key].empty(); } -int OrganicClawReader::whichFieldPresent(const char *name, const ModelUnion &u) const noexcept { +int OrganicClawReader::whichFieldPresent(CString const name, ModelUnion const &u) const noexcept { const auto &obj = m_json[name]; if (!obj.isObject()) { return -1; @@ -184,7 +184,7 @@ int OrganicClawReader::whichFieldPresent(const char *name, const ModelUnion &u) return u.getKeyIdx(keys.front().c_str()); } -Json::Value &OrganicClawReader::value(const char *key) noexcept { +Json::Value &OrganicClawReader::value(CString const key) noexcept { if (m_json.isArray()) { return m_json[m_fieldIt]; } else { diff --git a/deps/ox/src/ox/oc/read.hpp b/deps/ox/src/ox/oc/read.hpp index cb7c9af..973bcda 100644 --- a/deps/ox/src/ox/oc/read.hpp +++ b/deps/ox/src/ox/oc/read.hpp @@ -34,75 +34,76 @@ class OrganicClawReader { private: Json::Value m_json; Json::ArrayIndex m_fieldIt = 0; - int m_unionIdx = -1; + int const m_unionIdx = -1; public: OrganicClawReader() noexcept = default; - OrganicClawReader(const uint8_t *buff, std::size_t buffSize); + OrganicClawReader(uint8_t const *buff, size_t buffSize); - OrganicClawReader(const char *json, std::size_t buffSize); + OrganicClawReader(CString json, size_t buffSize); explicit OrganicClawReader(Json::Value json, int unionIdx = -1) noexcept; - Error field(const char *key, bool *val) noexcept; + Error field(CString key, bool *val) noexcept; // array handler template - Error field(const char *key, T *val, std::size_t len) noexcept; + Error field(CString key, T *val, size_t len) noexcept; template - Error field(const char*, HashMap *val) noexcept; + Error field(CString, HashMap *val) noexcept; template - Error field(const char *key, T *val) noexcept; + Error field(CString key, T *val) noexcept; template - Error field(const char *key, UnionView val) noexcept; + Error field(CString key, UnionView val) noexcept; - template - Error field(const char *key, BasicString *val) noexcept; + template + Error field(CString key, BasicString *val) noexcept; - template - Error field(const char *key, IString *val) noexcept; + template + Error field(CString key, IString *val) noexcept; - Error fieldCString(const char *key, char *val, std::size_t buffLen) noexcept; + Error fieldCString(CString key, char *val, size_t buffLen) noexcept; - Error fieldCString(const char *key, char **val) noexcept; + Error fieldCString(CString key, char **val) noexcept; - Error fieldCString(const char *key, char **val, std::size_t buffLen) noexcept; + Error fieldCString(CString key, char **val, size_t buffLen) noexcept; - Error field(const char *key, UUID *val) noexcept; + Error field(CString key, UUID *val) noexcept; /** * Reads an array length from the current location in the buffer. + * @param key * @param pass indicates that the parsing should iterate past the array length */ - Result arrayLength(const char *key, bool pass = true) noexcept; + Result arrayLength(CString key, bool pass = true) noexcept; /** * Reads an string length from the current location in the buffer. */ [[nodiscard]] - std::size_t stringLength(const char *name) noexcept; + size_t stringLength(CString key) noexcept; template - constexpr ox::Error setTypeInfo() noexcept { + constexpr Error setTypeInfo() noexcept { return {}; } template - constexpr ox::Error setTypeInfo(const char*) noexcept { + constexpr Error setTypeInfo(CString) noexcept { return {}; } template - constexpr ox::Error setTypeInfo(const char*, int, const Vector& = {}) noexcept { + constexpr Error setTypeInfo(CString, int, const Vector& = {}) noexcept { return {}; } template - constexpr ox::Error setTypeInfo(const char*, int, const Vector& = {}, std::size_t = {}) noexcept { + constexpr Error setTypeInfo(CString, int, const Vector& = {}, size_t = {}) noexcept { return {}; } @@ -110,16 +111,16 @@ class OrganicClawReader { * Returns a OrganicClawReader to parse a child object. */ [[nodiscard]] - OrganicClawReader child(const char *key, int unionIdx = -1) noexcept; + OrganicClawReader child(CString key, int unionIdx = -1) noexcept; // compatibility stub constexpr void nextField() noexcept {} [[nodiscard]] - bool fieldPresent(const char *key) noexcept; + bool fieldPresent(CString key) noexcept; [[nodiscard]] - int whichFieldPresent(const char *name, const ModelUnion &u) const noexcept; + int whichFieldPresent(CString name, const ModelUnion &u) const noexcept; [[nodiscard]] static constexpr auto opType() noexcept { @@ -128,7 +129,7 @@ class OrganicClawReader { private: [[nodiscard]] - Json::Value &value(const char *key) noexcept; + Json::Value &value(CString key) noexcept; [[nodiscard]] bool targetValid() const noexcept; @@ -136,102 +137,102 @@ class OrganicClawReader { }; template -Error OrganicClawReader::field(const char *key, T *val) noexcept { - ox::Error err{}; +Error OrganicClawReader::field(CString key, T *val) noexcept { + Error err{}; try { if constexpr (is_integer_v) { if (targetValid()) { - auto const&jv = value(key); + auto const &jv = value(key); auto const rightType = sizeof(T) == 8 ? - (ox::is_signed_v ? jv.isInt64() : jv.isUInt64()) : - (ox::is_signed_v ? jv.isInt() : jv.isUInt()); + (is_signed_v ? jv.isInt64() : jv.isUInt64()) : + (is_signed_v ? jv.isInt() : jv.isUInt()); if (jv.empty()) { *val = 0; } else if (rightType) { - if constexpr(ox::is_signed_v) { + if constexpr(is_signed_v) { *val = static_cast(jv.asInt64()); } else { *val = static_cast(jv.asUInt64()); } } else { - err = ox::Error(1, "Type mismatch"); + err = Error{1, "Type mismatch"}; } } } else if constexpr (isVector_v) { - const auto&srcVal = value(key); - const auto srcSize = srcVal.size(); - OX_RETURN_ERROR(ox::resizeVector(*val, srcSize)); + auto const &srcVal = value(key); + auto const srcSize = srcVal.size(); + OX_RETURN_ERROR(resizeVector(*val, srcSize)); err = field(key, val->data(), val->size()); } else if constexpr (isArray_v) { - const auto&srcVal = value(key); - const auto srcSize = srcVal.size(); + auto const &srcVal = value(key); + auto const srcSize = srcVal.size(); if (srcSize > val->size()) { - err = ox::Error(1, "Input array is too long"); + err = Error{1, "Input array is too long"}; } else { err = field(key, val->data(), val->size()); } } else if (targetValid()) { - const auto&jv = value(key); + auto const &jv = value(key); if (jv.empty() || jv.isObject()) { auto reader = child(key); - ModelHandlerInterface handler(&reader); + ModelHandlerInterface handler(reader); err = model(&handler, val); } else { - err = ox::Error(1, "Type mismatch"); + err = Error{1, "Type mismatch"}; } } - } catch (Json::LogicError const&e) { - err = ox::Error(1, "error reading JSON data"); + } catch (Json::LogicError const &e) { + err = Error{1, "error reading JSON data"}; } ++m_fieldIt; return err; } template -Error OrganicClawReader::field(const char *key, UnionView val) noexcept { - ox::Error err{}; +Error OrganicClawReader::field(CString const key, UnionView val) noexcept { + Error err{}; if (targetValid()) { - const auto &jv = value(key); + auto const &jv = value(key); if (jv.empty() || jv.isObject()) { auto reader = child(key, val.idx()); - ModelHandlerInterface handler(&reader); + ModelHandlerInterface handler(reader); err = model(&handler, val.get()); } else { - err = ox::Error(1, "Type mismatch"); + err = Error{1, "Type mismatch"}; } } ++m_fieldIt; return err; } -template -Error OrganicClawReader::field(const char *key, BasicString *val) noexcept { - ox::Error err{}; +template +Error OrganicClawReader::field(CString const key, BasicString *val) noexcept { + Error err{}; if (targetValid()) { - const auto &jv = value(key); + auto const &jv = value(key); if (jv.empty()) { *val = BasicString{}; } else if (jv.isString()) { *val = jv.asString().c_str(); } else { - err = ox::Error(1, "Type mismatch"); + err = Error{1, "Type mismatch"}; } } ++m_fieldIt; return err; } -template -Error OrganicClawReader::field(const char *key, IString *val) noexcept { - ox::Error err{}; +template +Error OrganicClawReader::field(CString const key, IString *val) noexcept { + Error err{}; if (targetValid()) { - const auto &jv = value(key); + auto const &jv = value(key); if (jv.empty()) { *val = IString{}; } else if (jv.isString()) { *val = jv.asString().c_str(); } else { - err = ox::Error(1, "Type mismatch"); + err = Error{1, "Type mismatch"}; } } ++m_fieldIt; @@ -240,17 +241,17 @@ Error OrganicClawReader::field(const char *key, IString *val) noexcept { // array handler template -Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noexcept { - const auto &srcVal = value(key); +Error OrganicClawReader::field(CString const key, T *val, size_t valLen) noexcept { + auto const &srcVal = value(key); if (!srcVal.isNull() && !srcVal.isArray()) { - return ox::Error(1, "Type mismatch"); + return Error{1, "Type mismatch"}; } auto srcSize = srcVal.size(); if (srcSize > valLen) { - return ox::Error(1); + return Error{1}; } OrganicClawReader r(srcVal); - ModelHandlerInterface handler{&r}; + ModelHandlerInterface handler{r}; for (decltype(srcSize) i = 0; i < srcSize; ++i) { OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_RETURN_ERROR(handler.field("", &val[i])); @@ -260,23 +261,23 @@ OX_ALLOW_UNSAFE_BUFFERS_END } template -Error OrganicClawReader::field(const char *key, HashMap *val) noexcept { - const auto &srcVal = value(key); +Error OrganicClawReader::field(CString const key, HashMap *val) noexcept { + auto const &srcVal = value(key); if (!srcVal.isObject()) { - return ox::Error(1, "Type mismatch"); + return Error{1, "Type mismatch"}; } auto keys = srcVal.getMemberNames(); auto srcSize = srcVal.size(); OrganicClawReader r(srcVal); - ModelHandlerInterface handler{&r}; + ModelHandlerInterface handler{r}; for (decltype(srcSize) i = 0; i < srcSize; ++i) { - const auto k = keys[i].c_str(); + auto const k = keys[i].c_str(); OX_RETURN_ERROR(handler.field(k, &val->operator[](k))); } return {}; } -Error readOC(BufferView buff, auto &val) noexcept { +Error readOC(BufferView const buff, auto &val) noexcept { // OrganicClawReader constructor can throw, but readOC should return its errors. try { Json::Value doc; @@ -285,15 +286,15 @@ Error readOC(BufferView buff, auto &val) noexcept { OX_ALLOW_UNSAFE_BUFFERS_BEGIN if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) { OX_ALLOW_UNSAFE_BUFFERS_END - return ox::Error(1, "Could not parse JSON"); + return Error{1, "Could not parse JSON"}; } OrganicClawReader reader(buff.data(), buff.size()); - ModelHandlerInterface handler(&reader); + ModelHandlerInterface handler(reader); return model(&handler, &val); - } catch (const Error &err) { + } catch (Error const &err) { return err; } catch (...) { - return ox::Error(1, "Unknown Error"); + return Error{1, "Unknown Error"}; } } @@ -305,8 +306,8 @@ Result readOC(BufferView buff) noexcept { } template -Result readOC(ox::StringView json) noexcept { - return readOC(ox::BufferView{json.data(), json.size()}); +Result readOC(StringViewCR json) noexcept { + return readOC(BufferView{json.data(), json.size()}); } } diff --git a/deps/ox/src/ox/oc/write.cpp b/deps/ox/src/ox/oc/write.cpp index 3e27a03..618b930 100644 --- a/deps/ox/src/ox/oc/write.cpp +++ b/deps/ox/src/ox/oc/write.cpp @@ -10,15 +10,15 @@ namespace ox { -OrganicClawWriter::OrganicClawWriter(int unionIdx) noexcept: m_unionIdx(unionIdx) { +OrganicClawWriter::OrganicClawWriter(int const unionIdx) noexcept: m_unionIdx(unionIdx) { } -OrganicClawWriter::OrganicClawWriter(Json::Value json, int unionIdx) noexcept: +OrganicClawWriter::OrganicClawWriter(Json::Value json, int const unionIdx) noexcept: m_json(std::move(json)), m_unionIdx(unionIdx) { } -Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, int len) noexcept { +Error OrganicClawWriter::fieldCString(const char *key, const char *const *val, int const len) noexcept { if (targetValid() && len) { value(key) = *val; } @@ -26,11 +26,11 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, in return {}; } -Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept { +Error OrganicClawWriter::fieldCString(const char *key, const char *const *val) noexcept { return fieldCString(key, const_cast(val), static_cast(ox::strlen(val))); } -Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept { +Error OrganicClawWriter::field(const char *key, UUID const *uuid) noexcept { const auto uuidStr = uuid->toString(); if (targetValid() && uuidStr.size()) { value(key) = uuidStr.c_str(); diff --git a/deps/ox/src/ox/oc/write.hpp b/deps/ox/src/ox/oc/write.hpp index b8ca98e..1f22db2 100644 --- a/deps/ox/src/ox/oc/write.hpp +++ b/deps/ox/src/ox/oc/write.hpp @@ -28,20 +28,20 @@ namespace ox { class OrganicClawWriter { - friend Result writeOC(const auto &val) noexcept; - friend Result writeOCString(const auto &val) noexcept; + friend Result writeOC(const auto &val) noexcept; + friend Result writeOCString(const auto &val) noexcept; protected: Json::Value m_json{Json::Value(Json::objectValue)}; Json::ArrayIndex m_fieldIt = 0; - int m_unionIdx = -1; + int const m_unionIdx = -1; public: explicit OrganicClawWriter(int unionIdx = -1) noexcept; explicit OrganicClawWriter(Json::Value json, int unionIdx = -1) noexcept; - Error field(const char *key, const int8_t *val) noexcept { + Error field(const char *key, int8_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -49,7 +49,7 @@ class OrganicClawWriter { return {}; } - Error field(const char *key, const int16_t *val) noexcept { + Error field(const char *key, int16_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -57,7 +57,7 @@ class OrganicClawWriter { return {}; } - Error field(const char *key, const int32_t *val) noexcept { + Error field(const char *key, int32_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -65,7 +65,7 @@ class OrganicClawWriter { return {}; } - Error field(const char *key, const int64_t *val) noexcept { + Error field(const char *key, int64_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -74,7 +74,7 @@ class OrganicClawWriter { } - Error field(const char *key, const uint8_t *val) noexcept { + Error field(const char *key, uint8_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -82,7 +82,7 @@ class OrganicClawWriter { return {}; } - Error field(const char *key, const uint16_t *val) noexcept { + Error field(const char *key, uint16_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -90,7 +90,7 @@ class OrganicClawWriter { return {}; } - Error field(const char *key, const uint32_t *val) noexcept { + Error field(const char *key, uint32_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -98,7 +98,7 @@ class OrganicClawWriter { return {}; } - Error field(const char *key, const uint64_t *val) noexcept { + Error field(const char *key, uint64_t const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -106,7 +106,7 @@ class OrganicClawWriter { return {}; } - Error field(char const*key, bool const*val) noexcept { + Error field(char const*key, bool const *val) noexcept { if (targetValid() && (*val || m_json.isArray())) { value(key) = *val; } @@ -118,12 +118,12 @@ class OrganicClawWriter { Error field(char const*, UnionView val) noexcept; template - Error field(char const*key, HashMap const*val) noexcept { + Error field(char const*key, HashMap const *val) noexcept { if (targetValid()) { const auto &keys = val->keys(); OrganicClawWriter w; - ModelHandlerInterface handler{&w}; - for (std::size_t i = 0; i < keys.size(); ++i) { + ModelHandlerInterface handler{w}; + for (size_t i = 0; i < keys.size(); ++i) { const auto k = keys[i].c_str(); if (k) [[likely]] { OX_REQUIRE_M(value, val->at(k)); @@ -136,8 +136,8 @@ class OrganicClawWriter { return {}; } - template - Error field(char const*key, IString const*val) noexcept { + template + Error field(char const*key, IString const *val) noexcept { if (targetValid() && val->size()) { value(key) = val->c_str(); } @@ -145,8 +145,8 @@ class OrganicClawWriter { return {}; } - template - Error field(char const*key, BasicString const*val) noexcept { + template + Error field(char const*key, BasicString const *val) noexcept { if (targetValid() && val->size()) { value(key) = val->c_str(); } @@ -154,31 +154,31 @@ class OrganicClawWriter { return {}; } - Error fieldCString(const char*, const char *const*val, int len) noexcept; + Error fieldCString(const char*, const char *const *val, int len) noexcept; Error fieldCString(const char *name, const char *const*val) noexcept; - Error field(const char *key, const UUID *uuid) noexcept; + Error field(const char *key, UUID const *uuid) noexcept; template - Error field(const char*, const T *val, std::size_t len) noexcept; + Error field(const char*, T const *val, size_t len) noexcept; template - Error field(const char*, const T *val) noexcept; + Error field(const char*, T const *val) noexcept; template - constexpr ox::Error setTypeInfo( + constexpr Error setTypeInfo( const char* = T::TypeName, int = T::TypeVersion) noexcept { return {}; } template - constexpr ox::Error setTypeInfo( + constexpr Error setTypeInfo( const char*, int, - const Vector&, - std::size_t) noexcept { + Vector const&, + size_t) noexcept { return {}; } @@ -199,11 +199,11 @@ class OrganicClawWriter { }; template -Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) noexcept { +Error OrganicClawWriter::field(const char *key, T const *val, size_t const len) noexcept { if (targetValid() && len) { OrganicClawWriter w((Json::Value(Json::arrayValue))); - ModelHandlerInterface handler{&w}; - for (std::size_t i = 0; i < len; ++i) { + ModelHandlerInterface handler{w}; + for (size_t i = 0; i < len; ++i) { OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_RETURN_ERROR(handler.field({}, &val[i])); OX_ALLOW_UNSAFE_BUFFERS_END @@ -215,22 +215,22 @@ OX_ALLOW_UNSAFE_BUFFERS_END } template -Error OrganicClawWriter::field(const char *key, const T *val) noexcept { +Error OrganicClawWriter::field(const char *key, T const *val) noexcept { if constexpr(is_integer_v) { if (targetValid() && (*val || m_json.isArray())) { // the int type needs to be normalized because jsoncpp doesn't // factor in every permutation unsigned long, etc. - if constexpr(ox::is_signed_v) { - value(key) = static_cast>(*val); + if constexpr(is_signed_v) { + value(key) = static_cast>(*val); } else { - value(key) = static_cast>(*val); + value(key) = static_cast>(*val); } } } else if constexpr(isVector_v || isArray_v) { return field(key, val->data(), val->size()); } else if (val && targetValid()) { OrganicClawWriter w; - ModelHandlerInterface handler{&w}; + ModelHandlerInterface handler{w}; OX_RETURN_ERROR(model(&handler, val)); if (!w.m_json.empty() || m_json.isArray()) { value(key) = w.m_json; @@ -244,7 +244,7 @@ template Error OrganicClawWriter::field(const char *key, UnionView val) noexcept { if (targetValid()) { OrganicClawWriter w(val.idx()); - ModelHandlerInterface handler{&w}; + ModelHandlerInterface handler{w}; OX_RETURN_ERROR(model(&handler, val.get())); if (!w.m_json.isNull()) { value(key) = w.m_json; @@ -254,12 +254,12 @@ Error OrganicClawWriter::field(const char *key, UnionView val) noexcep return {}; } -Result writeOC(const auto &val) noexcept { +Result writeOC(auto const &val) noexcept { OrganicClawWriter writer; - ModelHandlerInterface handler(&writer); + ModelHandlerInterface handler(writer); OX_RETURN_ERROR(model(&handler, &val)); Json::StreamWriterBuilder const jsonBuilder; - const auto str = Json::writeString(jsonBuilder, writer.m_json); + auto const str = Json::writeString(jsonBuilder, writer.m_json); Result buff; buff.value.resize(str.size() + 1); OX_ALLOW_UNSAFE_BUFFERS_BEGIN @@ -268,13 +268,13 @@ Result writeOC(const auto &val) noexcept { return buff; } -Result writeOCString(const auto &val) noexcept { +Result writeOCString(auto const &val) noexcept { OrganicClawWriter writer; - ModelHandlerInterface handler(&writer); + ModelHandlerInterface handler(writer); OX_RETURN_ERROR(model(&handler, &val)); Json::StreamWriterBuilder const jsonBuilder; - const auto str = Json::writeString(jsonBuilder, writer.m_json); - Result buff; + auto const str = Json::writeString(jsonBuilder, writer.m_json); + Result buff; buff.value.resize(str.size()); OX_ALLOW_UNSAFE_BUFFERS_BEGIN memcpy(buff.value.data(), str.data(), str.size() + 1); diff --git a/deps/ox/src/ox/std/array.hpp b/deps/ox/src/ox/std/array.hpp index 7a212f0..21863f1 100644 --- a/deps/ox/src/ox/std/array.hpp +++ b/deps/ox/src/ox/std/array.hpp @@ -181,13 +181,13 @@ constexpr Array &Array::operator=(Array &&other) noe template constexpr T &Array::operator[](std::size_t i) noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Array access overflow"); + boundsCheck(i, size(), "Array access overflow"); return m_items[i]; } template constexpr const T &Array::operator[](std::size_t i) const noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Array access overflow"); + boundsCheck(i, size(), "Array access overflow"); return m_items[i]; } diff --git a/deps/ox/src/ox/std/assert.cpp b/deps/ox/src/ox/std/assert.cpp index 3ac0fe4..d63a796 100644 --- a/deps/ox/src/ox/std/assert.cpp +++ b/deps/ox/src/ox/std/assert.cpp @@ -15,8 +15,8 @@ namespace ox { -void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const&err) noexcept { - oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg); +void panic(Error const &err, StringViewCR panicMsg, std::source_location const &src) noexcept { + oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", src.file_name(), src.line(), panicMsg); if (err.msg) { oxErrf("\tError Message:\t{}\n", err.msg); } @@ -26,7 +26,7 @@ void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const } #ifdef OX_USE_STDLIB printStackTrace(2); - oxTrace("panic").del("") << "Panic: " << panicMsg << " (" << file << ":" << line << ")"; + oxTrace("panic").del("") << "Panic: " << panicMsg << " (" << src.file_name() << ":" << src.line() << ")"; std::abort(); #else while (1); @@ -36,34 +36,51 @@ void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const #if __GNUC__ && !_WIN32 __attribute__((weak)) #endif -void panic(const char *file, int const line, char const*panicMsg, Error const&err) noexcept { - panic(StringView{file}, line, StringView{panicMsg}, err); +void panic(Error const &err, char const*panicMsg, std::source_location const &src) noexcept { + panic(err, StringView{panicMsg}, src); } void assertFailFuncRuntime( - StringViewCR file, - int const line, StringViewCR assertTxt, - StringViewCR msg) noexcept { + StringViewCR msg, + std::source_location const &src) noexcept { #ifdef OX_USE_STDLIB auto const st = genStackTrace(2); - oxTracef("assert", "Failed assert: {} ({}) [{}:{}]:\n{}", msg, assertTxt, file, line, st); + oxTracef( + "assert", "Failed assert: {} ({}) [{}:{}]:\n{}", + msg, + assertTxt, + src.file_name(), + src.line(), + st); abort(); #else - oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg); - oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line); - constexprPanic(file, line, msg); + oxErrf( + "\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", + src.file_name(), + src.line(), + msg); + oxTracef( + "assert", "Failed assert: {} ({}) [{}:{}]", + msg, + assertTxt, + src.file_name(), + src.line()); + constexprPanic(msg, {}, src); #endif } void assertFailFuncRuntime( - StringViewCR file, - int const line, - [[maybe_unused]] Error const&err, + [[maybe_unused]] Error const &err, StringViewCR, - StringViewCR assertMsg) noexcept { + StringViewCR assertMsg, + std::source_location const &src) noexcept { #if defined(OX_USE_STDLIB) - auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg); + auto msg = sfmt( + "\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", + src.file_name(), + src.line(), + assertMsg); if (err.msg) { msg += sfmt("\tError Message:\t{}\n", err.msg); } @@ -73,10 +90,10 @@ void assertFailFuncRuntime( } msg += genStackTrace(2); oxErr(msg); - oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line); + oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, src.file_name(), src.line()); abort(); #else - constexprPanic(file, line, assertMsg); + constexprPanic(assertMsg, {}, src); #endif } diff --git a/deps/ox/src/ox/std/assert.hpp b/deps/ox/src/ox/std/assert.hpp index 8573e6a..b531ff4 100644 --- a/deps/ox/src/ox/std/assert.hpp +++ b/deps/ox/src/ox/std/assert.hpp @@ -23,42 +23,49 @@ namespace ox { [[noreturn]] -void panic(StringViewCR file, int line, StringViewCR panicMsg, Error const&err = {}) noexcept; +void panic( + Error const&err, + StringViewCR panicMsg, + std::source_location const &src = std::source_location::current()) noexcept; + +[[noreturn]] +inline void panic( + StringViewCR panicMsg, + std::source_location const &src = std::source_location::current()) noexcept { + panic(Error{1}, panicMsg, src); +} [[noreturn]] constexpr void constexprPanic( - StringViewCR file, - int const line, StringViewCR panicMsg, - Error const&err = {}) noexcept { + Error const &err = {}, + std::source_location const &src = std::source_location::current()) noexcept { if (!std::is_constant_evaluated()) { - panic(file, line, panicMsg, err); + panic(err, panicMsg, src); } else { while (true); } } void assertFailFuncRuntime( - StringViewCR file, - int line, StringViewCR assertTxt, - StringViewCR msg) noexcept; + StringViewCR msg, + std::source_location const &src = std::source_location::current()) noexcept; + void assertFailFuncRuntime( - StringViewCR file, - int line, - Error const&err, + Error const &err, StringViewCR, - StringViewCR assertMsg) noexcept; + StringViewCR assertMsg, + std::source_location const &src = std::source_location::current()) noexcept; constexpr void assertFunc( - StringViewCR file, - int const line, bool const pass, [[maybe_unused]]StringViewCR assertTxt, - [[maybe_unused]]StringViewCR msg) noexcept { + [[maybe_unused]]StringViewCR msg, + std::source_location const &src = std::source_location::current()) noexcept { if (!pass) { if (!std::is_constant_evaluated()) { - assertFailFuncRuntime(file, line, assertTxt, msg); + assertFailFuncRuntime(assertTxt, msg, src); } else { while (true); } @@ -66,14 +73,13 @@ constexpr void assertFunc( } constexpr void assertFunc( - StringViewCR file, - int const line, - Error const&err, + Error const &err, StringViewCR, - StringViewCR assertMsg) noexcept { + StringViewCR assertMsg, + std::source_location const &src = std::source_location::current()) noexcept { if (err) { if (!std::is_constant_evaluated()) { - assertFailFuncRuntime(file, line, err, {}, assertMsg); + assertFailFuncRuntime(err, {}, assertMsg, src); } else { while (true); } @@ -81,20 +87,31 @@ constexpr void assertFunc( } constexpr void expect( - StringViewCR file, - int const line, - auto const&actual, - auto const&expected) noexcept { + auto const &actual, + auto const &expected, + std::source_location const &src = std::source_location::current()) noexcept { if (actual != expected) { if (!std::is_constant_evaluated()) { #if defined(OX_USE_STDLIB) - oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, "Value incorrect"); - oxErrf("expected: {}\nactual: {}\n", detail::toStringView(expected), detail::toStringView(actual)); + oxErrf( + "\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", + src.file_name(), + src.line(), + "Value incorrect"); + oxErrf( + "expected: {}\nactual: {}\n", + detail::toStringView(expected), + detail::toStringView(actual)); printStackTrace(2); - oxTracef("assert.expect", "Failed assert: {} == {} [{}:{}]", detail::toStringView(actual), detail::toStringView(expected), file, line); + oxTracef( + "assert.expect", "Failed assert: {} == {} [{}:{}]", + detail::toStringView(actual), + detail::toStringView(expected), + src.file_name(), + src.line()); std::abort(); #else - constexprPanic(file, line, "Comparison failed"); + constexprPanic("Comparison failed", {}, src); #endif } else { while (true); diff --git a/deps/ox/src/ox/std/byteswap.hpp b/deps/ox/src/ox/std/byteswap.hpp index b35b91f..d549c98 100644 --- a/deps/ox/src/ox/std/byteswap.hpp +++ b/deps/ox/src/ox/std/byteswap.hpp @@ -17,19 +17,19 @@ namespace ox { template [[nodiscard]] -constexpr T byteSwap(typename enable_if::type i) noexcept { +constexpr T byteSwap(T const i) noexcept requires(sizeof(T) == 1) { return i; } template [[nodiscard]] -constexpr T byteSwap(typename enable_if::type i) noexcept { +constexpr T byteSwap(T const i) noexcept requires(sizeof(T) == 2) { return static_cast(i << 8) | static_cast(i >> 8); } template [[nodiscard]] -constexpr T byteSwap(typename enable_if::type i) noexcept { +constexpr T byteSwap(T const i) noexcept requires(sizeof(T) == 4) { return ((i >> 24) & 0x000000ff) | ((i >> 8) & 0x0000ff00) | ((i << 8) & 0x00ff0000) | @@ -38,7 +38,7 @@ constexpr T byteSwap(typename enable_if::type i) noexcept { template [[nodiscard]] -constexpr T byteSwap(typename enable_if::type i) noexcept { +constexpr T byteSwap(T const i) noexcept requires(sizeof(T) == 8) { return ((i >> 56) & 0x00000000000000ff) | ((i >> 40) & 0x000000000000ff00) | ((i >> 24) & 0x0000000000ff0000) | diff --git a/deps/ox/src/ox/std/concepts.hpp b/deps/ox/src/ox/std/concepts.hpp index 1cf0138..857e3c4 100644 --- a/deps/ox/src/ox/std/concepts.hpp +++ b/deps/ox/src/ox/std/concepts.hpp @@ -32,4 +32,8 @@ concept Integral_c = ox::is_integral_v; template concept IntegerRange_c = ox::is_integer_v && ox::MaxValue >= max; + +template +concept Union_c = is_union_v; + } diff --git a/deps/ox/src/ox/std/def.hpp b/deps/ox/src/ox/std/def.hpp index 44eca5e..9af2bf4 100644 --- a/deps/ox/src/ox/std/def.hpp +++ b/deps/ox/src/ox/std/def.hpp @@ -48,9 +48,8 @@ // Asserts -#define oxPanic(errCode, msg) ox::panic(__FILE__, __LINE__, msg, errCode) #ifndef NDEBUG -#define oxAssert(pass, msg) ox::assertFunc(__FILE__, __LINE__, pass, #pass, msg) +#define oxAssert(pass, msg) ox::assertFunc(pass, #pass, msg) #else namespace ox { struct [[nodiscard]] Error; @@ -59,8 +58,6 @@ constexpr void oxAssert(bool, const char*) noexcept {} constexpr void oxAssert(const ox::Error&, const char*) noexcept {} #endif -#define oxExpect(actual, expected) ox::expect(__FILE__, __LINE__, actual, expected) - // Alloca #if defined(_MSC_VER) diff --git a/deps/ox/src/ox/std/error.hpp b/deps/ox/src/ox/std/error.hpp index 8b21166..1826931 100644 --- a/deps/ox/src/ox/std/error.hpp +++ b/deps/ox/src/ox/std/error.hpp @@ -17,7 +17,7 @@ class exception { virtual ~exception() = default; [[nodiscard]] - virtual char const*what() const noexcept { + virtual char const *what() const noexcept { return ""; } }; @@ -44,7 +44,7 @@ struct [[nodiscard]] Error { explicit constexpr Error( ErrorCode const errCode, - std::source_location const&src = std::source_location::current()) noexcept: + std::source_location const &src = std::source_location::current()) noexcept: src{src}, errCode{errCode} {} @@ -52,7 +52,7 @@ struct [[nodiscard]] Error { explicit constexpr Error( ErrorCode const errCode, ox::CString msg, - std::source_location const&src = std::source_location::current()) noexcept: + std::source_location const &src = std::source_location::current()) noexcept: src{src}, msg{msg}, errCode{errCode} @@ -65,13 +65,13 @@ struct [[nodiscard]] Error { }; [[nodiscard]] -constexpr auto errCode(Error const&err) noexcept { +constexpr auto errCode(Error const &err) noexcept { return err.errCode; } template [[nodiscard]] -constexpr auto toStr(Error const&err) noexcept { +constexpr auto toStr(Error const &err) noexcept { return err.msg ? T{err.msg} : ""; } @@ -82,19 +82,19 @@ struct Exception: public std::exception { explicit Exception( ErrorCode const errCode, - std::source_location const&src = std::source_location::current()) noexcept: + std::source_location const &src = std::source_location::current()) noexcept: src{src}, errCode{errCode} {} explicit Exception( ErrorCode const errCode, ox::CString msg, - std::source_location const&src = std::source_location::current()) noexcept: + std::source_location const &src = std::source_location::current()) noexcept: src{src}, msg{msg}, errCode{errCode} {} - explicit Exception(Error const&err) noexcept: + explicit Exception(Error const &err) noexcept: src{err.src}, msg{err.msg ? err.msg : ""}, errCode{err.errCode} {} @@ -104,13 +104,16 @@ struct Exception: public std::exception { } [[nodiscard]] - char const*what() const noexcept override { + char const *what() const noexcept override { return msg; } }; [[noreturn]] -void panic(char const*file, int line, char const*panicMsg, Error const&err) noexcept; +void panic( + Error const &err, + char const *panicMsg, + std::source_location const &src = std::source_location::current()) noexcept; template struct [[nodiscard]] Result { @@ -124,25 +127,25 @@ struct [[nodiscard]] Result { } template - constexpr Result(Result const&other) noexcept: value(other.value), error(other.error) { + constexpr Result(Result const &other) noexcept: value(other.value), error(other.error) { } template constexpr Result(Result &&other) noexcept: value(std::move(other.value)), error(std::move(other.error)) { } - constexpr Result(Error const&error) noexcept: value(), error(error) { + constexpr Result(Error const &error) noexcept: value(), error(error) { } - constexpr Result(type const&value, Error const&error = {}) noexcept: value(value), error(error) { + constexpr Result(type const &value, Error const &error = {}) noexcept: value(value), error(error) { } - constexpr Result(type &&value, Error const&error = {}) noexcept: value(std::move(value)), error(error) { + constexpr Result(type &&value, Error const &error = {}) noexcept: value(std::move(value)), error(error) { } constexpr ~Result() noexcept = default; - explicit constexpr operator type const&() const noexcept { + explicit constexpr operator type const &() const noexcept { return value; } @@ -156,7 +159,7 @@ struct [[nodiscard]] Result { } template - constexpr Error copyTo(U &val) const& noexcept { + constexpr Error copyTo(U &val) const & noexcept { if (!error) [[likely]] { val = value; } @@ -182,7 +185,7 @@ struct [[nodiscard]] Result { [[nodiscard]] constexpr T &unwrap() & noexcept { if (error) { - oxPanic(error, "Failed unwrap"); + ox::panic(error, "Failed unwrap"); } return value; } @@ -190,15 +193,15 @@ struct [[nodiscard]] Result { [[nodiscard]] constexpr T &&unwrap() && noexcept { if (error) { - oxPanic(error, "Failed unwrap"); + ox::panic(error, "Failed unwrap"); } return std::move(value); } [[nodiscard]] - constexpr T const&unwrap() const & noexcept { + constexpr T const &unwrap() const & noexcept { if (error) [[unlikely]] { - oxPanic(error, "Failed unwrap"); + ox::panic(error, "Failed unwrap"); } return value; } @@ -220,7 +223,7 @@ struct [[nodiscard]] Result { } [[nodiscard]] - constexpr T const&unwrapThrow() const & { + constexpr T const &unwrapThrow() const & { if (error) { throw ox::Exception(error); } @@ -244,7 +247,7 @@ struct [[nodiscard]] Result { } template - constexpr ox::Result to(auto const&f) & noexcept { + constexpr ox::Result to(auto const &f) & noexcept { if (error) [[unlikely]] { return error; } @@ -252,7 +255,7 @@ struct [[nodiscard]] Result { } template - constexpr ox::Result to(auto const&f) && noexcept { + constexpr ox::Result to(auto const &f) && noexcept { if (error) [[unlikely]] { return error; } @@ -264,7 +267,7 @@ struct [[nodiscard]] Result { * @param alt * @return value of Result or alt */ - constexpr T or_value(T &&alt) const& noexcept { + constexpr T or_value(T &&alt) const & noexcept { if (error) { return std::move(alt); } @@ -288,7 +291,7 @@ struct [[nodiscard]] Result { * @param alt * @return value of Result or alt */ - constexpr T or_value(T const&alt) const& noexcept { + constexpr T or_value(T const &alt) const & noexcept { if (error) { return alt; } @@ -300,7 +303,7 @@ struct [[nodiscard]] Result { * @param alt * @return value of Result or alt */ - constexpr T or_value(T const&alt) && noexcept { + constexpr T or_value(T const &alt) && noexcept { if (error) { return alt; } @@ -318,34 +321,36 @@ struct [[nodiscard]] Result { namespace detail { -constexpr Error toError(Error const&e) noexcept { +constexpr Error toError(Error const &e) noexcept { return e; } template -constexpr Error toError(Result const&r) noexcept { +constexpr Error toError(Result const &r) noexcept { return r.error; } } -constexpr void primitiveAssert(char const*file, int line, bool pass, char const*msg) noexcept { +constexpr void primitiveAssert( + bool const pass, + char const *msg, + std::source_location const &src = std::source_location::current()) noexcept { if constexpr(ox::defines::Debug) { if (!pass) [[unlikely]] { - panic(file, line, msg, ox::Error(1)); + panic(ox::Error{1}, msg, src); } } } constexpr void boundsCheck( - char const*file, - int const line, size_t const i, size_t const sz, - char const*msg) noexcept { + char const *msg, + std::source_location const &src = std::source_location::current()) noexcept { if constexpr(defines::CheckBounds) { if (i >= sz) [[unlikely]] { - panic(file, line, msg, ox::Error{1}); + panic(ox::Error{1}, msg, src); } } } diff --git a/deps/ox/src/ox/std/heapmgr.cpp b/deps/ox/src/ox/std/heapmgr.cpp index 0ab856e..90e9f19 100644 --- a/deps/ox/src/ox/std/heapmgr.cpp +++ b/deps/ox/src/ox/std/heapmgr.cpp @@ -77,7 +77,7 @@ static HeapSegment *findSegmentFor(std::size_t sz) noexcept { return s; } } - oxPanic(ox::Error(1), "malloc: could not find segment"); + ox::panic("malloc: could not find segment"); return nullptr; } @@ -102,7 +102,7 @@ void free(void *ptr) noexcept { } else if (p.segment) { p.segment->inUse = false; } else { - oxPanic(ox::Error(1), "Bad heap free"); + ox::panic("Bad heap free"); } } diff --git a/deps/ox/src/ox/std/iterator.hpp b/deps/ox/src/ox/std/iterator.hpp index 381a854..807fa3d 100644 --- a/deps/ox/src/ox/std/iterator.hpp +++ b/deps/ox/src/ox/std/iterator.hpp @@ -133,17 +133,17 @@ struct SpanIterator { } constexpr PtrType operator->() const noexcept { - boundsCheck(__FILE__, __LINE__, m_offset, m_max, "SpanIterator access overflow"); + boundsCheck(m_offset, m_max, "SpanIterator access overflow"); return &m_t[m_offset]; } constexpr RefType operator*() const noexcept { - boundsCheck(__FILE__, __LINE__, m_offset, m_max, "SpanIterator access overflow"); + boundsCheck(m_offset, m_max, "SpanIterator access overflow"); return m_t[m_offset]; } constexpr RefType operator[](std::size_t s) const noexcept { - boundsCheck(__FILE__, __LINE__, s, m_max, "SpanIterator access overflow"); + boundsCheck(s, m_max, "SpanIterator access overflow"); return m_t[s]; } diff --git a/deps/ox/src/ox/std/new.hpp b/deps/ox/src/ox/std/new.hpp index 26af045..cde3362 100644 --- a/deps/ox/src/ox/std/new.hpp +++ b/deps/ox/src/ox/std/new.hpp @@ -79,11 +79,11 @@ constexpr U *make(Args &&...args) noexcept { #ifdef __cpp_exceptions try { return new T(ox::forward(args)...); - } catch (std::exception const&ex) { - oxPanic(ox::Error(1, ex.what()), ex.what()); + } catch (std::exception const &ex) { + ox::panic(ox::Error(1, ex.what()), ex.what()); return nullptr; } catch (...) { - oxPanic(ox::Error(2, "Allocation or constructor failed"), "Allocation or constructor failed"); + ox::panic(ox::Error(2, "Allocation or constructor failed"), "Allocation or constructor failed"); return nullptr; } #else diff --git a/deps/ox/src/ox/std/span.hpp b/deps/ox/src/ox/std/span.hpp index 381e83e..f1a7e46 100644 --- a/deps/ox/src/ox/std/span.hpp +++ b/deps/ox/src/ox/std/span.hpp @@ -47,7 +47,7 @@ class Span { } template - constexpr Span(std::array, sz> const&a) noexcept: + constexpr Span(std::array, sz> const &a) noexcept: m_items(a.data()), m_size(a.size()) { } @@ -60,7 +60,7 @@ class Span { } template - constexpr Span(ox::Array, sz> const&a) noexcept: + constexpr Span(ox::Array, sz> const &a) noexcept: m_items(a.data()), m_size(a.size()) { } @@ -72,7 +72,7 @@ class Span { } template - constexpr Span(ox::Vector, sz, Allocator> const&v) noexcept: + constexpr Span(ox::Vector, sz, Allocator> const &v) noexcept: m_items(v.data()), m_size(v.size()) { } @@ -147,17 +147,17 @@ class Span { } constexpr T &operator[](std::size_t i) const noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); + boundsCheck(i, size(), "Span access overflow"); return m_items[i]; } constexpr Span operator+(size_t i) const noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); + boundsCheck(i, size(), "Span access overflow"); return {m_items + i, m_size - i}; } constexpr Span operator+=(size_t i) noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); + boundsCheck(i, size(), "Span access overflow"); m_items += i; m_size -= i; return *this; diff --git a/deps/ox/src/ox/std/strconv.hpp b/deps/ox/src/ox/std/strconv.hpp index b7f33de..614b4c7 100644 --- a/deps/ox/src/ox/std/strconv.hpp +++ b/deps/ox/src/ox/std/strconv.hpp @@ -17,35 +17,41 @@ namespace ox { template -constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept { - if (v) { - ox::ResizedInt_t mod = 1000000000000000000; - ox::ResizedInt_t val = v; - constexpr auto base = 10; - auto it = 0; - if (val < 0) { - OX_RETURN_ERROR(writer.put('-')); +constexpr ox::Error writeItoa(Integer const v, ox::Writer_c auto &writer) noexcept { + if (v) { + ox::ResizedInt_t mod = 1000000000000000000; + ox::ResizedInt_t val = v; + constexpr auto base = 10; + auto it = 0; + if (val < 0) { + OX_RETURN_ERROR(writer.put('-')); + val = ~val + 1; + } + if constexpr(sizeof(v) == 8 && !ox::is_signed_v) { + auto digit = val / mod; + val %= mod; + mod /= base; + if (digit) { + digit -= 10; + OX_RETURN_ERROR(writer.put('1')); + OX_RETURN_ERROR(writer.put(static_cast('0' + digit))); ++it; } - while (mod) { - auto digit = val / mod; - val %= mod; - mod /= base; - if (it || digit) { - ox::ResizedInt_t start = '0'; - if (digit >= 10) { - start = 'a'; - digit -= 10; - } - OX_RETURN_ERROR(writer.put(static_cast(start + digit))); - ++it; - } - } - } else { - // 0 is a special case - OX_RETURN_ERROR(writer.put('0')); } - return {}; + while (mod) { + auto const digit = val / mod; + val %= mod; + mod /= base; + if (it || digit) { + OX_RETURN_ERROR(writer.put(static_cast('0' + digit))); + ++it; + } + } + } else { + // 0 is a special case + OX_RETURN_ERROR(writer.put('0')); + } + return {}; } } diff --git a/deps/ox/src/ox/std/stringliteral.hpp b/deps/ox/src/ox/std/stringliteral.hpp index adf4127..03e3678 100644 --- a/deps/ox/src/ox/std/stringliteral.hpp +++ b/deps/ox/src/ox/std/stringliteral.hpp @@ -23,12 +23,12 @@ class StringLiteral: public detail::BaseStringView { constexpr StringLiteral(StringLiteral const &sv) noexcept = default; - consteval explicit StringLiteral(std::nullptr_t) noexcept {} + consteval StringLiteral(std::nullptr_t) noexcept {} - consteval explicit StringLiteral(char const *str, std::size_t const len) noexcept: BaseStringView{str, len} {} + consteval StringLiteral(char const *str, std::size_t const len) noexcept: BaseStringView{str, len} {} OX_ALLOW_UNSAFE_BUFFERS_BEGIN - consteval explicit StringLiteral(char const *str) noexcept: StringLiteral{str, ox::strlen(str)} {} + consteval StringLiteral(char const *str) noexcept: StringLiteral{str, ox::strlen(str)} {} OX_ALLOW_UNSAFE_BUFFERS_END constexpr StringLiteral &operator=(StringLiteral const &other) noexcept { diff --git a/deps/ox/src/ox/std/test/CMakeLists.txt b/deps/ox/src/ox/std/test/CMakeLists.txt index 2fa8f28..a05283b 100644 --- a/deps/ox/src/ox/std/test/CMakeLists.txt +++ b/deps/ox/src/ox/std/test/CMakeLists.txt @@ -28,3 +28,4 @@ add_test("[ox/std] FromHex" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "FromHex") add_test("[ox/std] ToHex" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ToHex") add_test("[ox/std] UUID" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "UUID") add_test("[ox/std] UUID::generate" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "UUID::generate") +add_test("[ox/std] intToStr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "intToStr") diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index e776a57..0093c89 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -30,7 +30,7 @@ static uint64_t steadyNowMs() { } template> -uint64_t timeMapStrToUuid(int elemCnt, int lookups, uint64_t seed = 4321) noexcept { +uint64_t timeMapStrToUuid(int const elemCnt, int const lookups, uint64_t seed = 4321) noexcept { ox::UUID::seedGenerator({1234, seed}); Map map; // setup test map @@ -43,15 +43,16 @@ uint64_t timeMapStrToUuid(int elemCnt, int lookups, uint64_t seed = 4321) noexce // start auto const startTime = steadyNowMs(); for (int i = 0; i < lookups; ++i) { - auto const&k = keys[rand.gen() % keys.size()]; + auto const &k = keys[rand.gen() % keys.size()]; map[k]; - oxExpect(map[k], ox::UUID::fromString(k).unwrap()); + ox::expect(map[k], ox::UUID::fromString(k).unwrap()); } return steadyNowMs() - startTime; } template> -uint64_t timeMapUuidToStr(int elemCnt, int lookups, uint64_t seed = 4321) noexcept { +[[nodiscard]] +uint64_t timeMapUuidToStr(int const elemCnt, int const lookups, uint64_t seed = 4321) noexcept { ox::UUID::seedGenerator({1234, seed}); Map map; // setup test map @@ -64,13 +65,13 @@ uint64_t timeMapUuidToStr(int elemCnt, int lookups, uint64_t seed = 4321) noexce // start auto const startTime = steadyNowMs(); for (int i = 0; i < lookups; ++i) { - auto const&k = keys[rand.gen() % keys.size()]; - oxExpect(map[k], k.toString()); + auto const &k = keys[rand.gen() % keys.size()]; + ox::expect(map[k], k.toString()); } return steadyNowMs() - startTime; } -static ox::Error compareMaps(int lookupCnt = 1'000'000) { +static ox::Error compareMaps(int const lookupCnt = 1'000'000) { auto const seed = steadyNowMs(); uint64_t hashTime{}; uint64_t smallTime{}; @@ -126,7 +127,7 @@ OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) OX_CLANG_NOWARN_END ox::heapmgr::free(a1); ox::heapmgr::free(a2); - return ox::Error(0); + return ox::Error{}; } }, { @@ -135,13 +136,13 @@ OX_CLANG_NOWARN_END ox::Array buff; ox::CharBuffWriter bw(buff); oxAssert(ox::writeItoa(5, bw), "ox::writeItoa returned Error"); - oxExpect(ox::StringView(buff.data()), ox::StringView("5")); + ox::expect(ox::StringView(buff.data()), ox::StringView("5")); OX_RETURN_ERROR(bw.seekp(0)); oxAssert(ox::writeItoa(50, bw), "ox::writeItoa returned Error"); - oxExpect(ox::StringView(buff.data()), ox::StringView("50")); + ox::expect(ox::StringView(buff.data()), ox::StringView("50")); OX_RETURN_ERROR(bw.seekp(0)); oxAssert(ox::writeItoa(500, bw), "ox::writeItoa returned Error"); - oxExpect(ox::StringView(buff.data()), ox::StringView("500")); + ox::expect(ox::StringView(buff.data()), ox::StringView("500")); return ox::Error{}; } }, @@ -184,7 +185,7 @@ OX_CLANG_NOWARN_END oxAssert(s == "asdf", "String assign broken"); oxAssert(s != "aoeu", "String assign broken"); oxAssert(s.size() == 4, "String assign broken"); - return ox::Error(0); + return ox::Error{}; } }, { @@ -214,11 +215,11 @@ OX_CLANG_NOWARN_END oxAssert(ox::StringView("Write") != ox::String(""), "String / StringView comparison broken"); oxAssert(ox::String("Write") != ox::StringView(""), "String / StringView comparison broken"); oxAssert(ox::String("Write") == ox::StringView("Write"), "String / StringView comparison broken"); - oxExpect(ox::String("asdf").substr(1, 3), "sd"); + ox::expect(ox::String("asdf").substr(1, 3), "sd"); oxAssert( ox::String(ox::StringView("Write")) == ox::StringView("Write"), "String / StringView comparison broken"); - return ox::Error(0); + return ox::Error{}; } }, { @@ -227,16 +228,16 @@ OX_CLANG_NOWARN_END ox::Vector v; oxAssert(v.size() == 0, "Initial Vector size not 0"); oxAssert(v.empty(), "Vector::empty() is broken"); - auto insertTest = [&v](int val, std::size_t size) { + auto insertTest = [&v](int const val, std::size_t const size) { v.push_back(val); OX_RETURN_ERROR(ox::Error(v.size() != size, "Vector size incorrect")); OX_RETURN_ERROR(ox::Error(v[v.size() - 1] != val, "Vector value wrong")); - return ox::Error(0); + return ox::Error{}; }; oxAssert(insertTest(42, 1), "Vector insertion failed"); oxAssert(insertTest(100, 2), "Vector insertion failed"); oxAssert(insertTest(102, 3), "Vector insertion failed"); - return ox::Error(0); + return ox::Error{}; } }, { @@ -249,9 +250,9 @@ OX_CLANG_NOWARN_END v.emplace_back("aoeu"); auto const origData = v.data(); v.shrink_to_fit(); - oxExpect(v[0], "asdf"); - oxExpect(v[1], "aoeu"); - oxExpect(v.capacity(), 2u); + ox::expect(v[0], "asdf"); + ox::expect(v[1], "aoeu"); + ox::expect(v.capacity(), 2u); oxAssert(origData != v.data(), "shrink_to_fit did not create a new allocation"); } { @@ -261,9 +262,9 @@ OX_CLANG_NOWARN_END v.emplace_back("aoeu"); auto const origData = v.data(); v.shrink_to_fit(); - oxExpect(v[0], "asdf"); - oxExpect(v[1], "aoeu"); - oxExpect(v.capacity(), 2u); + ox::expect(v[0], "asdf"); + ox::expect(v[1], "aoeu"); + ox::expect(v.capacity(), 2u); oxAssert(origData == v.data(), "shrink_to_fit inappropriately created a new allocation"); } return ox::Error{}; @@ -273,13 +274,13 @@ OX_CLANG_NOWARN_END "findIdx", [] { ox::Vector> const v {"zero", "one", "two", "three", "four"}; - oxExpect(ox::findIdx(v.begin(), v.end(), "zero").or_value(5), 0u); - oxExpect(ox::findIdx(v.begin(), v.end(), "one").or_value(5), 1u); - oxExpect(ox::findIdx(v.begin(), v.end(), "two").or_value(5), 2u); - oxExpect(ox::findIdx(v.begin(), v.end(), "three").or_value(5), 3u); - oxExpect(ox::findIdx(v.begin(), v.end(), "four").or_value(5), 4u); - oxExpect(ox::findIdx(v.begin(), v.end(), "five").or_value(5), 5u); - oxExpect(ox::findIdx(v.begin(), v.end(), "six").or_value(6), 6u); + ox::expect(ox::findIdx(v.begin(), v.end(), "zero").or_value(5), 0u); + ox::expect(ox::findIdx(v.begin(), v.end(), "one").or_value(5), 1u); + ox::expect(ox::findIdx(v.begin(), v.end(), "two").or_value(5), 2u); + ox::expect(ox::findIdx(v.begin(), v.end(), "three").or_value(5), 3u); + ox::expect(ox::findIdx(v.begin(), v.end(), "four").or_value(5), 4u); + ox::expect(ox::findIdx(v.begin(), v.end(), "five").or_value(5), 5u); + ox::expect(ox::findIdx(v.begin(), v.end(), "six").or_value(6), 6u); return ox::Error{}; } }, @@ -288,19 +289,19 @@ OX_CLANG_NOWARN_END [] { ox::SmallMap map; map["asdf"] = "aoeu"; - oxExpect(map["asdf"], "aoeu"); - oxExpect(map.size(), 1u); - oxExpect(map["aoeu"], ""); - oxExpect(map.size(), 2u); + ox::expect(map["asdf"], "aoeu"); + ox::expect(map.size(), 1u); + ox::expect(map["aoeu"], ""); + ox::expect(map.size(), 2u); ox::SmallMap cmap; cmap["asdf"] = "aoeu"; - auto constexpr constTest = [](ox::SmallMap const&map) { + auto constexpr constTest = [](ox::SmallMap const &map) { OX_REQUIRE(asdf, map.at("asdf")); - oxExpect(*asdf, "aoeu"); - oxExpect(map.size(), 1u); + ox::expect(*asdf, "aoeu"); + ox::expect(map.size(), 1u); auto const aoeu = map.at("aoeu"); - oxExpect(aoeu.ok(), false); - oxExpect(map.size(), 1u); + ox::expect(aoeu.ok(), false); + ox::expect(map.size(), 1u); return ox::Error{}; }; return constTest(cmap); @@ -319,7 +320,7 @@ OX_CLANG_NOWARN_END ii[5] = 100; oxAssert(ii[4] == 42, "4 != 42"); oxAssert(ii[5] == 100, "5 != 100"); - return ox::Error(0); + return ox::Error{}; } }, { @@ -334,17 +335,17 @@ OX_CLANG_NOWARN_END oxAssert(!si.contains("asdf"), "wrongly contains asdf"); oxAssert(si.contains("aoeu"), "does not contains aoeu"); oxAssert(!si.at("asdf").ok(), "asdf != 0"); - oxExpect(si["asdf"], 0); + ox::expect(si["asdf"], 0); oxAssert(si["aoeu"] == 100, "aoeu != 100"); auto si2 = si; - oxExpect(si2["asdf"], 0); + ox::expect(si2["asdf"], 0); oxAssert(si2["aoeu"] == 100, "aoeu != 100"); ox::HashMap ii; ii[4] = 42; ii[5] = 100; oxAssert(ii[4] == 42, "4 != 42"); oxAssert(ii[5] == 100, "5 != 100"); - return ox::Error(0); + return ox::Error{}; } }, { @@ -377,15 +378,15 @@ OX_CLANG_NOWARN_END static_cast(actual[1]), static_cast(actual[2]), static_cast(actual[3])); - oxExpect(ox::serialize(4).unwrap(), BA({4, 0, 0, 0})); - oxExpect(ox::serialize(256).unwrap(), BA({0, 1, 0, 0})); - oxExpect(ox::serialize(257).unwrap(), BA({1, 1, 0, 0})); - oxExpect(ox::serialize(4).unwrap(), BA({4, 0, 0, 0})); - oxExpect(ox::serialize(256).unwrap(), BA({0, 1, 0, 0})); - oxExpect(ox::serialize(257).unwrap(), BA({1, 1, 0, 0})); + ox::expect(ox::serialize(4).unwrap(), BA({4, 0, 0, 0})); + ox::expect(ox::serialize(256).unwrap(), BA({0, 1, 0, 0})); + ox::expect(ox::serialize(257).unwrap(), BA({1, 1, 0, 0})); + ox::expect(ox::serialize(4).unwrap(), BA({4, 0, 0, 0})); + ox::expect(ox::serialize(256).unwrap(), BA({0, 1, 0, 0})); + ox::expect(ox::serialize(257).unwrap(), BA({1, 1, 0, 0})); constexpr auto neg1 = static_cast(-1); // ARM64 Linux assumes -1 literals are ints... - oxExpect(ox::serialize(0xffff'ffff).unwrap(), BA({neg1, neg1, neg1, neg1})); - return ox::Error(0); + ox::expect(ox::serialize(0xffff'ffff).unwrap(), BA({neg1, neg1, neg1, neg1})); + return ox::Error{}; } }, { @@ -394,58 +395,58 @@ OX_CLANG_NOWARN_END ox::Buffer b; ox::BufferWriter w(&b); oxAssert(w.write("asdf", 4), "write failed"); - oxExpect(b.size(), 4u); + ox::expect(b.size(), 4u); oxAssert(w.write("aoeu", 4), "write failed"); - oxExpect(b.size(), 8u); - oxExpect(ox::StringView(b.data(), b.size()), "asdfaoeu"); + ox::expect(b.size(), 8u); + ox::expect(ox::StringView(b.data(), b.size()), "asdfaoeu"); ox::StringView constexpr qwerty = "qwerty"; oxAssert(w.write(qwerty.data(), qwerty.bytes()), "write failed"); - oxExpect(b.size(), 14u); - oxExpect(ox::StringView(b.data(), b.size()), "asdfaoeuqwerty"); - return ox::Error(0); + ox::expect(b.size(), 14u); + ox::expect(ox::StringView(b.data(), b.size()), "asdfaoeuqwerty"); + return ox::Error{}; } }, { "FromHex", [] { - oxExpect(ox::detail::fromHex("01").unwrap(), 0x01); - oxExpect(ox::detail::fromHex("02").unwrap(), 0x02); - oxExpect(ox::detail::fromHex("03").unwrap(), 0x03); - oxExpect(ox::detail::fromHex("04").unwrap(), 0x04); - oxExpect(ox::detail::fromHex("05").unwrap(), 0x05); - oxExpect(ox::detail::fromHex("06").unwrap(), 0x06); - oxExpect(ox::detail::fromHex("07").unwrap(), 0x07); - oxExpect(ox::detail::fromHex("08").unwrap(), 0x08); - oxExpect(ox::detail::fromHex("0d").unwrap(), 0x0d); - oxExpect(ox::detail::fromHex("0e").unwrap(), 0x0e); - oxExpect(ox::detail::fromHex("0f").unwrap(), 0x0f); - oxExpect(ox::detail::fromHex("0F").unwrap(), 0x0f); - oxExpect(ox::detail::fromHex("fF").unwrap(), 0xff); - oxExpect(ox::detail::fromHex("ff").unwrap(), 0xff); - oxExpect(ox::detail::fromHex("a0").unwrap(), 0xa0); - oxExpect(ox::detail::fromHex("93").unwrap(), 0x93); - oxExpect(ox::detail::fromHex("40").unwrap(), 0x40); - return ox::Error(0); + ox::expect(ox::detail::fromHex("01").unwrap(), 0x01); + ox::expect(ox::detail::fromHex("02").unwrap(), 0x02); + ox::expect(ox::detail::fromHex("03").unwrap(), 0x03); + ox::expect(ox::detail::fromHex("04").unwrap(), 0x04); + ox::expect(ox::detail::fromHex("05").unwrap(), 0x05); + ox::expect(ox::detail::fromHex("06").unwrap(), 0x06); + ox::expect(ox::detail::fromHex("07").unwrap(), 0x07); + ox::expect(ox::detail::fromHex("08").unwrap(), 0x08); + ox::expect(ox::detail::fromHex("0d").unwrap(), 0x0d); + ox::expect(ox::detail::fromHex("0e").unwrap(), 0x0e); + ox::expect(ox::detail::fromHex("0f").unwrap(), 0x0f); + ox::expect(ox::detail::fromHex("0F").unwrap(), 0x0f); + ox::expect(ox::detail::fromHex("fF").unwrap(), 0xff); + ox::expect(ox::detail::fromHex("ff").unwrap(), 0xff); + ox::expect(ox::detail::fromHex("a0").unwrap(), 0xa0); + ox::expect(ox::detail::fromHex("93").unwrap(), 0x93); + ox::expect(ox::detail::fromHex("40").unwrap(), 0x40); + return ox::Error{}; } }, { "ToHex", [] { - oxExpect(ox::detail::toHex(0x01), "01"); - oxExpect(ox::detail::toHex(0x02), "02"); - oxExpect(ox::detail::toHex(0x03), "03"); - oxExpect(ox::detail::toHex(0x04), "04"); - oxExpect(ox::detail::toHex(0x05), "05"); - oxExpect(ox::detail::toHex(0x06), "06"); - oxExpect(ox::detail::toHex(0x07), "07"); - oxExpect(ox::detail::toHex(0x08), "08"); - oxExpect(ox::detail::toHex(0x0d), "0d"); - oxExpect(ox::detail::toHex(0x0e), "0e"); - oxExpect(ox::detail::toHex(0x0f), "0f"); - oxExpect(ox::detail::toHex(0x93), "93"); - oxExpect(ox::detail::toHex(0x40), "40"); - oxExpect(ox::detail::toHex(0xf0), "f0"); - return ox::Error(0); + ox::expect(ox::detail::toHex(0x01), "01"); + ox::expect(ox::detail::toHex(0x02), "02"); + ox::expect(ox::detail::toHex(0x03), "03"); + ox::expect(ox::detail::toHex(0x04), "04"); + ox::expect(ox::detail::toHex(0x05), "05"); + ox::expect(ox::detail::toHex(0x06), "06"); + ox::expect(ox::detail::toHex(0x07), "07"); + ox::expect(ox::detail::toHex(0x08), "08"); + ox::expect(ox::detail::toHex(0x0d), "0d"); + ox::expect(ox::detail::toHex(0x0e), "0e"); + ox::expect(ox::detail::toHex(0x0f), "0f"); + ox::expect(ox::detail::toHex(0x93), "93"); + ox::expect(ox::detail::toHex(0x40), "40"); + ox::expect(ox::detail::toHex(0xf0), "f0"); + return ox::Error{}; } }, { @@ -453,20 +454,20 @@ OX_CLANG_NOWARN_END [] { constexpr ox::StringView uuidStr = "8d814442-f46e-4cc3-8edc-ca3c01cc86db"; OX_REQUIRE(uuid, ox::UUID::fromString(uuidStr)); - oxExpect(uuid.toString(), uuidStr); - oxExpect(ox::UUID{}.isNull(), true); - oxExpect(ox::UUID::fromString(uuidStr).value.isNull(), false); - return ox::Error(0); + ox::expect(uuid.toString(), uuidStr); + ox::expect(ox::UUID{}.isNull(), true); + ox::expect(ox::UUID::fromString(uuidStr).value.isNull(), false); + return ox::Error{}; } }, { "UUID::generate", [] { ox::UUID::seedGenerator({1234, 4321}); - oxExpect(ox::UUID::generate().unwrap().toString(), "5c3f4b5e-ccbf-4727-7f03-3053dedc8827"); - oxExpect(ox::UUID::generate().unwrap().toString(), "90d0274a-2774-4afa-88e5-0c1d60ba3abf"); - oxExpect(ox::UUID::generate().unwrap().toString(), "7df77910-841c-48ba-ea2e-44521ac47c2e"); - return ox::Error(0); + ox::expect(ox::UUID::generate().unwrap().toString(), "5c3f4b5e-ccbf-4727-7f03-3053dedc8827"); + ox::expect(ox::UUID::generate().unwrap().toString(), "90d0274a-2774-4afa-88e5-0c1d60ba3abf"); + ox::expect(ox::UUID::generate().unwrap().toString(), "7df77910-841c-48ba-ea2e-44521ac47c2e"); + return ox::Error{}; } }, { @@ -474,71 +475,100 @@ OX_CLANG_NOWARN_END [] { ox::StringView sv = "ab.cd"; auto list = ox::split(sv, "."); - oxExpect(list.size(), 2u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); + ox::expect(list.size(), 2u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); sv = "ab.cd.fg"; list = ox::split(sv, "."); - oxExpect(list.size(), 3u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); - oxExpect(list[2], "fg"); + ox::expect(list.size(), 3u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); + ox::expect(list[2], "fg"); sv = "ab.cd."; list = ox::split(sv, "."); - oxExpect(list.size(), 2u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); + ox::expect(list.size(), 2u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); sv = ".ab.cd."; list = ox::split(sv, "."); - oxExpect(list.size(), 2u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); + ox::expect(list.size(), 2u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); sv = "."; list = ox::split(sv, "."); - oxExpect(list.size(), 0u); + ox::expect(list.size(), 0u); sv = "."; list = ox::split(sv, "."); - oxExpect(list.size(), 0u); + ox::expect(list.size(), 0u); sv = ""; list = ox::split(sv, "."); - oxExpect(list.size(), 0u); + ox::expect(list.size(), 0u); // split by single char sv = "ab.cd"; list = ox::split(sv, '.'); - oxExpect(list.size(), 2u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); + ox::expect(list.size(), 2u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); sv = "ab.cd.fg"; list = ox::split(sv, '.'); - oxExpect(list.size(), 3u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); - oxExpect(list[2], "fg"); + ox::expect(list.size(), 3u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); + ox::expect(list[2], "fg"); sv = "ab.cd."; list = ox::split(sv, '.'); - oxExpect(list.size(), 2u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); + ox::expect(list.size(), 2u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); sv = ".ab.cd."; list = ox::split(sv, '.'); - oxExpect(list.size(), 2u); - oxExpect(list[0], "ab"); - oxExpect(list[1], "cd"); + ox::expect(list.size(), 2u); + ox::expect(list[0], "ab"); + ox::expect(list[1], "cd"); sv = "."; list = ox::split(sv, '.'); - oxExpect(list.size(), 0u); + ox::expect(list.size(), 0u); sv = "."; list = ox::split(sv, '.'); - oxExpect(list.size(), 0u); + ox::expect(list.size(), 0u); sv = ""; list = ox::split(sv, '.'); - oxExpect(list.size(), 0u); - return ox::Error(0); + ox::expect(list.size(), 0u); + return ox::Error{}; + } + }, + { + "intToStr", + [] { + ox::expect(ox::intToStr(255u), "255"); + ox::expect(ox::intToStr(127), "127"); + ox::expect(ox::intToStr(-128), "-128"); + ox::expect(ox::intToStr(65535u), "65535"); + ox::expect(ox::intToStr(32767), "32767"); + ox::expect(ox::intToStr(-32768), "-32768"); + ox::expect(ox::intToStr(4294967295u), "4294967295"); + ox::expect(ox::intToStr(2147483647), "2147483647"); + ox::expect(ox::intToStr(-2147483648), "-2147483648"); + ox::expect(ox::intToStr(18446744073709551615u), "18446744073709551615"); + ox::expect(ox::intToStr(9223372036854775807), "9223372036854775807"); + ox::expect(ox::intToStr(-9223372036854775807), "-9223372036854775807"); + ox::expect(ox::intToStr(0), "0"); + ox::expect(ox::intToStr(5), "5"); + ox::expect(ox::intToStr(0), "0"); + ox::expect(ox::intToStr(5), "5"); + ox::expect(ox::intToStr(5000), "5000"); + ox::expect(ox::intToStr(50000), "50000"); + ox::expect(ox::intToStr(500000), "500000"); + ox::expect(ox::intToStr(-5), "-5"); + ox::expect(ox::intToStr(-5000), "-5000"); + ox::expect(ox::intToStr(-50000), "-50000"); + ox::expect(ox::intToStr(-500000), "-500000"); + return ox::Error{}; } }, }; -int main(int argc, const char **argv) { +int main(int const argc, const char **argv) { if (argc < 2) { oxError("Must specify test to run"); return -1; diff --git a/deps/ox/src/ox/std/typetraits.hpp b/deps/ox/src/ox/std/typetraits.hpp index f123ed0..c4368e8 100644 --- a/deps/ox/src/ox/std/typetraits.hpp +++ b/deps/ox/src/ox/std/typetraits.hpp @@ -180,20 +180,6 @@ struct is_same: true_type {}; template constexpr auto is_same_v = is_same::value; -// enable_if /////////////////////////////////////////////////////////////////// - -template -struct enable_if { -}; - -template -struct enable_if { - using type = T; -}; - -template -using enable_if_t = typename enable_if::type; - template struct is_pointer { static constexpr bool value = false; diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index 6126091..5c3f3c8 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -247,6 +247,8 @@ class Vector: detail::VectorAllocator { constexpr void resize(std::size_t size) noexcept(useNoexcept); + constexpr void reserveResize(std::size_t size) noexcept(useNoexcept); + [[nodiscard]] constexpr T *data() noexcept { return m_items; @@ -261,7 +263,7 @@ class Vector: detail::VectorAllocator { constexpr bool contains(MaybeView_t const&) const noexcept; constexpr iterator insert( - std::size_t pos, std::size_t cnt, T const&val) noexcept(useNoexcept); + std::size_t pos, std::size_t cnt, T const &val) noexcept(useNoexcept); constexpr iterator insert(std::size_t pos, T val) noexcept(useNoexcept); @@ -417,13 +419,13 @@ constexpr Vector &Vector constexpr T &Vector::operator[](std::size_t i) noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Vector access overflow"); + boundsCheck(i, size(), "Vector access overflow"); return m_items[i]; } template constexpr const T &Vector::operator[](std::size_t i) const noexcept { - boundsCheck(__FILE__, __LINE__, i, size(), "Vector access overflow"); + boundsCheck(i, size(), "Vector access overflow"); return m_items[i]; } @@ -518,7 +520,13 @@ constexpr void Vector::resize(std::size_t size) n } template -constexpr bool Vector::contains(MaybeView_t const&v) const noexcept { +constexpr void Vector::reserveResize(std::size_t const size) noexcept(useNoexcept) { + reserve(size); + resize(size); +} + +template +constexpr bool Vector::contains(MaybeView_t const &v) const noexcept { for (std::size_t i = 0; i < m_size; ++i) { if (m_items[i] == v) { return true; @@ -530,7 +538,7 @@ constexpr bool Vector::contains(MaybeView_t co template constexpr typename Vector::template iterator Vector::insert( - std::size_t pos, std::size_t cnt, T const&val) noexcept(useNoexcept) { + std::size_t pos, std::size_t cnt, T const &val) noexcept(useNoexcept) { if (m_size + cnt > m_cap) { reserveInsert(m_cap ? m_size + cnt : initialCap, pos, cnt); } diff --git a/developer-handbook.md b/developer-handbook.md index b5168da..f3d7e11 100644 --- a/developer-handbook.md +++ b/developer-handbook.md @@ -27,9 +27,9 @@ All components have a platform indicator next to them: * opengl - OpenGL implementation (P-) * studio - studio plugin for core (P-) * keel - keel plugin for core (PG) - * scene - defines & processes map data (PG) - * studio - studio plugin for scene (P-) - * keel - keel plugin for scene (PG) + * sound - sound system for Nostalgia (PG) + * studio - studio plugin for sound (P-) + * keel - keel plugin for sound (PG) * player - plays the games (PG) * studio - makes the games (P-) * tools - command line tools (P-) @@ -48,7 +48,7 @@ All components have a platform indicator next to them: Not really that external... (PG) * GlUtils - OpenGL helpers (P-) * teagba - GBA assembly startup code (mostly pulled from devkitPro under MPL - 2.0), and custom GBA hardware interop code (-G) + 2.0), and custom GBA hardware interop code (-G) Most GBA code is built on PC because it is small and helps to work on both projects with the same CMake build dir, but GBA code is never linked with any @@ -89,7 +89,8 @@ The GBA has two major resources for learning about its hardware: On the surface, it seems like C++ changes the way we do things from C for no reason, but there are reasons for many of these duplications of functionality. -The C++ language designers aren't stupid. Question them, but don't ignore them. +The C++ language designers aren't stupid. +Question them, but don't ignore them. #### Casting @@ -163,10 +164,11 @@ The Ox way of doing things is the Olympic way of doing things. ### Error Handling Instead of throwing exceptions, generally try to use -[ox::Errors](deps/ox/ox-docs.md#error-handling) for error reporting, -but exceptions may be used where they make sense. +[ox::Error](deps/ox/ox-docs.md#error-handling) for error reporting. +Exceptions may be used where errors-as-values will not work, but catch them and +convert them to ```ox::Error``` as soon as possible. -Exceptions should generally just use ```OxException```, which is bascially an +Exceptions should generally just use ```ox::Exception```, which is basically an exception form of ```ox::Error```. ### File I/O diff --git a/src/nostalgia/modules/gfx/src/gfx-gba.cpp b/src/nostalgia/modules/gfx/src/gfx-gba.cpp index 766f74b..e7db12d 100644 --- a/src/nostalgia/modules/gfx/src/gfx-gba.cpp +++ b/src/nostalgia/modules/gfx/src/gfx-gba.cpp @@ -321,23 +321,23 @@ void showSprite(Context&, unsigned const idx) noexcept { }); } -void setSprite(Context&, uint_t const idx, Sprite const &s) noexcept { +void setSprite(Context&, uint_t const idx, Sprite const &sprite) noexcept { //oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow"); - uint16_t const eightBpp = s.bpp == 8; + uint16_t const eightBpp = sprite.bpp == 8; teagba::addSpriteUpdate({ .attr0 = static_cast( - (static_cast(s.y & ox::onMask(0b111'1111))) + (static_cast(sprite.y & ox::onMask(0b111'1111))) | (static_cast(1) << 10) // enable alpha | (static_cast(eightBpp) << 13) - | (static_cast(s.spriteShape) << 14)), + | (static_cast(sprite.spriteShape) << 14)), .attr1 = static_cast( - (static_cast(s.x) & ox::onMask(8)) - | (static_cast(s.flipX) << 12) - | (static_cast(s.spriteSize) << 14)), + (static_cast(sprite.x) & ox::onMask(8)) + | (static_cast(sprite.flipX) << 12) + | (static_cast(sprite.spriteSize) << 14)), .attr2 = static_cast( // double tileIdx if 8 bpp - (static_cast((s.tileIdx * (1 + eightBpp)) & ox::onMask(8))) - | (static_cast(s.priority & 0b11) << 10)), + (static_cast((sprite.tileIdx * (1 + eightBpp)) & ox::onMask(8))) + | (static_cast(sprite.priority & 0b11) << 10)), .idx = static_cast(idx), }); } @@ -350,7 +350,7 @@ uint_t spriteCount(Context const &) noexcept { namespace ox { -void panic(char const *file, int line, char const *panicMsg, ox::Error const &err) noexcept { +void panic(char const*panicMsg, Error const&err, std::source_location const &src) noexcept { using namespace nostalgia::gfx; // reset heap to make sure we have enough memory to allocate context data OX_ALLOW_UNSAFE_BUFFERS_BEGIN @@ -374,7 +374,7 @@ void panic(char const *file, int line, char const *panicMsg, ox::Error const &er } consoleWrite(*ctx, 32 + 1, 15, "PLEASE RESTART THE SYSTEM"); // print to terminal if in mGBA - oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg); + oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", src.file_name(), src.line(), panicMsg); if (err.msg) { oxErrf("\tError Message:\t{}\n", err.msg); } diff --git a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixelgrid.cpp b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixelgrid.cpp index c24549c..a443e03 100644 --- a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixelgrid.cpp +++ b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixelgrid.cpp @@ -69,7 +69,7 @@ void TileSheetGrid::update(ox::Vec2 const &paneSize, TileSheet::SubSheet const & glBindVertexArray(m_bufferSet.vao); setBufferObjects(paneSize, subsheet); glutils::sendVbo(m_bufferSet); - glutils::sendEbo(m_bufferSet); + //glutils::sendEbo(m_bufferSet); } void TileSheetGrid::setBufferObject( @@ -89,7 +89,6 @@ void TileSheetGrid::setBufferObject( void TileSheetGrid::setBufferObjects(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept { if (subsheet.columns < 1 || subsheet.rows < 1) { - m_bufferSet.elements.clear(); m_bufferSet.vertices.clear(); return; } diff --git a/src/nostalgia/modules/gfx/test/CMakeLists.txt b/src/nostalgia/modules/gfx/test/CMakeLists.txt index bfcaf5d..66b0877 100644 --- a/src/nostalgia/modules/gfx/test/CMakeLists.txt +++ b/src/nostalgia/modules/gfx/test/CMakeLists.txt @@ -8,4 +8,4 @@ target_link_libraries( NostalgiaGfx ) -add_test("[NostalgiaGfx] readWriteTileSheet" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/NostalgiaGfxTest readWriteTileSheet) +add_test("[nostalgia/gfx] readWriteTileSheet" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/NostalgiaGfxTest readWriteTileSheet) diff --git a/src/nostalgia/modules/gfx/test/tests.cpp b/src/nostalgia/modules/gfx/test/tests.cpp index cb3f018..1f3d30c 100644 --- a/src/nostalgia/modules/gfx/test/tests.cpp +++ b/src/nostalgia/modules/gfx/test/tests.cpp @@ -18,7 +18,7 @@ static std::map tests = { gfx::TileSheet const in; OX_REQUIRE(buff, ox::writeMC(in)); OX_REQUIRE(out, ox::readMC(buff)); - oxAssert(in.subsheet.name == out.subsheet.name, "subsheet.name serialization broken"); + ox::expect(in.subsheet.name, out.subsheet.name); return {}; } }, diff --git a/src/olympic/keel/test/tests.cpp b/src/olympic/keel/test/tests.cpp index 52dfc7c..deeb57b 100644 --- a/src/olympic/keel/test/tests.cpp +++ b/src/olympic/keel/test/tests.cpp @@ -19,7 +19,7 @@ static std::map tests = { ox::Array buff; ox::CharBuffWriter bw(buff); OX_RETURN_ERROR(keel::writeUuidHeader(bw, uuid)); - oxExpect(ox::StringView(buff.data(), buff.size()), hdr); + ox::expect(ox::StringView(buff.data(), buff.size()), hdr); return {}; } }, diff --git a/src/olympic/turbine/src/glfw/turbine.cpp b/src/olympic/turbine/src/glfw/turbine.cpp index 6efb6dd..cc4b1ba 100644 --- a/src/olympic/turbine/src/glfw/turbine.cpp +++ b/src/olympic/turbine/src/glfw/turbine.cpp @@ -285,11 +285,11 @@ static void handleKeyPress(Context &ctx, int const key, bool const down) noexcep map[GLFW_KEY_ESCAPE] = Key::Escape; return map; }(); - auto const eventHandler = keyEventHandler(ctx); auto const keyIdx = static_cast(key); if (keyIdx < keyMap.size()) { auto const k = keyMap[keyIdx]; setKeyDownStatus(ctx, k, down); + auto const eventHandler = keyEventHandler(ctx); if (eventHandler) { eventHandler(ctx, k, down); } @@ -306,7 +306,9 @@ static void handleGlfwMouseButtonEvent( int) noexcept { auto &ctx = *static_cast(glfwGetWindowUserPointer(window)); setMandatoryRefreshPeriod(ctx, ticksMs(ctx) + config::MandatoryRefreshPeriod); - ctx.mouseButtonEventHandler(ctx, btn, action == 1); + if (ctx.mouseButtonEventHandler) { + ctx.mouseButtonEventHandler(ctx, btn, action == 1); + } } static void handleGlfwKeyEvent(GLFWwindow *window, int const key, int, int const action, int) noexcept {