diff --git a/source/mijin/debug/assert.hpp b/source/mijin/debug/assert.hpp index 033515f..efc5263 100644 --- a/source/mijin/debug/assert.hpp +++ b/source/mijin/debug/assert.hpp @@ -10,6 +10,11 @@ #include "../internal/common.hpp" +#if MIJIN_THROWING_ASSERTS +#include +#include // I'd prefer mijin Exceptions here, but that would result in a circual include :/ +#endif + #ifdef _WIN32 #pragma comment(lib, "kernel32") extern "C" __declspec(dllimport) void __stdcall DebugBreak(); @@ -127,6 +132,49 @@ enum class ErrorHandling ABORT = 2 }; +#if MIJIN_THROWING_ASSERTS +namespace impl +{ +inline std::string formatAssertionExceptionMessage(const char* condition, const char* message, const std::source_location& location) +{ + std::ostringstream oss; + oss << "Assertion failed!\n" + << "Condition: " << condition << "\n" + << "Message: " << message << "\n" + << "Location: " << location.file_name() << ":" << location.line() << ":" << location.column() << "\n" + << "Function: " << location.function_name(); + return oss.str(); +} + +inline std::string formatErrorExceptionMessage(const char* message, const std::source_location& location) +{ + std::ostringstream oss; + oss << "Mijin error!\n" + << "Message: " << message << "\n" + << "Location: " << location.file_name() << ":" << location.line() << ":" << location.column() << "\n" + << "Function: " << location.function_name(); + return oss.str(); +} +} +class AssertionException : public std::runtime_error +{ +public: + AssertionException(const char* condition, const char* message, const std::source_location& location) + : std::runtime_error(impl::formatAssertionExceptionMessage(condition, message, location)) + { + } +}; + +class ErrorException : public std::runtime_error +{ +public: + ErrorException(const char* message, const std::source_location& location) + : std::runtime_error(impl::formatErrorExceptionMessage(message, location)) + { + } +}; +#endif + // // public functions // @@ -134,9 +182,14 @@ enum class ErrorHandling #ifdef MIJIN_USE_CUSTOM_ASSERTION_HANDLER AssertionResult handleAssert(const char* condition, const char* message, const std::source_location& location); +#elif MIJIN_THROWING_ASSERTS +inline AssertionResult handleAssert(const char* condition, const char* message, const std::source_location& location) +{ + throw AssertionException(condition, message, location); +} #else -constexpr AssertionResult handleAssert(const char* /* condition */, - const char* /* message */, const std::source_location& /* location */) +constexpr AssertionResult handleAssert(const char* /* condition */, const char* /* message */, + const std::source_location& /* location */) { return AssertionResult::ERROR; } @@ -147,11 +200,15 @@ ErrorHandling handleError(const char* message, const std::source_location& locat #else inline ErrorHandling handleError(const char* message, const std::source_location& location) MIJIN_NOEXCEPT { +#if MIJIN_THROWING_ASSERTS + throw ErrorException(message, location); +#else std::puts(message); std::printf("Function: %s\n", location.function_name()); std::printf("Location: %s:%d:%d\n", location.file_name(), location.line(), location.column()); (void) std::fflush(stdout); return ErrorHandling::TRAP; +#endif } #endif diff --git a/source/mijin/internal/exception.hpp b/source/mijin/internal/exception.hpp index fe6c3df..cd7fad6 100644 --- a/source/mijin/internal/exception.hpp +++ b/source/mijin/internal/exception.hpp @@ -8,6 +8,14 @@ #define MIJIN_WITH_EXCEPTIONS 0 #endif +#if !defined(MIJIN_THROWING_ASSERTS) +#define MIJIN_THROWING_ASSERTS 0 +#endif + +#if MIJIN_THROWING_ASSERTS && !defined(MIJIN_TEST_NO_NOEXCEPT) +#define MIJIN_TEST_NO_NOEXCEPT +#endif + #if MIJIN_WITH_EXCEPTIONS #error "Maybe someday" #else diff --git a/source/mijin/net/ip.cpp b/source/mijin/net/ip.cpp index 3daf02c..c800e53 100644 --- a/source/mijin/net/ip.cpp +++ b/source/mijin/net/ip.cpp @@ -14,6 +14,11 @@ #include #endif +#if MIJIN_COMPILER == MIJIN_COMPILER_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif // MIJIN_COMPILER == MIJIN_COMPILER_CLANG + namespace mijin { namespace @@ -289,3 +294,7 @@ Task>> c_resolveHostname(std::string host co_return osResolveResult(resolveHandle); } } + +#if MIJIN_COMPILER == MIJIN_COMPILER_CLANG +#pragma clang diagnostic pop +#endif // MIJIN_COMPILER == MIJIN_COMPILER_CLANG diff --git a/source/mijin/net/request.cpp b/source/mijin/net/request.cpp index d8e0bae..1f271b8 100644 --- a/source/mijin/net/request.cpp +++ b/source/mijin/net/request.cpp @@ -131,6 +131,7 @@ Task> c_request(const URL& url, HTTPRequestOptions op #undef HANDLE_CURL_RESULT HTTPResponse response = { + .version = {}, .body = std::move(body) }; if (const curl::Result httpVersion = easy.getHTTPVersion(); httpVersion.isSuccess()) diff --git a/source/mijin/net/socket.cpp b/source/mijin/net/socket.cpp index 432d56e..0cb4fa9 100644 --- a/source/mijin/net/socket.cpp +++ b/source/mijin/net/socket.cpp @@ -6,6 +6,11 @@ #include "../internal/common.hpp" #include "../util/variant.hpp" +#if MIJIN_COMPILER == MIJIN_COMPILER_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif // MIJIN_COMPILER == MIJIN_COMPILER_CLANG + namespace mijin { namespace @@ -472,3 +477,7 @@ Task>> TCPServerSocket::c_waitForConnection co_return StreamError::CONNECTION_CLOSED; } } + +#if MIJIN_COMPILER == MIJIN_COMPILER_CLANG +#pragma clang diagnostic pop +#endif // MIJIN_COMPILER == MIJIN_COMPILER_CLANG diff --git a/source/mijin/types/script_value.hpp b/source/mijin/types/script_value.hpp index 2ae6729..ba44ef6 100644 --- a/source/mijin/types/script_value.hpp +++ b/source/mijin/types/script_value.hpp @@ -13,6 +13,7 @@ #include "../container/map_view.hpp" #include "../container/optional.hpp" +#include "../container/vector_map.hpp" #include "../internal/common.hpp" #include "../util/traits.hpp" #include "../util/variant.hpp" @@ -39,7 +40,7 @@ struct ArrayValue template struct MapValue { - std::unordered_map values; + VectorMap values; auto operator<=>(const MapValue&) const MIJIN_NOEXCEPT = default; };