19#define DC_TRAIT_DEBUGABLE(SELF) \
20 DC_REQUIRE_METHOD(void, SELF, debug, (SELF const*, dc_debug_fmt fmt, FILE*))
22#define DC_NO_DEBUG PRIV(no_debug)
27 fprintf(
stream,
"(no DEBUG function provided)");
30#define _DC_DERIVE_DEBUG_MEMBER(MEMBER_TYPE, MEMBER_NAME) \
31 dc_debug_fmt_print(fmt, stream, DC_STRINGIFY(MEMBER_NAME) ": "); \
32 NS(MEMBER_TYPE, debug)(&self->MEMBER_NAME, fmt, stream); \
33 fprintf(stream, ",\n");
35#define DC_DERIVE_DEBUG(TYPE) \
36 DC_PUBLIC static TYPE NS(TYPE, DEBUG)(TYPE const* self, dc_debug_fmt fmt, FILE* stream) { \
37 fprintf(stream, DC_STRINGIFY(TYPE) "@%p {\n", self); \
38 fmt = dc_debug_fmt_scope_begin(fmt); \
39 NS(TYPE, REFLECT)(_DC_DERIVE_DEBUG_MEMBER); \
40 fmt = dc_debug_fmt_scope_end(fmt); \
43#define _DC_DERIVE_STD_DEBUG(TYPE, FMT, ...) \
44 DC_PUBLIC static void NS(TYPE, debug)(TYPE const* self, dc_debug_fmt fmt, FILE* stream) { \
46 fprintf(stream, FMT, *self); \
49#define _DC_DERIVE_STD_DEBUG_FLOAT(TYPE, FMT, ...) \
50 DC_PUBLIC static void NS(TYPE, debug)(TYPE const* self, dc_debug_fmt fmt, FILE* stream) { \
52 fprintf(stream, FMT, (double)*self); \
60 fprintf(
stream,
"char*@%p \"%s\"", *
string, *
string);
66 fprintf(
stream,
"char*@%p \"%s\"", *
string, *
string);
71 fprintf(
stream,
"void*@%p", *ptr);
77 fprintf(
stream,
"void const*@%p", *ptr);
80#if defined DC_GENERIC_KEYWORD_SUPPORTED
81 #define _DC_DEFAULT_DEBUG_CASE(TYPE, _, x) \
85 #define _DC_DEFAULT_DEBUG(SELF, FMT, STREAM) \
87 DC_STD_REFLECT(_DC_DEFAULT_DEBUG_CASE, f) \
88 DC_FLOAT_REFLECT(_DC_DEFAULT_DEBUG_CASE, f) char const*: dc_string_const_debug, \
89 char*: dc_string_debug, \
90 void const*: dc_void_const_ptr_debug, \
91 void*: dc_void_ptr_debug, \
92 default: PRIV(no_debug))(SELF, FMT, STREAM);
94 #include <type_traits>
96 #define _DC_DEFAULT_DEBUG_CASE(TYPE, _, FMT, STREAM) \
97 if constexpr (std::is_same_v< \
98 TYPE, std::remove_cv_t<std::remove_reference_t<decltype(*item)>>>) { \
99 NS(TYPE, debug)(item, FMT, STREAM); \
102 #define _DC_DEFAULT_DEBUG(SELF, FMT, STREAM) \
103 [&]<typename T>(T item) { \
104 DC_STD_REFLECT(_DC_DEFAULT_DEBUG_CASE, FMT, STREAM) \
105 DC_FLOAT_REFLECT(_DC_DEFAULT_DEBUG_CASE, FMT, STREAM) \
106 if constexpr (std::is_same_v<void*, std::remove_cv_t< \
107 std::remove_reference_t<decltype(*item)>>>) { \
108 dc_void_const_ptr_debug(item, FMT, STREAM); \
109 } else if constexpr (std::is_same_v<void const*, \
111 std::remove_reference_t<decltype(*item)>>>) { \
112 dc_void_ptr_debug(item, FMT, STREAM); \
113 } else if constexpr (std::is_same_v<char*, std::remove_cv_t<std::remove_reference_t< \
114 decltype(*item)>>>) { \
115 dc_string_debug(item, FMT, STREAM); \
116 } else if constexpr (std::is_same_v<char const*, \
118 std::remove_reference_t<decltype(*item)>>>) { \
119 dc_string_const_debug(item, FMT, STREAM); \
121 DC_NO_DEBUG(item, FMT, STREAM); \
126#define DC_DEFAULT_DEBUG _DC_DEFAULT_DEBUG
static DC_PUBLIC void dc_void_const_ptr_debug(void const *const *ptr, dc_debug_fmt fmt, FILE *stream)
#define _DC_DERIVE_STD_DEBUG(TYPE, FMT,...)
static DC_PUBLIC void dc_void_ptr_debug(void *const *ptr, dc_debug_fmt fmt, FILE *stream)
static DC_PUBLIC void dc_string_debug(char *const *string, dc_debug_fmt fmt, FILE *stream)
#define _DC_DERIVE_STD_DEBUG_FLOAT(TYPE, FMT,...)
static DC_INTERNAL void PRIV no_debug(void const *self, dc_debug_fmt fmt, FILE *stream)
static DC_PUBLIC void dc_string_const_debug(char const *const *string, dc_debug_fmt fmt, FILE *stream)
#define DC_STD_REFLECT(F,...)
#define DC_FLOAT_REFLECT(F,...)
Debug format helpers for debug printin data structures.
static DC_PUBLIC FILE * stream(SELF *self)