| 32 | |
| 33 | template<size_t Args> |
| 34 | constexpr auto makeBraces() |
| 35 | { |
| 36 | // #A Define a string with empty braces and a space |
| 37 | constexpr std::array<char, 4> c{"{} "}; |
| 38 | // #B Calculate the size of c without the string-terminator |
| 39 | constexpr auto brace_size = c.size() - 1; |
| 40 | // #C Reserve 2 characters for newline and string-terminator |
| 41 | constexpr auto offset{2u}; |
| 42 | // #D Create a std::array with the required size for all |
| 43 | // braces and newline |
| 44 | std::array<char, Args * brace_size + offset> braces{}; |
| 45 | |
| 46 | // #E Braces string length is array size minus newline and |
| 47 | // string-terminator |
| 48 | constexpr auto bracesLength = (braces.size() - offset); |
| 49 | |
| 50 | auto i{0u}; |
| 51 | std::for_each_n( |
| 52 | braces.begin(), bracesLength, [&](auto& element) { |
| 53 | element = c[i % brace_size]; |
| 54 | ++i; |
| 55 | }); |
| 56 | |
| 57 | braces[bracesLength] = '\n'; // #F Add the newline |
| 58 | |
| 59 | return braces; |
| 60 | } |
| 61 | |
| 62 | void vlog(LogLevel level, |
| 63 | std::string_view fmt, |