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