HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
debugger.hpp
1// Copyright Take Vos 2019-2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5
6#pragma once
7
8#include "os_detect.hpp"
9#include <fmt/format.h>
10
11namespace tt {
12
13#if TT_OPERATING_SYSTEM == TT_OS_WINDOWS
14void _debugger_break();
15#define tt_debugger_break() _debugger_break()
16
17#elif TT_COMPILER == TT_CC_GCC || TT_COMPILER == TT_CC_CLANG
18#define tt_debugger_break() __builtin_trap()
19
20#else
21#error "Not implemented"
22#endif
23
24
27bool debugger_is_present() noexcept;
28
29void _debugger_log(char const *text) noexcept;
30
33template<typename... Args>
34void debugger_log(char const *fmt, Args... args) noexcept
35{
36 if constexpr (sizeof...(Args) > 0) {
37 _debugger_log(fmt::format(fmt, std::forward<Args>(args)...).data());
38 } else {
39 _debugger_log(fmt);
40 }
41}
42
45template<typename... Args>
46void debugger_log(std::string fmt, Args... args) noexcept
47{
48 if constexpr (sizeof...(Args) > 0) {
49 _debugger_log(fmt::format(fmt, std::forward<Args>(args)...).data());
50 } else {
51 _debugger_log(fmt.data());
52 }
53}
54
57void _debugger_dialogue(char const *caption, char const *message);
58
61template<typename... Args>
62void debugger_dialogue(char const *caption, char const *fmt, Args... args) noexcept
63{
64 if constexpr (sizeof...(Args) > 0) {
65 _debugger_dialogue(caption, fmt::format(fmt, std::forward<Args>(args)...).data());
66 } else {
67 _debugger_dialogue(caption, fmt);
68 }
69}
70
73template<typename... Args>
74void debugger_dialogue(std::string caption, std::string fmt, Args... args) noexcept
75{
76 if (sizeof...(Args) > 0) {
77 _debugger_dialogue(caption.data(), fmt::format(fmt, std::forward<Args>(args)...).data());
78 } else {
79 _debugger_dialogue(caption.data(), fmt.data());
80 }
81}
82
83
90template<typename... Args>
91[[noreturn]] tt_no_inline void debugger_abort(char const *source_file, int source_line, std::string_view fmt, Args &&... args)
92{
93 std::string message;
94
95 if constexpr (sizeof...(Args) == 0) {
96 message = fmt;
97 } else {
98 message = fmt::format(fmt, std::forward<Args>(args)...);
99 }
100
101 if (debugger_is_present()) {
102 debugger_log("{}:{} {}", source_file, source_line, message);
103 tt_debugger_break();
104 } else {
105 debugger_dialogue("Aborting", "{}:{} {}", source_file, source_line, message);
106 }
107
108 std::abort();
109}
110
111[[noreturn]] tt_no_inline inline void debugger_abort(char const *source_file, int source_line)
112{
113 debugger_abort(source_file, source_line, "<unknown>");
114}
115
116#define tt_debugger_abort(...) ::tt::debugger_abort(__FILE__, __LINE__ __VA_OPT__(,) __VA_ARGS__)
117
118}
T abort(T... args)