mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-22 10:30:05 +00:00
Move wchar/custom char overloads to xchar.h
This commit is contained in:
parent
e77b22d6da
commit
76ee490468
@ -2803,24 +2803,6 @@ constexpr auto operator"" _format(const char* s, size_t n)
|
||||
}
|
||||
} // namespace literals
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto vformat(basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
-> std::basic_string<Char> {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
// Pass char_t as a default template parameter instead of using
|
||||
// std::basic_string<char_t<S>> to reduce the symbol size.
|
||||
template <typename S, typename... Args, typename Char = char_t<S>,
|
||||
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto format(const S& format_str, Args&&... args) -> std::basic_string<Char> {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return vformat(to_string_view(format_str), vargs);
|
||||
}
|
||||
|
||||
template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
|
||||
inline auto vformat(const Locale& loc, string_view fmt, format_args args)
|
||||
-> std::string {
|
||||
|
@ -73,6 +73,24 @@ auto join(std::initializer_list<T> list, wstring_view sep)
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto vformat(basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
-> std::basic_string<Char> {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
// Pass char_t as a default template parameter instead of using
|
||||
// std::basic_string<char_t<S>> to reduce the symbol size.
|
||||
template <typename S, typename... Args, typename Char = char_t<S>,
|
||||
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto format(const S& format_str, Args&&... args) -> std::basic_string<Char> {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return vformat(to_string_view(format_str), vargs);
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename Char = char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
|
@ -48,8 +48,6 @@ TEST(chrono_test, format_tm) {
|
||||
tm.tm_sec = 33;
|
||||
EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm),
|
||||
"The date is 2016-04-25 11:22:33.");
|
||||
EXPECT_EQ(fmt::format(L"The date is {:%Y-%m-%d %H:%M:%S}.", tm),
|
||||
L"The date is 2016-04-25 11:22:33.");
|
||||
}
|
||||
|
||||
TEST(chrono_test, grow_buffer) {
|
||||
@ -151,10 +149,6 @@ TEST(chrono_test, format_default) {
|
||||
fmt::format("{}", std::chrono::duration<int, std::ratio<15, 4>>(42)));
|
||||
}
|
||||
|
||||
TEST(chrono_test, format_wide) {
|
||||
EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42)));
|
||||
}
|
||||
|
||||
TEST(chrono_test, align) {
|
||||
auto s = std::chrono::seconds(42);
|
||||
EXPECT_EQ("42s ", fmt::format("{:5}", s));
|
||||
|
@ -634,13 +634,6 @@ TEST(format_test, space_sign) {
|
||||
format_error, "format specifier requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(format_test, sign_not_truncated) {
|
||||
wchar_t format_str[] = {
|
||||
L'{', L':',
|
||||
'+' | static_cast<wchar_t>(1 << fmt::detail::num_bits<char>()), L'}', 0};
|
||||
EXPECT_THROW(fmt::format(format_str, 42), format_error);
|
||||
}
|
||||
|
||||
TEST(format_test, hash_flag) {
|
||||
EXPECT_EQ("42", fmt::format("{0:#}", 42));
|
||||
EXPECT_EQ("-42", fmt::format("{0:#}", -42));
|
||||
@ -1019,7 +1012,6 @@ TEST(format_test, format_bool) {
|
||||
EXPECT_EQ("false", fmt::format("{}", false));
|
||||
EXPECT_EQ("1", fmt::format("{:d}", true));
|
||||
EXPECT_EQ("true ", fmt::format("{:5}", true));
|
||||
EXPECT_EQ(L"true", fmt::format(L"{}", true));
|
||||
EXPECT_EQ("true", fmt::format("{:s}", true));
|
||||
EXPECT_EQ("false", fmt::format("{:s}", false));
|
||||
EXPECT_EQ("false ", fmt::format("{:6s}", false));
|
||||
@ -1330,7 +1322,6 @@ TEST(format_test, format_char) {
|
||||
check_unknown_types('a', types, "char");
|
||||
EXPECT_EQ("a", fmt::format("{0}", 'a'));
|
||||
EXPECT_EQ("z", fmt::format("{0:c}", 'z'));
|
||||
EXPECT_EQ(L"a", fmt::format(L"{0}", 'a'));
|
||||
int n = 'x';
|
||||
for (const char* type = types + 1; *type; ++type) {
|
||||
std::string format_str = fmt::format("{{:{}}}", *type);
|
||||
@ -1351,12 +1342,6 @@ TEST(format_test, format_unsigned_char) {
|
||||
EXPECT_EQ("42", fmt::format("{}", static_cast<uint8_t>(42)));
|
||||
}
|
||||
|
||||
TEST(format_test, format_wchar) {
|
||||
EXPECT_EQ(L"a", fmt::format(L"{0}", L'a'));
|
||||
// This shouldn't compile:
|
||||
// format("{}", L'a');
|
||||
}
|
||||
|
||||
TEST(format_test, format_cstring) {
|
||||
check_unknown_types("test", "sp", "string");
|
||||
EXPECT_EQ("test", fmt::format("{0}", "test"));
|
||||
@ -1451,28 +1436,6 @@ TEST(format_test, format_explicitly_convertible_to_std_string_view) {
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace fake_qt {
|
||||
class QString {
|
||||
public:
|
||||
QString(const wchar_t* s) : s_(s) {}
|
||||
const wchar_t* utf16() const FMT_NOEXCEPT { return s_.data(); }
|
||||
int size() const FMT_NOEXCEPT { return static_cast<int>(s_.size()); }
|
||||
|
||||
private:
|
||||
std::wstring s_;
|
||||
};
|
||||
|
||||
fmt::basic_string_view<wchar_t> to_string_view(const QString& s) FMT_NOEXCEPT {
|
||||
return {s.utf16(), static_cast<size_t>(s.size())};
|
||||
}
|
||||
} // namespace fake_qt
|
||||
|
||||
TEST(format_test, format_foreign_strings) {
|
||||
using fake_qt::QString;
|
||||
EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42");
|
||||
EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42");
|
||||
}
|
||||
|
||||
class Answer {};
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
@ -1513,14 +1476,6 @@ TEST(format_test, format_to_custom) {
|
||||
EXPECT_STREQ(buf, "42");
|
||||
}
|
||||
|
||||
TEST(format_test, wide_format_string) {
|
||||
EXPECT_EQ(L"42", fmt::format(L"{}", 42));
|
||||
EXPECT_EQ(L"4.2", fmt::format(L"{}", 4.2));
|
||||
EXPECT_EQ(L"abc", fmt::format(L"{}", L"abc"));
|
||||
EXPECT_EQ(L"z", fmt::format(L"{}", L'z'));
|
||||
EXPECT_THROW(fmt::format(L"{:*\x343E}", 42), fmt::format_error);
|
||||
}
|
||||
|
||||
TEST(format_test, format_string_from_speed_test) {
|
||||
EXPECT_EQ("1.2340000000:0042:+3.13:str:0x3e8:X:%",
|
||||
fmt::format("{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%", 1.234, 42,
|
||||
@ -1587,9 +1542,6 @@ TEST(format_test, format_examples) {
|
||||
EXPECT_THROW_MSG(fmt::format(runtime("The answer is {:d}"), "forty-two"),
|
||||
format_error, "invalid type specifier");
|
||||
|
||||
EXPECT_EQ(L"Cyrillic letter \x42e",
|
||||
fmt::format(L"Cyrillic letter {}", L'\x42e'));
|
||||
|
||||
EXPECT_WRITE(
|
||||
stdout, fmt::print("{}", std::numeric_limits<double>::infinity()), "inf");
|
||||
}
|
||||
@ -1602,7 +1554,6 @@ TEST(format_test, print) {
|
||||
|
||||
TEST(format_test, variadic) {
|
||||
EXPECT_EQ("abc1", fmt::format("{}c{}", "ab", 1));
|
||||
EXPECT_EQ(L"abc1", fmt::format(L"{}c{}", L"ab", 1));
|
||||
}
|
||||
|
||||
TEST(format_test, dynamic) {
|
||||
@ -1698,15 +1649,11 @@ fmt::string_view to_string_view(string_like) { return "foo"; }
|
||||
constexpr char with_null[3] = {'{', '}', '\0'};
|
||||
constexpr char no_null[2] = {'{', '}'};
|
||||
static FMT_CONSTEXPR_DECL const char static_with_null[3] = {'{', '}', '\0'};
|
||||
static FMT_CONSTEXPR_DECL const wchar_t static_with_null_wide[3] = {'{', '}',
|
||||
'\0'};
|
||||
static FMT_CONSTEXPR_DECL const char static_no_null[2] = {'{', '}'};
|
||||
static FMT_CONSTEXPR_DECL const wchar_t static_no_null_wide[2] = {'{', '}'};
|
||||
|
||||
TEST(format_test, compile_time_string) {
|
||||
EXPECT_EQ("foo", fmt::format(FMT_STRING("foo")));
|
||||
EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42));
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42));
|
||||
EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like()));
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
|
||||
@ -1718,14 +1665,10 @@ TEST(format_test, compile_time_string) {
|
||||
#endif
|
||||
|
||||
(void)static_with_null;
|
||||
(void)static_with_null_wide;
|
||||
(void)static_no_null;
|
||||
(void)static_no_null_wide;
|
||||
#ifndef _MSC_VER
|
||||
EXPECT_EQ("42", fmt::format(FMT_STRING(static_with_null), 42));
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_STRING(static_with_null_wide), 42));
|
||||
EXPECT_EQ("42", fmt::format(FMT_STRING(static_no_null), 42));
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_STRING(static_no_null_wide), 42));
|
||||
#endif
|
||||
|
||||
(void)with_null;
|
||||
@ -1736,7 +1679,6 @@ TEST(format_test, compile_time_string) {
|
||||
#endif
|
||||
#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L
|
||||
EXPECT_EQ("42", fmt::format(FMT_STRING(std::string_view("{}")), 42));
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2119,49 +2061,6 @@ TEST(format_test, char_traits_is_not_ambiguous) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __cplusplus > 201103L
|
||||
struct custom_char {
|
||||
int value;
|
||||
custom_char() = default;
|
||||
|
||||
template <typename T>
|
||||
constexpr custom_char(T val) : value(static_cast<int>(val)) {}
|
||||
|
||||
operator int() const { return value; }
|
||||
};
|
||||
|
||||
int to_ascii(custom_char c) { return c; }
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <> struct is_char<custom_char> : std::true_type {};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
TEST(format_test, format_custom_char) {
|
||||
const custom_char format[] = {'{', '}', 0};
|
||||
auto result = fmt::format(format, custom_char('x'));
|
||||
EXPECT_EQ(result.size(), 1);
|
||||
EXPECT_EQ(result[0], custom_char('x'));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Convert a char8_t string to std::string. Otherwise GTest will insist on
|
||||
// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423.
|
||||
template <typename S> std::string from_u8str(const S& str) {
|
||||
return std::string(str.begin(), str.end());
|
||||
}
|
||||
|
||||
TEST(format_test, format_utf8_precision) {
|
||||
using str_type = std::basic_string<fmt::detail::char8_type>;
|
||||
auto format =
|
||||
str_type(reinterpret_cast<const fmt::detail::char8_type*>(u8"{:.4}"));
|
||||
auto str = str_type(reinterpret_cast<const fmt::detail::char8_type*>(
|
||||
u8"caf\u00e9s")); // cafés
|
||||
auto result = fmt::format(format, str);
|
||||
EXPECT_EQ(fmt::detail::compute_width(result), 4);
|
||||
EXPECT_EQ(result.size(), 5);
|
||||
EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5)));
|
||||
}
|
||||
|
||||
struct check_back_appender {};
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
@ -80,18 +80,6 @@ TEST(os_test, format_std_error_code) {
|
||||
std::error_code(-42, fmt::system_category())));
|
||||
}
|
||||
|
||||
TEST(os_test, format_std_error_code_wide) {
|
||||
EXPECT_EQ(L"generic:42",
|
||||
fmt::format(FMT_STRING(L"{0}"),
|
||||
std::error_code(42, std::generic_category())));
|
||||
EXPECT_EQ(L"system:42",
|
||||
fmt::format(FMT_STRING(L"{0}"),
|
||||
std::error_code(42, fmt::system_category())));
|
||||
EXPECT_EQ(L"system:-42",
|
||||
fmt::format(FMT_STRING(L"{0}"),
|
||||
std::error_code(-42, fmt::system_category())));
|
||||
}
|
||||
|
||||
TEST(os_test, format_windows_error) {
|
||||
LPWSTR message = 0;
|
||||
auto result = FormatMessageW(
|
||||
|
@ -45,29 +45,22 @@ template <typename T> void operator,(type_with_comma_op, const T&);
|
||||
template <typename T> type_with_comma_op operator<<(T&, const date&);
|
||||
|
||||
enum streamable_enum {};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, streamable_enum) {
|
||||
return os << "streamable_enum";
|
||||
}
|
||||
|
||||
std::wostream& operator<<(std::wostream& os, streamable_enum) {
|
||||
return os << L"streamable_enum";
|
||||
}
|
||||
|
||||
enum unstreamable_enum {};
|
||||
|
||||
TEST(ostream_test, enum) {
|
||||
EXPECT_EQ("streamable_enum", fmt::format("{}", streamable_enum()));
|
||||
EXPECT_EQ("0", fmt::format("{}", unstreamable_enum()));
|
||||
EXPECT_EQ(L"streamable_enum", fmt::format(L"{}", streamable_enum()));
|
||||
EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum()));
|
||||
}
|
||||
|
||||
TEST(ostream_test, format) {
|
||||
EXPECT_EQ("a string", fmt::format("{0}", test_string("a string")));
|
||||
EXPECT_EQ("The date is 2012-12-9",
|
||||
fmt::format("The date is {0}", date(2012, 12, 9)));
|
||||
EXPECT_EQ(L"The date is 2012-12-9",
|
||||
fmt::format(L"The date is {0}", date(2012, 12, 9)));
|
||||
}
|
||||
|
||||
TEST(ostream_test, format_specs) {
|
||||
@ -220,7 +213,6 @@ template <typename T> struct convertible {
|
||||
|
||||
TEST(ostream_test, disable_builtin_ostream_operators) {
|
||||
EXPECT_EQ("42", fmt::format("{:d}", convertible<unsigned short>(42)));
|
||||
EXPECT_EQ(L"42", fmt::format(L"{:d}", convertible<unsigned short>(42)));
|
||||
EXPECT_EQ("foo", fmt::format("{}", convertible<const char*>("foo")));
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "fmt/ostream.h"
|
||||
#include "fmt/xchar.h"
|
||||
#include "gtest-extra.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -219,11 +219,6 @@ TEST(ranges_test, join_tuple) {
|
||||
EXPECT_EQ(fmt::format("{}", fmt::join(t4, "/")), "4");
|
||||
}
|
||||
|
||||
TEST(ranges_test, wide_string_join_tuple) {
|
||||
auto t = std::tuple<wchar_t, int, float>('a', 1, 2.0f);
|
||||
EXPECT_EQ(fmt::format(L"({})", fmt::join(t, L", ")), L"(a, 1, 2)");
|
||||
}
|
||||
|
||||
TEST(ranges_test, join_initializer_list) {
|
||||
EXPECT_EQ(fmt::format("{}", fmt::join({1, 2, 3}, ", ")), "1, 2, 3");
|
||||
EXPECT_EQ(fmt::format("{}", fmt::join({"fmt", "rocks", "!"}, " ")),
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "fmt/chrono.h"
|
||||
#include "fmt/ostream.h"
|
||||
#include "fmt/ranges.h"
|
||||
#include "fmt/xchar.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@ -24,6 +27,69 @@ TEST(wchar_test, format_explicitly_convertible_to_wstring_view) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(wchar_test, format) {
|
||||
EXPECT_EQ(L"42", fmt::format(L"{}", 42));
|
||||
EXPECT_EQ(L"4.2", fmt::format(L"{}", 4.2));
|
||||
EXPECT_EQ(L"abc", fmt::format(L"{}", L"abc"));
|
||||
EXPECT_EQ(L"z", fmt::format(L"{}", L'z'));
|
||||
EXPECT_THROW(fmt::format(L"{:*\x343E}", 42), fmt::format_error);
|
||||
EXPECT_EQ(L"true", fmt::format(L"{}", true));
|
||||
EXPECT_EQ(L"a", fmt::format(L"{0}", 'a'));
|
||||
EXPECT_EQ(L"a", fmt::format(L"{0}", L'a'));
|
||||
EXPECT_EQ(L"Cyrillic letter \x42e",
|
||||
fmt::format(L"Cyrillic letter {}", L'\x42e'));
|
||||
EXPECT_EQ(L"abc1", fmt::format(L"{}c{}", L"ab", 1));
|
||||
}
|
||||
|
||||
TEST(wchar_test, compile_time_string) {
|
||||
#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __cplusplus > 201103L
|
||||
struct custom_char {
|
||||
int value;
|
||||
custom_char() = default;
|
||||
|
||||
template <typename T>
|
||||
constexpr custom_char(T val) : value(static_cast<int>(val)) {}
|
||||
|
||||
operator int() const { return value; }
|
||||
};
|
||||
|
||||
int to_ascii(custom_char c) { return c; }
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <> struct is_char<custom_char> : std::true_type {};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
TEST(wchar_test, format_custom_char) {
|
||||
const custom_char format[] = {'{', '}', 0};
|
||||
auto result = fmt::format(format, custom_char('x'));
|
||||
EXPECT_EQ(result.size(), 1);
|
||||
EXPECT_EQ(result[0], custom_char('x'));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Convert a char8_t string to std::string. Otherwise GTest will insist on
|
||||
// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423.
|
||||
template <typename S> std::string from_u8str(const S& str) {
|
||||
return std::string(str.begin(), str.end());
|
||||
}
|
||||
|
||||
TEST(wchar_test, format_utf8_precision) {
|
||||
using str_type = std::basic_string<fmt::detail::char8_type>;
|
||||
auto format =
|
||||
str_type(reinterpret_cast<const fmt::detail::char8_type*>(u8"{:.4}"));
|
||||
auto str = str_type(reinterpret_cast<const fmt::detail::char8_type*>(
|
||||
u8"caf\u00e9s")); // cafés
|
||||
auto result = fmt::format(format, str);
|
||||
EXPECT_EQ(fmt::detail::compute_width(result), 4);
|
||||
EXPECT_EQ(result.size(), 5);
|
||||
EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5)));
|
||||
}
|
||||
|
||||
TEST(wchar_test, format_to) {
|
||||
auto buf = std::vector<wchar_t>();
|
||||
fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0');
|
||||
@ -88,6 +154,63 @@ TEST(wchar_test, print) {
|
||||
TEST(wchar_test, join) {
|
||||
int v[3] = {1, 2, 3};
|
||||
EXPECT_EQ(fmt::format(L"({})", fmt::join(v, v + 3, L", ")), L"(1, 2, 3)");
|
||||
auto t = std::tuple<wchar_t, int, float>('a', 1, 2.0f);
|
||||
EXPECT_EQ(fmt::format(L"({})", fmt::join(t, L", ")), L"(a, 1, 2)");
|
||||
}
|
||||
|
||||
enum streamable_enum {};
|
||||
|
||||
std::wostream& operator<<(std::wostream& os, streamable_enum) {
|
||||
return os << L"streamable_enum";
|
||||
}
|
||||
|
||||
enum unstreamable_enum {};
|
||||
|
||||
TEST(wchar_test, enum) {
|
||||
EXPECT_EQ(L"streamable_enum", fmt::format(L"{}", streamable_enum()));
|
||||
EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum()));
|
||||
}
|
||||
|
||||
TEST(wchar_test, sign_not_truncated) {
|
||||
wchar_t format_str[] = {
|
||||
L'{', L':',
|
||||
'+' | static_cast<wchar_t>(1 << fmt::detail::num_bits<char>()), L'}', 0};
|
||||
EXPECT_THROW(fmt::format(format_str, 42), fmt::format_error);
|
||||
}
|
||||
|
||||
namespace fake_qt {
|
||||
class QString {
|
||||
public:
|
||||
QString(const wchar_t* s) : s_(s) {}
|
||||
const wchar_t* utf16() const FMT_NOEXCEPT { return s_.data(); }
|
||||
int size() const FMT_NOEXCEPT { return static_cast<int>(s_.size()); }
|
||||
|
||||
private:
|
||||
std::wstring s_;
|
||||
};
|
||||
|
||||
fmt::basic_string_view<wchar_t> to_string_view(const QString& s) FMT_NOEXCEPT {
|
||||
return {s.utf16(), static_cast<size_t>(s.size())};
|
||||
}
|
||||
} // namespace fake_qt
|
||||
|
||||
TEST(format_test, format_foreign_strings) {
|
||||
using fake_qt::QString;
|
||||
EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42");
|
||||
EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42");
|
||||
}
|
||||
|
||||
TEST(wchar_test, chrono) {
|
||||
auto tm = std::tm();
|
||||
tm.tm_year = 116;
|
||||
tm.tm_mon = 3;
|
||||
tm.tm_mday = 25;
|
||||
tm.tm_hour = 11;
|
||||
tm.tm_min = 22;
|
||||
tm.tm_sec = 33;
|
||||
EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm),
|
||||
"The date is 2016-04-25 11:22:33.");
|
||||
EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42)));
|
||||
}
|
||||
|
||||
TEST(wchar_test, to_wstring) { EXPECT_EQ(L"42", fmt::to_wstring(42)); }
|
||||
|
Loading…
Reference in New Issue
Block a user