journal/include/journal.hpp
2022-06-21 00:04:32 +01:00

178 lines
5.3 KiB
C++

#pragma once
#include <format>
#include <ios>
#include <string_view>
namespace journal {
namespace detail {
struct source_location {
_NODISCARD static constexpr source_location
current(const uint_least32_t _Line_ = __builtin_LINE(),
const uint_least32_t _Column_ = __builtin_COLUMN(),
const char *const _File_ = __builtin_FILE(),
const char *const _Function_ = __builtin_FUNCTION()) noexcept {
source_location _Result;
_Result._Line = _Line_;
_Result._Column = _Column_;
_Result._File = _File_;
_Result._Function = _Function_;
return _Result;
}
_NODISCARD_CTOR constexpr source_location() noexcept = default;
_NODISCARD constexpr uint_least32_t line() const noexcept { return _Line; }
_NODISCARD constexpr uint_least32_t column() const noexcept {
return _Column;
}
_NODISCARD constexpr const char *file_name() const noexcept { return _File; }
_NODISCARD constexpr const char *function_name() const noexcept {
return _Function;
}
private:
uint_least32_t _Line{};
uint_least32_t _Column{};
const char *_File = "";
const char *_Function = "";
};
enum LogVerbosity {
Trace,
Debug,
Info,
Warn,
Error,
};
constexpr auto to_string(const LogVerbosity& verbosity) -> std::string;
template <typename... Args>
inline constexpr auto log(const LogVerbosity &verbosity, std::string_view fmt,
Args... args, const detail::source_location source)
-> void {
const auto msg = std::vformat(fmt, std::make_format_args(args...));
log_internal(verbosity, source, msg);
}
auto log_internal(const LogVerbosity &verbosity,
const detail::source_location source, const std::string &msg)
-> void;
} // namespace detail
using detail::LogVerbosity;
auto init_std_out(const LogVerbosity &min = LogVerbosity::Info) -> void;
auto init_std_out_err(const LogVerbosity &min = LogVerbosity::Info) -> void;
auto init() -> void;
auto init_no_threads() -> void;
auto add_std_out() -> void;
auto add_std_err() -> void;
auto add_file(std::string_view file_path,
std::ios_base::openmode = std::ios_base::ate,
const LogVerbosity &min = LogVerbosity::Trace,
const LogVerbosity &max = LogVerbosity::Error) -> void;
auto add_sink(std::shared_ptr<std::ostream> stream,
const LogVerbosity &min = LogVerbosity::Trace,
const LogVerbosity &max = LogVerbosity::Error) -> void;
/// JOURNAL_NONE: undefines all logs
/// JOURNAL_ALL: defines all logs, on by default
/// JOURNAL_NOT_ALL: does not define any logs by default even it JOURNAL_ALL is
/// defined, off by default
#if defined(JOURNAL_ALL) && !defined(JOURNAL_NONE) && !defined(JOURNAL_NOT_ALL)
#define JOURNAL_TRACE
#define JOURNAL_DEBUG
#define JOURNAL_INFO
#define JOURNAL_WARN
#define JOURNAL_ERROR
#endif
#if defined(JOURNAL_NONE)
#undef JOURNAL_TRACE
#undef JOURNAL_DEBUG
#undef JOURNAL_INFO
#undef JOURNAL_WARN
#undef JOURNAL_ERROR
#endif
#ifdef JOURNAL_TRACE
template <typename... Args>
inline constexpr auto
trace(std::string_view fmt, Args... args,
const detail::source_location source = detail::source_location::current())
-> void {
detail::log(detail::LogVerbosity::Trace, fmt, args..., source);
}
#else
template <typename... Args>
inline constexpr auto trace(std::string_view fmt, Args... args) -> void {}
#endif
#ifdef JOURNAL_DEBUG
template <typename... Args>
inline constexpr auto
debug(std::string_view fmt, Args... args,
const detail::source_location source = detail::source_location::current())
-> void {
detail::log(detail::LogVerbosity::Debug, fmt, args..., source);
}
#else
template <typename... Args>
inline constexpr auto debug(std::string_view fmt, Args... args) -> void {}
#endif
#ifdef JOURNAL_INFO
template <typename... Args>
inline constexpr auto
info(std::string_view fmt, Args... args,
const detail::source_location source = detail::source_location::current())
-> void {
detail::log(detail::LogVerbosity::Info, fmt, args..., source);
}
#else
template <typename... Args>
inline constexpr auto info(std::string_view fmt, Args... args) -> void {}
#endif
#ifdef JOURNAL_WARN
template <typename... Args>
inline constexpr auto
warn(std::string_view fmt, Args... args,
const detail::source_location source = detail::source_location::current())
-> void {
detail::log(detail::LogVerbosity::Warn, fmt, args..., source);
}
#else
template <typename... Args>
inline constexpr auto warn(std::string_view fmt, Args... args) -> void {}
#endif
#ifdef JOURNAL_ERROR
template <typename... Args>
inline constexpr auto
error(std::string_view fmt, Args... args,
const detail::source_location source = detail::source_location::current())
-> void {
detail::log(detail::LogVerbosity::Error, fmt, args..., source);
}
#else
template <typename... Args>
inline constexpr auto error(std::string_view fmt, Args... args) -> void {}
#endif
/// JOURNAL_GLOG_COMPAT: enables LOG_F macro format which GLOG and Loguru use
/// for compatibility, on by default
#if defined(JOURNAL_GLOG_COMPAT)
#define LOG_F_TRACE(...) trace(__VA_ARGS__)
#define LOG_F_DEBUG(...) debug(__VA_ARGS__)
#define LOG_F_INFO(...) info(__VA_ARGS__)
#define LOG_F_WARN(...) warn(__VA_ARGS__)
#define LOG_F_ERROR(...) error(__VA_ARGS__)
#define LOG_F(V, ...) LOG_F_##V(__VA_ARGS__)
#endif
} // namespace journal