From 3369e345678aaa4199b76a099c750ed00754c548 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Tue, 21 Nov 2023 13:42:53 +0100 Subject: basic ZEN_ASSERT_FORMAT implementation (#556) includes porting some compact binary builder code to use it since it had vestiges of the UE-side asserts --- src/zencore/include/zencore/assertfmt.h | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/zencore/include/zencore/assertfmt.h (limited to 'src/zencore/include') diff --git a/src/zencore/include/zencore/assertfmt.h b/src/zencore/include/zencore/assertfmt.h new file mode 100644 index 000000000..56383ffd9 --- /dev/null +++ b/src/zencore/include/zencore/assertfmt.h @@ -0,0 +1,48 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include + +#include +#include + +namespace zen { + +namespace assert { + template + auto AssertCaptureArguments(T&&... Args) + { + return fmt::make_format_args(Args...); + } + + void ExecAssertFmt + [[noreturn]] (const char* Filename, int LineNumber, const char* FunctionName, std::string_view Format, fmt::format_args Args); + + // MSVC (v19.00.24215.1 at time of writing) ignores no-inline attributes on + // lambdas. This can be worked around by calling the lambda from inside this + // templated (and correctly non-inlined) function. + template + RetType ZEN_FORCENOINLINE ZEN_DEBUG_SECTION CallColdNoInline(InnerType&& Inner, ArgTypes const&... Args) + { + return Inner(Args...); + } + +} // namespace assert + +#define ZEN_ASSERT_FORMAT(x, fmt, ...) \ + do \ + { \ + using namespace std::literals; \ + if (x) [[likely]] \ + break; \ + zen::assert::CallColdNoInline([&]() ZEN_FORCEINLINE { \ + zen::assert::ExecAssertFmt(__FILE__, \ + __LINE__, \ + __FUNCTION__, \ + "assert(" #x ") failed: " fmt ""sv, \ + zen::assert::AssertCaptureArguments(__VA_ARGS__)); \ + }); \ + } while (false) + +} // namespace zen -- cgit v1.2.3