GF2++
Loading...
Searching...
No Matches
assert.h
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: 2025 Nessan Fitzmaurice <nzznfitz+gh@icloud.com>
3// SPDX-License-Identifier: MIT
4
8
9#include <format>
10#include <print>
11#include <string>
12#include <source_location>
13
14// Avoid macro redefinition warnings ...
15#ifdef gf2_assert
16 #undef gf2_assert
17#endif
18#ifdef gf2_assert_eq
19 #undef gf2_assert_eq
20#endif
21#ifdef gf2_debug_assert
22 #undef gf2_debug_assert
23#endif
24#ifdef gf2_debug_assert_eq
25 #undef gf2_debug_assert_eq
26#endif
27#ifdef gf2_always_assert
28 #undef gf2_always_assert
29#endif
30#ifdef gf2_always_assert_eq
31 #undef gf2_always_assert_eq
32#endif
33
41#define gf2_always_assert(expr, ...) \
42 if (!(expr)) [[unlikely]] { gf2::assert_failed(#expr, std::source_location::current() __VA_OPT__(, __VA_ARGS__)); }
43
51#define gf2_always_assert_eq(a, b, ...) \
52 if (!((a) == (b))) [[unlikely]] { \
53 gf2::assert_eq_failed(#a, #b, (a), (b), std::source_location::current() __VA_OPT__(, __VA_ARGS__)); \
54 }
55
65#ifdef DEBUG
66 #define gf2_debug_assert(cond, ...) gf2_always_assert(cond __VA_OPT__(, __VA_ARGS__))
67#else
68 #define gf2_debug_assert(cond, ...) void(0)
69#endif
70
80#ifdef DEBUG
81 #define gf2_debug_assert_eq(lhs, rhs, ...) gf2_always_assert_eq(lhs, rhs __VA_OPT__(, __VA_ARGS__))
82#else
83 #define gf2_debug_assert_eq(a, b, ...) void(0)
84#endif
85
95#ifdef NDEBUG
96 #define gf2_assert(cond, ...) void(0)
97#else
98 #define gf2_assert(cond, ...) gf2_always_assert(cond __VA_OPT__(, __VA_ARGS__))
99#endif
100
110#ifdef NDEBUG
111 #define gf2_assert_eq(lhs, rhs, ...) void(0)
112#else
113 #define gf2_assert_eq(lhs, rhs, ...) gf2_always_assert_eq(lhs, rhs __VA_OPT__(, __VA_ARGS__))
114#endif
115
116// ---------------------------------------------------------------------------------------------------------------------
117// Functions to handle confirmation failures ...
118// ---------------------------------------------------------------------------------------------------------------------
119namespace gf2 {
120
123inline static auto exit_on_assert_failure = true;
124
125// Given a path like `/home/jj/dev/project/src/foo.cpp` this returns its "basename" `foo.cpp`
126constexpr auto
127basename(std::string_view path) {
128 const auto pos = path.find_last_of("/\\");
129 if (pos == std::string_view::npos) { return path; }
130 return path.substr(pos + 1);
131}
132
133// Prints an error message with source code location information and optionally exits the program.
134// This handles simple boolean gf2_assert `gf2_assert(expr, ...)` failures.
135void
136assert_failed(std::string_view expr_str, std::source_location loc, std::string_view msg_fmt = "", auto... msg_args) {
137 std::println(stderr);
138 std::println(stderr, "GF2 FAILED: `gf2_assert({})` [{}:{}]", expr_str, basename(loc.file_name()), loc.line());
139 if (!msg_fmt.empty()) {
140 std::vprint_nonunicode(stderr, msg_fmt, std::make_format_args(msg_args...));
141 std::println(stderr);
142 }
143 std::println(stderr);
144 if (exit_on_assert_failure) { ::exit(1); }
145}
146
147// Prints an error message with source code location information and optionally exits the program.
148// This handles fails for equality confirmations `gf2_assert_eq(x, y, ...)`.
149void
150assert_eq_failed(std::string_view lhs_str, std::string_view rhs_str, auto lhs, auto rhs, std::source_location loc,
151 std::string_view msg_fmt = "", auto... msg_args) {
152 std::println(stderr);
153 std::println(stderr, "GF2 FAILED: `gf2_assert_eq({}, {})` [{}:{}]", lhs_str, rhs_str, basename(loc.file_name()),
154 loc.line());
155 if (!msg_fmt.empty()) {
156 std::vprint_nonunicode(stderr, msg_fmt, std::make_format_args(msg_args...));
157 std::println(stderr);
158 }
159 std::println(stderr, "lhs = {}", lhs);
160 std::println(stderr, "rhs = {}", rhs);
161 std::println(stderr);
162 if (exit_on_assert_failure) { ::exit(1); }
163}
164
165} // namespace gf2
The namespace for the gf2 library.
Definition assert.h:119
static auto exit_on_assert_failure
By default, all failed confirmations exit the program. You can set this variable to false to preven...
Definition assert.h:123