14namespace Stroika::Foundation::Debug {
17 struct ModuleInit_ final {
18 ModuleInit_ () noexcept;
21 const inline ModuleInit_ _MI_;
24 class Private_::Emitter final {
27 Emitter (
const Emitter&) =
delete;
30 static Emitter& Get () noexcept;
36 [[deprecated ("Since Stroika v3.0d6 - use _f format strings")]]
void EmitTraceMessage (const
char* format, ...) noexcept;
37 [[deprecated ("Since Stroika v3.0d6 - use _f format strings")]]
void EmitTraceMessage (const
wchar_t* format, ...) noexcept;
40 template <typename CHAR_T, typename... Args>
41 nonvirtual
void EmitTraceMessage (Characters::FormatString<CHAR_T> fmt, Args&&... args) noexcept
44 Characters::Private_::WithFormatArgs_<void> (
45 [&] (Common::StdCompat::wformat_args a) { EmitTraceMessage_ (fmt.get (), move (a)); }, args...);
51 template <IFormatLiteral_ FORMAT_LITERAL,
typename... Args>
52 nonvirtual
void EmitTraceMessage (
const FORMAT_LITERAL& fmt, Args&&... args)
noexcept
54 FORMAT_LITERAL::template CheckArgs<Args...> ();
55 EmitTraceMessage (
static_cast<const Characters::FormatString<wchar_t>&
> (fmt), forward<Args> (args)...);
59 nonvirtual TraceLastBufferedWriteTokenType EmitTraceMessage_ (
size_t bufferLastNChars, wstring_view format,
60 Common::StdCompat::wformat_args&& args)
noexcept;
61 nonvirtual
void EmitTraceMessage_ (wstring_view format, Common::StdCompat::wformat_args&& args)
noexcept;
62 nonvirtual
void EmitTraceMessage_ (string_view format, Common::StdCompat::format_args&& args)
noexcept;
63 nonvirtual
void EmitTraceMessage_ (
const wstring& raw)
noexcept;
68 nonvirtual
bool UnputBufferedCharactersForMatchingToken (TraceLastBufferedWriteTokenType token);
70 template <
typename CHARTYPE>
71 nonvirtual
void EmitUnadornedText (
const CHARTYPE* p);
75 template <
typename CHARTYPE>
76 nonvirtual TraceLastBufferedWriteTokenType DoEmitMessage_ (
size_t bufferLastNChars,
const CHARTYPE* p,
const CHARTYPE* e);
79 size_t fLastNCharBufCharCount_{0};
80 char fLastNCharBuf_CHAR_[10];
81 wchar_t fLastNCharBuf_WCHAR_[10];
82 bool fLastNCharBuf_WCHARFlag_{
false};
83 TraceLastBufferedWriteTokenType fLastNCharBuf_Token_{0};
84 Time::DisplayedRealtimeClock::time_point fLastNCharBuf_WriteTickcount_{};
86 nonvirtual
void BufferNChars_ (
size_t nChars,
const char* p);
87 nonvirtual
void BufferNChars_ (
size_t nChars,
const wchar_t* p);
90 nonvirtual
void FlushBufferedCharacters_ ();
93 nonvirtual
void DoEmit_ (
const char* p)
noexcept;
94 nonvirtual
void DoEmit_ (
const wchar_t* p)
noexcept;
95 nonvirtual
void DoEmit_ (
const char* p,
const char* e)
noexcept;
96 nonvirtual
void DoEmit_ (
const wchar_t* p,
const wchar_t* e)
noexcept;
99 friend class Debug::TraceContextBumper;
109#if qStroika_Foundation_Debug_DefaultTracingOn
113 template <
typename CHAR_T>
115 requires (same_as<CHAR_T, char> or same_as<CHAR_T, wchar_t>)
116#
if qStroika_Foundation_Debug_DefaultTracingOn
121 template <
typename CHAR_T,
typename FCHAR_T,
typename... ARGS>
124 requires ((same_as<CHAR_T, char> or same_as<CHAR_T, wchar_t>) and (same_as<FCHAR_T, char> or same_as<FCHAR_T, wchar_t>))
125#
if qStroika_Foundation_Debug_DefaultTracingOn
126 : TraceContextBumper{cvt2WChartArrayTrunc_ (contextName), ProcessFmtString_ (fmt, forward<ARGS> (args)...)}
130 template <
typename CHAR_T, Private_::IFormatLiteral_ FORMAT_LITERAL,
typename... ARGS>
132 requires (same_as<CHAR_T, char> or same_as<CHAR_T, wchar_t>)
133 :
TraceContextBumper{contextName, static_cast<const Characters::FormatString<wchar_t>&> (fmt), forward<ARGS> (args)...}
135 FORMAT_LITERAL::template CheckArgs<ARGS...> ();
137#if !qStroika_Foundation_Debug_DefaultTracingOn
142#if qStroika_Foundation_Debug_DefaultTracingOn
143 template <
typename CHAR_T,
typename... ARGS>
145 requires (same_as<CHAR_T, char> or same_as<CHAR_T, wchar_t>)
148 wstring r = Characters::Private_::WithFormatArgs_<wstring> (
149 [&] (Common::StdCompat::wformat_args a) {
150 return Common::StdCompat::vformat (qStroika_Foundation_Characters_FMT_PREFIX_::wstring_view{fmt.get ()}, a);
153 size_t len = min<size_t> (r.size (), kMaxContextNameLen_);
156 char_traits<wchar_t>::copy (result.data (), r.data (), len);
168 template <
typename CHAR_T>
169 auto TraceContextBumper::cvt2WChartArrayTrunc_ (span<const CHAR_T> contextName) -> CHAR_ARRAY_T
172 array<wchar_t, kMaxContextNameLen_ + 1> r;
173 auto ci = contextName.begin ();
174 for (; ci != contextName.end (); ++ci) {
175 size_t i = ci - contextName.begin ();
176 if (i < kMaxContextNameLen_) {
183 Assert (ci - contextName.begin () <= kMaxContextNameLen_);
184 r[ci - contextName.begin ()] =
'\0';
187 template <
typename CHAR_T>
188 auto TraceContextBumper::cvt2WChartArrayTrunc_ (
const CHAR_T* contextName) -> CHAR_ARRAY_T
190 return cvt2WChartArrayTrunc_ (span{contextName, char_traits<CHAR_T>::length (contextName)});
199 inline TraceContextSuppressor::TraceContextSuppressor () noexcept
203 inline TraceContextSuppressor::~TraceContextSuppressor ()
207 inline bool TraceContextSuppressor::GetSuppressTraceInThisThread ()
209 return tSuppressCnt_ > 0;
#define CompileTimeFlagChecker_HEADER(NS_PREFIX, NAME, VALUE)
CompileTimeFlagChecker_HEADER () will generate a LINK ERROR if you ever compile a header with one val...
#define qStroika_Foundation_Debug_TraceToFile
TraceContextBumper() noexcept