|
3 | 3 |
|
4 | 4 | #include <RcppSpdlog> |
5 | 5 |
|
6 | | -// we accommodate C++20 where fmt::format is available as std::format |
7 | | -// this defines a helper function used below |
8 | | -#if defined(SPDLOG_USE_STD_FORMAT) && __cplusplus >= 202002L |
| 6 | +constexpr int max_args = 15; // Arbitrary but 'smallish' |
9 | 7 |
|
10 | | - template<std::size_t... S> |
11 | | - std::format_args unpack_vector(const std::vector<std::string>& vec, std::index_sequence<S...>) { |
12 | | - return std::make_format_args(vec[S]...); |
| 8 | +template<class... Args> |
| 9 | +std::string forward_to_format(const std::string s, |
| 10 | + const std::vector<std::string>& v, |
| 11 | + const Args... args) { |
| 12 | + if (v.size() == sizeof...(args)) { |
| 13 | +#if defined(SPDLOG_USE_STD_FORMAT) && __cplusplus >= 202002L |
| 14 | + // As of 2026-02 we do _not_ set SPDLOG_USE_STD_FORMAT so this section is unused |
| 15 | + return std::vformat(std::string_view(s), args...); |
| 16 | +#elif __cplusplus >= 202002L |
| 17 | + // This section is now the default under C++20 or later |
| 18 | + return fmt::format(fmt::runtime(s), args...); |
| 19 | +#else |
| 20 | + // Fallback |
| 21 | + return fmt::format(s, args...); |
| 22 | +#endif |
13 | 23 | } |
14 | | - |
15 | | - template<std::size_t size> |
16 | | - std::format_args unpack_vector(const std::vector<std::string>& vec) { |
17 | | - return unpack_vector(vec, std::make_index_sequence<size>()); |
| 24 | + if constexpr(sizeof...(args) < max_args) { |
| 25 | + return forward_to_format(s, v, args..., v[sizeof...(args)]); |
18 | 26 | } |
19 | | - |
20 | | -#endif |
| 27 | + return std::string(""); // not reached |
| 28 | +} |
21 | 29 |
|
22 | 30 | //' Simple Pass-Through Formatter to \code{fmt::format()} |
23 | 31 | //' |
|
37 | 45 | //' @seealso https://github.com/fmtlib/fmt |
38 | 46 | // [[Rcpp::export]] |
39 | 47 | std::string formatter(const std::string s, std::vector<std::string> v) { |
40 | | - size_t n = v.size(); |
41 | | - switch (n) { |
42 | | -#if defined(SPDLOG_USE_STD_FORMAT) && __cplusplus >= 202002L |
43 | | - // As of 2026-02 we do _not_ set SPDLOG_USE_STD_FORMAT so this section is unused |
44 | | - case 0: return std::vformat(std::string_view(s), std::make_format_args()); |
45 | | - case 1: return std::vformat(std::string_view(s), unpack_vector<1>(v)); |
46 | | - case 2: return std::vformat(std::string_view(s), unpack_vector<2>(v)); |
47 | | - case 3: return std::vformat(std::string_view(s), unpack_vector<3>(v)); |
48 | | - case 4: return std::vformat(std::string_view(s), unpack_vector<4>(v)); |
49 | | - case 5: return std::vformat(std::string_view(s), unpack_vector<5>(v)); |
50 | | - case 6: return std::vformat(std::string_view(s), unpack_vector<6>(v)); |
51 | | - case 7: return std::vformat(std::string_view(s), unpack_vector<7>(v)); |
52 | | - case 8: return std::vformat(std::string_view(s), unpack_vector<8>(v)); |
53 | | - case 9: return std::vformat(std::string_view(s), unpack_vector<9>(v)); |
54 | | - case 10: return std::vformat(std::string_view(s), unpack_vector<10>(v)); |
55 | | - case 11: return std::vformat(std::string_view(s), unpack_vector<11>(v)); |
56 | | - case 12: return std::vformat(std::string_view(s), unpack_vector<12>(v)); |
57 | | - case 13: return std::vformat(std::string_view(s), unpack_vector<13>(v)); |
58 | | - case 14: return std::vformat(std::string_view(s), unpack_vector<14>(v)); |
59 | | - case 15: return std::vformat(std::string_view(s), unpack_vector<15>(v)); |
60 | | - default: { |
61 | | - Rcpp::warning("Only up to fifteen arguments support for now."); |
62 | | - return std::vformat(std::string_view(s), unpack_vector<12>(v)); |
63 | | - } |
64 | | -#elif __cplusplus >= 202002L |
65 | | - // This section is now the default under C++20 or later |
66 | | - case 0: return fmt::format(fmt::runtime(s)); |
67 | | - case 1: return fmt::format(fmt::runtime(s), std::string(v[0])); |
68 | | - case 2: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1])); |
69 | | - case 3: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2])); |
70 | | - case 4: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3])); |
71 | | - case 5: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4])); |
72 | | - case 6: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5])); |
73 | | - case 7: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6])); |
74 | | - case 8: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7])); |
75 | | - case 9: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8])); |
76 | | - case 10: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9])); |
77 | | - case 11: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10])); |
78 | | - case 12: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11])); |
79 | | - case 13: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11]), std::string(v[12])); |
80 | | - case 14: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11]), std::string(v[12]), std::string(v[13])); |
81 | | - case 15: return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11]), std::string(v[12]), std::string(v[13]), std::string(v[14])); |
82 | | - default: { |
83 | | - Rcpp::warning("Only up to fifteen arguments support for now."); |
84 | | - return fmt::format(fmt::runtime(s), std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11])); |
85 | | - } |
86 | | -#else |
87 | | - case 0: return fmt::format(s); |
88 | | - case 1: return fmt::format(s, std::string(v[0])); |
89 | | - case 2: return fmt::format(s, std::string(v[0]), std::string(v[1])); |
90 | | - case 3: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2])); |
91 | | - case 4: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3])); |
92 | | - case 5: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4])); |
93 | | - case 6: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5])); |
94 | | - case 7: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6])); |
95 | | - case 8: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7])); |
96 | | - case 9: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8])); |
97 | | - case 10: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9])); |
98 | | - case 11: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10])); |
99 | | - case 12: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11])); |
100 | | - case 13: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11]), std::string(v[12])); |
101 | | - case 14: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11]), std::string(v[12]), std::string(v[13])); |
102 | | - case 15: return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11]), std::string(v[12]), std::string(v[13]), std::string(v[14])); |
103 | | - default: { |
104 | | - Rcpp::warning("Only up to fifteen arguments support for now."); |
105 | | - return fmt::format(s, std::string(v[0]), std::string(v[1]), std::string(v[2]), std::string(v[3]), std::string(v[4]), std::string(v[5]), std::string(v[6]), std::string(v[7]), std::string(v[8]), std::string(v[9]), std::string(v[10]), std::string(v[11])); |
106 | | - } |
107 | | -#endif |
108 | | - } |
| 48 | + if (v.size() > max_args) |
| 49 | + Rcpp::warning("Only up to " + std::to_string(max_args) + " arguments support for now."); |
| 50 | + return forward_to_format(s, v); |
109 | 51 | } |
0 commit comments