mirror of
https://github.com/gabime/spdlog.git
synced 2024-12-25 10:01:33 +08:00
Enable std::source_location if SPDLOG_EMIT_SOURCE_LOCATION is defined
This commit is contained in:
parent
1f2561c548
commit
b2372fd076
@ -10,7 +10,7 @@
|
||||
|
||||
void bench_formatter(benchmark::State &state, std::string pattern)
|
||||
{
|
||||
auto formatter = spdlog::std::make_unique<spdlog::pattern_formatter>(pattern);
|
||||
auto formatter = std::make_unique<spdlog::pattern_formatter>(pattern);
|
||||
spdlog::memory_buf_t dest;
|
||||
std::string logger_name = "logger-name";
|
||||
const char *text = "Hello. This is some message with length of 80 ";
|
||||
|
@ -15,9 +15,19 @@
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <version>
|
||||
|
||||
# if __cpp_lib_source_location >= 201907
|
||||
# include <source_location>
|
||||
# define SPDLOG_STD_SOURCE_LOCATION
|
||||
# elif __has_include(<experimental/source_location>)
|
||||
# include <experimental/source_location>
|
||||
# define SPDLOG_EXPERIMENTAL_SOURCE_LOCATION
|
||||
# endif
|
||||
|
||||
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
# include <version>
|
||||
# if __cpp_lib_format >= 202207L
|
||||
# include <format>
|
||||
# else
|
||||
@ -114,9 +124,7 @@ using format_string_t = std::format_string<Args...>;
|
||||
using format_string_t = std::string_view;
|
||||
# endif
|
||||
|
||||
template<class T, class Char = char>
|
||||
struct is_convertible_to_basic_format_string : std::integral_constant<bool, std::is_convertible<T, std::basic_string_view<Char>>::value>
|
||||
{};
|
||||
|
||||
# define SPDLOG_BUF_TO_STRING(x) x
|
||||
#else // use fmt lib instead of std::format
|
||||
namespace fmt_lib = fmt;
|
||||
@ -127,20 +135,9 @@ using memory_buf_t = fmt::basic_memory_buffer<char, 250>;
|
||||
template<typename... Args>
|
||||
using format_string_t = fmt::format_string<Args...>;
|
||||
|
||||
template<class T>
|
||||
using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
template<typename Char>
|
||||
using fmt_runtime_string = fmt::runtime_format_string<Char>;
|
||||
|
||||
// clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the condition from basic_format_string here,
|
||||
// in addition, fmt::basic_runtime<Char> is only convertible to basic_format_string<Char> but not basic_string_view<Char>
|
||||
template<class T, class Char = char>
|
||||
struct is_convertible_to_basic_format_string
|
||||
: std::integral_constant<bool,
|
||||
std::is_convertible<T, fmt::basic_string_view<Char>>::value || std::is_same<remove_cvref_t<T>, fmt_runtime_string<Char>>::value>
|
||||
{};
|
||||
|
||||
# if defined(SPDLOG_WCHAR_FILENAMES)
|
||||
using wstring_view_t = fmt::basic_string_view<wchar_t>;
|
||||
using wmemory_buf_t = fmt::basic_memory_buffer<wchar_t, 250>;
|
||||
@ -151,11 +148,6 @@ using wformat_string_t = fmt::wformat_string<Args...>;
|
||||
# define SPDLOG_BUF_TO_STRING(x) fmt::to_string(x)
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
struct is_convertible_to_any_format_string : std::integral_constant<bool, is_convertible_to_basic_format_string<T, char>::value ||
|
||||
is_convertible_to_basic_format_string<T, wchar_t>::value>
|
||||
{};
|
||||
|
||||
#if defined(SPDLOG_NO_ATOMIC_LEVELS)
|
||||
using level_t = details::null_atomic_int;
|
||||
#else
|
||||
@ -174,6 +166,10 @@ using level_t = std::atomic<int>;
|
||||
# define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
|
||||
#endif
|
||||
|
||||
// Is convertable to string_view_t ?
|
||||
template <typename T>
|
||||
using is_convertible_to_sv = std::enable_if_t<std::is_convertible_v<T, string_view_t>>;
|
||||
|
||||
// Log level enum
|
||||
namespace level {
|
||||
enum level_enum : int
|
||||
@ -255,24 +251,50 @@ private:
|
||||
[[noreturn]] SPDLOG_API void throw_spdlog_ex(const std::string &msg, int last_errno);
|
||||
[[noreturn]] SPDLOG_API void throw_spdlog_ex(std::string msg);
|
||||
|
||||
|
||||
struct source_loc
|
||||
{
|
||||
constexpr source_loc() = default;
|
||||
constexpr source_loc(const char *filename_in, int line_in, const char *funcname_in)
|
||||
constexpr source_loc(const char *filename_in, std::uint_least32_t line_in, const char *funcname_in)
|
||||
: filename{filename_in}
|
||||
, line{line_in}
|
||||
, funcname{funcname_in}
|
||||
{}
|
||||
|
||||
constexpr bool empty() const noexcept
|
||||
#ifdef SPDLOG_STD_SOURCE_LOCATION
|
||||
static constexpr source_loc current(const std::source_location source_location = std::source_location::current())
|
||||
{
|
||||
return source_loc{source_location.file_name(), source_location.line(), source_location.function_name()};
|
||||
}
|
||||
#elif defined(SPDLOG_EXPERIMENTAL_SOURCE_LOCATION)
|
||||
static constexpr source_loc current(const std::experimental::source_location source_location = std::experimental::source_location::current())
|
||||
{
|
||||
return source_loc{source_location.file_name(), source_location.line(), source_location.function_name()};
|
||||
}
|
||||
#else // no source location support
|
||||
static constexpr source_loc current()
|
||||
{
|
||||
return source_loc{};
|
||||
}
|
||||
#endif
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept
|
||||
{
|
||||
return line == 0;
|
||||
}
|
||||
const char *filename{nullptr};
|
||||
int line{0};
|
||||
std::uint_least32_t line{0};
|
||||
const char *funcname{nullptr};
|
||||
};
|
||||
|
||||
struct loc_with_fmt
|
||||
{
|
||||
source_loc loc;
|
||||
string_view_t fmt_string;
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
constexpr loc_with_fmt(S fmt_str, source_loc loc = source_loc::current()) noexcept: loc(loc), fmt_string(fmt_str) {}
|
||||
};
|
||||
|
||||
struct file_event_handlers
|
||||
{
|
||||
file_event_handlers()
|
||||
@ -328,21 +350,6 @@ constexpr std::basic_string_view<T> to_string_view(std::basic_format_string<T, A
|
||||
}
|
||||
#endif
|
||||
|
||||
// make_unique support for pre c++14
|
||||
|
||||
|
||||
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
|
||||
template<typename T, typename U, std::enable_if_t<!std::is_same<T, U>::value, int> = 0>
|
||||
constexpr T conditional_static_cast(U value)
|
||||
{
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template<typename T, typename U, std::enable_if_t<std::is_same<T, U>::value, int> = 0>
|
||||
constexpr T conditional_static_cast(U value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
@ -420,9 +420,9 @@ SPDLOG_INLINE int pid() noexcept
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
return conditional_static_cast<int>(::GetCurrentProcessId());
|
||||
return static_cast<int>(::GetCurrentProcessId());
|
||||
#else
|
||||
return conditional_static_cast<int>(::getpid());
|
||||
return static_cast<int>(::getpid());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -77,14 +77,14 @@ public:
|
||||
logger &operator=(logger other) noexcept;
|
||||
void swap(spdlog::logger &other) noexcept;
|
||||
|
||||
// log functions
|
||||
template<typename... Args>
|
||||
void log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args)
|
||||
{
|
||||
if (should_log(lvl))
|
||||
{
|
||||
log_with_format_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
|
||||
log_with_format_(loc, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -93,20 +93,36 @@ public:
|
||||
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void log(level::level_enum lvl, const T &msg)
|
||||
template<typename S,
|
||||
typename = is_convertible_to_sv<S>,
|
||||
typename... Args>
|
||||
void log(source_loc loc, level::level_enum lvl, S fmt, Args &&...args)
|
||||
{
|
||||
if (should_log(lvl))
|
||||
{
|
||||
log_with_format_(loc, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
// log with no format string, just string message
|
||||
template<typename S,
|
||||
typename = is_convertible_to_sv<S>>
|
||||
void log(source_loc loc, level::level_enum lvl, S msg)
|
||||
{
|
||||
if (should_log(lvl))
|
||||
{
|
||||
sink_it_(details::log_msg(loc, name_, lvl, msg));
|
||||
}
|
||||
}
|
||||
template<typename S>
|
||||
void log(level::level_enum lvl, S msg)
|
||||
{
|
||||
log(source_loc{}, lvl, msg);
|
||||
}
|
||||
|
||||
// T cannot be statically converted to format string (including string_view/wstring_view)
|
||||
template<class T, typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value, int>::type = 0>
|
||||
void log(source_loc loc, level::level_enum lvl, const T &msg)
|
||||
{
|
||||
log(loc, lvl, "{}", msg);
|
||||
}
|
||||
|
||||
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg)
|
||||
// support for custom time
|
||||
template<typename S>
|
||||
void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, S msg)
|
||||
{
|
||||
if (should_log(lvl))
|
||||
{
|
||||
@ -114,19 +130,80 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void log(source_loc loc, level::level_enum lvl, string_view_t msg)
|
||||
#ifdef SPDLOG_EMIT_SOURCE_LOCATION
|
||||
template<typename... Args>
|
||||
void trace(loc_with_fmt fmt, Args &&...args)
|
||||
{
|
||||
if (should_log(lvl))
|
||||
{
|
||||
sink_it_(details::log_msg(loc, name_, lvl, msg));
|
||||
}
|
||||
log(fmt.loc, level::trace, fmt.fmt_string, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void log(level::level_enum lvl, string_view_t msg)
|
||||
template<typename... Args>
|
||||
void debug(loc_with_fmt fmt, Args &&...args)
|
||||
{
|
||||
log(source_loc{}, lvl, msg);
|
||||
log(fmt.loc, level::debug, fmt.fmt_string, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void info(loc_with_fmt fmt, Args &&...args)
|
||||
{
|
||||
log(fmt.loc, level::info, fmt.fmt_string, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void warn(loc_with_fmt fmt, Args &&...args)
|
||||
{
|
||||
log(fmt.loc, level::warn, fmt.fmt_string, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void error(loc_with_fmt fmt, Args &&...args)
|
||||
{
|
||||
log(fmt.loc, level::err, fmt.fmt_string, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void critical(loc_with_fmt fmt, Args &&...args)
|
||||
{
|
||||
log(fmt.loc, level::critical, fmt.fmt_string, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// log functions with no format string, just argument
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void trace(const S &msg, source_loc loc = source_loc::current())
|
||||
{
|
||||
log(loc, level::trace, msg);
|
||||
}
|
||||
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void debug(const S &msg, source_loc loc = source_loc::current())
|
||||
{
|
||||
log(loc, level::debug, msg);
|
||||
}
|
||||
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void info(const S &msg, source_loc loc = source_loc::current())
|
||||
{
|
||||
log(loc, level::info, msg);
|
||||
}
|
||||
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void warn(const S &msg, source_loc loc = source_loc::current())
|
||||
{
|
||||
log(loc, level::warn, msg);
|
||||
}
|
||||
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void error(const S &msg, source_loc loc = source_loc::current())
|
||||
{
|
||||
log(loc, level::err, msg);
|
||||
}
|
||||
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void critical(const S &msg, source_loc loc = source_loc::current())
|
||||
{
|
||||
log(loc, level::critical, msg);
|
||||
}
|
||||
#else
|
||||
template<typename... Args>
|
||||
void trace(format_string_t<Args...> fmt, Args &&...args)
|
||||
{
|
||||
@ -163,41 +240,44 @@ public:
|
||||
log(level::critical, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void trace(const T &msg)
|
||||
// log functions with no format string, just argument
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void trace(const S &msg)
|
||||
{
|
||||
log(level::trace, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void debug(const T &msg)
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void debug(const S &msg)
|
||||
{
|
||||
log(level::debug, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void info(const T &msg)
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void info(const S &msg)
|
||||
{
|
||||
log(level::info, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void warn(const T &msg)
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void warn(const S &msg)
|
||||
{
|
||||
log(level::warn, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void error(const T &msg)
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void error(const S &msg)
|
||||
{
|
||||
log(level::err, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void critical(const T &msg)
|
||||
template<typename S, typename = is_convertible_to_sv<S>>
|
||||
void critical(const S &msg)
|
||||
{
|
||||
log(level::critical, msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// return true logging is enabled for the given level.
|
||||
[[nodiscard]] bool should_log(level::level_enum msg_level) const
|
||||
|
Loading…
Reference in New Issue
Block a user