tess 1.0.0
Performance-first tile and path simulation substrate
Loading...
Searching...
No Matches
assert.h
1#pragma once
2
3#include <cstdio>
4#include <cstdlib>
5
6// TESS_ASSERT documents and enforces preconditions of unchecked fast-path
7// APIs (for example World::resolve with an out-of-shape coordinate).
8//
9// Policy:
10// - Checked entry points (try_resolve, try_field, plan validation) stay the
11// runtime-validated API and never assert on bad input.
12// - Unchecked hot accessors keep noexcept and assert their preconditions.
13// - Asserts are enabled when TESS_ENABLE_ASSERTS is defined non-zero, and
14// default to on exactly when NDEBUG is absent. Release and bench builds
15// define NDEBUG, so asserts have zero cost there.
16// - A failed assert aborts; it never throws, so noexcept functions stay
17// noexcept.
18// TESS_ENABLE_ASSERTS changes the bodies of inline functions -- 14 in
19// storage/world.h alone -- so a program that enables it for some
20// translation units and not others violates the one-definition rule with
21// no diagnostic: the linker keeps one arbitrary definition and the checks
22// silently vanish from the others. docs/integration-policy.md tells
23// consumers to set this, which makes the mismatch easy to reach by
24// building the library's TUs and the consumer's with different flags.
25//
26// The pragma gives MSVC a link-time check; GCC and Clang have no
27// equivalent mechanism, so consistency there is the build system's job.
28// Placed before the default derivation below so it reports the value the
29// translation unit actually compiled with.
30#if defined(_MSC_VER)
31#if defined(TESS_ENABLE_ASSERTS) && TESS_ENABLE_ASSERTS
32#pragma detect_mismatch("tess_assert_mode", "enabled")
33#elif defined(TESS_ENABLE_ASSERTS)
34#pragma detect_mismatch("tess_assert_mode", "disabled")
35#elif defined(NDEBUG)
36#pragma detect_mismatch("tess_assert_mode", "disabled")
37#else
38#pragma detect_mismatch("tess_assert_mode", "enabled")
39#endif
40#endif
41
42#if !defined(TESS_ENABLE_ASSERTS)
43#if defined(NDEBUG)
45#define TESS_ENABLE_ASSERTS 0
46#else
47#define TESS_ENABLE_ASSERTS 1
48#endif
49#endif
50
51namespace tess::detail {
52
53[[noreturn]] inline void assert_fail(const char* expression, const char* file,
54 unsigned line) noexcept {
55 std::fprintf(stderr, "%s:%u: tess assertion failed: %s\n", file, line,
56 expression);
57 std::abort();
58}
59
60} // namespace tess::detail
61
62#if TESS_ENABLE_ASSERTS
64#define TESS_ASSERT(condition) \
65 ((condition) ? static_cast<void>(0) \
66 : ::tess::detail::assert_fail(#condition, __FILE__, __LINE__))
68#define TESS_ASSERT_MSG(condition, message) \
69 ((condition) ? static_cast<void>(0) \
70 : ::tess::detail::assert_fail(message, __FILE__, __LINE__))
71#else
72#define TESS_ASSERT(condition) static_cast<void>(0)
73#define TESS_ASSERT_MSG(condition, message) static_cast<void>(0)
74#endif