Skip to content

Commit 4680284

Browse files
committed
Add assertion macros to base
1 parent 68f04ac commit 4680284

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

base/assertions.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2026 Vector 35 Inc
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to
5+
// deal in the Software without restriction, including without limitation the
6+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
// sell copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19+
// IN THE SOFTWARE.
20+
21+
#pragma once
22+
23+
// Assertion macros for internal consistency checks.
24+
//
25+
// There are two categories of assertions:
26+
// 1) BN_ASSERT: These assertions can be enabled or disabled at compile time
27+
// using the BN_ASSERTIONS_ENABLED macro. They are intended for checking
28+
// conditions during development and debugging, but are compiled out of
29+
// production builds, either for performance reasons or because there is
30+
// a recovery path beyond trapping.
31+
// 2) BN_RELEASE_ASSERT: These assertions are always enabled, regardless of
32+
// the BN_ASSERTIONS_ENABLED setting. They are intended for checking
33+
// conditions that must always hold true for the program to function
34+
// correctly, and indicate a serious error if they fail.
35+
//
36+
// By default, BN_ASSERTIONS_ENABLED is enabled in debug builds and disabled
37+
// in release builds.
38+
39+
#ifndef BN_ASSERTIONS_ENABLED
40+
#ifdef NDEBUG
41+
#define BN_ASSERTIONS_ENABLED 0
42+
#else
43+
#define BN_ASSERTIONS_ENABLED 1
44+
#endif
45+
#endif
46+
47+
#ifdef _MSC_VER
48+
#include <intrin.h>
49+
#define BN_ASSERT_TRAP __fastfail(7 /* FAST_FAIL_FATAL_APP_EXIT */)
50+
#else
51+
#define BN_ASSERT_TRAP __builtin_trap()
52+
#endif
53+
54+
#if BN_ASSERTIONS_ENABLED
55+
56+
// When assertions are enabled, reporting an assertion failure logs an error message then traps.
57+
#define BN_REPORT_ASSERTION_FAILURE(message) \
58+
do \
59+
{ \
60+
BNLogError("Assertion failed: %s (%s:%d)", message, __FILE__, __LINE__); \
61+
BN_ASSERT_TRAP; \
62+
} while (0)
63+
64+
// BN_ASSERT checks the given condition and reports an assertion failure if the condition is false.
65+
#define BN_ASSERT(condition) \
66+
do \
67+
{ \
68+
if (!(condition)) [[unlikely]] \
69+
{ \
70+
BN_REPORT_ASSERTION_FAILURE(#condition); \
71+
} \
72+
} while (0)
73+
74+
#else
75+
76+
// When assertions are disabled, reporting an assertion failure traps without logging.
77+
// This is used for release assertions that are always enabled.
78+
#define BN_REPORT_ASSERTION_FAILURE(message) BN_ASSERT_TRAP
79+
80+
// BN_ASSERT does nothing when assertions are disabled.
81+
// Note that it does not evaluate the condition.
82+
#define BN_ASSERT(condition) (void)0
83+
84+
#endif
85+
86+
// BN_RELEASE_ASSERT checks the given condition and reports an assertion failure
87+
// if the condition is false.
88+
// This assertion is always enabled, regardless of the BN_ASSERTIONS_ENABLED setting.
89+
#define BN_RELEASE_ASSERT(condition) \
90+
do \
91+
{ \
92+
if (!(condition)) [[unlikely]] \
93+
{ \
94+
BN_REPORT_ASSERTION_FAILURE(#condition); \
95+
} \
96+
} while (0)
97+
98+
// Assert that this code path is not reached.
99+
// This assertion is always enabled, regardless of the BN_ASSERTIONS_ENABLED setting.
100+
#define BN_RELEASE_ASSERT_NOT_REACHED() \
101+
do \
102+
{ \
103+
BN_REPORT_ASSERTION_FAILURE("Unreachable code reached"); \
104+
} while (0)

0 commit comments

Comments
 (0)