godot_voxel/util/errors.h
2022-04-11 02:10:44 +01:00

62 lines
3.1 KiB
C

#ifndef ZN_ERRORS_H
#define ZN_ERRORS_H
#include "log.h"
// Tell the compiler to favour a certain branch of a condition.
// Until C++20 can be used with the [[likely]] and [[unlikely]] attributes.
#if defined(__GNUC__)
#define ZN_LIKELY(x) __builtin_expect(!!(x), 1)
#define ZN_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define ZN_LIKELY(x) x
#define ZN_UNLIKELY(x) x
#endif
// Abnormally terminate the program
#ifdef _MSC_VER
#define ZN_GENERATE_TRAP() __debugbreak()
#else
#define ZN_GENERATE_TRAP() __builtin_trap()
#endif
// The following macros print a message and crash the program.
#define ZN_CRASH_MSG(msg) \
zylann::print_error("FATAL: Method/function failed.", msg, __FUNCTION__, __FILE__, __LINE__); \
zylann::flush_stdout(); \
ZN_GENERATE_TRAP()
#define ZN_CRASH() ZN_CRASH_MSG("")
// The following macros check a condition. If it fails, they print a message and crash the program.
#define ZN_ASSERT_MSG(cond, msg) \
if (ZN_UNLIKELY(!(cond))) { \
zylann::print_error( \
"FATAL: Assertion failed: \"" #cond "\" is false.", msg, __FUNCTION__, __FILE__, __LINE__); \
zylann::flush_stdout(); \
ZN_GENERATE_TRAP(); \
} else \
((void)0)
#define ZN_ASSERT(cond) ZN_ASSERT_MSG(cond, "")
// The following macros check a condition. If it fails, they print a message, then return or continue.
#define ZN_INTERNAL_ASSERT_ACT(cond, act, msg) \
if (ZN_UNLIKELY(!(cond))) { \
zylann::print_error("Assertion failed: \"" #cond "\" is false.", msg, __FUNCTION__, __FILE__, __LINE__); \
act; \
} else \
((void)0)
#define ZN_ASSERT_RETURN(cond) ZN_INTERNAL_ASSERT_ACT(cond, return, "")
#define ZN_ASSERT_RETURN_MSG(cond, msg) ZN_INTERNAL_ASSERT_ACT(cond, return, msg)
#define ZN_ASSERT_RETURN_V(cond, retval) ZN_INTERNAL_ASSERT_ACT(cond, return retval, "")
#define ZN_ASSERT_RETURN_V_MSG(cond, retval, msg) ZN_INTERNAL_ASSERT_ACT(cond, return retval, msg)
#define ZN_ASSERT_CONTINUE(cond) ZN_INTERNAL_ASSERT_ACT(cond, continue, "")
#define ZN_ASSERT_CONTINUE_MSG(cond, msg) ZN_INTERNAL_ASSERT_ACT(cond, continue, msg)
#endif // ZN_ERRORS_H