Assert.h#
Fully qualified name: carb/Assert.h
File members: carb/Assert.h
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
#pragma once
#include "assert/IAssert.h"
#include <exception> // for std::terminate
#ifdef DOXYGEN_BUILD
# define CARB_ASSERT_ENABLED CARB_DEBUG
# define CARB_CHECK_ENABLED 1
# define CARB_RELEASE_ASSERT_ENABLED 1
# define CARB_FATAL_UNLESS_ENABLED 1
# define CARB_ASSERT(cond, ...) ((void)0)
# define CARB_CHECK(cond, ...) ((void)0)
# define CARB_RELEASE_ASSERT(cond, ...) ((void)0)
# define CARB_FATAL_UNLESS(cond, fmt, ...) (!(cond) ? (std::terminate(), false) : true)
#else
/* main assertion test entry point. This is implemented as a single conditional statement to
* ensure that the assertion failure breakpoint occurs on the same line of code as the assertion
* test itself. CARB_CHECK() exists in release and debug, and CARB_ASSERT() is debug-only.
*/
// example-begin CARB_IMPL_ASSERT
# define CARB_IMPL_ASSERT(cond, type, ...) \
(CARB_LIKELY(cond) || \
 CARB_NOINLINE { \
return ::carb::assert::detail::dispatchAssert( \
::carb::assert::AssertEntry{ (type), #cond, funcname__, __FILE__, __LINE__ }, ##__VA_ARGS__); \
}(CARB_PRETTY_FUNCTION) || \
(CARB_BREAK_POINT(), false))
// Use as:
// #define CARB_ASSERT(cond, ...) CARB_IMPL_ASSERT(cond, ::carb::assert::Type::eAssert, ##__VA_ARGS__)
// #define CARB_CHECK(cond, ...) CARB_IMPL_ASSERT(cond, ::carb::assert::Type::eCheck, ##__VA_ARGS__)
// #define CARB_RELEASE_ASSERT(cond, ...) CARB_IMPL_ASSERT(cond, ::carb::assert::Type::eReleaseAssert, ##__VA_ARGS__)
// NOTE: Ideal implementation is below, but this requires C++23 for static in constexpr functions where it might be used
# if 0
# define CARB_IMPL_ASSERT(cond, type, ...) \
do \
{ \
CARB_LIKELY_IF(cond) break; \
constexpr static ::carb::assert::AssertEntry implAssertEntry{ (type), #cond, CARB_PRETTY_FUNCTION, \
__FILE__, __LINE__ }; \
if (::carb::assert::detail::dispatchAssert(&implAssertEntry, ##__VA_ARGS__)) \
CARB_BREAK_POINT(); \
} while (false)
# endif
// example-end CARB_IMPL_ASSERT
# ifndef CARB_ASSERT
# ifndef CARB_ASSERT_ENABLED
# define CARB_ASSERT_ENABLED CARB_DEBUG
# endif
# if CARB_ASSERT_ENABLED
# define CARB_ASSERT(cond, ...) CARB_IMPL_ASSERT(cond, ::carb::assert::Type::eAssert, ##__VA_ARGS__)
# else
# define CARB_ASSERT(cond, ...) ((void)0)
# endif
# else
// CARB_ASSERT was already defined
# ifndef CARB_ASSERT_ENABLED
# define CARB_ASSERT /* cause an error showing where it was already defined */
# error CARB_ASSERT_ENABLED must also be defined if CARB_ASSERT is pre-defined!
# endif
# endif
#endif
#ifndef CARB_CHECK
# ifndef CARB_CHECK_ENABLED
# define CARB_CHECK_ENABLED 1
# endif
# if CARB_CHECK_ENABLED
# define CARB_CHECK(cond, ...) CARB_IMPL_ASSERT(cond, ::carb::assert::Type::eCheck, ##__VA_ARGS__)
# else
# define CARB_CHECK(...) ((void)0)
# endif
#else
// CARB_CHECK was already defined
# ifndef CARB_CHECK_ENABLED
# define CARB_CHECK /* cause an error showing where it was already defined */
# error CARB_CHECK_ENABLED must also be defined if CARB_CHECK is pre-defined!
# endif
#endif
#ifndef CARB_RELEASE_ASSERT
# ifndef CARB_RELEASE_ASSERT_ENABLED
# define CARB_RELEASE_ASSERT_ENABLED 1
# endif
# if CARB_RELEASE_ASSERT_ENABLED
# define CARB_RELEASE_ASSERT(cond, ...) \
CARB_IMPL_ASSERT(cond, ::carb::assert::Type::eReleaseAssert, ##__VA_ARGS__)
# else
# define CARB_RELEASE_ASSERT(...) ((void)0)
# endif
#else
// CARB_RELEASE_ASSERT was already defined
# ifndef CARB_RELEASE_ASSERT_ENABLED
# define CARB_RELEASE_ASSERT /* cause an error showing where it was already defined */
# error CARB_RELEASE_ASSERT_ENABLED must also be defined if CARB_RELEASE_ASSERT is pre-defined!
# endif
#endif
#define CARB_FATAL_UNLESS_ENABLED 1
#ifndef CARB_FATAL_UNLESS
// example-begin CARB_FATAL_UNLESS
# define CARB_FATAL_UNLESS(cond, fmt, ...) \
(CARB_LIKELY(cond) || \
([&](const char* funcname__, ...) CARB_NOINLINE { \
if (false) \
::printf(fmt, ##__VA_ARGS__); \
::carb::assert::detail::dispatchAssert(::carb::assert::AssertEntry{ ::carb::assert::Type::eFatal, \
#cond, funcname__, __FILE__, __LINE__ }, fmt, ##__VA_ARGS__); \
}(CARB_PRETTY_FUNCTION), std::terminate(), false))
// example-end CARB_FATAL_UNLESS
#endif
#define CARB_UNIMPLEMENTED(msg, ...) \
do \
{ \
CARB_FATAL_UNLESS(false, (msg), ##__VA_ARGS__); \
std::terminate(); \
} while (0)
#define CARB_MACOS_UNIMPLEMENTED() CARB_UNIMPLEMENTED("Unimplemented on Mac OS")
#define CARB_ASSERT_STRUCTS_MATCH(A, B) \
static_assert( \
sizeof(A) == sizeof(B) && alignof(A) == alignof(B), "Size or alignment mismatch between " #A " and " #B ".")
#define CARB_ASSERT_MEMBERS_MATCH(A, a, B, b) \
static_assert(offsetof(A, a) == offsetof(B, b) && sizeof(A::a) == sizeof(B::b), \
"Offset or size mismatch between members " #a " of " #A " and " #b " of " #B ".")