Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
assert.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <source_location>
5#include <string_view>
6#include <cstdio>
7#include <cstdlib>
8#include <iostream>
9
10namespace pulp::runtime {
11
12[[noreturn]] inline void assert_fail(
13 std::string_view expr,
14 std::string_view msg,
15 std::source_location loc = std::source_location::current())
16{
17 std::fprintf(stderr,
18 "[pulp:ASSERT] %.*s\n"
19 " expression: %.*s\n"
20 " file: %s:%d\n"
21 " function: %s\n",
22 static_cast<int>(msg.size()), msg.data(),
23 static_cast<int>(expr.size()), expr.data(),
24 loc.file_name(), loc.line(),
25 loc.function_name());
26 std::abort();
27}
28
29namespace detail {
30
31// PULP_DBG_VAR helpers. Pre-stringified names + per-arg values come
32// from the variadic macro below; here we just print them with a stable
33// "[pulp:DBG] file:line | name = value | …" prefix.
34template <typename T>
35inline void dbg_var_one(std::string_view name, const T& value) {
36 std::cerr << " | " << name << " = " << value;
37}
38
39inline void dbg_var_emit_prefix(std::source_location loc) {
40 std::cerr << "[pulp:DBG] "
41 << loc.file_name() << ':' << loc.line();
42}
43
44inline void dbg_var_emit_suffix() {
45 std::cerr << '\n';
46}
47
48} // namespace detail
49
50} // namespace pulp::runtime
51
52// PULP_ASSERT: always checked (debug and release)
53#define PULP_ASSERT(expr, msg) \
54 do { \
55 if (!(expr)) [[unlikely]] { \
56 ::pulp::runtime::assert_fail(#expr, msg); \
57 } \
58 } while (false)
59
60// PULP_DBG_ASSERT: checked only in debug builds
61#if defined(NDEBUG)
62 #define PULP_DBG_ASSERT(expr, msg) ((void)0)
63#else
64 #define PULP_DBG_ASSERT(expr, msg) PULP_ASSERT(expr, msg)
65#endif
66
67// PULP_DBG_VAR: name-printing debug print for ad-hoc inspection.
68//
69// Usage:
70// PULP_DBG_VAR(x); // → [pulp:DBG] foo.cpp:42 | x = 7
71// PULP_DBG_VAR(x, y, z); // → ... | x = 7 | y = 3.14 | z = "hi"
72//
73// Each argument is stringified once at the call site (`#x`) and the
74// runtime value is streamed via `operator<<`. Compiles away to a
75// no-op in NDEBUG builds — leave call sites in your code while you're
76// chasing a bug, and they'll vanish when you flip to Release.
77//
78// A compile-away debug value-logging macro in the spirit of common
79// `DBG_VAR` / `LOG_VAR` helpers. Replaces ad-hoc
80// `std::cout << "x=" << x` scaffolding.
81#if defined(NDEBUG)
82 #define PULP_DBG_VAR(...) ((void)0)
83#else
84 // Fold expression over the comma-separated arguments. Each one is
85 // stringified at the call site by PULP_DBG_VAR_ONE and forwarded
86 // to detail::dbg_var_one for value printing.
87 #define PULP_DBG_VAR_ONE(x) ::pulp::runtime::detail::dbg_var_one(#x, (x))
88
89 // Variadic version: comma-fold a single PULP_DBG_VAR_ONE per arg.
90 // The do/while wraps the comma operator so the macro is statement-
91 // safe inside `if`/`else` chains.
92 #define PULP_DBG_VAR(...) \
93 do { \
94 ::pulp::runtime::detail::dbg_var_emit_prefix( \
95 std::source_location::current()); \
96 PULP_DBG_VAR_EXPAND(__VA_ARGS__) \
97 ::pulp::runtime::detail::dbg_var_emit_suffix(); \
98 } while (false)
99
100 // Variadic expansion: this handles 1..8 args without needing
101 // C++20 __VA_OPT__. Beyond 8 args, call PULP_DBG_VAR twice.
102 #define PULP_DBG_VAR_NARGS_(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
103 #define PULP_DBG_VAR_NARGS(...) \
104 PULP_DBG_VAR_NARGS_(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)
105 #define PULP_DBG_VAR_CAT_(a, b) a##b
106 #define PULP_DBG_VAR_CAT(a, b) PULP_DBG_VAR_CAT_(a, b)
107 #define PULP_DBG_VAR_EXPAND(...) \
108 PULP_DBG_VAR_CAT(PULP_DBG_VAR_EXPAND_, PULP_DBG_VAR_NARGS(__VA_ARGS__))(__VA_ARGS__)
109 #define PULP_DBG_VAR_EXPAND_1(x1) PULP_DBG_VAR_ONE(x1);
110 #define PULP_DBG_VAR_EXPAND_2(x1, x2) PULP_DBG_VAR_ONE(x1); PULP_DBG_VAR_ONE(x2);
111 #define PULP_DBG_VAR_EXPAND_3(x1, x2, x3) \
112 PULP_DBG_VAR_ONE(x1); PULP_DBG_VAR_ONE(x2); PULP_DBG_VAR_ONE(x3);
113 #define PULP_DBG_VAR_EXPAND_4(x1, x2, x3, x4) \
114 PULP_DBG_VAR_ONE(x1); PULP_DBG_VAR_ONE(x2); \
115 PULP_DBG_VAR_ONE(x3); PULP_DBG_VAR_ONE(x4);
116 #define PULP_DBG_VAR_EXPAND_5(x1, x2, x3, x4, x5) \
117 PULP_DBG_VAR_EXPAND_4(x1, x2, x3, x4) PULP_DBG_VAR_ONE(x5);
118 #define PULP_DBG_VAR_EXPAND_6(x1, x2, x3, x4, x5, x6) \
119 PULP_DBG_VAR_EXPAND_4(x1, x2, x3, x4) \
120 PULP_DBG_VAR_ONE(x5); PULP_DBG_VAR_ONE(x6);
121 #define PULP_DBG_VAR_EXPAND_7(x1, x2, x3, x4, x5, x6, x7) \
122 PULP_DBG_VAR_EXPAND_4(x1, x2, x3, x4) \
123 PULP_DBG_VAR_ONE(x5); PULP_DBG_VAR_ONE(x6); PULP_DBG_VAR_ONE(x7);
124 #define PULP_DBG_VAR_EXPAND_8(x1, x2, x3, x4, x5, x6, x7, x8) \
125 PULP_DBG_VAR_EXPAND_4(x1, x2, x3, x4) PULP_DBG_VAR_EXPAND_4(x5, x6, x7, x8)
126#endif
Definition assert.hpp:29
void dbg_var_emit_suffix()
Definition assert.hpp:44
void dbg_var_emit_prefix(std::source_location loc)
Definition assert.hpp:39
void dbg_var_one(std::string_view name, const T &value)
Definition assert.hpp:35
Definition generated_event_source.hpp:33
void assert_fail(std::string_view expr, std::string_view msg, std::source_location loc=std::source_location::current())
Definition assert.hpp:12