|
15 | 15 | #include <cstddef> |
16 | 16 | #include <string> |
17 | 17 | #include <string_view> |
| 18 | +#include <type_traits> |
18 | 19 |
|
19 | 20 | namespace boost::redis::detail { |
20 | 21 |
|
@@ -47,25 +48,31 @@ struct log_traits<system::error_code> { |
47 | 48 | } |
48 | 49 | }; |
49 | 50 |
|
| 51 | +template <class... Args> |
| 52 | +void format_log_args(std::string& to, const Args&... args) |
| 53 | +{ |
| 54 | + auto dummy = {(log_traits<Args>::log(to, args), 0)...}; |
| 55 | + ignore_unused(dummy); |
| 56 | +} |
| 57 | + |
50 | 58 | // Logs a message with the specified severity to the logger. |
51 | 59 | // Formatting won't be performed if the logger's level is inferior to lvl. |
52 | 60 | // args are stringized using log_traits, and concatenated. |
53 | | -template <class... Args> |
54 | | -void log(buffered_logger& to, logger::level lvl, const Args&... args) |
| 61 | +template <class Arg0, class... Rest> |
| 62 | +void log(buffered_logger& to, logger::level lvl, const Arg0& arg0, const Rest&... arg_rest) |
55 | 63 | { |
56 | 64 | // Severity check |
57 | 65 | if (to.lgr.lvl < lvl) |
58 | 66 | return; |
59 | 67 |
|
60 | | - // Clear the buffer |
61 | | - to.buffer.clear(); |
62 | | - |
63 | | - // Format all arguments |
64 | | - auto dummy = {(log_traits<Args>::log(to.buffer, args), 0)...}; |
65 | | - ignore_unused(dummy); |
66 | | - |
67 | | - // Invoke the function |
68 | | - to.lgr.fn(lvl, to.buffer); |
| 68 | + // Optimization: if we get passed a single string, don't copy it to the buffer |
| 69 | + if constexpr (sizeof...(Rest) == 0u && std::is_convertible_v<Arg0, std::string_view>) { |
| 70 | + to.lgr.fn(lvl, arg0); |
| 71 | + } else { |
| 72 | + to.buffer.clear(); |
| 73 | + format_log_args(to.buffer, arg0, arg_rest...); |
| 74 | + to.lgr.fn(lvl, to.buffer); |
| 75 | + } |
69 | 76 | } |
70 | 77 |
|
71 | 78 | // Shorthand for each log level we use |
|
0 commit comments