add non-char support for compile-time format check

This commit is contained in:
XZiar 2018-10-26 15:55:03 -07:00 committed by Victor Zverovich
parent ccd3e8bbf3
commit b98e8301d5
3 changed files with 15 additions and 7 deletions

View File

@ -472,9 +472,11 @@ struct compile_string {};
template <typename S> template <typename S>
struct is_compile_string : std::is_base_of<compile_string, S> {}; struct is_compile_string : std::is_base_of<compile_string, S> {};
template <typename S> template <typename S, typename Enable = std::enable_if<is_compile_string<S>::value>>
inline typename std::enable_if<is_compile_string<S>::value, string_view>::type inline auto to_string_view(const S &s) -> basic_string_view<typename S::Char> {
to_string_view(const S &s) { return {s.data(), s.size() - 1}; } typedef typename S::Char Char;
return basic_string_view<Char>{s.data(), s.size() - 1};
}
template <typename Context> template <typename Context>
class basic_format_arg; class basic_format_arg;

View File

@ -2243,9 +2243,10 @@ FMT_CONSTEXPR bool check_format_string(
template <typename... Args, typename String> template <typename... Args, typename String>
typename std::enable_if<is_compile_string<String>::value>::type typename std::enable_if<is_compile_string<String>::value>::type
check_format_string(String format_str) { check_format_string(String format_str) {
typedef typename String::Char Char;
FMT_CONSTEXPR_DECL bool invalid_format = FMT_CONSTEXPR_DECL bool invalid_format =
internal::check_format_string<char, internal::error_handler, Args...>( internal::check_format_string<Char, internal::error_handler, Args...>(
string_view(format_str.data(), format_str.size())); basic_string_view<Char>(format_str.data(), format_str.size()));
(void)invalid_format; (void)invalid_format;
} }
@ -3597,9 +3598,10 @@ FMT_END_NAMESPACE
#define FMT_STRING(s) [] { \ #define FMT_STRING(s) [] { \
typedef typename std::decay<decltype(s)>::type pointer; \ typedef typename std::decay<decltype(s)>::type pointer; \
struct S : fmt::compile_string { \ struct S : fmt::compile_string { \
typedef typename std::remove_cv<std::remove_pointer<pointer>::type>::type Char;\
static FMT_CONSTEXPR pointer data() { return s; } \ static FMT_CONSTEXPR pointer data() { return s; } \
static FMT_CONSTEXPR size_t size() { return sizeof(s); } \ static FMT_CONSTEXPR size_t size() { return sizeof(s) / sizeof(Char); } \
explicit operator fmt::string_view() const { return s; } \ explicit operator fmt::basic_string_view<Char>() const { return s; } \
}; \ }; \
return S{}; \ return S{}; \
}() }()

View File

@ -1859,6 +1859,7 @@ TEST(FormatTest, UdlTemplate) {
EXPECT_EQ("foo", "foo"_format()); EXPECT_EQ("foo", "foo"_format());
EXPECT_EQ(" 42", "{0:10}"_format(42)); EXPECT_EQ(" 42", "{0:10}"_format(42));
EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42)); EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42));
EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42));
} }
#endif // FMT_USE_USER_DEFINED_LITERALS #endif // FMT_USE_USER_DEFINED_LITERALS
@ -2378,6 +2379,9 @@ TEST(FormatTest, VFormatTo) {
std::wstring w; std::wstring w;
fmt::vformat_to(std::back_inserter(w), L"{}", wargs); fmt::vformat_to(std::back_inserter(w), L"{}", wargs);
EXPECT_EQ(L"42", w); EXPECT_EQ(L"42", w);
w.clear();
fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), args);
EXPECT_EQ("42", w);
} }
#endif // FMT_USE_CONSTEXPR #endif // FMT_USE_CONSTEXPR