1 #pragma once 2 3 #if __cplusplus < 202002L 4 #error "phosphor-logging lg2 requires C++20" 5 #else 6 7 #include <phosphor-logging/lg2/concepts.hpp> 8 #include <phosphor-logging/lg2/conversion.hpp> 9 #include <phosphor-logging/lg2/flags.hpp> 10 #include <phosphor-logging/lg2/header.hpp> 11 #include <phosphor-logging/lg2/level.hpp> 12 13 #include <source_location> 14 15 namespace lg2 16 { 17 /** Implementation of the structured logging `lg2::log` interface. */ 18 template <level S = level::debug, details::any_but<std::source_location>... Ts> 19 struct log 20 { 21 /** log with a custom source_location. 22 * 23 * @param[in] s - The custom source location. 24 * @param[in] msg - The message to log. 25 * @param[in] ts - The rest of the arguments. 26 */ loglg2::log27 explicit log(const std::source_location& s, const char* msg, 28 details::header_str_conversion_t<Ts&&>... ts) 29 { 30 details::log_conversion::start( 31 S, s, msg, 32 std::forward<details::header_str_conversion_t<Ts&&>>(ts)...); 33 } 34 35 /** default log (source_location is determined by calling location). 36 * 37 * @param[in] msg - The message to log. 38 * @param[in] ts - The rest of the arguments. 39 * @param[in] s - The derived source_location. 40 */ loglg2::log41 explicit log( 42 const char* msg, details::header_str_conversion_t<Ts&&>... ts, 43 const std::source_location& s = std::source_location::current()) : 44 log(s, msg, std::forward<details::header_str_conversion_t<Ts&&>>(ts)...) 45 {} 46 47 // Give a nicer compile error if someone tries to log without a message. 48 log() = delete; 49 }; 50 51 /** Macro to define aliases for lg2::level(...) -> lg2::log<level>(...) 52 * 53 * Creates a simple inherited structure and corresponding deduction guides. 54 */ 55 #define PHOSPHOR_LOG2_DECLARE_LEVEL(levelval) \ 56 template <typename... Ts> \ 57 struct levelval : public log<level::levelval, Ts...> \ 58 { \ 59 using log<level::levelval, Ts...>::log; \ 60 }; \ 61 \ 62 template <typename... Ts> \ 63 explicit levelval(const char*, Ts&&...) -> levelval<Ts...>; \ 64 \ 65 template <typename... Ts> \ 66 explicit levelval(const std::source_location&, const char*, Ts&&...) \ 67 ->levelval<Ts...> 68 69 // Enumerate the aliases for each log level. 70 PHOSPHOR_LOG2_DECLARE_LEVEL(emergency); 71 PHOSPHOR_LOG2_DECLARE_LEVEL(alert); 72 PHOSPHOR_LOG2_DECLARE_LEVEL(critical); 73 PHOSPHOR_LOG2_DECLARE_LEVEL(error); 74 PHOSPHOR_LOG2_DECLARE_LEVEL(warning); 75 PHOSPHOR_LOG2_DECLARE_LEVEL(notice); 76 PHOSPHOR_LOG2_DECLARE_LEVEL(info); 77 PHOSPHOR_LOG2_DECLARE_LEVEL(debug); 78 79 #undef PHOSPHOR_LOG2_DECLARE_LEVEL 80 81 /** Handy scope-level `using` to get the necessary bits of lg2. */ 82 #define PHOSPHOR_LOG2_USING \ 83 using lg2::emergency; \ 84 using lg2::alert; \ 85 using lg2::critical; \ 86 using lg2::error; \ 87 using lg2::warning; \ 88 using lg2::notice; \ 89 using lg2::info; \ 90 using lg2::debug 91 // We purposefully left out `using lg2::log` above to avoid collisions with 92 // the math function `log`. There is little use for direct calls to `lg2::log`, 93 // when the level-aliases are available, since it is just a more awkward syntax. 94 95 /** Scope-level `using` to get the everything, incluing format flags. */ 96 #define PHOSPHOR_LOG2_USING_WITH_FLAGS \ 97 PHOSPHOR_LOG2_USING; \ 98 PHOSPHOR_LOG2_USING_FLAGS 99 100 } // namespace lg2 101 102 #endif 103