include/DetourModKit/logger.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef DETOURMODKIT_LOGGER_HPP | ||
| 2 | #define DETOURMODKIT_LOGGER_HPP | ||
| 3 | |||
| 4 | #include <string> | ||
| 5 | #include <string_view> | ||
| 6 | #include <mutex> | ||
| 7 | #include <memory> | ||
| 8 | #include <chrono> | ||
| 9 | #include <format> | ||
| 10 | #include <atomic> | ||
| 11 | |||
| 12 | #include "DetourModKit/win_file_stream.hpp" | ||
| 13 | |||
| 14 | namespace DetourModKit | ||
| 15 | { | ||
| 16 | /** | ||
| 17 | * @enum LogLevel | ||
| 18 | * @brief Defines the severity levels for log messages. | ||
| 19 | * @note This is an enum class (C++ Core Guidelines Enum.3) to prevent namespace pollution. | ||
| 20 | */ | ||
| 21 | enum class LogLevel | ||
| 22 | { | ||
| 23 | Trace = 0, | ||
| 24 | Debug = 1, | ||
| 25 | Info = 2, | ||
| 26 | Warning = 3, | ||
| 27 | Error = 4 | ||
| 28 | }; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * @brief Converts a LogLevel enum to its string representation. | ||
| 32 | * @param level The LogLevel enum value. | ||
| 33 | * @return std::string_view String representation of the log level. | ||
| 34 | */ | ||
| 35 | 3360 | constexpr std::string_view log_level_to_string(LogLevel level) noexcept | |
| 36 | { | ||
| 37 |
6/6✓ Branch 2 → 3 taken 24 times.
✓ Branch 2 → 4 taken 21 times.
✓ Branch 2 → 5 taken 3180 times.
✓ Branch 2 → 6 taken 41 times.
✓ Branch 2 → 7 taken 93 times.
✓ Branch 2 → 8 taken 1 time.
|
3360 | switch (level) |
| 38 | { | ||
| 39 | 24 | case LogLevel::Trace: | |
| 40 | 24 | return "TRACE"; | |
| 41 | 21 | case LogLevel::Debug: | |
| 42 | 21 | return "DEBUG"; | |
| 43 | 3180 | case LogLevel::Info: | |
| 44 | 3180 | return "INFO"; | |
| 45 | 41 | case LogLevel::Warning: | |
| 46 | 41 | return "WARNING"; | |
| 47 | 93 | case LogLevel::Error: | |
| 48 | 93 | return "ERROR"; | |
| 49 | 1 | default: | |
| 50 | 1 | return "UNKNOWN"; | |
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | // Logger configuration defaults | ||
| 55 | inline constexpr const char *DEFAULT_LOG_PREFIX = "DetourModKit"; | ||
| 56 | inline constexpr const char *DEFAULT_LOG_FILE_NAME = "DetourModKit_Log.txt"; | ||
| 57 | inline constexpr const char *DEFAULT_TIMESTAMP_FORMAT = "%Y-%m-%d %H:%M:%S"; | ||
| 58 | |||
| 59 | // Forward declarations | ||
| 60 | struct AsyncLoggerConfig; | ||
| 61 | class AsyncLogger; | ||
| 62 | |||
| 63 | /** | ||
| 64 | * @class Logger | ||
| 65 | * @brief A singleton class for logging messages to a file. | ||
| 66 | * @details Provides thread-safe logging with configurable levels, timestamps, | ||
| 67 | * and log file location. Uses atomic LogLevel for thread-safe level changes. | ||
| 68 | */ | ||
| 69 | class Logger | ||
| 70 | { | ||
| 71 | public: | ||
| 72 | /** | ||
| 73 | * @brief Retrieves the singleton instance of the Logger. | ||
| 74 | * @return Logger& Reference to the single Logger instance. | ||
| 75 | */ | ||
| 76 | 1230 | static Logger &get_instance() | |
| 77 | { | ||
| 78 |
4/8✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 8 taken 1229 times.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
1230 | static Logger instance; |
| 79 | 1230 | return instance; | |
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * @brief Configures global static settings for the logger before first instantiation. | ||
| 84 | * @details If the logger instance already exists, this will also reconfigure the instance | ||
| 85 | * by reopening the log file with the new settings. | ||
| 86 | * @param prefix Default log prefix string. | ||
| 87 | * @param file_name Default log file name. | ||
| 88 | * @param timestamp_fmt Default timestamp format string (strftime compatible). | ||
| 89 | */ | ||
| 90 | static void configure(std::string_view prefix, std::string_view file_name, std::string_view timestamp_fmt); | ||
| 91 | |||
| 92 | /** | ||
| 93 | * @brief Reconfigures an existing logger instance with new settings. | ||
| 94 | * @details Closes the current log file (if open) and reopens it with the new settings. | ||
| 95 | * Thread-safe. Logs a message about the reconfiguration. | ||
| 96 | * @param prefix New log prefix string. | ||
| 97 | * @param file_name New log file name. | ||
| 98 | * @param timestamp_fmt New timestamp format string (strftime compatible). | ||
| 99 | */ | ||
| 100 | void reconfigure(std::string_view prefix, std::string_view file_name, std::string_view timestamp_fmt); | ||
| 101 | |||
| 102 | /** | ||
| 103 | * @brief Enables asynchronous logging mode. | ||
| 104 | * @details When enabled, log messages are queued and written by a dedicated | ||
| 105 | * writer thread, reducing latency on the calling thread. | ||
| 106 | * @param config Optional async logger configuration. Uses defaults if not provided. | ||
| 107 | */ | ||
| 108 | void enable_async_mode(const AsyncLoggerConfig &config); | ||
| 109 | void enable_async_mode(); | ||
| 110 | |||
| 111 | /** | ||
| 112 | * @brief Disables asynchronous logging mode and returns to synchronous mode. | ||
| 113 | * @details Flushes all pending async messages before switching. | ||
| 114 | */ | ||
| 115 | void disable_async_mode(); | ||
| 116 | |||
| 117 | /** | ||
| 118 | * @brief Checks if async logging mode is enabled. | ||
| 119 | * @return true if async mode is enabled, false otherwise. | ||
| 120 | */ | ||
| 121 | bool is_async_mode_enabled() const; | ||
| 122 | |||
| 123 | /** | ||
| 124 | * @brief Flushes all pending log messages. | ||
| 125 | * @details In async mode, waits for all queued messages to be written. | ||
| 126 | * In sync mode, flushes the file stream. | ||
| 127 | */ | ||
| 128 | void flush(); | ||
| 129 | |||
| 130 | /** | ||
| 131 | * @brief Explicitly shuts down the Logger, closing files without logging. | ||
| 132 | * @details This method is safe to call during shutdown. It closes the log file | ||
| 133 | * and shuts down async logger without attempting to log, preventing | ||
| 134 | * use-after-free if called after other singletons are destroyed. | ||
| 135 | * After calling shutdown(), the destructor becomes a no-op. | ||
| 136 | */ | ||
| 137 | void shutdown(); | ||
| 138 | |||
| 139 | /** | ||
| 140 | * @brief Gets the current log level. | ||
| 141 | * @return LogLevel The current minimum log level. | ||
| 142 | */ | ||
| 143 | 13 | LogLevel get_log_level() const | |
| 144 | { | ||
| 145 | 13 | return current_log_level_.load(std::memory_order_acquire); | |
| 146 | } | ||
| 147 | |||
| 148 | /** | ||
| 149 | * @brief Checks whether messages at the given level would be logged. | ||
| 150 | * @details Useful for gating expensive trace-only work (e.g. iterating | ||
| 151 | * a data structure solely to build a log message). | ||
| 152 | * @param level The LogLevel to test. | ||
| 153 | * @return true if a message at this level would pass the current filter. | ||
| 154 | */ | ||
| 155 | 40 | bool is_enabled(LogLevel level) const noexcept | |
| 156 | { | ||
| 157 | 40 | return level >= current_log_level_.load(std::memory_order_acquire); | |
| 158 | } | ||
| 159 | |||
| 160 | /** | ||
| 161 | * @brief Sets the minimum log level for messages to be recorded. | ||
| 162 | * @param level The minimum LogLevel to record. | ||
| 163 | */ | ||
| 164 | void set_log_level(LogLevel level); | ||
| 165 | |||
| 166 | /** | ||
| 167 | * @brief Logs a message if its level is at or above the current log level. | ||
| 168 | * @param level The LogLevel of the message. | ||
| 169 | * @param message The message string to log. | ||
| 170 | */ | ||
| 171 | void log(LogLevel level, std::string_view message); | ||
| 172 | |||
| 173 | /** | ||
| 174 | * @brief Logs a formatted message with the specified log level. | ||
| 175 | * @details Uses std::format-style placeholders. Arguments are only formatted | ||
| 176 | * if the log level is enabled (lazy evaluation). | ||
| 177 | * @tparam Args Types of the format arguments. | ||
| 178 | * @param level The LogLevel of the message. | ||
| 179 | * @param fmt The format string with {} placeholders. | ||
| 180 | * @param args The arguments to substitute into the format string. | ||
| 181 | */ | ||
| 182 | template <typename... Args> | ||
| 183 | 2557 | void log(LogLevel level, std::format_string<Args...> fmt, Args &&...args) | |
| 184 | { | ||
| 185 |
56/98void DetourModKit::Logger::log<>(DetourModKit::LogLevel, std::basic_format_string<char>):
✓ Branch 3 → 4 taken 60 times.
✓ Branch 3 → 9 taken 458 times.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 2 times.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<unsigned long>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, unsigned long&&):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 15 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<unsigned long>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, unsigned long&&):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 13 not taken.
void DetourModKit::Logger::log<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<char const*>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type>, char const*&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 13 not taken.
void DetourModKit::Logger::log<void*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<void*>::type>, void*&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 1 time.
void DetourModKit::Logger::log<char const (&) [6]>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<char const (&) [6]>::type>, char const (&) [6]):
✓ Branch 3 → 4 taken 5 times.
✗ Branch 3 → 11 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 1 time.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<char const*>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 1 time.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, float const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<float const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, float const&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 1 time.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<int const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int const&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 4 times.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 4 times.
void DetourModKit::Logger::log<int const&, int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int const&>::type, std::type_identity<int&>::type>, int const&, int&):
✓ Branch 3 → 4 taken 796 times.
✓ Branch 3 → 13 taken 3 times.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 11 taken 117 times.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type, std::type_identity<char const*>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const*&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 14 times.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type, std::type_identity<int&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&):
✓ Branch 3 → 4 taken 26 times.
✗ Branch 3 → 13 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned long long&, char const*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type, std::type_identity<unsigned long long&>::type, std::type_identity<char const*>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned long long&, char const*&&):
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 15 not taken.
void DetourModKit::Logger::log<void*&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<void*&>::type>, void*&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 1 time.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type>, std::basic_string_view<char, std::char_traits<char> >&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 113 times.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 17 taken 3 times.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 185 times.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type>, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&):
✓ Branch 3 → 4 taken 7 times.
✗ Branch 3 → 13 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 15 taken 10 times.
void DetourModKit::Logger::log<int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int&>::type>, int&):
✓ Branch 3 → 4 taken 182 times.
✓ Branch 3 → 11 taken 3 times.
void DetourModKit::Logger::log<int&, int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int&>::type, std::type_identity<int&>::type>, int&, int&):
✓ Branch 3 → 4 taken 25 times.
✗ Branch 3 → 13 not taken.
void DetourModKit::Logger::log<unsigned long long&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type>, unsigned long long&):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 11 taken 130 times.
void DetourModKit::Logger::log<unsigned long long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, unsigned long long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 6 times.
void DetourModKit::Logger::log<unsigned long long&, unsigned long long const&, unsigned int&, unsigned long long const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type, std::type_identity<unsigned long long const&>::type, std::type_identity<unsigned int&>::type, std::type_identity<unsigned long long const&>::type>, unsigned long long&, unsigned long long const&, unsigned int&, unsigned long long const&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 17 taken 167 times.
void DetourModKit::Logger::log<unsigned long long&, unsigned long long&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type, std::type_identity<unsigned long long&>::type>, unsigned long long&, unsigned long long&):
✓ Branch 3 → 4 taken 16 times.
✓ Branch 3 → 13 taken 3 times.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<unsigned long long>::type>, std::basic_string_view<char, std::char_traits<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long long&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 15 taken 26 times.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&&, std::basic_string_view<char, std::char_traits<char> >&&):
✓ Branch 3 → 4 taken 20 times.
✓ Branch 3 → 13 taken 12 times.
void DetourModKit::Logger::log<bool>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<bool>::type>, bool&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 3 times.
void DetourModKit::Logger::log<char>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<char>::type>, char&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 1 time.
void DetourModKit::Logger::log<double>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<double>::type>, double&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 3 times.
void DetourModKit::Logger::log<float>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<float>::type>, float&&):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 11 taken 2 times.
void DetourModKit::Logger::log<int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type>, int&&):
✓ Branch 3 → 4 taken 18 times.
✓ Branch 3 → 11 taken 17 times.
void DetourModKit::Logger::log<int, char const (&) [4], float>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<char const (&) [4]>::type, std::type_identity<float>::type>, int&&, char const (&) [4], float&&):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 15 not taken.
void DetourModKit::Logger::log<int, char const (&) [4], float, bool, char>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<char const (&) [4]>::type, std::type_identity<float>::type, std::type_identity<bool>::type, std::type_identity<char>::type>, int&&, char const (&) [4], float&&, bool&&, char&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 19 taken 1 time.
void DetourModKit::Logger::log<int, double>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<double>::type>, int&&, double&&):
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 13 not taken.
void DetourModKit::Logger::log<int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 13 taken 1 time.
void DetourModKit::Logger::log<int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&):
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 15 taken 1 time.
void DetourModKit::Logger::log<int, int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&, int&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 17 taken 1 time.
void DetourModKit::Logger::log<int, int, int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&, int&&, int&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 19 taken 1 time.
void DetourModKit::Logger::log<int, int, int, int, int, int, int, int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&, int&&, int&&, int&&, int&&, int&&, int&&, int&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 29 taken 1 time.
void DetourModKit::Logger::log<long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<long>::type>, long&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 1 time.
void DetourModKit::Logger::log<unsigned long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type>, unsigned long long&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 11 taken 3 times.
void DetourModKit::Logger::log<unsigned long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type>, unsigned long long&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 68 times.
void DetourModKit::Logger::log<unsigned long long, long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type, std::type_identity<long long>::type>, unsigned long long&&, long long&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 20 times.
void DetourModKit::Logger::log<unsigned long long, unsigned long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type, std::type_identity<unsigned long long>::type>, unsigned long long&&, unsigned long long&&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 13 taken 6 times.
|
2557 | if (level >= current_log_level_.load(std::memory_order_acquire)) |
| 186 | { | ||
| 187 |
34/196void DetourModKit::Logger::log<>(DetourModKit::LogLevel, std::basic_format_string<char>):
✓ Branch 4 → 5 taken 60 times.
✗ Branch 4 → 12 not taken.
✓ Branch 6 → 7 taken 60 times.
✗ Branch 6 → 10 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<unsigned long>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, unsigned long&&):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 18 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 16 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<unsigned long>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, unsigned long&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<char const*>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type>, char const*&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<void*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<void*>::type>, void*&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<char const (&) [6]>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<char const (&) [6]>::type>, char const (&) [6]):
✓ Branch 6 → 7 taken 5 times.
✗ Branch 6 → 14 not taken.
✓ Branch 8 → 9 taken 5 times.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<char const*>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, float const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<float const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, float const&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<int const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int const&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<int const&, int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int const&>::type, std::type_identity<int&>::type>, int const&, int&):
✓ Branch 8 → 9 taken 775 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 798 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 6 → 7 taken 4 times.
✗ Branch 6 → 14 not taken.
✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type, std::type_identity<char const*>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const*&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type, std::type_identity<int&>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&):
✓ Branch 8 → 9 taken 26 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 26 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned long long&, char const*>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type, std::type_identity<unsigned long long&>::type, std::type_identity<char const*>::type>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned long long&, char const*&&):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 18 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 16 not taken.
void DetourModKit::Logger::log<void*&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<void*&>::type>, void*&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type>, std::basic_string_view<char, std::char_traits<char> >&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 20 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 18 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type>, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&):
✓ Branch 8 → 9 taken 7 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 7 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> >&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 18 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 16 not taken.
void DetourModKit::Logger::log<int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int&>::type>, int&):
✓ Branch 6 → 7 taken 182 times.
✗ Branch 6 → 14 not taken.
✓ Branch 8 → 9 taken 182 times.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<int&, int&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int&>::type, std::type_identity<int&>::type>, int&, int&):
✓ Branch 8 → 9 taken 25 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 25 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<unsigned long long&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type>, unsigned long long&):
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 14 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<unsigned long long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::type>, unsigned long long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<unsigned long long&, unsigned long long const&, unsigned int&, unsigned long long const&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type, std::type_identity<unsigned long long const&>::type, std::type_identity<unsigned int&>::type, std::type_identity<unsigned long long const&>::type>, unsigned long long&, unsigned long long const&, unsigned int&, unsigned long long const&):
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 20 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 18 not taken.
void DetourModKit::Logger::log<unsigned long long&, unsigned long long&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long&>::type, std::type_identity<unsigned long long&>::type>, unsigned long long&, unsigned long long&):
✓ Branch 8 → 9 taken 16 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 16 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type, std::type_identity<unsigned long long>::type>, std::basic_string_view<char, std::char_traits<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long long&&):
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 18 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 16 not taken.
void DetourModKit::Logger::log<std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> > >(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type, std::type_identity<std::basic_string_view<char, std::char_traits<char> > >::type>, std::basic_string_view<char, std::char_traits<char> >&&, std::basic_string_view<char, std::char_traits<char> >&&):
✓ Branch 8 → 9 taken 20 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 20 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<bool>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<bool>::type>, bool&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<char>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<char>::type>, char&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<double>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<double>::type>, double&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<float>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<float>::type>, float&&):
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 14 not taken.
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type>, int&&):
✓ Branch 6 → 7 taken 18 times.
✗ Branch 6 → 14 not taken.
✓ Branch 8 → 9 taken 18 times.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<int, char const (&) [4], float>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<char const (&) [4]>::type, std::type_identity<float>::type>, int&&, char const (&) [4], float&&):
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 18 not taken.
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 16 not taken.
void DetourModKit::Logger::log<int, char const (&) [4], float, bool, char>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<char const (&) [4]>::type, std::type_identity<float>::type, std::type_identity<bool>::type, std::type_identity<char>::type>, int&&, char const (&) [4], float&&, bool&&, char&&):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 22 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void DetourModKit::Logger::log<int, double>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<double>::type>, int&&, double&&):
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&):
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&):
✓ Branch 10 → 11 taken 5 times.
✗ Branch 10 → 18 not taken.
✓ Branch 12 → 13 taken 5 times.
✗ Branch 12 → 16 not taken.
void DetourModKit::Logger::log<int, int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&, int&&):
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 20 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 18 not taken.
void DetourModKit::Logger::log<int, int, int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&, int&&, int&&):
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 22 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 20 not taken.
void DetourModKit::Logger::log<int, int, int, int, int, int, int, int, int, int>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type, std::type_identity<int>::type>, int&&, int&&, int&&, int&&, int&&, int&&, int&&, int&&, int&&, int&&):
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 32 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 30 not taken.
void DetourModKit::Logger::log<long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<long>::type>, long&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<unsigned long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type>, unsigned long long&&):
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
void DetourModKit::Logger::log<unsigned long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type, std::type_identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type>, unsigned long long&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<unsigned long long, long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type, std::type_identity<long long>::type>, unsigned long long&&, long long&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
void DetourModKit::Logger::log<unsigned long long, unsigned long long>(DetourModKit::LogLevel, std::basic_format_string<char, std::type_identity<unsigned long long>::type, std::type_identity<unsigned long long>::type>, unsigned long long&&, unsigned long long&&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
|
2076 | log(level, std::format(fmt, std::forward<Args>(args)...)); |
| 188 | } | ||
| 189 | 2564 | } | |
| 190 | |||
| 191 | /// @name Convenience log methods | ||
| 192 | /// Shorthand for `log(LogLevel::X, fmt, args...)`. See log() for parameter docs. | ||
| 193 | /// @{ | ||
| 194 | template <typename... Args> | ||
| 195 | 16 | void trace(std::format_string<Args...> fmt, Args &&...args) | |
| 196 | { | ||
| 197 | 19 | log(LogLevel::Trace, fmt, std::forward<Args>(args)...); | |
| 198 | 16 | } | |
| 199 | |||
| 200 | template <typename... Args> | ||
| 201 | 850 | void debug(std::format_string<Args...> fmt, Args &&...args) | |
| 202 | { | ||
| 203 | 1442 | log(LogLevel::Debug, fmt, std::forward<Args>(args)...); | |
| 204 | 850 | } | |
| 205 | |||
| 206 | template <typename... Args> | ||
| 207 | 1278 | void info(std::format_string<Args...> fmt, Args &&...args) | |
| 208 | { | ||
| 209 | 2236 | log(LogLevel::Info, fmt, std::forward<Args>(args)...); | |
| 210 | 1281 | } | |
| 211 | |||
| 212 | template <typename... Args> | ||
| 213 | 299 | void warning(std::format_string<Args...> fmt, Args &&...args) | |
| 214 | { | ||
| 215 | 486 | log(LogLevel::Warning, fmt, std::forward<Args>(args)...); | |
| 216 | 303 | } | |
| 217 | |||
| 218 | template <typename... Args> | ||
| 219 | 56 | void error(std::format_string<Args...> fmt, Args &&...args) | |
| 220 | { | ||
| 221 | 91 | log(LogLevel::Error, fmt, std::forward<Args>(args)...); | |
| 222 | 56 | } | |
| 223 | /// @} | ||
| 224 | |||
| 225 | /** | ||
| 226 | * @brief Converts a log level string to the LogLevel enum. | ||
| 227 | * @param level_str The string to convert (case-insensitive). | ||
| 228 | * @return The corresponding LogLevel enum. Defaults to LogLevel::Info if unrecognized. | ||
| 229 | */ | ||
| 230 | static LogLevel string_to_log_level(std::string_view level_str); | ||
| 231 | |||
| 232 | /** | ||
| 233 | * @struct StaticConfig | ||
| 234 | * @brief Immutable configuration snapshot for thread-safe static configuration. | ||
| 235 | * @details Stored behind an atomic shared_ptr so readers never need a mutex. | ||
| 236 | */ | ||
| 237 | struct StaticConfig | ||
| 238 | { | ||
| 239 | std::string log_prefix; | ||
| 240 | std::string log_file_name; | ||
| 241 | std::string timestamp_format; | ||
| 242 | |||
| 243 | 198 | StaticConfig(std::string prefix, std::string file, std::string ts_fmt) | |
| 244 | 396 | : log_prefix(std::move(prefix)), | |
| 245 | 396 | log_file_name(std::move(file)), | |
| 246 | 396 | timestamp_format(std::move(ts_fmt)) {} | |
| 247 | }; | ||
| 248 | |||
| 249 | private: | ||
| 250 | Logger(); | ||
| 251 | ~Logger() noexcept; | ||
| 252 | |||
| 253 | Logger(const Logger &) = delete; | ||
| 254 | Logger &operator=(const Logger &) = delete; | ||
| 255 | Logger(Logger &&) = delete; | ||
| 256 | Logger &operator=(Logger &&) = delete; | ||
| 257 | |||
| 258 | /** | ||
| 259 | * @brief Shared shutdown logic used by both ~Logger() and shutdown(). | ||
| 260 | */ | ||
| 261 | void shutdown_internal(); | ||
| 262 | |||
| 263 | /** | ||
| 264 | * @brief Generates the current timestamp formatted according to timestamp_format_. | ||
| 265 | * @return std::string The formatted timestamp string. | ||
| 266 | */ | ||
| 267 | std::string get_timestamp() const; | ||
| 268 | |||
| 269 | /** | ||
| 270 | * @brief Determines the full path for the log file. | ||
| 271 | * @return std::string The absolute path to the log file. | ||
| 272 | */ | ||
| 273 | std::string generate_log_file_path() const; | ||
| 274 | |||
| 275 | static std::shared_ptr<const StaticConfig> get_static_config(); | ||
| 276 | static void set_static_config(std::shared_ptr<const StaticConfig> config); | ||
| 277 | |||
| 278 | // Lock ordering (must be acquired in this order to prevent deadlock): | ||
| 279 | // 1. async_mutex_ — async logger lifecycle | ||
| 280 | // 2. *log_mutex_ptr_ — file stream I/O | ||
| 281 | |||
| 282 | std::string log_prefix_; | ||
| 283 | std::string log_file_name_; | ||
| 284 | std::string timestamp_format_; | ||
| 285 | |||
| 286 | std::shared_ptr<WinFileStream> log_file_stream_ptr_; | ||
| 287 | std::shared_ptr<std::mutex> log_mutex_ptr_; | ||
| 288 | std::atomic<LogLevel> current_log_level_{LogLevel::Info}; | ||
| 289 | std::atomic<bool> shutdown_called_{false}; | ||
| 290 | |||
| 291 | // Async logging support (forward declared). | ||
| 292 | // async_logger_ is atomic for lock-free reads on the log() hot path. | ||
| 293 | // async_mutex_ serializes lifecycle operations (enable/disable/shutdown). | ||
| 294 | std::atomic<std::shared_ptr<AsyncLogger>> async_logger_{}; | ||
| 295 | std::atomic<bool> async_mode_enabled_{false}; | ||
| 296 | std::mutex async_mutex_; | ||
| 297 | }; | ||
| 298 | } // namespace DetourModKit | ||
| 299 | |||
| 300 | #endif // DETOURMODKIT_LOGGER_HPP | ||
| 301 |