@@ -109,7 +109,7 @@ struct format_result<Str, Args, Spans> {
109109
110110template <typename Spans = type_list<>, typename Str, typename Args = tuple<>>
111111constexpr auto make_format_result (Str s, Args args = {}) {
112- return format_result<Str, Args, Spans>{s, args};
112+ return format_result<Str, Args, Spans>{s, std::move ( args) };
113113}
114114
115115inline namespace literals {
@@ -228,13 +228,13 @@ CONSTEVAL auto arg_type(fmt_cx_value auto a) {
228228
229229template <typename Str, typename Args, typename Spans, typename S>
230230constexpr auto operator +(format_result<Str, Args, Spans> r, S s) {
231- return make_format_result<Spans>(r.str + s, r.args );
231+ return make_format_result<Spans>(r.str + s, std::move ( r.args ) );
232232}
233233
234234template <typename S, typename Str, typename Args, typename Spans>
235235constexpr auto operator +(S s, format_result<Str, Args, Spans> r) {
236- return make_format_result<detail::apply_offset<s.size (), Spans>>(s + r. str ,
237- r.args );
236+ return make_format_result<detail::apply_offset<s.size (), Spans>>(
237+ s + r. str , std::move ( r.args ) );
238238}
239239
240240template <typename Str1, typename Args1, typename Spans1, typename Str2,
@@ -243,7 +243,7 @@ constexpr auto operator+(format_result<Str1, Args1, Spans1> r1,
243243 format_result<Str2, Args2, Spans2> r2) {
244244 return make_format_result<boost::mp11::mp_append<
245245 Spans1, detail::apply_offset<r1.str .size (), Spans2>>>(
246- r1.str + r2.str , tuple_cat (r1.args , r2.args ));
246+ r1.str + r2.str , tuple_cat (std::move ( r1.args ), std::move ( r2.args ) ));
247247}
248248
249249template <typename T, T...> struct null_output ;
@@ -271,7 +271,7 @@ CONSTEVAL auto convert_output() {
271271}
272272
273273template <std::size_t N>
274- CONSTEVAL auto perform_format (auto s, auto v) -> ct_string<N + 1> {
274+ CONSTEVAL auto perform_format (auto s, auto const & v) -> ct_string<N + 1> {
275275 ct_string<N + 1 > cts{};
276276 fmt::format_to (cts.begin (), s, v);
277277 return cts;
@@ -302,10 +302,10 @@ constexpr auto format1(Arg arg) {
302302 auto const sub_result = format1<Fmt, Start>(arg.str );
303303 using Spans = typename Arg::spans_t ;
304304 return make_format_result<detail::apply_offset<Start, Spans>>(
305- sub_result.str , arg.args );
305+ sub_result.str , std::move ( arg) .args );
306306 } else {
307307 using Spans = type_list<format_span<Start, Fmt.size ()>>;
308- return make_format_result<Spans>(cts_t <Fmt>{}, tuple{arg});
308+ return make_format_result<Spans>(cts_t <Fmt>{}, tuple{std::move ( arg) });
309309 }
310310}
311311
@@ -324,10 +324,20 @@ template <ct_string Fmt> struct fmt_data {
324324 to_ct_string<splits[N].view.size()>(splits[N].view);
325325};
326326
327- template <typename T>
328- constexpr auto ct_format_as (T const &t) -> decltype(auto ) {
329- return (t);
330- }
327+ [[maybe_unused]] constexpr inline struct format_as_t {
328+ template <typename T>
329+ requires true
330+ constexpr auto operator ()(T &&t) const
331+ noexcept (noexcept (ct_format_as(std::forward<T>(t))))
332+ -> decltype(ct_format_as(std::forward<T>(t))) {
333+ return ct_format_as (std::forward<T>(t));
334+ }
335+
336+ template <typename T>
337+ constexpr auto operator ()(T &&t) const -> decltype(auto ) {
338+ return T (std::forward<T>(t));
339+ }
340+ } format_as;
331341} // namespace detail
332342
333343template <ct_string Fmt,
@@ -343,20 +353,20 @@ constexpr auto ct_format = [](auto &&...args) {
343353 " Format string has a mismatch between the number of format "
344354 " specifiers and arguments." );
345355
346- [[maybe_unused]] auto const format1 = [& ]<std::size_t I>(auto &&arg) {
356+ [[maybe_unused]] auto const format1 = []<std::size_t I>(auto &&arg) {
347357 constexpr auto cts = detail::to_ct_string<data::splits[I].view .size ()>(
348358 data::splits[I].view );
349359 return detail::format1<cts, data::splits[I].start >(FWD (arg));
350360 };
351361
352- auto const result = [&]<std::size_t ... Is>(std::index_sequence<Is...>) {
353- using detail::ct_format_as;
354- return (format1.template operator ()<Is>(ct_format_as (FWD (args ))) + ... +
355- make_format_result (cts_t <data::last_cts>{}));
356- }(std::make_index_sequence<data::N>{});
362+ auto result = [&]<std::size_t ... Is>(std::index_sequence<Is...>,
363+ auto &&... as ) {
364+ return (format1.template operator ()<Is>(detail::format_as (FWD (as ))) +
365+ ... + make_format_result (cts_t <data::last_cts>{}));
366+ }(std::make_index_sequence<data::N>{}, FWD (args)... );
357367 constexpr auto str = detail::convert_output<result.str .value , Output>();
358368 using Spans = typename std::remove_cvref_t <decltype (result)>::spans_t ;
359- return make_format_result<Spans>(str, result.args );
369+ return make_format_result<Spans>(str, std::move ( result) .args );
360370};
361371
362372template <ct_string Fmt>
0 commit comments