From c8dd9cc99da8464fce62dfd1e4304c9e74587a47 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 15 Jan 2020 08:09:48 -0800 Subject: [PATCH] Use type_identity to block unnecessary template argument deduction (thanks Tim Song) --- include/fmt/color.h | 6 ++---- include/fmt/compile.h | 7 ++++--- include/fmt/core.h | 28 +++++++++++++++++++++------- include/fmt/format-inl.h | 7 ++++--- include/fmt/format.h | 19 ++++++++++--------- include/fmt/printf.h | 32 ++++++++++++++++++-------------- test/format | 12 ++++++------ 7 files changed, 65 insertions(+), 46 deletions(-) diff --git a/include/fmt/color.h b/include/fmt/color.h index 362a95e1..f101c892 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -491,10 +491,8 @@ void vformat_to(basic_memory_buffer& buf, const text_style& ts, internal::make_background_color(ts.get_background()); buf.append(background.begin(), background.end()); } - vformat_to(buf, format_str, args); - if (has_style) { - internal::reset_color(buf); - } + internal::vformat_to(buf, format_str, args); + if (has_style) internal::reset_color(buf); } } // namespace internal diff --git a/include/fmt/compile.h b/include/fmt/compile.h index 5829f623..2e166b5c 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -9,6 +9,7 @@ #define FMT_COMPILE_H_ #include + #include "format.h" FMT_BEGIN_NAMESPACE @@ -549,7 +550,7 @@ std::basic_string format(const CompiledFormat& cf, const Args&... args) { using range = buffer_range; using context = buffer_context; internal::cf::vformat_to(range(buffer), cf, - {make_format_args(args...)}); + make_format_args(args...)); return to_string(buffer); } @@ -561,8 +562,8 @@ OutputIt format_to(OutputIt out, const CompiledFormat& cf, using char_type = typename CompiledFormat::char_type; using range = internal::output_range; using context = format_context_t; - return internal::cf::vformat_to( - range(out), cf, {make_format_args(args...)}); + return internal::cf::vformat_to(range(out), cf, + make_format_args(args...)); } template using enable_if_t = typename std::enable_if::type; template @@ -229,6 +229,8 @@ template using remove_const_t = typename std::remove_const::type; template using remove_cvref_t = typename std::remove_cv>::type; +template struct type_identity { using type = T; }; +template using type_identity_t = typename type_identity::type; struct monostate {}; @@ -1220,7 +1222,13 @@ using wformat_context = buffer_context; such as `~fmt::vformat`. \endrst */ -template class format_arg_store { +template +class format_arg_store +#if FMT_GCC_VERSION < 409 + // Workaround a GCC template argument substitution bug. + : public basic_format_args +#endif +{ private: static const size_t num_args = sizeof...(Args); static const bool is_packed = num_args < internal::max_packed_args; @@ -1239,7 +1247,12 @@ template class format_arg_store { : internal::is_unpacked_bit | num_args; format_arg_store(const Args&... args) - : data_{internal::make_arg(args)...} {} + : +#if FMT_GCC_VERSION < 409 + basic_format_args(*this), +#endif + data_{internal::make_arg(args)...} { + } }; /** @@ -1426,9 +1439,10 @@ template > inline format_arg_store, remove_reference_t...> make_args_checked(const S& format_str, const remove_reference_t&... args) { - static_assert(all_true<(!std::is_base_of>::value || - !std::is_reference::value)...>::value, - "passing views as lvalues is disallowed"); + static_assert( + all_true<(!std::is_base_of>::value || + !std::is_reference::value)...>::value, + "passing views as lvalues is disallowed"); check_format_string>...>(format_str); return {args...}; } @@ -1440,7 +1454,7 @@ std::basic_string vformat(basic_string_view format_str, template typename buffer_context::iterator vformat_to( buffer& buf, basic_string_view format_str, - basic_format_args> args); + basic_format_args>> args); FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); } // namespace internal diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 117212e9..5f07a465 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -8,8 +8,6 @@ #ifndef FMT_FORMAT_INL_H_ #define FMT_FORMAT_INL_H_ -#include "format.h" - #include #include #include @@ -17,6 +15,8 @@ #include #include // for std::memmove #include + +#include "format.h" #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) # include #endif @@ -1380,7 +1380,8 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { FMT_FUNC void internal::vprint_mojibake(std::FILE* f, string_view format_str, format_args args) { memory_buffer buffer; - vformat_to(buffer, format_str, basic_format_args>(args)); + internal::vformat_to(buffer, format_str, + basic_format_args>(args)); fwrite_fully(buffer.data(), 1, buffer.size(), f); } #endif diff --git a/include/fmt/format.h b/include/fmt/format.h index 38626caf..7552a1b5 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -33,8 +33,6 @@ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ -#include "core.h" - #include #include #include @@ -43,6 +41,8 @@ #include #include +#include "core.h" + #ifdef __clang__ # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else @@ -3228,7 +3228,7 @@ std::basic_string to_string(const basic_memory_buffer& buf) { template typename buffer_context::iterator internal::vformat_to( internal::buffer& buf, basic_string_view format_str, - basic_format_args> args) { + basic_format_args>> args) { using range = buffer_range; return vformat_to>(buf, to_string_view(format_str), args); @@ -3238,7 +3238,7 @@ template , FMT_ENABLE_IF(internal::is_string::value)> inline typename buffer_context::iterator vformat_to( internal::buffer& buf, const S& format_str, - basic_format_args> args) { + basic_format_args>> args) { return internal::vformat_to(buf, to_string_view(format_str), args); } @@ -3262,8 +3262,9 @@ template ::value && !internal::is_contiguous_back_insert_iterator::value)> -inline OutputIt vformat_to(OutputIt out, const S& format_str, - format_args_t> args) { +inline OutputIt vformat_to( + OutputIt out, const S& format_str, + format_args_t, char_t> args) { using range = internal::output_range>; return vformat_to>(range(out), to_string_view(format_str), args); @@ -3289,7 +3290,7 @@ inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) { internal::check_format_string(format_str); using context = format_context_t>; return vformat_to(out, to_string_view(format_str), - {make_format_args(args...)}); + make_format_args(args...)); } template struct format_to_n_result { @@ -3317,7 +3318,7 @@ template ::value)> inline format_to_n_result vformat_to_n( OutputIt out, std::size_t n, basic_string_view format_str, - format_to_n_args args) { + format_to_n_args, type_identity_t> args) { auto it = vformat_to(internal::truncating_iterator(out, n), format_str, args); return {it.base(), it.count()}; @@ -3339,7 +3340,7 @@ inline format_to_n_result format_to_n(OutputIt out, std::size_t n, internal::check_format_string(format_str); using context = format_to_n_context>; return vformat_to_n(out, n, to_string_view(format_str), - {make_format_args(args...)}); + make_format_args(args...)); } template diff --git a/include/fmt/printf.h b/include/fmt/printf.h index 047aa323..8a2a8c20 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -597,7 +597,8 @@ inline format_arg_store make_wprintf_args( template > inline std::basic_string vsprintf( - const S& format, basic_format_args> args) { + const S& format, + basic_format_args>> args) { basic_memory_buffer buffer; printf(buffer, to_string_view(format), args); return to_string(buffer); @@ -616,12 +617,13 @@ template ::value, char_t>> inline std::basic_string sprintf(const S& format, const Args&... args) { using context = basic_printf_context_t; - return vsprintf(to_string_view(format), {make_format_args(args...)}); + return vsprintf(to_string_view(format), make_format_args(args...)); } template > -inline int vfprintf(std::FILE* f, const S& format, - basic_format_args> args) { +inline int vfprintf( + std::FILE* f, const S& format, + basic_format_args>> args) { basic_memory_buffer buffer; printf(buffer, to_string_view(format), args); std::size_t size = buffer.size(); @@ -644,12 +646,13 @@ template ; return vfprintf(f, to_string_view(format), - {make_format_args(args...)}); + make_format_args(args...)); } template > -inline int vprintf(const S& format, - basic_format_args> args) { +inline int vprintf( + const S& format, + basic_format_args>> args) { return vfprintf(stdout, to_string_view(format), args); } @@ -667,12 +670,13 @@ template >; return vprintf(to_string_view(format_str), - {make_format_args(args...)}); + make_format_args(args...)); } template > -inline int vfprintf(std::basic_ostream& os, const S& format, - basic_format_args> args) { +inline int vfprintf( + std::basic_ostream& os, const S& format, + basic_format_args>> args) { basic_memory_buffer buffer; printf(buffer, to_string_view(format), args); internal::write(os, buffer); @@ -683,9 +687,9 @@ inline int vfprintf(std::basic_ostream& os, const S& format, template > -typename ArgFormatter::iterator vprintf(internal::buffer& out, - basic_string_view format_str, - basic_format_args args) { +typename ArgFormatter::iterator vprintf( + internal::buffer& out, basic_string_view format_str, + basic_format_args> args) { typename ArgFormatter::iterator iter(out); Context(iter, format_str, args).template format(); return iter; @@ -705,7 +709,7 @@ inline int fprintf(std::basic_ostream& os, const S& format_str, const Args&... args) { using context = basic_printf_context_t; return vfprintf(os, to_string_view(format_str), - {make_format_args(args...)}); + make_format_args(args...)); } FMT_END_NAMESPACE diff --git a/test/format b/test/format index ea26a005..62fa3167 100644 --- a/test/format +++ b/test/format @@ -83,9 +83,9 @@ namespace std { Out format_to(Out out, wstring_view fmt, const Args&... args); template - Out vformat_to(Out out, string_view fmt, format_args_t args); + Out vformat_to(Out out, string_view fmt, format_args_t, char> args); template - Out vformat_to(Out out, wstring_view fmt, format_args_t args); + Out vformat_to(Out out, wstring_view fmt, format_args_t, wchar_t> args); template struct format_to_n_result { @@ -730,17 +730,17 @@ wstring vformat(wstring_view fmt, wformat_args args); template Out format_to(Out out, string_view fmt, const Args&... args) { using context = basic_format_context; - return vformat_to(out, fmt, {make_format_args(args...)}); + return vformat_to(out, fmt, make_format_args(args...)); } template Out format_to(Out out, wstring_view fmt, const Args&... args) { using context = basic_format_context; - return vformat_to(out, fmt, {make_format_args(args...)}); + return vformat_to(out, fmt, make_format_args(args...)); } template - Out vformat_to(Out out, string_view fmt, format_args_t args) { + Out vformat_to(Out out, string_view fmt, format_args_t, char> args) { using range = fmt::internal::output_range; detail::format_handler, char, basic_format_context> h(range(out), fmt, args, {}); @@ -749,7 +749,7 @@ template } template - Out vformat_to(Out out, wstring_view fmt, format_args_t args); + Out vformat_to(Out out, wstring_view fmt, format_args_t, wchar_t> args); template format_to_n_result format_to_n(Out out, iter_difference_t n,