Added STL formatters for Stacktrace and Stackframe.
This commit is contained in:
parent
2b368c1d4f
commit
7284d3d15f
@ -5,6 +5,7 @@
|
|||||||
#define MIJIN_DEBUG_STACKTRACE_HPP_INCLUDED 1
|
#define MIJIN_DEBUG_STACKTRACE_HPP_INCLUDED 1
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <format>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#if __has_include(<fmt/format.h>)
|
#if __has_include(<fmt/format.h>)
|
||||||
@ -87,6 +88,68 @@ TStream& operator<<(TStream& stream, const Stacktrace& stacktrace)
|
|||||||
|
|
||||||
} // namespace mijin
|
} // namespace mijin
|
||||||
|
|
||||||
|
template<typename TChar>
|
||||||
|
struct std::formatter<mijin::Stackframe, TChar>
|
||||||
|
{
|
||||||
|
using char_t = TChar;
|
||||||
|
|
||||||
|
template<typename TContext>
|
||||||
|
constexpr TContext::iterator parse(TContext& ctx)
|
||||||
|
{
|
||||||
|
auto it = ctx.begin();
|
||||||
|
auto end = ctx.end();
|
||||||
|
|
||||||
|
if (it != end && *it != MIJIN_SMART_QUOTE(char_t, '}'))
|
||||||
|
{
|
||||||
|
throw std::format_error("invalid format");
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TContext>
|
||||||
|
TContext::iterator format(const mijin::Stackframe& stackframe, TContext& ctx) const
|
||||||
|
{
|
||||||
|
auto it = ctx.out();
|
||||||
|
it = std::format_to(it, MIJIN_SMART_QUOTE(char_t, "[{}] {}:{} in {}"), stackframe.address, stackframe.filename,
|
||||||
|
stackframe.lineNumber, mijin::demangleCPPIdentifier(stackframe.function.c_str()));
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TChar>
|
||||||
|
struct std::formatter<mijin::Stacktrace, TChar>
|
||||||
|
{
|
||||||
|
using char_t = TChar;
|
||||||
|
|
||||||
|
template<class TContext>
|
||||||
|
constexpr TContext::iterator parse(TContext& ctx)
|
||||||
|
{
|
||||||
|
auto it = ctx.begin();
|
||||||
|
auto end = ctx.end();
|
||||||
|
|
||||||
|
if (it != end && *it != MIJIN_SMART_QUOTE(char_t, '}'))
|
||||||
|
{
|
||||||
|
throw std::format_error("invalid format");
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TContext>
|
||||||
|
TContext::iterator format(const mijin::Stacktrace& stacktrace, TContext& ctx) const
|
||||||
|
{
|
||||||
|
const int numDigits = static_cast<int>(std::ceil(std::log10(stacktrace.getFrames().size())));
|
||||||
|
auto it = ctx.out();
|
||||||
|
it = std::format_to(it, MIJIN_SMART_QUOTE(char_t, "[{} frames]"), stacktrace.getFrames().size());
|
||||||
|
for (const auto& [idx, frame] : mijin::enumerate(stacktrace.getFrames()))
|
||||||
|
{
|
||||||
|
it = std::format_to(it, MIJIN_SMART_QUOTE(char_t, "\n #{:<{}} at {}"), idx, numDigits, frame);
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#if __has_include(<fmt/format.h>)
|
#if __has_include(<fmt/format.h>)
|
||||||
template<>
|
template<>
|
||||||
struct fmt::formatter<mijin::Stackframe>
|
struct fmt::formatter<mijin::Stackframe>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user