summaryrefslogtreecommitdiff
path: root/base/assertions.h
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2025-12-20 16:30:19 -0800
committerMark Rowe <mark@vector35.com>2026-04-20 12:26:06 -0700
commit468028455f5b7d9bf71fc111c078487c6dbf8a73 (patch)
tree43821e5d5479b19629283e3fda3ff3e5554bb0e3 /base/assertions.h
parent68f04aca3f4e04c1ec2c3b5d54c04ff05e9b0c58 (diff)
Add assertion macros to base
Diffstat (limited to 'base/assertions.h')
-rw-r--r--base/assertions.h104
1 files changed, 104 insertions, 0 deletions
diff --git a/base/assertions.h b/base/assertions.h
new file mode 100644
index 00000000..30a06661
--- /dev/null
+++ b/base/assertions.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2026 Vector 35 Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#pragma once
+
+// Assertion macros for internal consistency checks.
+//
+// There are two categories of assertions:
+// 1) BN_ASSERT: These assertions can be enabled or disabled at compile time
+// using the BN_ASSERTIONS_ENABLED macro. They are intended for checking
+// conditions during development and debugging, but are compiled out of
+// production builds, either for performance reasons or because there is
+// a recovery path beyond trapping.
+// 2) BN_RELEASE_ASSERT: These assertions are always enabled, regardless of
+// the BN_ASSERTIONS_ENABLED setting. They are intended for checking
+// conditions that must always hold true for the program to function
+// correctly, and indicate a serious error if they fail.
+//
+// By default, BN_ASSERTIONS_ENABLED is enabled in debug builds and disabled
+// in release builds.
+
+#ifndef BN_ASSERTIONS_ENABLED
+#ifdef NDEBUG
+#define BN_ASSERTIONS_ENABLED 0
+#else
+#define BN_ASSERTIONS_ENABLED 1
+#endif
+#endif
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#define BN_ASSERT_TRAP __fastfail(7 /* FAST_FAIL_FATAL_APP_EXIT */)
+#else
+#define BN_ASSERT_TRAP __builtin_trap()
+#endif
+
+#if BN_ASSERTIONS_ENABLED
+
+// When assertions are enabled, reporting an assertion failure logs an error message then traps.
+#define BN_REPORT_ASSERTION_FAILURE(message) \
+ do \
+ { \
+ BNLogError("Assertion failed: %s (%s:%d)", message, __FILE__, __LINE__); \
+ BN_ASSERT_TRAP; \
+ } while (0)
+
+// BN_ASSERT checks the given condition and reports an assertion failure if the condition is false.
+#define BN_ASSERT(condition) \
+ do \
+ { \
+ if (!(condition)) [[unlikely]] \
+ { \
+ BN_REPORT_ASSERTION_FAILURE(#condition); \
+ } \
+ } while (0)
+
+#else
+
+// When assertions are disabled, reporting an assertion failure traps without logging.
+// This is used for release assertions that are always enabled.
+#define BN_REPORT_ASSERTION_FAILURE(message) BN_ASSERT_TRAP
+
+// BN_ASSERT does nothing when assertions are disabled.
+// Note that it does not evaluate the condition.
+#define BN_ASSERT(condition) (void)0
+
+#endif
+
+// BN_RELEASE_ASSERT checks the given condition and reports an assertion failure
+// if the condition is false.
+// This assertion is always enabled, regardless of the BN_ASSERTIONS_ENABLED setting.
+#define BN_RELEASE_ASSERT(condition) \
+ do \
+ { \
+ if (!(condition)) [[unlikely]] \
+ { \
+ BN_REPORT_ASSERTION_FAILURE(#condition); \
+ } \
+ } while (0)
+
+// Assert that this code path is not reached.
+// This assertion is always enabled, regardless of the BN_ASSERTIONS_ENABLED setting.
+#define BN_RELEASE_ASSERT_NOT_REACHED() \
+ do \
+ { \
+ BN_REPORT_ASSERTION_FAILURE("Unreachable code reached"); \
+ } while (0)