git repos / blockattack-game

blame: source/misc/embedded_libs/fmt-8.1.1/test/xchar-test.cc

normal view · raw

f8deb5b9 Poul Sander 2022-01-15 13:55 1
// Formatting library for C++ - formatting library tests
f8deb5b9 Poul Sander 2022-01-15 13:55 2
//
f8deb5b9 Poul Sander 2022-01-15 13:55 3
// Copyright (c) 2012 - present, Victor Zverovich
f8deb5b9 Poul Sander 2022-01-15 13:55 4
// All rights reserved.
f8deb5b9 Poul Sander 2022-01-15 13:55 5
//
f8deb5b9 Poul Sander 2022-01-15 13:55 6
// For the license information refer to format.h.
f8deb5b9 Poul Sander 2022-01-15 13:55 7
f8deb5b9 Poul Sander 2022-01-15 13:55 8
#include "fmt/xchar.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 9
f8deb5b9 Poul Sander 2022-01-15 13:55 10
#include <complex>
f8deb5b9 Poul Sander 2022-01-15 13:55 11
#include <cwchar>
f8deb5b9 Poul Sander 2022-01-15 13:55 12
#include <vector>
f8deb5b9 Poul Sander 2022-01-15 13:55 13
f8deb5b9 Poul Sander 2022-01-15 13:55 14
#include "fmt/chrono.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 15
#include "fmt/color.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 16
#include "fmt/ostream.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 17
#include "fmt/ranges.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 18
#include "gtest-extra.h"  // Contains
f8deb5b9 Poul Sander 2022-01-15 13:55 19
#include "util.h"         // get_locale
f8deb5b9 Poul Sander 2022-01-15 13:55 20
f8deb5b9 Poul Sander 2022-01-15 13:55 21
using fmt::detail::max_value;
f8deb5b9 Poul Sander 2022-01-15 13:55 22
using testing::Contains;
f8deb5b9 Poul Sander 2022-01-15 13:55 23
f8deb5b9 Poul Sander 2022-01-15 13:55 24
namespace test_ns {
f8deb5b9 Poul Sander 2022-01-15 13:55 25
template <typename Char> class test_string {
f8deb5b9 Poul Sander 2022-01-15 13:55 26
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 27
  std::basic_string<Char> s_;
f8deb5b9 Poul Sander 2022-01-15 13:55 28
f8deb5b9 Poul Sander 2022-01-15 13:55 29
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 30
  test_string(const Char* s) : s_(s) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 31
  const Char* data() const { return s_.data(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 32
  size_t length() const { return s_.size(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 33
  operator const Char*() const { return s_.c_str(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 34
};
f8deb5b9 Poul Sander 2022-01-15 13:55 35
f8deb5b9 Poul Sander 2022-01-15 13:55 36
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 37
fmt::basic_string_view<Char> to_string_view(const test_string<Char>& s) {
f8deb5b9 Poul Sander 2022-01-15 13:55 38
  return {s.data(), s.length()};
f8deb5b9 Poul Sander 2022-01-15 13:55 39
}
f8deb5b9 Poul Sander 2022-01-15 13:55 40
f8deb5b9 Poul Sander 2022-01-15 13:55 41
struct non_string {};
f8deb5b9 Poul Sander 2022-01-15 13:55 42
}  // namespace test_ns
f8deb5b9 Poul Sander 2022-01-15 13:55 43
f8deb5b9 Poul Sander 2022-01-15 13:55 44
template <typename T> class is_string_test : public testing::Test {};
f8deb5b9 Poul Sander 2022-01-15 13:55 45
f8deb5b9 Poul Sander 2022-01-15 13:55 46
using string_char_types = testing::Types<char, wchar_t, char16_t, char32_t>;
f8deb5b9 Poul Sander 2022-01-15 13:55 47
TYPED_TEST_SUITE(is_string_test, string_char_types);
f8deb5b9 Poul Sander 2022-01-15 13:55 48
f8deb5b9 Poul Sander 2022-01-15 13:55 49
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 50
struct derived_from_string_view : fmt::basic_string_view<Char> {};
f8deb5b9 Poul Sander 2022-01-15 13:55 51
f8deb5b9 Poul Sander 2022-01-15 13:55 52
TYPED_TEST(is_string_test, is_string) {
f8deb5b9 Poul Sander 2022-01-15 13:55 53
  EXPECT_TRUE(fmt::detail::is_string<TypeParam*>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 54
  EXPECT_TRUE(fmt::detail::is_string<const TypeParam*>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 55
  EXPECT_TRUE(fmt::detail::is_string<TypeParam[2]>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 56
  EXPECT_TRUE(fmt::detail::is_string<const TypeParam[2]>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 57
  EXPECT_TRUE(fmt::detail::is_string<std::basic_string<TypeParam>>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 58
  EXPECT_TRUE(fmt::detail::is_string<fmt::basic_string_view<TypeParam>>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 59
  EXPECT_TRUE(
f8deb5b9 Poul Sander 2022-01-15 13:55 60
      fmt::detail::is_string<derived_from_string_view<TypeParam>>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 61
  using fmt_string_view = fmt::detail::std_string_view<TypeParam>;
f8deb5b9 Poul Sander 2022-01-15 13:55 62
  EXPECT_TRUE(std::is_empty<fmt_string_view>::value !=
f8deb5b9 Poul Sander 2022-01-15 13:55 63
              fmt::detail::is_string<fmt_string_view>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 64
  EXPECT_TRUE(fmt::detail::is_string<test_ns::test_string<TypeParam>>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 65
  EXPECT_FALSE(fmt::detail::is_string<test_ns::non_string>::value);
f8deb5b9 Poul Sander 2022-01-15 13:55 66
}
f8deb5b9 Poul Sander 2022-01-15 13:55 67
f8deb5b9 Poul Sander 2022-01-15 13:55 68
// std::is_constructible is broken in MSVC until version 2015.
f8deb5b9 Poul Sander 2022-01-15 13:55 69
#if !FMT_MSC_VER || FMT_MSC_VER >= 1900
f8deb5b9 Poul Sander 2022-01-15 13:55 70
struct explicitly_convertible_to_wstring_view {
f8deb5b9 Poul Sander 2022-01-15 13:55 71
  explicit operator fmt::wstring_view() const { return L"foo"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 72
};
f8deb5b9 Poul Sander 2022-01-15 13:55 73
f8deb5b9 Poul Sander 2022-01-15 13:55 74
TEST(xchar_test, format_explicitly_convertible_to_wstring_view) {
f8deb5b9 Poul Sander 2022-01-15 13:55 75
  EXPECT_EQ(L"foo",
f8deb5b9 Poul Sander 2022-01-15 13:55 76
            fmt::format(L"{}", explicitly_convertible_to_wstring_view()));
f8deb5b9 Poul Sander 2022-01-15 13:55 77
}
f8deb5b9 Poul Sander 2022-01-15 13:55 78
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 79
f8deb5b9 Poul Sander 2022-01-15 13:55 80
TEST(xchar_test, format) {
f8deb5b9 Poul Sander 2022-01-15 13:55 81
  EXPECT_EQ(L"42", fmt::format(L"{}", 42));
f8deb5b9 Poul Sander 2022-01-15 13:55 82
  EXPECT_EQ(L"4.2", fmt::format(L"{}", 4.2));
f8deb5b9 Poul Sander 2022-01-15 13:55 83
  EXPECT_EQ(L"abc", fmt::format(L"{}", L"abc"));
f8deb5b9 Poul Sander 2022-01-15 13:55 84
  EXPECT_EQ(L"z", fmt::format(L"{}", L'z'));
f8deb5b9 Poul Sander 2022-01-15 13:55 85
  EXPECT_THROW(fmt::format(L"{:*\x343E}", 42), fmt::format_error);
f8deb5b9 Poul Sander 2022-01-15 13:55 86
  EXPECT_EQ(L"true", fmt::format(L"{}", true));
f8deb5b9 Poul Sander 2022-01-15 13:55 87
  EXPECT_EQ(L"a", fmt::format(L"{0}", 'a'));
f8deb5b9 Poul Sander 2022-01-15 13:55 88
  EXPECT_EQ(L"a", fmt::format(L"{0}", L'a'));
f8deb5b9 Poul Sander 2022-01-15 13:55 89
  EXPECT_EQ(L"Cyrillic letter \x42e",
f8deb5b9 Poul Sander 2022-01-15 13:55 90
            fmt::format(L"Cyrillic letter {}", L'\x42e'));
f8deb5b9 Poul Sander 2022-01-15 13:55 91
  EXPECT_EQ(L"abc1", fmt::format(L"{}c{}", L"ab", 1));
f8deb5b9 Poul Sander 2022-01-15 13:55 92
}
f8deb5b9 Poul Sander 2022-01-15 13:55 93
f8deb5b9 Poul Sander 2022-01-15 13:55 94
TEST(xchar_test, is_formattable) {
f8deb5b9 Poul Sander 2022-01-15 13:55 95
  static_assert(!fmt::is_formattable<const wchar_t*>::value, "");
f8deb5b9 Poul Sander 2022-01-15 13:55 96
}
f8deb5b9 Poul Sander 2022-01-15 13:55 97
f8deb5b9 Poul Sander 2022-01-15 13:55 98
TEST(xchar_test, compile_time_string) {
f8deb5b9 Poul Sander 2022-01-15 13:55 99
#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L
f8deb5b9 Poul Sander 2022-01-15 13:55 100
  EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42));
f8deb5b9 Poul Sander 2022-01-15 13:55 101
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 102
}
f8deb5b9 Poul Sander 2022-01-15 13:55 103
f8deb5b9 Poul Sander 2022-01-15 13:55 104
#if __cplusplus > 201103L
f8deb5b9 Poul Sander 2022-01-15 13:55 105
struct custom_char {
f8deb5b9 Poul Sander 2022-01-15 13:55 106
  int value;
f8deb5b9 Poul Sander 2022-01-15 13:55 107
  custom_char() = default;
f8deb5b9 Poul Sander 2022-01-15 13:55 108
f8deb5b9 Poul Sander 2022-01-15 13:55 109
  template <typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 110
  constexpr custom_char(T val) : value(static_cast<int>(val)) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 111
f8deb5b9 Poul Sander 2022-01-15 13:55 112
  operator int() const { return value; }
f8deb5b9 Poul Sander 2022-01-15 13:55 113
};
f8deb5b9 Poul Sander 2022-01-15 13:55 114
f8deb5b9 Poul Sander 2022-01-15 13:55 115
int to_ascii(custom_char c) { return c; }
f8deb5b9 Poul Sander 2022-01-15 13:55 116
f8deb5b9 Poul Sander 2022-01-15 13:55 117
FMT_BEGIN_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 118
template <> struct is_char<custom_char> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 119
FMT_END_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 120
f8deb5b9 Poul Sander 2022-01-15 13:55 121
TEST(xchar_test, format_custom_char) {
f8deb5b9 Poul Sander 2022-01-15 13:55 122
  const custom_char format[] = {'{', '}', 0};
f8deb5b9 Poul Sander 2022-01-15 13:55 123
  auto result = fmt::format(format, custom_char('x'));
f8deb5b9 Poul Sander 2022-01-15 13:55 124
  EXPECT_EQ(result.size(), 1);
f8deb5b9 Poul Sander 2022-01-15 13:55 125
  EXPECT_EQ(result[0], custom_char('x'));
f8deb5b9 Poul Sander 2022-01-15 13:55 126
}
f8deb5b9 Poul Sander 2022-01-15 13:55 127
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 128
f8deb5b9 Poul Sander 2022-01-15 13:55 129
// Convert a char8_t string to std::string. Otherwise GTest will insist on
f8deb5b9 Poul Sander 2022-01-15 13:55 130
// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423.
f8deb5b9 Poul Sander 2022-01-15 13:55 131
template <typename S> std::string from_u8str(const S& str) {
f8deb5b9 Poul Sander 2022-01-15 13:55 132
  return std::string(str.begin(), str.end());
f8deb5b9 Poul Sander 2022-01-15 13:55 133
}
f8deb5b9 Poul Sander 2022-01-15 13:55 134
f8deb5b9 Poul Sander 2022-01-15 13:55 135
TEST(xchar_test, format_utf8_precision) {
f8deb5b9 Poul Sander 2022-01-15 13:55 136
  using str_type = std::basic_string<fmt::detail::char8_type>;
f8deb5b9 Poul Sander 2022-01-15 13:55 137
  auto format =
f8deb5b9 Poul Sander 2022-01-15 13:55 138
      str_type(reinterpret_cast<const fmt::detail::char8_type*>(u8"{:.4}"));
f8deb5b9 Poul Sander 2022-01-15 13:55 139
  auto str = str_type(reinterpret_cast<const fmt::detail::char8_type*>(
f8deb5b9 Poul Sander 2022-01-15 13:55 140
      u8"caf\u00e9s"));  // cafés
f8deb5b9 Poul Sander 2022-01-15 13:55 141
  auto result = fmt::format(format, str);
f8deb5b9 Poul Sander 2022-01-15 13:55 142
  EXPECT_EQ(fmt::detail::compute_width(result), 4);
f8deb5b9 Poul Sander 2022-01-15 13:55 143
  EXPECT_EQ(result.size(), 5);
f8deb5b9 Poul Sander 2022-01-15 13:55 144
  EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5)));
f8deb5b9 Poul Sander 2022-01-15 13:55 145
}
f8deb5b9 Poul Sander 2022-01-15 13:55 146
f8deb5b9 Poul Sander 2022-01-15 13:55 147
TEST(xchar_test, format_to) {
f8deb5b9 Poul Sander 2022-01-15 13:55 148
  auto buf = std::vector<wchar_t>();
f8deb5b9 Poul Sander 2022-01-15 13:55 149
  fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0');
f8deb5b9 Poul Sander 2022-01-15 13:55 150
  EXPECT_STREQ(buf.data(), L"42");
f8deb5b9 Poul Sander 2022-01-15 13:55 151
}
f8deb5b9 Poul Sander 2022-01-15 13:55 152
f8deb5b9 Poul Sander 2022-01-15 13:55 153
TEST(xchar_test, vformat_to) {
f8deb5b9 Poul Sander 2022-01-15 13:55 154
  using wcontext = fmt::wformat_context;
f8deb5b9 Poul Sander 2022-01-15 13:55 155
  fmt::basic_format_arg<wcontext> warg = fmt::detail::make_arg<wcontext>(42);
f8deb5b9 Poul Sander 2022-01-15 13:55 156
  auto wargs = fmt::basic_format_args<wcontext>(&warg, 1);
f8deb5b9 Poul Sander 2022-01-15 13:55 157
  auto w = std::wstring();
f8deb5b9 Poul Sander 2022-01-15 13:55 158
  fmt::vformat_to(std::back_inserter(w), L"{}", wargs);
f8deb5b9 Poul Sander 2022-01-15 13:55 159
  EXPECT_EQ(L"42", w);
f8deb5b9 Poul Sander 2022-01-15 13:55 160
  w.clear();
f8deb5b9 Poul Sander 2022-01-15 13:55 161
  fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs);
f8deb5b9 Poul Sander 2022-01-15 13:55 162
  EXPECT_EQ(L"42", w);
f8deb5b9 Poul Sander 2022-01-15 13:55 163
}
f8deb5b9 Poul Sander 2022-01-15 13:55 164
f8deb5b9 Poul Sander 2022-01-15 13:55 165
TEST(format_test, wide_format_to_n) {
f8deb5b9 Poul Sander 2022-01-15 13:55 166
  wchar_t buffer[4];
f8deb5b9 Poul Sander 2022-01-15 13:55 167
  buffer[3] = L'x';
f8deb5b9 Poul Sander 2022-01-15 13:55 168
  auto result = fmt::format_to_n(buffer, 3, L"{}", 12345);
f8deb5b9 Poul Sander 2022-01-15 13:55 169
  EXPECT_EQ(5u, result.size);
f8deb5b9 Poul Sander 2022-01-15 13:55 170
  EXPECT_EQ(buffer + 3, result.out);
f8deb5b9 Poul Sander 2022-01-15 13:55 171
  EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4));
f8deb5b9 Poul Sander 2022-01-15 13:55 172
  buffer[0] = L'x';
f8deb5b9 Poul Sander 2022-01-15 13:55 173
  buffer[1] = L'x';
f8deb5b9 Poul Sander 2022-01-15 13:55 174
  buffer[2] = L'x';
f8deb5b9 Poul Sander 2022-01-15 13:55 175
  result = fmt::format_to_n(buffer, 3, L"{}", L'A');
f8deb5b9 Poul Sander 2022-01-15 13:55 176
  EXPECT_EQ(1u, result.size);
f8deb5b9 Poul Sander 2022-01-15 13:55 177
  EXPECT_EQ(buffer + 1, result.out);
f8deb5b9 Poul Sander 2022-01-15 13:55 178
  EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4));
f8deb5b9 Poul Sander 2022-01-15 13:55 179
  result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C');
f8deb5b9 Poul Sander 2022-01-15 13:55 180
  EXPECT_EQ(3u, result.size);
f8deb5b9 Poul Sander 2022-01-15 13:55 181
  EXPECT_EQ(buffer + 3, result.out);
f8deb5b9 Poul Sander 2022-01-15 13:55 182
  EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4));
f8deb5b9 Poul Sander 2022-01-15 13:55 183
}
f8deb5b9 Poul Sander 2022-01-15 13:55 184
f8deb5b9 Poul Sander 2022-01-15 13:55 185
#if FMT_USE_USER_DEFINED_LITERALS
f8deb5b9 Poul Sander 2022-01-15 13:55 186
TEST(xchar_test, format_udl) {
f8deb5b9 Poul Sander 2022-01-15 13:55 187
  using namespace fmt::literals;
f8deb5b9 Poul Sander 2022-01-15 13:55 188
  EXPECT_EQ(L"{}c{}"_format(L"ab", 1), fmt::format(L"{}c{}", L"ab", 1));
f8deb5b9 Poul Sander 2022-01-15 13:55 189
}
f8deb5b9 Poul Sander 2022-01-15 13:55 190
f8deb5b9 Poul Sander 2022-01-15 13:55 191
TEST(xchar_test, named_arg_udl) {
f8deb5b9 Poul Sander 2022-01-15 13:55 192
  using namespace fmt::literals;
f8deb5b9 Poul Sander 2022-01-15 13:55 193
  auto udl_a =
f8deb5b9 Poul Sander 2022-01-15 13:55 194
      fmt::format(L"{first}{second}{first}{third}", L"first"_a = L"abra",
f8deb5b9 Poul Sander 2022-01-15 13:55 195
                  L"second"_a = L"cad", L"third"_a = 99);
f8deb5b9 Poul Sander 2022-01-15 13:55 196
  EXPECT_EQ(
f8deb5b9 Poul Sander 2022-01-15 13:55 197
      fmt::format(L"{first}{second}{first}{third}", fmt::arg(L"first", L"abra"),
f8deb5b9 Poul Sander 2022-01-15 13:55 198
                  fmt::arg(L"second", L"cad"), fmt::arg(L"third", 99)),
f8deb5b9 Poul Sander 2022-01-15 13:55 199
      udl_a);
f8deb5b9 Poul Sander 2022-01-15 13:55 200
}
f8deb5b9 Poul Sander 2022-01-15 13:55 201
#endif  // FMT_USE_USER_DEFINED_LITERALS
f8deb5b9 Poul Sander 2022-01-15 13:55 202
f8deb5b9 Poul Sander 2022-01-15 13:55 203
TEST(xchar_test, print) {
f8deb5b9 Poul Sander 2022-01-15 13:55 204
  // Check that the wide print overload compiles.
f8deb5b9 Poul Sander 2022-01-15 13:55 205
  if (fmt::detail::const_check(false)) fmt::print(L"test");
f8deb5b9 Poul Sander 2022-01-15 13:55 206
}
f8deb5b9 Poul Sander 2022-01-15 13:55 207
f8deb5b9 Poul Sander 2022-01-15 13:55 208
TEST(xchar_test, join) {
f8deb5b9 Poul Sander 2022-01-15 13:55 209
  int v[3] = {1, 2, 3};
f8deb5b9 Poul Sander 2022-01-15 13:55 210
  EXPECT_EQ(fmt::format(L"({})", fmt::join(v, v + 3, L", ")), L"(1, 2, 3)");
f8deb5b9 Poul Sander 2022-01-15 13:55 211
  auto t = std::tuple<wchar_t, int, float>('a', 1, 2.0f);
f8deb5b9 Poul Sander 2022-01-15 13:55 212
  EXPECT_EQ(fmt::format(L"({})", fmt::join(t, L", ")), L"(a, 1, 2)");
f8deb5b9 Poul Sander 2022-01-15 13:55 213
}
f8deb5b9 Poul Sander 2022-01-15 13:55 214
f8deb5b9 Poul Sander 2022-01-15 13:55 215
enum streamable_enum {};
f8deb5b9 Poul Sander 2022-01-15 13:55 216
f8deb5b9 Poul Sander 2022-01-15 13:55 217
std::wostream& operator<<(std::wostream& os, streamable_enum) {
f8deb5b9 Poul Sander 2022-01-15 13:55 218
  return os << L"streamable_enum";
f8deb5b9 Poul Sander 2022-01-15 13:55 219
}
f8deb5b9 Poul Sander 2022-01-15 13:55 220
f8deb5b9 Poul Sander 2022-01-15 13:55 221
enum unstreamable_enum {};
f8deb5b9 Poul Sander 2022-01-15 13:55 222
f8deb5b9 Poul Sander 2022-01-15 13:55 223
TEST(xchar_test, enum) {
f8deb5b9 Poul Sander 2022-01-15 13:55 224
  EXPECT_EQ(L"streamable_enum", fmt::format(L"{}", streamable_enum()));
f8deb5b9 Poul Sander 2022-01-15 13:55 225
  EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum()));
f8deb5b9 Poul Sander 2022-01-15 13:55 226
}
f8deb5b9 Poul Sander 2022-01-15 13:55 227
f8deb5b9 Poul Sander 2022-01-15 13:55 228
TEST(xchar_test, sign_not_truncated) {
f8deb5b9 Poul Sander 2022-01-15 13:55 229
  wchar_t format_str[] = {
f8deb5b9 Poul Sander 2022-01-15 13:55 230
      L'{', L':',
f8deb5b9 Poul Sander 2022-01-15 13:55 231
      '+' | static_cast<wchar_t>(1 << fmt::detail::num_bits<char>()), L'}', 0};
f8deb5b9 Poul Sander 2022-01-15 13:55 232
  EXPECT_THROW(fmt::format(format_str, 42), fmt::format_error);
f8deb5b9 Poul Sander 2022-01-15 13:55 233
}
f8deb5b9 Poul Sander 2022-01-15 13:55 234
f8deb5b9 Poul Sander 2022-01-15 13:55 235
namespace fake_qt {
f8deb5b9 Poul Sander 2022-01-15 13:55 236
class QString {
f8deb5b9 Poul Sander 2022-01-15 13:55 237
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 238
  QString(const wchar_t* s) : s_(s) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 239
  const wchar_t* utf16() const FMT_NOEXCEPT { return s_.data(); }
f8deb5b9 Poul Sander 2022-01-15 13:55 240
  int size() const FMT_NOEXCEPT { return static_cast<int>(s_.size()); }
f8deb5b9 Poul Sander 2022-01-15 13:55 241
f8deb5b9 Poul Sander 2022-01-15 13:55 242
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 243
  std::wstring s_;
f8deb5b9 Poul Sander 2022-01-15 13:55 244
};
f8deb5b9 Poul Sander 2022-01-15 13:55 245
f8deb5b9 Poul Sander 2022-01-15 13:55 246
fmt::basic_string_view<wchar_t> to_string_view(const QString& s) FMT_NOEXCEPT {
f8deb5b9 Poul Sander 2022-01-15 13:55 247
  return {s.utf16(), static_cast<size_t>(s.size())};
f8deb5b9 Poul Sander 2022-01-15 13:55 248
}
f8deb5b9 Poul Sander 2022-01-15 13:55 249
}  // namespace fake_qt
f8deb5b9 Poul Sander 2022-01-15 13:55 250
f8deb5b9 Poul Sander 2022-01-15 13:55 251
TEST(format_test, format_foreign_strings) {
f8deb5b9 Poul Sander 2022-01-15 13:55 252
  using fake_qt::QString;
f8deb5b9 Poul Sander 2022-01-15 13:55 253
  EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42");
f8deb5b9 Poul Sander 2022-01-15 13:55 254
  EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42");
f8deb5b9 Poul Sander 2022-01-15 13:55 255
}
f8deb5b9 Poul Sander 2022-01-15 13:55 256
f8deb5b9 Poul Sander 2022-01-15 13:55 257
TEST(xchar_test, chrono) {
f8deb5b9 Poul Sander 2022-01-15 13:55 258
  auto tm = std::tm();
f8deb5b9 Poul Sander 2022-01-15 13:55 259
  tm.tm_year = 116;
f8deb5b9 Poul Sander 2022-01-15 13:55 260
  tm.tm_mon = 3;
f8deb5b9 Poul Sander 2022-01-15 13:55 261
  tm.tm_mday = 25;
f8deb5b9 Poul Sander 2022-01-15 13:55 262
  tm.tm_hour = 11;
f8deb5b9 Poul Sander 2022-01-15 13:55 263
  tm.tm_min = 22;
f8deb5b9 Poul Sander 2022-01-15 13:55 264
  tm.tm_sec = 33;
f8deb5b9 Poul Sander 2022-01-15 13:55 265
  EXPECT_EQ(fmt::format("The date is {:%Y-%m-%d %H:%M:%S}.", tm),
f8deb5b9 Poul Sander 2022-01-15 13:55 266
            "The date is 2016-04-25 11:22:33.");
f8deb5b9 Poul Sander 2022-01-15 13:55 267
  EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42)));
f8deb5b9 Poul Sander 2022-01-15 13:55 268
  EXPECT_EQ(fmt::format(L"{:%F}", tm), L"2016-04-25");
f8deb5b9 Poul Sander 2022-01-15 13:55 269
  EXPECT_EQ(fmt::format(L"{:%T}", tm), L"11:22:33");
f8deb5b9 Poul Sander 2022-01-15 13:55 270
}
f8deb5b9 Poul Sander 2022-01-15 13:55 271
f8deb5b9 Poul Sander 2022-01-15 13:55 272
std::wstring system_wcsftime(const std::wstring& format, const std::tm* timeptr,
f8deb5b9 Poul Sander 2022-01-15 13:55 273
                             std::locale* locptr = nullptr) {
f8deb5b9 Poul Sander 2022-01-15 13:55 274
  auto loc = locptr ? *locptr : std::locale::classic();
f8deb5b9 Poul Sander 2022-01-15 13:55 275
  auto& facet = std::use_facet<std::time_put<wchar_t>>(loc);
f8deb5b9 Poul Sander 2022-01-15 13:55 276
  std::wostringstream os;
f8deb5b9 Poul Sander 2022-01-15 13:55 277
  os.imbue(loc);
f8deb5b9 Poul Sander 2022-01-15 13:55 278
  facet.put(os, os, L' ', timeptr, format.c_str(),
f8deb5b9 Poul Sander 2022-01-15 13:55 279
            format.c_str() + format.size());
f8deb5b9 Poul Sander 2022-01-15 13:55 280
#ifdef _WIN32
f8deb5b9 Poul Sander 2022-01-15 13:55 281
  // Workaround a bug in older versions of Universal CRT.
f8deb5b9 Poul Sander 2022-01-15 13:55 282
  auto str = os.str();
f8deb5b9 Poul Sander 2022-01-15 13:55 283
  if (str == L"-0000") str = L"+0000";
f8deb5b9 Poul Sander 2022-01-15 13:55 284
  return str;
f8deb5b9 Poul Sander 2022-01-15 13:55 285
#else
f8deb5b9 Poul Sander 2022-01-15 13:55 286
  return os.str();
f8deb5b9 Poul Sander 2022-01-15 13:55 287
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 288
}
f8deb5b9 Poul Sander 2022-01-15 13:55 289
f8deb5b9 Poul Sander 2022-01-15 13:55 290
TEST(chrono_test, time_point) {
f8deb5b9 Poul Sander 2022-01-15 13:55 291
  auto t1 = std::chrono::system_clock::now();
f8deb5b9 Poul Sander 2022-01-15 13:55 292
f8deb5b9 Poul Sander 2022-01-15 13:55 293
  std::vector<std::wstring> spec_list = {
f8deb5b9 Poul Sander 2022-01-15 13:55 294
      L"%%",  L"%n",  L"%t",  L"%Y",  L"%EY", L"%y",  L"%Oy", L"%Ey", L"%C",
f8deb5b9 Poul Sander 2022-01-15 13:55 295
      L"%EC", L"%G",  L"%g",  L"%b",  L"%h",  L"%B",  L"%m",  L"%Om", L"%U",
f8deb5b9 Poul Sander 2022-01-15 13:55 296
      L"%OU", L"%W",  L"%OW", L"%V",  L"%OV", L"%j",  L"%d",  L"%Od", L"%e",
f8deb5b9 Poul Sander 2022-01-15 13:55 297
      L"%Oe", L"%a",  L"%A",  L"%w",  L"%Ow", L"%u",  L"%Ou", L"%H",  L"%OH",
f8deb5b9 Poul Sander 2022-01-15 13:55 298
      L"%I",  L"%OI", L"%M",  L"%OM", L"%S",  L"%OS", L"%x",  L"%Ex", L"%X",
f8deb5b9 Poul Sander 2022-01-15 13:55 299
      L"%EX", L"%D",  L"%F",  L"%R",  L"%T",  L"%p",  L"%z",  L"%Z"};
f8deb5b9 Poul Sander 2022-01-15 13:55 300
  spec_list.push_back(L"%Y-%m-%d %H:%M:%S");
f8deb5b9 Poul Sander 2022-01-15 13:55 301
#ifndef _WIN32
f8deb5b9 Poul Sander 2022-01-15 13:55 302
  // Disabled on Windows, because these formats is not consistent among
f8deb5b9 Poul Sander 2022-01-15 13:55 303
  // platforms.
f8deb5b9 Poul Sander 2022-01-15 13:55 304
  spec_list.insert(spec_list.end(), {L"%c", L"%Ec", L"%r"});
f8deb5b9 Poul Sander 2022-01-15 13:55 305
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 306
f8deb5b9 Poul Sander 2022-01-15 13:55 307
  for (const auto& spec : spec_list) {
f8deb5b9 Poul Sander 2022-01-15 13:55 308
    auto t = std::chrono::system_clock::to_time_t(t1);
f8deb5b9 Poul Sander 2022-01-15 13:55 309
    auto tm = *std::localtime(&t);
f8deb5b9 Poul Sander 2022-01-15 13:55 310
f8deb5b9 Poul Sander 2022-01-15 13:55 311
    auto sys_output = system_wcsftime(spec, &tm);
f8deb5b9 Poul Sander 2022-01-15 13:55 312
f8deb5b9 Poul Sander 2022-01-15 13:55 313
    auto fmt_spec = fmt::format(L"{{:{}}}", spec);
f8deb5b9 Poul Sander 2022-01-15 13:55 314
    EXPECT_EQ(sys_output, fmt::format(fmt_spec, t1));
f8deb5b9 Poul Sander 2022-01-15 13:55 315
    EXPECT_EQ(sys_output, fmt::format(fmt_spec, tm));
f8deb5b9 Poul Sander 2022-01-15 13:55 316
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 317
}
f8deb5b9 Poul Sander 2022-01-15 13:55 318
f8deb5b9 Poul Sander 2022-01-15 13:55 319
TEST(xchar_test, color) {
f8deb5b9 Poul Sander 2022-01-15 13:55 320
  EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), L"rgb(255,20,30) wide"),
f8deb5b9 Poul Sander 2022-01-15 13:55 321
            L"\x1b[38;2;255;020;030mrgb(255,20,30) wide\x1b[0m");
f8deb5b9 Poul Sander 2022-01-15 13:55 322
}
f8deb5b9 Poul Sander 2022-01-15 13:55 323
f8deb5b9 Poul Sander 2022-01-15 13:55 324
TEST(xchar_test, ostream) {
f8deb5b9 Poul Sander 2022-01-15 13:55 325
  std::wostringstream wos;
f8deb5b9 Poul Sander 2022-01-15 13:55 326
  fmt::print(wos, L"Don't {}!", L"panic");
f8deb5b9 Poul Sander 2022-01-15 13:55 327
  EXPECT_EQ(L"Don't panic!", wos.str());
f8deb5b9 Poul Sander 2022-01-15 13:55 328
}
f8deb5b9 Poul Sander 2022-01-15 13:55 329
f8deb5b9 Poul Sander 2022-01-15 13:55 330
TEST(xchar_test, to_wstring) { EXPECT_EQ(L"42", fmt::to_wstring(42)); }
f8deb5b9 Poul Sander 2022-01-15 13:55 331
f8deb5b9 Poul Sander 2022-01-15 13:55 332
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
f8deb5b9 Poul Sander 2022-01-15 13:55 333
template <typename Char> struct numpunct : std::numpunct<Char> {
f8deb5b9 Poul Sander 2022-01-15 13:55 334
 protected:
f8deb5b9 Poul Sander 2022-01-15 13:55 335
  Char do_decimal_point() const override { return '?'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 336
  std::string do_grouping() const override { return "\03"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 337
  Char do_thousands_sep() const override { return '~'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 338
};
f8deb5b9 Poul Sander 2022-01-15 13:55 339
f8deb5b9 Poul Sander 2022-01-15 13:55 340
template <typename Char> struct no_grouping : std::numpunct<Char> {
f8deb5b9 Poul Sander 2022-01-15 13:55 341
 protected:
f8deb5b9 Poul Sander 2022-01-15 13:55 342
  Char do_decimal_point() const override { return '.'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 343
  std::string do_grouping() const override { return ""; }
f8deb5b9 Poul Sander 2022-01-15 13:55 344
  Char do_thousands_sep() const override { return ','; }
f8deb5b9 Poul Sander 2022-01-15 13:55 345
};
f8deb5b9 Poul Sander 2022-01-15 13:55 346
f8deb5b9 Poul Sander 2022-01-15 13:55 347
template <typename Char> struct special_grouping : std::numpunct<Char> {
f8deb5b9 Poul Sander 2022-01-15 13:55 348
 protected:
f8deb5b9 Poul Sander 2022-01-15 13:55 349
  Char do_decimal_point() const override { return '.'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 350
  std::string do_grouping() const override { return "\03\02"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 351
  Char do_thousands_sep() const override { return ','; }
f8deb5b9 Poul Sander 2022-01-15 13:55 352
};
f8deb5b9 Poul Sander 2022-01-15 13:55 353
f8deb5b9 Poul Sander 2022-01-15 13:55 354
template <typename Char> struct small_grouping : std::numpunct<Char> {
f8deb5b9 Poul Sander 2022-01-15 13:55 355
 protected:
f8deb5b9 Poul Sander 2022-01-15 13:55 356
  Char do_decimal_point() const override { return '.'; }
f8deb5b9 Poul Sander 2022-01-15 13:55 357
  std::string do_grouping() const override { return "\01"; }
f8deb5b9 Poul Sander 2022-01-15 13:55 358
  Char do_thousands_sep() const override { return ','; }
f8deb5b9 Poul Sander 2022-01-15 13:55 359
};
f8deb5b9 Poul Sander 2022-01-15 13:55 360
f8deb5b9 Poul Sander 2022-01-15 13:55 361
TEST(locale_test, localized_double) {
f8deb5b9 Poul Sander 2022-01-15 13:55 362
  auto loc = std::locale(std::locale(), new numpunct<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 363
  EXPECT_EQ("1?23", fmt::format(loc, "{:L}", 1.23));
f8deb5b9 Poul Sander 2022-01-15 13:55 364
  EXPECT_EQ("1?230000", fmt::format(loc, "{:Lf}", 1.23));
f8deb5b9 Poul Sander 2022-01-15 13:55 365
  EXPECT_EQ("1~234?5", fmt::format(loc, "{:L}", 1234.5));
f8deb5b9 Poul Sander 2022-01-15 13:55 366
  EXPECT_EQ("12~000", fmt::format(loc, "{:L}", 12000.0));
f8deb5b9 Poul Sander 2022-01-15 13:55 367
}
f8deb5b9 Poul Sander 2022-01-15 13:55 368
f8deb5b9 Poul Sander 2022-01-15 13:55 369
TEST(locale_test, format) {
f8deb5b9 Poul Sander 2022-01-15 13:55 370
  auto loc = std::locale(std::locale(), new numpunct<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 371
  EXPECT_EQ("1234567", fmt::format(std::locale(), "{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 372
  EXPECT_EQ("1~234~567", fmt::format(loc, "{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 373
  EXPECT_EQ("-1~234~567", fmt::format(loc, "{:L}", -1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 374
  EXPECT_EQ("-256", fmt::format(loc, "{:L}", -256));
f8deb5b9 Poul Sander 2022-01-15 13:55 375
  fmt::format_arg_store<fmt::format_context, int> as{1234567};
f8deb5b9 Poul Sander 2022-01-15 13:55 376
  EXPECT_EQ("1~234~567", fmt::vformat(loc, "{:L}", fmt::format_args(as)));
f8deb5b9 Poul Sander 2022-01-15 13:55 377
  auto s = std::string();
f8deb5b9 Poul Sander 2022-01-15 13:55 378
  fmt::format_to(std::back_inserter(s), loc, "{:L}", 1234567);
f8deb5b9 Poul Sander 2022-01-15 13:55 379
  EXPECT_EQ("1~234~567", s);
f8deb5b9 Poul Sander 2022-01-15 13:55 380
f8deb5b9 Poul Sander 2022-01-15 13:55 381
  auto no_grouping_loc = std::locale(std::locale(), new no_grouping<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 382
  EXPECT_EQ("1234567", fmt::format(no_grouping_loc, "{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 383
f8deb5b9 Poul Sander 2022-01-15 13:55 384
  auto special_grouping_loc =
f8deb5b9 Poul Sander 2022-01-15 13:55 385
      std::locale(std::locale(), new special_grouping<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 386
  EXPECT_EQ("1,23,45,678", fmt::format(special_grouping_loc, "{:L}", 12345678));
f8deb5b9 Poul Sander 2022-01-15 13:55 387
  EXPECT_EQ("12,345", fmt::format(special_grouping_loc, "{:L}", 12345));
f8deb5b9 Poul Sander 2022-01-15 13:55 388
f8deb5b9 Poul Sander 2022-01-15 13:55 389
  auto small_grouping_loc =
f8deb5b9 Poul Sander 2022-01-15 13:55 390
      std::locale(std::locale(), new small_grouping<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 391
  EXPECT_EQ("4,2,9,4,9,6,7,2,9,5",
f8deb5b9 Poul Sander 2022-01-15 13:55 392
            fmt::format(small_grouping_loc, "{:L}", max_value<uint32_t>()));
f8deb5b9 Poul Sander 2022-01-15 13:55 393
}
f8deb5b9 Poul Sander 2022-01-15 13:55 394
f8deb5b9 Poul Sander 2022-01-15 13:55 395
TEST(locale_test, format_detault_align) {
f8deb5b9 Poul Sander 2022-01-15 13:55 396
  auto loc = std::locale({}, new special_grouping<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 397
  EXPECT_EQ("  12,345", fmt::format(loc, "{:8L}", 12345));
f8deb5b9 Poul Sander 2022-01-15 13:55 398
}
f8deb5b9 Poul Sander 2022-01-15 13:55 399
f8deb5b9 Poul Sander 2022-01-15 13:55 400
TEST(locale_test, format_plus) {
f8deb5b9 Poul Sander 2022-01-15 13:55 401
  auto loc = std::locale({}, new special_grouping<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 402
  EXPECT_EQ("+100", fmt::format(loc, "{:+L}", 100));
f8deb5b9 Poul Sander 2022-01-15 13:55 403
}
f8deb5b9 Poul Sander 2022-01-15 13:55 404
f8deb5b9 Poul Sander 2022-01-15 13:55 405
TEST(locale_test, wformat) {
f8deb5b9 Poul Sander 2022-01-15 13:55 406
  auto loc = std::locale(std::locale(), new numpunct<wchar_t>());
f8deb5b9 Poul Sander 2022-01-15 13:55 407
  EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 408
  EXPECT_EQ(L"1~234~567", fmt::format(loc, L"{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 409
  using wcontext = fmt::buffer_context<wchar_t>;
f8deb5b9 Poul Sander 2022-01-15 13:55 410
  fmt::format_arg_store<wcontext, int> as{1234567};
f8deb5b9 Poul Sander 2022-01-15 13:55 411
  EXPECT_EQ(L"1~234~567",
f8deb5b9 Poul Sander 2022-01-15 13:55 412
            fmt::vformat(loc, L"{:L}", fmt::basic_format_args<wcontext>(as)));
f8deb5b9 Poul Sander 2022-01-15 13:55 413
  EXPECT_EQ(L"1234567", fmt::format(std::locale("C"), L"{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 414
f8deb5b9 Poul Sander 2022-01-15 13:55 415
  auto no_grouping_loc = std::locale(std::locale(), new no_grouping<wchar_t>());
f8deb5b9 Poul Sander 2022-01-15 13:55 416
  EXPECT_EQ(L"1234567", fmt::format(no_grouping_loc, L"{:L}", 1234567));
f8deb5b9 Poul Sander 2022-01-15 13:55 417
f8deb5b9 Poul Sander 2022-01-15 13:55 418
  auto special_grouping_loc =
f8deb5b9 Poul Sander 2022-01-15 13:55 419
      std::locale(std::locale(), new special_grouping<wchar_t>());
f8deb5b9 Poul Sander 2022-01-15 13:55 420
  EXPECT_EQ(L"1,23,45,678",
f8deb5b9 Poul Sander 2022-01-15 13:55 421
            fmt::format(special_grouping_loc, L"{:L}", 12345678));
f8deb5b9 Poul Sander 2022-01-15 13:55 422
f8deb5b9 Poul Sander 2022-01-15 13:55 423
  auto small_grouping_loc =
f8deb5b9 Poul Sander 2022-01-15 13:55 424
      std::locale(std::locale(), new small_grouping<wchar_t>());
f8deb5b9 Poul Sander 2022-01-15 13:55 425
  EXPECT_EQ(L"4,2,9,4,9,6,7,2,9,5",
f8deb5b9 Poul Sander 2022-01-15 13:55 426
            fmt::format(small_grouping_loc, L"{:L}", max_value<uint32_t>()));
f8deb5b9 Poul Sander 2022-01-15 13:55 427
}
f8deb5b9 Poul Sander 2022-01-15 13:55 428
f8deb5b9 Poul Sander 2022-01-15 13:55 429
TEST(locale_test, double_formatter) {
f8deb5b9 Poul Sander 2022-01-15 13:55 430
  auto loc = std::locale(std::locale(), new special_grouping<char>());
f8deb5b9 Poul Sander 2022-01-15 13:55 431
  auto f = fmt::formatter<int>();
f8deb5b9 Poul Sander 2022-01-15 13:55 432
  auto parse_ctx = fmt::format_parse_context("L");
f8deb5b9 Poul Sander 2022-01-15 13:55 433
  f.parse(parse_ctx);
f8deb5b9 Poul Sander 2022-01-15 13:55 434
  char buf[10] = {};
f8deb5b9 Poul Sander 2022-01-15 13:55 435
  fmt::basic_format_context<char*, char> format_ctx(
f8deb5b9 Poul Sander 2022-01-15 13:55 436
      buf, {}, fmt::detail::locale_ref(loc));
f8deb5b9 Poul Sander 2022-01-15 13:55 437
  *f.format(12345, format_ctx) = 0;
f8deb5b9 Poul Sander 2022-01-15 13:55 438
  EXPECT_STREQ("12,345", buf);
f8deb5b9 Poul Sander 2022-01-15 13:55 439
}
f8deb5b9 Poul Sander 2022-01-15 13:55 440
f8deb5b9 Poul Sander 2022-01-15 13:55 441
FMT_BEGIN_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 442
template <class charT> struct formatter<std::complex<double>, charT> {
f8deb5b9 Poul Sander 2022-01-15 13:55 443
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 444
  detail::dynamic_format_specs<char> specs_;
f8deb5b9 Poul Sander 2022-01-15 13:55 445
f8deb5b9 Poul Sander 2022-01-15 13:55 446
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 447
  FMT_CONSTEXPR typename basic_format_parse_context<charT>::iterator parse(
f8deb5b9 Poul Sander 2022-01-15 13:55 448
      basic_format_parse_context<charT>& ctx) {
f8deb5b9 Poul Sander 2022-01-15 13:55 449
    using handler_type =
f8deb5b9 Poul Sander 2022-01-15 13:55 450
        detail::dynamic_specs_handler<basic_format_parse_context<charT>>;
f8deb5b9 Poul Sander 2022-01-15 13:55 451
    detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
f8deb5b9 Poul Sander 2022-01-15 13:55 452
                                                detail::type::string_type);
f8deb5b9 Poul Sander 2022-01-15 13:55 453
    auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
f8deb5b9 Poul Sander 2022-01-15 13:55 454
    detail::parse_float_type_spec(specs_, ctx.error_handler());
f8deb5b9 Poul Sander 2022-01-15 13:55 455
    return it;
f8deb5b9 Poul Sander 2022-01-15 13:55 456
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 457
f8deb5b9 Poul Sander 2022-01-15 13:55 458
  template <class FormatContext>
f8deb5b9 Poul Sander 2022-01-15 13:55 459
  typename FormatContext::iterator format(const std::complex<double>& c,
f8deb5b9 Poul Sander 2022-01-15 13:55 460
                                          FormatContext& ctx) {
f8deb5b9 Poul Sander 2022-01-15 13:55 461
    detail::handle_dynamic_spec<detail::precision_checker>(
f8deb5b9 Poul Sander 2022-01-15 13:55 462
        specs_.precision, specs_.precision_ref, ctx);
f8deb5b9 Poul Sander 2022-01-15 13:55 463
    auto specs = std::string();
f8deb5b9 Poul Sander 2022-01-15 13:55 464
    if (specs_.precision > 0) specs = fmt::format(".{}", specs_.precision);
f8deb5b9 Poul Sander 2022-01-15 13:55 465
    if (specs_.type == presentation_type::fixed_lower) specs += 'f';
f8deb5b9 Poul Sander 2022-01-15 13:55 466
    auto real = fmt::format(ctx.locale().template get<std::locale>(),
f8deb5b9 Poul Sander 2022-01-15 13:55 467
                            fmt::runtime("{:" + specs + "}"), c.real());
f8deb5b9 Poul Sander 2022-01-15 13:55 468
    auto imag = fmt::format(ctx.locale().template get<std::locale>(),
f8deb5b9 Poul Sander 2022-01-15 13:55 469
                            fmt::runtime("{:" + specs + "}"), c.imag());
f8deb5b9 Poul Sander 2022-01-15 13:55 470
    auto fill_align_width = std::string();
f8deb5b9 Poul Sander 2022-01-15 13:55 471
    if (specs_.width > 0) fill_align_width = fmt::format(">{}", specs_.width);
f8deb5b9 Poul Sander 2022-01-15 13:55 472
    return format_to(ctx.out(), runtime("{:" + fill_align_width + "}"),
f8deb5b9 Poul Sander 2022-01-15 13:55 473
                     c.real() != 0 ? fmt::format("({}+{}i)", real, imag)
f8deb5b9 Poul Sander 2022-01-15 13:55 474
                                   : fmt::format("{}i", imag));
f8deb5b9 Poul Sander 2022-01-15 13:55 475
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 476
};
f8deb5b9 Poul Sander 2022-01-15 13:55 477
FMT_END_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 478
f8deb5b9 Poul Sander 2022-01-15 13:55 479
TEST(locale_test, complex) {
f8deb5b9 Poul Sander 2022-01-15 13:55 480
  std::string s = fmt::format("{}", std::complex<double>(1, 2));
f8deb5b9 Poul Sander 2022-01-15 13:55 481
  EXPECT_EQ(s, "(1+2i)");
f8deb5b9 Poul Sander 2022-01-15 13:55 482
  EXPECT_EQ(fmt::format("{:.2f}", std::complex<double>(1, 2)), "(1.00+2.00i)");
f8deb5b9 Poul Sander 2022-01-15 13:55 483
  EXPECT_EQ(fmt::format("{:8}", std::complex<double>(1, 2)), "  (1+2i)");
f8deb5b9 Poul Sander 2022-01-15 13:55 484
}
f8deb5b9 Poul Sander 2022-01-15 13:55 485
f8deb5b9 Poul Sander 2022-01-15 13:55 486
TEST(locale_test, chrono_weekday) {
f8deb5b9 Poul Sander 2022-01-15 13:55 487
  auto loc = get_locale("ru_RU.UTF-8", "Russian_Russia.1251");
f8deb5b9 Poul Sander 2022-01-15 13:55 488
  auto loc_old = std::locale::global(loc);
f8deb5b9 Poul Sander 2022-01-15 13:55 489
  auto mon = fmt::weekday(1);
f8deb5b9 Poul Sander 2022-01-15 13:55 490
  EXPECT_EQ(fmt::format(L"{}", mon), L"Mon");
f8deb5b9 Poul Sander 2022-01-15 13:55 491
  if (loc != std::locale::classic()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 492
    // {L"\x43F\x43D", L"\x41F\x43D", L"\x43F\x43D\x434", L"\x41F\x43D\x434"}
f8deb5b9 Poul Sander 2022-01-15 13:55 493
    // {L"пн", L"Пн", L"пнд", L"Пнд"}
f8deb5b9 Poul Sander 2022-01-15 13:55 494
    EXPECT_THAT(
f8deb5b9 Poul Sander 2022-01-15 13:55 495
        (std::vector<std::wstring>{L"\x43F\x43D", L"\x41F\x43D",
f8deb5b9 Poul Sander 2022-01-15 13:55 496
                                   L"\x43F\x43D\x434", L"\x41F\x43D\x434"}),
f8deb5b9 Poul Sander 2022-01-15 13:55 497
        Contains(fmt::format(loc, L"{:L}", mon)));
f8deb5b9 Poul Sander 2022-01-15 13:55 498
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 499
  std::locale::global(loc_old);
f8deb5b9 Poul Sander 2022-01-15 13:55 500
}
f8deb5b9 Poul Sander 2022-01-15 13:55 501
f8deb5b9 Poul Sander 2022-01-15 13:55 502
#endif  // FMT_STATIC_THOUSANDS_SEPARATOR
1970-01-01 00:00 503