#pragma once #include #include #include #include #include #include #include #include #include #include #include template struct fmt::formatter> { constexpr static auto parse(format_parse_context &ctx) { return ctx.begin(); } template auto format(std::integral_constant, FormatContext &ctx) const { return ::fmt::format_to(ctx.out(), logging::to_text()); } }; namespace logging::fmt { template struct log_handler { constexpr explicit log_handler(TDestinations &&ds) : dests{std::move(ds)} {} template auto log(FilenameStringType, LineNumberType, MsgType const &msg) -> void { auto const currentTime = std::chrono::duration_cast( std::chrono::steady_clock::now() - start_time) .count(); stdx::for_each( [&](auto &out) { ::fmt::format_to(out, "{:>8}us {} [{}]: ", currentTime, get_level(Env{}), get_module(Env{}).value); msg.apply( [&](StringType, auto const &...args) { ::fmt::format_to(out, StringType::value, args...); }); *out = '\n'; }, dests); } private: static inline auto const start_time = std::chrono::steady_clock::now(); TDestinations dests; }; template struct config { using destinations_tuple_t = stdx::tuple; constexpr explicit config(TDestinations... dests) : logger{stdx::tuple{std::move(dests)...}} {} log_handler logger; }; } // namespace logging::fmt