HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
debugger.hpp
1
2
3#pragma once
4
5#include "TTauri/Foundation/os_detect.hpp"
6#include <fmt/format.h>
7
8namespace tt {
9
10#if TT_OPERATING_SYSTEM == TT_OS_WINDOWS
11void _debugger_break();
12#define debugger_break _debugger_break()
13
14#elif TT_COMPILER == TT_CC_GCC || TT_COMPILER == TT_CC_CLANG
15#define debugger_break __builtin_trap()
16
17#else
18#error "Not implemented"
19#endif
20
21
24bool debugger_is_present() noexcept;
25
26void _debugger_log(char const *text) noexcept;
27
30template<typename... Args>
31void debugger_log(char const *fmt, Args... args) noexcept
32{
33 if constexpr (sizeof...(Args) > 0) {
34 _debugger_log(fmt::format(fmt, std::forward<Args>(args)...).data());
35 } else {
36 _debugger_log(fmt);
37 }
38}
39
42template<typename... Args>
43void debugger_log(std::string fmt, Args... args) noexcept
44{
45 if constexpr (sizeof...(Args) > 0) {
46 _debugger_log(fmt::format(fmt, std::forward<Args>(args)...).data());
47 } else {
48 _debugger_log(fmt.data());
49 }
50}
51
54void _debugger_dialogue(char const *caption, char const *message);
55
58template<typename... Args>
59void debugger_dialogue(char const *caption, char const *fmt, Args... args) noexcept
60{
61 if constexpr (sizeof...(Args) > 0) {
62 _debugger_dialogue(caption, fmt::format(fmt, std::forward<Args>(args)...).data());
63 } else {
64 _debugger_dialogue(caption, fmt);
65 }
66}
67
70template<typename... Args>
71void debugger_dialogue(std::string caption, std::string fmt, Args... args) noexcept
72{
73 if (sizeof...(Args) > 0) {
74 _debugger_dialogue(caption.data(), fmt::format(fmt, std::forward<Args>(args)...).data());
75 } else {
76 _debugger_dialogue(caption.data(), fmt.data());
77 }
78}
79
80
88template<typename... Args>
89[[noreturn]] tt_no_inline void _debugger_abort(char const *source_file, int source_line, char const *fmt, Args &&... args)
90{
91 std::string message;
92
93 if constexpr (sizeof...(Args) == 0) {
94 message = fmt;
95 } else {
96 message = fmt::format(fmt, std::forward<Args>(args)...);
97 }
98
99 if (debugger_is_present()) {
100 debugger_log("{}:{} {}", source_file, source_line, message);
101 debugger_break;
102 } else {
103 debugger_dialogue("Aborting", "{}:{} {}", source_file, source_line, message);
104 }
105
106 std::abort();
107}
108
109#define debugger_abort(...) ::tt::_debugger_abort(__FILE__, __LINE__, __VA_ARGS__)
110
111}
T abort(T... args)