tdesktop/Telegram/SourceFiles/base/assertion.h

102 lines
2.3 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <cstdlib>
// Ensures/Expects.
#include <gsl/gsl_assert>
namespace base {
namespace assertion {
// Client must define that method.
void log(const char *message, const char *file, int line);
// Release build assertions.
inline constexpr void noop() {
}
[[noreturn]] inline void fail(
const char *message,
const char *file,
int line) {
log(message, file, line);
// Crash with access violation and generate crash report.
volatile auto nullptr_value = (int*)nullptr;
*nullptr_value = 0;
// Silent the possible failure to comply noreturn warning.
std::abort();
}
constexpr const char* extract_basename(const char* path, size_t size) {
while (size != 0 && path[size - 1] != '/' && path[size - 1] != '\\') {
--size;
}
return path + size;
}
} // namespace assertion
} // namespace base
#if defined(__clang__) || defined(__GNUC__)
#define AssertUnlikelyHelper(x) __builtin_expect(!!(x), 0)
#else
#define AssertUnlikelyHelper(x) (!!(x))
#endif
#define AssertValidationCondition(condition, message, file, line)\
((AssertUnlikelyHelper(!(condition)))\
? ::base::assertion::fail(message, file, line)\
: ::base::assertion::noop())
#define SOURCE_FILE_BASENAME (::base::assertion::extract_basename(\
__FILE__,\
sizeof(__FILE__)))
#define AssertCustom(condition, message) (AssertValidationCondition(\
condition,\
message,\
SOURCE_FILE_BASENAME,\
__LINE__))
#define Assert(condition) AssertCustom(condition, "\"" #condition "\"")
// Define our own versions of Expects() and Ensures().
// Let them crash with reports and logging.
#ifdef Expects
#undef Expects
#endif // Expects
#define Expects(condition) (AssertValidationCondition(\
condition,\
"\"" #condition "\"",\
SOURCE_FILE_BASENAME,\
__LINE__))
#ifdef Ensures
#undef Ensures
#endif // Ensures
#define Ensures(condition) (AssertValidationCondition(\
condition,\
"\"" #condition "\"",\
SOURCE_FILE_BASENAME,\
__LINE__))
#ifdef Unexpected
#undef Unexpected
#endif // Unexpected
#define Unexpected(message) (::base::assertion::fail(\
"Unexpected: " message,\
SOURCE_FILE_BASENAME,\
__LINE__))
#ifdef _DEBUG
#define AssertIsDebug(...)
#endif // _DEBUG