#pragma once
#include "BuildSettings.h"
#include "mptBaseMacros.h"
OPENMPT_NAMESPACE_BEGIN
#define MPT_CHECKER_ASSUME_ASSERTIONS 1
#ifdef MPT_BUILD_ANALYZED
#if MPT_COMPILER_MSVC
#if MPT_CHECKER_ASSUME_ASSERTIONS
#define MPT_CHECKER_ASSUME(x) __analysis_assume(!!(x))
#endif
#elif MPT_COMPILER_CLANG
#if MPT_CHECKER_ASSUME_ASSERTIONS
#ifdef NDEBUG
#error "Builds for static analyzers depend on assert() being enabled, but the current build has #define NDEBUG. This makes no sense."
#endif
OPENMPT_NAMESPACE_END
#include <cassert>
OPENMPT_NAMESPACE_BEGIN
#define MPT_CHECKER_ASSUME(x) assert(!!(x))
#endif
#endif
#endif
#ifndef MPT_CHECKER_ASSUME
#define MPT_CHECKER_ASSUME(x) MPT_DO { } MPT_WHILE_0
#endif
#if defined(_MFC_VER) && !defined(MPT_CPPCHECK_CUSTOM)
#if !defined(ASSERT)
#error "MFC is expected to #define ASSERT"
#endif #define MPT_FRAMEWORK_ASSERT_IS_DEFINED
#if defined(_DEBUG)
#define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 1
#else
#define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 0
#endif
#define MPT_ASSERT_USE_FRAMEWORK 1
#else
#if defined(ASSERT)
#define MPT_FRAMEWORK_ASSERT_IS_DEFINED
#if defined(_DEBUG)
#define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 1
#else
#define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 0
#endif #endif
#define MPT_ASSERT_USE_FRAMEWORK 0
#endif
#if defined(MPT_FRAMEWORK_ASSERT_IS_DEFINED) && (MPT_ASSERT_USE_FRAMEWORK == 1)
#define MPT_ASSERT_NOTREACHED() ASSERT(0)
#define MPT_ASSERT(expr) ASSERT((expr))
#define MPT_ASSERT_MSG(expr, msg) ASSERT((expr) && (msg))
#if (MPT_FRAMEWORK_ASSERT_IS_ACTIVE == 1)
#define MPT_ASSERT_ALWAYS(expr) ASSERT((expr))
#define MPT_ASSERT_ALWAYS_MSG(expr, msg) ASSERT((expr) && (msg))
#else
#define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#ifndef MPT_ASSERT_HANDLER_NEEDED
#define MPT_ASSERT_HANDLER_NEEDED
#endif
#endif
#elif defined(NO_ASSERTS)
#define MPT_ASSERT_NOTREACHED() MPT_CHECKER_ASSUME(0)
#define MPT_ASSERT(expr) MPT_CHECKER_ASSUME(expr)
#define MPT_ASSERT_MSG(expr, msg) MPT_CHECKER_ASSUME(expr)
#define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#ifndef MPT_ASSERT_HANDLER_NEEDED
#define MPT_ASSERT_HANDLER_NEEDED
#endif
#else
#define MPT_ASSERT_NOTREACHED() MPT_DO { MPT_CONSTANT_IF(!(0)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), "0"); } MPT_CHECKER_ASSUME(0); } MPT_WHILE_0
#define MPT_ASSERT(expr) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#ifndef MPT_ASSERT_HANDLER_NEEDED
#define MPT_ASSERT_HANDLER_NEEDED
#endif
#endif
#if defined(MPT_ASSERT_HANDLER_NEEDED)
MPT_NOINLINE void AssertHandler(const mpt::source_location &loc, const char *expr, const char *msg=nullptr);
#endif
#define MPT_CONSTEXPR11_ASSERT MPT_STATIC_ASSERT
#if !MPT_MSVC_BEFORE(2017,5)
#define MPT_CONSTEXPR14_ASSERT MPT_STATIC_ASSERT
#else
#define MPT_CONSTEXPR14_ASSERT MPT_ASSERT
#endif
#if MPT_CXX_AT_LEAST(17) && !MPT_MSVC_BEFORE(2017,5)
#define MPT_CONSTEXPR17_ASSERT MPT_STATIC_ASSERT
#else
#define MPT_CONSTEXPR17_ASSERT MPT_ASSERT
#endif
OPENMPT_NAMESPACE_END