/* * Copyright (C) 2023 Christopher J. Howard * * This file is part of Antkeeper source code. * * Antkeeper source code is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Antkeeper source code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Antkeeper source code. If not, see . */ #ifndef ANTKEEPER_DEBUG_LOG_HPP #define ANTKEEPER_DEBUG_LOG_HPP #include "config.hpp" #include "debug/log/message-severity.hpp" #include "debug/log/logger.hpp" #include #include #include // Enable logging of messages of all severities by default. #if !defined(ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY) #define ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY (ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_TRACE) #endif namespace debug { /** * Debug message logging. */ namespace log { /** * Returns the default logger. */ [[nodiscard]] logger& default_logger() noexcept; /** * Self-formatting message that logs itself to the default logger on construction. * * @tparam Severity Message severity. A message will not log itself if @p Severity is less than the user-defined macro `ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY`. * @tparam Args Types of arguments to be formatted. */ template struct message { /** * Formats and logs a message. * * Class template argument deduction (CTAD) is utilized to capture source location as a default argument following variadic format arguments. * * @param format Message format string. * @param args Arguments to be formatted. * @param location Source location from which the message was sent. */ message ( [[maybe_unused]] std::string_view format, [[maybe_unused]] Args&&... args, [[maybe_unused]] std::source_location&& location = std::source_location::current() ) { if constexpr (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= static_cast>(Severity)) { default_logger().log(std::vformat(format, std::make_format_args(std::forward(args)...)), Severity, std::forward(location)); } } }; // Use class template argument deduction (CTAD) to capture source location as a default argument following variadic format arguments. template message(std::string_view, Args&&...) -> message; #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_TRACE) /** * Formats and logs a trace message. * * @tparam Args Types of arguments to be formatted. */ template using trace = message; #else // Disable trace message logging. template inline void trace([[maybe_unused]] Args&&...) noexcept {}; #endif #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_DEBUG) /** * Formats and logs a debug message. * * @tparam Args Types of arguments to be formatted. */ template using debug = message; #else // Disable debug message logging. template inline void debug([[maybe_unused]] Args&&...) noexcept {}; #endif #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_INFO) /** * Formats and logs an info message. * * @tparam Args Types of arguments to be formatted. */ template using info = message; #else // Disable info message logging. template inline void info([[maybe_unused]] Args&&...) noexcept {}; #endif #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_WARNING) /** * Formats and logs a warning message. * * @tparam Args Types of arguments to be formatted. */ template using warning = message; #else // Disable warning message logging. template inline void warning([[maybe_unused]] Args&&...) noexcept {}; #endif #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_ERROR) /** * Formats and logs an error message. * * @tparam Args Types of arguments to be formatted. */ template using error = message; #else // Disable error message logging. template inline void error([[maybe_unused]] Args&&...) noexcept {}; #endif #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_FATAL) /** * Formats and logs a fatal error message. * * @tparam Args Types of arguments to be formatted. */ template using fatal = message; #else // Disable fatal error message logging. template inline void fatal([[maybe_unused]] Args&&...) noexcept {}; #endif } // namespace log } // namespace debug #endif // ANTKEEPER_DEBUG_LOG_HPP