98 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			98 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>
 | 
						|
 | 
						|
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
 |