diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 0802a5d9..2521a099 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -27,6 +27,13 @@ #include +#ifdef __has_include +# if __has_include() && __cplusplus >= 202002L +# include +# define SPDLOG_SOURCE_LOCATION +# endif +#endif + #ifndef SPDLOG_NO_EXCEPTIONS # define SPDLOG_LOGGER_CATCH(location) \ catch (const std::exception &ex) \ @@ -90,6 +97,14 @@ public: log_(loc, lvl, details::to_string_view(fmt), std::forward(args)...); } +#ifdef SPDLOG_SOURCE_LOCATION + template + void log(std::source_location loc, level::level_enum lvl, format_string_t fmt, Args &&... args) + { + log_(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, details::to_string_view(fmt), std::forward(args)...); + } +#endif + template void log(level::level_enum lvl, format_string_t fmt, Args &&...args) { @@ -109,6 +124,14 @@ public: log(loc, lvl, "{}", msg); } +#ifdef SPDLOG_SOURCE_LOCATION + template + void log(std::source_location loc, level::level_enum lvl, const T &msg) + { + log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, msg); + } +#endif + void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg) { bool log_enabled = should_log(lvl); @@ -183,6 +206,14 @@ public: log_(loc, lvl, details::to_string_view(fmt), std::forward(args)...); } +# ifdef SPDLOG_SOURCE_LOCATION + template + void log(std::source_location loc, level::level_enum lvl, wformat_string_t fmt, Args &&... args) + { + log_(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, details::to_string_view(fmt), std::forward(args)...); + } +# endif + template void log(level::level_enum lvl, wformat_string_t fmt, Args &&...args) { diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index fbfe5fb8..1d0a2e35 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -140,6 +140,7 @@ SPDLOG_API void set_default_logger(std::shared_ptr default_logge // spdlog::apply_logger_env_levels(mylogger); SPDLOG_API void apply_logger_env_levels(std::shared_ptr logger); +#ifndef SPDLOG_SOURCE_LOCATION template inline void log(source_loc source, level::level_enum lvl, format_string_t fmt, Args &&...args) { @@ -200,7 +201,43 @@ inline void log(level::level_enum lvl, const T &msg) default_logger_raw()->log(lvl, msg); } -#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT +template +inline void trace(const T &msg) +{ + default_logger_raw()->trace(msg); +} + +template +inline void debug(const T &msg) +{ + default_logger_raw()->debug(msg); +} + +template +inline void info(const T &msg) +{ + default_logger_raw()->info(msg); +} + +template +inline void warn(const T &msg) +{ + default_logger_raw()->warn(msg); +} + +template +inline void error(const T &msg) +{ + default_logger_raw()->error(msg); +} + +template +inline void critical(const T &msg) +{ + default_logger_raw()->critical(msg); +} + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT template inline void log(source_loc source, level::level_enum lvl, wformat_string_t fmt, Args &&...args) { @@ -248,43 +285,295 @@ inline void critical(wformat_string_t fmt, Args &&...args) { default_logger_raw()->critical(fmt, std::forward(args)...); } +# endif #endif +#ifdef SPDLOG_SOURCE_LOCATION +template +struct log +{ + log(level::level_enum lvl, format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, fmt, std::forward(args)...); + } + + log(source_loc source, level::level_enum lvl, format_string_t fmt, Args &&... args) + { + default_logger_raw()->log(source, lvl, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + log(level::level_enum lvl, wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, fmt, std::forward(args)...); + } +# endif +}; + +template +struct trace +{ + trace(format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::trace, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + trace(wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::trace, fmt, std::forward(args)...); + } +# endif +}; + +template +struct debug +{ + debug(format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::debug, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + debug(wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::debug, fmt, std::forward(args)...); + } +# endif +}; + +template +struct info +{ + info(format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::info, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + info(wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::info, fmt, std::forward(args)...); + } +# endif +}; + +template +struct warn +{ + warn(format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::warn, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + warn(wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::warn, fmt, std::forward(args)...); + } +# endif +}; + +template +struct error +{ + error(format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::err, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + error(wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::err, fmt, std::forward(args)...); + } +# endif +}; + +template +struct critical +{ + critical(format_string_t fmt, Args &&...args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::critical, fmt, std::forward(args)...); + } + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + critical(wformat_string_t fmt, Args &&... args, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::critical, fmt, std::forward(args)...); + } +# endif +}; + +template +log(level::level_enum lvl, format_string_t fmt, Args &&... args) -> log; + +template +trace(format_string_t fmt, Args &&... args) -> trace; + +template +debug(format_string_t fmt, Args &&... args) -> debug; + +template +info(format_string_t fmt, Args &&... args) -> info; + +template +warn(format_string_t fmt, Args &&... args) -> warn; + +template +error(format_string_t fmt, Args &&... args) -> error; + +template +critical(format_string_t fmt, Args &&... args) -> critical; + +# ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT +template +log(level::level_enum lvl, wformat_string_t fmt, Args &&... args) -> log; + +template +trace(wformat_string_t fmt, Args &&... args) -> trace; + +template +debug(wformat_string_t fmt, Args &&... args) -> debug; + +template +info(wformat_string_t fmt, Args &&... args) -> info; + +template +warn(wformat_string_t fmt, Args &&... args) -> warn; + +template +error(wformat_string_t fmt, Args &&... args) -> error; + +template +critical(wformat_string_t fmt, Args &&... args) -> critical; +# endif + template -inline void trace(const T &msg) +struct log { - default_logger_raw()->trace(msg); -} + log(source_loc source, level::level_enum lvl, const T &msg) + { + default_logger_raw()->log(source, lvl, msg); + } + + log(level::level_enum lvl, const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, msg); + } + + log(level::level_enum lvl, format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, lvl, fmt, std::forward(arg)); + } +}; template -inline void debug(const T &msg) +struct trace { - default_logger_raw()->debug(msg); -} + trace(const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::trace, msg); + } + + trace(format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::trace, fmt, std::forward(arg)); + } +}; template -inline void info(const T &msg) +struct debug { - default_logger_raw()->info(msg); -} + debug(const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::debug, msg); + } + + debug(format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::debug, fmt, std::forward(arg)); + } +}; template -inline void warn(const T &msg) +struct info { - default_logger_raw()->warn(msg); -} + info(const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::info, msg); + } + + info(format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::info, fmt, std::forward(arg)); + } +}; template -inline void error(const T &msg) +struct warn { - default_logger_raw()->error(msg); -} + warn(const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::warn, msg); + } + + warn(format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::warn, fmt, std::forward(arg)); + } +}; template -inline void critical(const T &msg) +struct error { - default_logger_raw()->critical(msg); -} + error(const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::err, msg); + } + + error(format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::err, fmt, std::forward(arg)); + } +}; + +template +struct critical +{ + critical(const T &msg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::critical, msg); + } + + critical(format_string_t fmt, T&& arg, const std::source_location &loc = std::source_location::current()) + { + default_logger_raw()->log(spdlog::source_loc{loc.file_name(), static_cast(loc.line()), loc.function_name()}, level::critical, fmt, std::forward(arg)); + } +}; + +template +log(level::level_enum lvl, const T &msg) -> log; + +template +trace(const T &msg) -> trace; + +template +debug(const T &msg) -> debug; + +template +info(const T &msg) -> info; + +template +warn(const T &msg) -> warn; + +template +error(const T &msg) -> error; + +template +critical(const T &msg) -> critical; +#endif } // namespace spdlog diff --git a/tests/test_misc.cpp b/tests/test_misc.cpp index 6199641f..7cc082e0 100644 --- a/tests/test_misc.cpp +++ b/tests/test_misc.cpp @@ -167,6 +167,18 @@ TEST_CASE("default logger API", "[default logger]") spdlog::error(123); REQUIRE(oss.str() == "*** 123" + std::string(spdlog::details::os::default_eol)); + oss.str(""); + spdlog::log(spdlog::level::err, 123); + REQUIRE(oss.str() == "*** 123" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::log(spdlog::level::err, "{}", 123); + REQUIRE(oss.str() == "*** 123" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::log(spdlog::level::err, "{}{}{}", 1, 2, 3); + REQUIRE(oss.str() == "*** 123" + std::string(spdlog::details::os::default_eol)); + oss.str(""); spdlog::critical(std::string("some string")); REQUIRE(oss.str() == "*** some string" + std::string(spdlog::details::os::default_eol));