mijin2/source/mijin/logging/stdio_sink.hpp

59 lines
1.9 KiB
C++

#pragma once
#if !defined(MIJIN_LOGGING_STDIO_SINK_HPP_INCLUDED)
#define MIJIN_LOGGING_STDIO_SINK_HPP_INCLUDED 1
#include "./formatting.hpp"
#include "../util/traits.hpp"
namespace mijin
{
template<MIJIN_FORMATTING_SINK_TMPL_ARGS_INIT>
requires(allocator_type<TAllocator<TChar>>)
class StdioSink : public BaseFormattingLogSink<MIJIN_FORMATTING_SINK_TMP_ARG_NAMES>
{
public:
using base_t = BaseFormattingLogSink<MIJIN_FORMATTING_SINK_TMP_ARG_NAMES>;
using typename base_t::char_t;
using typename base_t::allocator_t;
using typename base_t::formatter_ptr_t;
using typename base_t::message_t;
private:
int mMinStderrLevel;
public:
explicit StdioSink(not_null_t<formatter_ptr_t> formatter, allocator_t allocator = {},
int minStderrLevel = MIJIN_LOG_LEVEL_VALUE_WARNING)
MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v<allocator_t>)
: base_t(std::move(formatter), std::move(allocator)), mMinStderrLevel(minStderrLevel) {}
void handleMessageFormatted(const message_t& message, const char_t* formatted) MIJIN_NOEXCEPT override
{
FILE* stream = (message.level->value >= mMinStderrLevel) ? stderr : stdout;
if constexpr (std::is_same_v<char_t, char>)
{
std::fputs(formatted, stream);
std::fputc('\n', stream);
}
else if constexpr (std::is_same_v<char_t, wchar_t>)
{
std::fputws(formatted, stream);
std::fputwc(L'\n', stream);
}
else if constexpr (sizeof(char_t) == sizeof(char))
{
// char8_t etc.
std::fputs(std::bit_cast<const char*>(formatted), stream);
std::fputc('\n', stream);
}
else
{
static_assert(always_false_v<char_t>, "Character type not supported.");
}
}
};
} // namespace mijin
#endif // !defined(MIJIN_LOGGING_STDIO_SINK_HPP_INCLUDED)