dynarmic/src/common/assert.h
2020-08-14 14:45:53 -04:00

69 lines
2.5 KiB
C++

/* This file is part of the dynarmic project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <fmt/format.h>
#include "common/unlikely.h"
namespace Dynarmic::Common {
[[noreturn]] void Terminate(fmt::string_view msg, fmt::format_args args);
namespace detail {
template <typename... Ts>
[[noreturn]] void TerminateHelper(fmt::string_view msg, Ts... args) {
Terminate(msg, fmt::make_format_args(args...));
}
} // namespace detail
} // namespace Dynarmic::Common
#if defined(NDEBUG)
#if defined(__clang) || defined(__GNUC__)
#define UNREACHABLE() __builtin_unreachable()
#define ASSUME(expr) [&]{ if (!(expr)) __builtin_unreachable(); }()
#elif defined(_MSC_VER)
#define UNREACHABLE() __assume(0)
#define ASSUME(expr) __assume(expr)
#else
#define UNREACHABLE() ASSERT_FALSE("Unreachable code!")
#define ASSUME(expr)
#endif
#else
#define UNREACHABLE() ASSERT_FALSE("Unreachable code!")
#define ASSUME(expr)
#endif
#ifdef DYNARMIC_IGNORE_ASSERTS
#define ASSERT(expr) ASSUME(expr)
#define ASSERT_MSG(expr, ...) ASSUME(expr)
#define ASSERT_FALSE(...) UNREACHABLE()
#else
#define ASSERT(expr) \
[&]{ \
if (UNLIKELY(!(expr))) { \
::Dynarmic::Common::detail::TerminateHelper(#expr); \
} \
}()
#define ASSERT_MSG(expr, ...) \
[&]{ \
if (UNLIKELY(!(expr))) { \
::Dynarmic::Common::detail::TerminateHelper(#expr "\nMessage: " __VA_ARGS__); \
} \
}()
#define ASSERT_FALSE(...) ::Dynarmic::Common::detail::TerminateHelper("false\nMessage: " __VA_ARGS__)
#endif
#if defined(NDEBUG) || defined(DYNARMIC_IGNORE_ASSERTS)
#define DEBUG_ASSERT(expr) ASSUME(expr)
#define DEBUG_ASSERT_MSG(expr, ...) ASSUME(expr)
#else
#define DEBUG_ASSERT(expr) ASSERT(expr)
#define DEBUG_ASSERT_MSG(expr, ...) ASSERT_MSG(expr, __VA_ARGS__)
#endif