💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.3 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_DEBUG_LOG_HPP
  20. #define ANTKEEPER_DEBUG_LOG_HPP
  21. #include "config.hpp"
  22. #include "debug/log/message-severity.hpp"
  23. #include "debug/log/logger.hpp"
  24. #include <source_location>
  25. #include <string>
  26. #include <format>
  27. // Enable logging of messages of all severities by default.
  28. #if !defined(ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY)
  29. #define ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY (ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_TRACE)
  30. #endif
  31. namespace debug {
  32. /**
  33. * Debug message logging.
  34. */
  35. namespace log {
  36. /**
  37. * Returns the default logger.
  38. */
  39. [[nodiscard]] logger& default_logger() noexcept;
  40. /**
  41. * Self-formatting message that logs itself to the default logger on construction.
  42. *
  43. * @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`.
  44. * @tparam Args Types of arguments to be formatted.
  45. */
  46. template <message_severity Severity, class... Args>
  47. struct message
  48. {
  49. /**
  50. * Formats and logs a message.
  51. *
  52. * Class template argument deduction (CTAD) is utilized to capture source location as a default argument following variadic format arguments.
  53. *
  54. * @param format Message format string.
  55. * @param args Arguments to be formatted.
  56. * @param location Source location from which the message was sent.
  57. */
  58. message
  59. (
  60. [[maybe_unused]] std::string_view format,
  61. [[maybe_unused]] Args&&... args,
  62. [[maybe_unused]] std::source_location&& location = std::source_location::current()
  63. )
  64. {
  65. if constexpr (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= static_cast<std::underlying_type_t<message_severity>>(Severity))
  66. {
  67. default_logger().log(std::vformat(format, std::make_format_args(std::forward<Args>(args)...)), Severity, std::forward<std::source_location>(location));
  68. }
  69. }
  70. };
  71. // Use class template argument deduction (CTAD) to capture source location as a default argument following variadic format arguments.
  72. template <message_severity Severity, class... Args>
  73. message(std::string_view, Args&&...) -> message<Severity, Args...>;
  74. #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_TRACE)
  75. /**
  76. * Formats and logs a trace message.
  77. *
  78. * @tparam Args Types of arguments to be formatted.
  79. */
  80. template <class... Args>
  81. using trace = message<message_severity::trace, Args...>;
  82. #else
  83. // Disable trace message logging.
  84. template <class... Args>
  85. inline void trace([[maybe_unused]] Args&&...) noexcept {};
  86. #endif
  87. #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_DEBUG)
  88. /**
  89. * Formats and logs a debug message.
  90. *
  91. * @tparam Args Types of arguments to be formatted.
  92. */
  93. template <class... Args>
  94. using debug = message<message_severity::debug, Args...>;
  95. #else
  96. // Disable debug message logging.
  97. template <class... Args>
  98. inline void debug([[maybe_unused]] Args&&...) noexcept {};
  99. #endif
  100. #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_INFO)
  101. /**
  102. * Formats and logs an info message.
  103. *
  104. * @tparam Args Types of arguments to be formatted.
  105. */
  106. template <class... Args>
  107. using info = message<message_severity::info, Args...>;
  108. #else
  109. // Disable info message logging.
  110. template <class... Args>
  111. inline void info([[maybe_unused]] Args&&...) noexcept {};
  112. #endif
  113. #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_WARNING)
  114. /**
  115. * Formats and logs a warning message.
  116. *
  117. * @tparam Args Types of arguments to be formatted.
  118. */
  119. template <class... Args>
  120. using warning = message<message_severity::warning, Args...>;
  121. #else
  122. // Disable warning message logging.
  123. template <class... Args>
  124. inline void warning([[maybe_unused]] Args&&...) noexcept {};
  125. #endif
  126. #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_ERROR)
  127. /**
  128. * Formats and logs an error message.
  129. *
  130. * @tparam Args Types of arguments to be formatted.
  131. */
  132. template <class... Args>
  133. using error = message<message_severity::error, Args...>;
  134. #else
  135. // Disable error message logging.
  136. template <class... Args>
  137. inline void error([[maybe_unused]] Args&&...) noexcept {};
  138. #endif
  139. #if (ANTKEEPER_DEBUG_LOG_MIN_MESSAGE_SEVERITY <= ANTKEEPER_DEBUG_LOG_MESSAGE_SEVERITY_FATAL)
  140. /**
  141. * Formats and logs a fatal error message.
  142. *
  143. * @tparam Args Types of arguments to be formatted.
  144. */
  145. template <class... Args>
  146. using fatal = message<message_severity::fatal, Args...>;
  147. #else
  148. // Disable fatal error message logging.
  149. template <class... Args>
  150. inline void fatal([[maybe_unused]] Args&&...) noexcept {};
  151. #endif
  152. } // namespace log
  153. } // namespace debug
  154. #endif // ANTKEEPER_DEBUG_LOG_HPP