From ae3cc844e790021e926474fbc5366777d4c14864 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 7 Mar 2018 05:41:45 -0800 Subject: [PATCH] Check format string at compile time in print --- include/fmt/format.h | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 2ec2f889..57f1867e 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1468,6 +1468,10 @@ class arg_formatter_base { struct format_string {}; +template +struct is_format_string: + std::integral_constant::value> {}; + template FMT_CONSTEXPR bool is_name_start(Char c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; @@ -2093,6 +2097,14 @@ FMT_CONSTEXPR bool check_format_string( return true; } +template +void check_format_string(String format_str) { + FMT_CONSTEXPR_DECL bool invalid_format = + internal::check_format_string( + string_view(format_str.data(), format_str.size())); + (void)invalid_format; +} + // Specifies whether to format T using the standard formatter. // It is not possible to use get_type in formatter specialization directly // because of a bug in MSVC. @@ -3399,13 +3411,17 @@ inline std::wstring vformat(wstring_view format_str, wformat_args args) { template inline typename std::enable_if< - std::is_base_of::value, std::string>::type + internal::is_format_string::value, std::string>::type format(String format_str, const Args & ... args) { - FMT_CONSTEXPR_DECL bool invalid_format = - internal::check_format_string( - string_view(format_str.value(), format_str.size())); - (void)invalid_format; - return vformat(format_str.value(), make_args(args...)); + internal::check_format_string(format_str); + return vformat(format_str.data(), make_args(args...)); +} + +template +inline typename std::enable_if::value>::type + print(String format_str, const Args & ... args) { + internal::check_format_string(format_str); + return vprint(format_str.data(), make_args(args...)); } // Counts the number of characters in the output of format(format_str, args...). @@ -3505,7 +3521,7 @@ operator"" _a(const wchar_t *s, std::size_t) { return {s}; } #define FMT_STRING(s) [] { \ struct S : fmt::internal::format_string { \ - static FMT_CONSTEXPR auto value() { return s; } \ + static FMT_CONSTEXPR auto data() { return s; } \ static FMT_CONSTEXPR size_t size() { return sizeof(s); } \ }; \ return S{}; \