/* * Copyright 2015 - 2024 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once // Logging #define oxLogError(...) ox::trace::logError(__FILE__, __LINE__, __VA_ARGS__) #define oxTrace(...) ox::trace::TraceStream(__FILE__, __LINE__, __VA_ARGS__) #define oxOut(...) ox::trace::OutStream(__FILE__, __LINE__, "stdout", __VA_ARGS__) #define oxErr(...) ox::trace::OutStream(__FILE__, __LINE__, "stderr", __VA_ARGS__) #define oxTracef(ch, fmt, ...) ox::trace::TraceStream(__FILE__, __LINE__, ch, ox::detail::fmtSegments(fmt), __VA_ARGS__) #define oxOutf(fmt, ...) ox::trace::OutStream(__FILE__, __LINE__, "stdout", ox::detail::fmtSegments(fmt), __VA_ARGS__) #define oxErrf(fmt, ...) ox::trace::OutStream(__FILE__, __LINE__, "stderr", ox::detail::fmtSegments(fmt), __VA_ARGS__) #define oxInfo(...) oxTrace("info", __VA_ARGS__) #define oxInfof(...) oxTracef("info", __VA_ARGS__) #define oxError(...) oxTrace("error", __VA_ARGS__) #define oxErrorf(...) oxTracef("error", __VA_ARGS__) #ifndef OX_NODEBUG #define oxDebug(...) ox::trace::OutStream(__FILE__, __LINE__, "debug", __VA_ARGS__) #define oxDebugf(fmt, ...) ox::trace::OutStream(__FILE__, __LINE__, "debug", ox::detail::fmtSegments(fmt), __VA_ARGS__) #else #define oxDebug(...) static_assert(false, "Debug prints were checked in."); #define oxDebugf(...) static_assert(false, "Debug prints were checked in."); #endif // Error handling #define oxReturnError(x) { if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] return _ox_error; } (void) 0 #define oxThrowError(x) { if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] throw ox::Exception(_ox_error); } (void) 0 #define oxConcatImpl(a, b) a##b #define oxConcat(a, b) oxConcatImpl(a, b) // oxRequire Mutable #define oxRequireM(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__)) #define oxRequire(out, x) const oxRequireM(out, x) // oxRequire Mutable Throw #define oxRequireMT(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxThrowError(oxConcat(oxRequire_err_, __LINE__)) // oxRequire Throw #define oxRequireT(out, x) const oxRequireMT(out, x) // Asserts #define oxPanic(errCode, msg) ox::panic(__FILE__, __LINE__, msg, errCode) #ifndef NDEBUG #define oxAssert(pass, msg) ox::assertFunc(__FILE__, __LINE__, pass, #pass, msg) #else namespace ox { struct [[nodiscard]] Error; } 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) #define ox_alloca(size) _alloca(size) #elif OX_USE_STDLIB #define ox_alloca(size) alloca(size) #else #define ox_alloca(size) __builtin_alloca(size) #endif /** * @return an ox::MallocaPtr of the given type pointing to the requested size memory allocation */ #if defined(OX_USE_STDLIB) #define ox_malloca(size, Type, ...) ox::MallocaPtr(size > ox::MallocaStackLimit, new (size > ox::MallocaStackLimit ? new uint8_t[size] : ox_alloca(size)) Type(__VA_ARGS__)) #else #define ox_malloca(size, Type, ...) ox::MallocaPtr(false, new (ox_alloca(size)) Type(__VA_ARGS__)) #endif