diff --git a/include/fmt/core.h b/include/fmt/core.h index 744d2ab8..62ab7867 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -979,16 +979,22 @@ struct arg_data { template inline void init_named_args(named_arg_info*, int, int) {} -template +template struct is_named_arg : std::false_type {}; + +template +struct is_named_arg> : std::true_type {}; + +template ::value)> void init_named_args(named_arg_info* named_args, int arg_count, int named_arg_count, const T&, const Tail&... args) { init_named_args(named_args, arg_count + 1, named_arg_count, args...); } -template +template ::value)> void init_named_args(named_arg_info* named_args, int arg_count, - int named_arg_count, const named_arg& arg, - const Tail&... args) { + int named_arg_count, const T& arg, const Tail&... args) { named_args[named_arg_count++] = {arg.name, arg_count}; init_named_args(named_args, arg_count + 1, named_arg_count, args...); } @@ -997,11 +1003,6 @@ template FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int, const Args&...) {} -template struct is_named_arg : std::false_type {}; - -template -struct is_named_arg> : std::true_type {}; - template constexpr size_t count() { return B ? 1 : 0; } template constexpr size_t count() { return (B1 ? 1 : 0) + count(); @@ -1277,10 +1278,10 @@ template struct arg_mapper { return val; } - template - FMT_CONSTEXPR FMT_INLINE auto map(const named_arg& val) - -> decltype(std::declval().map(val.value)) { - return map(val.value); + template ::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& named_arg) + -> decltype(std::declval().map(named_arg.value)) { + return map(named_arg.value); } unformattable map(...) { return {}; } diff --git a/include/fmt/format.h b/include/fmt/format.h index be079b66..8b1e8cb6 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3941,6 +3941,24 @@ template struct udl_formatter { } }; +# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template Str> +struct statically_named_arg : view { + static constexpr auto name = Str.data; + + const T& value; + statically_named_arg(const T& v) : value(v) {} +}; + +template Str> +struct is_named_arg> : std::true_type {}; + +template Str> struct udl_arg { + template auto operator=(T&& value) const { + return statically_named_arg(std::forward(value)); + } +}; +# else template struct udl_arg { const Char* str; @@ -3948,6 +3966,7 @@ template struct udl_arg { return {str, std::forward(value)}; } }; +# endif } // namespace detail FMT_MODULE_EXPORT_BEGIN @@ -3981,12 +4000,21 @@ constexpr detail::udl_formatter operator"" _format(const wchar_t* s, fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); \endrst */ +# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template +constexpr detail::udl_arg, + sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> +operator""_a() { + return {}; +} +# else constexpr detail::udl_arg operator"" _a(const char* s, size_t) { return {s}; } constexpr detail::udl_arg operator"" _a(const wchar_t* s, size_t) { return {s}; } +# endif } // namespace literals FMT_MODULE_EXPORT_END