git repos / blockattack-game

blame: source/misc/embedded_libs/fmt-11.0.2/test/format-impl-test.cc

normal view · raw

47fd5c32 Poul Sander 2024-10-05 08:44 1
// Formatting library for C++ - formatting library implementation tests
47fd5c32 Poul Sander 2024-10-05 08:44 2
//
47fd5c32 Poul Sander 2024-10-05 08:44 3
// Copyright (c) 2012 - present, Victor Zverovich
47fd5c32 Poul Sander 2024-10-05 08:44 4
// All rights reserved.
47fd5c32 Poul Sander 2024-10-05 08:44 5
//
47fd5c32 Poul Sander 2024-10-05 08:44 6
// For the license information refer to format.h.
47fd5c32 Poul Sander 2024-10-05 08:44 7
47fd5c32 Poul Sander 2024-10-05 08:44 8
#include <algorithm>
47fd5c32 Poul Sander 2024-10-05 08:44 9
#include <cstring>
47fd5c32 Poul Sander 2024-10-05 08:44 10
47fd5c32 Poul Sander 2024-10-05 08:44 11
// clang-format off
47fd5c32 Poul Sander 2024-10-05 08:44 12
#include "test-assert.h"
47fd5c32 Poul Sander 2024-10-05 08:44 13
// clang-format on
47fd5c32 Poul Sander 2024-10-05 08:44 14
47fd5c32 Poul Sander 2024-10-05 08:44 15
#include "fmt/format.h"
47fd5c32 Poul Sander 2024-10-05 08:44 16
#include "gmock/gmock.h"
47fd5c32 Poul Sander 2024-10-05 08:44 17
#include "util.h"
47fd5c32 Poul Sander 2024-10-05 08:44 18
47fd5c32 Poul Sander 2024-10-05 08:44 19
using fmt::detail::bigint;
47fd5c32 Poul Sander 2024-10-05 08:44 20
using fmt::detail::fp;
47fd5c32 Poul Sander 2024-10-05 08:44 21
using fmt::detail::max_value;
47fd5c32 Poul Sander 2024-10-05 08:44 22
47fd5c32 Poul Sander 2024-10-05 08:44 23
static_assert(!std::is_copy_constructible<bigint>::value, "");
47fd5c32 Poul Sander 2024-10-05 08:44 24
static_assert(!std::is_copy_assignable<bigint>::value, "");
47fd5c32 Poul Sander 2024-10-05 08:44 25
47fd5c32 Poul Sander 2024-10-05 08:44 26
TEST(bigint_test, construct) {
47fd5c32 Poul Sander 2024-10-05 08:44 27
  EXPECT_EQ(fmt::to_string(bigint()), "");
47fd5c32 Poul Sander 2024-10-05 08:44 28
  EXPECT_EQ(fmt::to_string(bigint(0x42)), "42");
47fd5c32 Poul Sander 2024-10-05 08:44 29
  EXPECT_EQ(fmt::to_string(bigint(0x123456789abcedf0)), "123456789abcedf0");
47fd5c32 Poul Sander 2024-10-05 08:44 30
}
47fd5c32 Poul Sander 2024-10-05 08:44 31
47fd5c32 Poul Sander 2024-10-05 08:44 32
TEST(bigint_test, compare) {
47fd5c32 Poul Sander 2024-10-05 08:44 33
  bigint n1(42);
47fd5c32 Poul Sander 2024-10-05 08:44 34
  bigint n2(42);
47fd5c32 Poul Sander 2024-10-05 08:44 35
  EXPECT_EQ(compare(n1, n2), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 36
  n2 <<= 32;
47fd5c32 Poul Sander 2024-10-05 08:44 37
  EXPECT_LT(compare(n1, n2), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 38
  bigint n3(43);
47fd5c32 Poul Sander 2024-10-05 08:44 39
  EXPECT_LT(compare(n1, n3), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 40
  EXPECT_GT(compare(n3, n1), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 41
  bigint n4(42 * 0x100000001);
47fd5c32 Poul Sander 2024-10-05 08:44 42
  EXPECT_LT(compare(n2, n4), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 43
  EXPECT_GT(compare(n4, n2), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 44
}
47fd5c32 Poul Sander 2024-10-05 08:44 45
47fd5c32 Poul Sander 2024-10-05 08:44 46
TEST(bigint_test, add_compare) {
47fd5c32 Poul Sander 2024-10-05 08:44 47
  EXPECT_LT(
47fd5c32 Poul Sander 2024-10-05 08:44 48
      add_compare(bigint(0xffffffff), bigint(0xffffffff), bigint(1) <<= 64), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 49
  EXPECT_LT(add_compare(bigint(1) <<= 32, bigint(1), bigint(1) <<= 96), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 50
  EXPECT_GT(add_compare(bigint(1) <<= 32, bigint(0), bigint(0xffffffff)), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 51
  EXPECT_GT(add_compare(bigint(0), bigint(1) <<= 32, bigint(0xffffffff)), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 52
  EXPECT_GT(add_compare(bigint(42), bigint(1), bigint(42)), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 53
  EXPECT_GT(add_compare(bigint(0xffffffff), bigint(1), bigint(0xffffffff)), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 54
  EXPECT_LT(add_compare(bigint(10), bigint(10), bigint(22)), 0);
47fd5c32 Poul Sander 2024-10-05 08:44 55
  EXPECT_LT(add_compare(bigint(0x100000010), bigint(0x100000010),
47fd5c32 Poul Sander 2024-10-05 08:44 56
                        bigint(0x300000010)),
47fd5c32 Poul Sander 2024-10-05 08:44 57
            0);
47fd5c32 Poul Sander 2024-10-05 08:44 58
  EXPECT_GT(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
47fd5c32 Poul Sander 2024-10-05 08:44 59
                        bigint(0x300000000)),
47fd5c32 Poul Sander 2024-10-05 08:44 60
            0);
47fd5c32 Poul Sander 2024-10-05 08:44 61
  EXPECT_EQ(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
47fd5c32 Poul Sander 2024-10-05 08:44 62
                        bigint(0x300000001)),
47fd5c32 Poul Sander 2024-10-05 08:44 63
            0);
47fd5c32 Poul Sander 2024-10-05 08:44 64
  EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
47fd5c32 Poul Sander 2024-10-05 08:44 65
                        bigint(0x300000002)),
47fd5c32 Poul Sander 2024-10-05 08:44 66
            0);
47fd5c32 Poul Sander 2024-10-05 08:44 67
  EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
47fd5c32 Poul Sander 2024-10-05 08:44 68
                        bigint(0x300000003)),
47fd5c32 Poul Sander 2024-10-05 08:44 69
            0);
47fd5c32 Poul Sander 2024-10-05 08:44 70
}
47fd5c32 Poul Sander 2024-10-05 08:44 71
47fd5c32 Poul Sander 2024-10-05 08:44 72
TEST(bigint_test, shift_left) {
47fd5c32 Poul Sander 2024-10-05 08:44 73
  bigint n(0x42);
47fd5c32 Poul Sander 2024-10-05 08:44 74
  n <<= 0;
47fd5c32 Poul Sander 2024-10-05 08:44 75
  EXPECT_EQ(fmt::to_string(n), "42");
47fd5c32 Poul Sander 2024-10-05 08:44 76
  n <<= 1;
47fd5c32 Poul Sander 2024-10-05 08:44 77
  EXPECT_EQ(fmt::to_string(n), "84");
47fd5c32 Poul Sander 2024-10-05 08:44 78
  n <<= 25;
47fd5c32 Poul Sander 2024-10-05 08:44 79
  EXPECT_EQ(fmt::to_string(n), "108000000");
47fd5c32 Poul Sander 2024-10-05 08:44 80
}
47fd5c32 Poul Sander 2024-10-05 08:44 81
47fd5c32 Poul Sander 2024-10-05 08:44 82
TEST(bigint_test, multiply) {
47fd5c32 Poul Sander 2024-10-05 08:44 83
  bigint n(0x42);
47fd5c32 Poul Sander 2024-10-05 08:44 84
  EXPECT_THROW(n *= 0, assertion_failure);
47fd5c32 Poul Sander 2024-10-05 08:44 85
  n *= 1;
47fd5c32 Poul Sander 2024-10-05 08:44 86
  EXPECT_EQ(fmt::to_string(n), "42");
47fd5c32 Poul Sander 2024-10-05 08:44 87
47fd5c32 Poul Sander 2024-10-05 08:44 88
  n *= 2;
47fd5c32 Poul Sander 2024-10-05 08:44 89
  EXPECT_EQ(fmt::to_string(n), "84");
47fd5c32 Poul Sander 2024-10-05 08:44 90
  n *= 0x12345678;
47fd5c32 Poul Sander 2024-10-05 08:44 91
  EXPECT_EQ(fmt::to_string(n), "962fc95e0");
47fd5c32 Poul Sander 2024-10-05 08:44 92
47fd5c32 Poul Sander 2024-10-05 08:44 93
  bigint bigmax(max_value<uint32_t>());
47fd5c32 Poul Sander 2024-10-05 08:44 94
  bigmax *= max_value<uint32_t>();
47fd5c32 Poul Sander 2024-10-05 08:44 95
  EXPECT_EQ(fmt::to_string(bigmax), "fffffffe00000001");
47fd5c32 Poul Sander 2024-10-05 08:44 96
47fd5c32 Poul Sander 2024-10-05 08:44 97
  const auto max64 = max_value<uint64_t>();
47fd5c32 Poul Sander 2024-10-05 08:44 98
  bigmax = max64;
47fd5c32 Poul Sander 2024-10-05 08:44 99
  bigmax *= max64;
47fd5c32 Poul Sander 2024-10-05 08:44 100
  EXPECT_EQ(fmt::to_string(bigmax), "fffffffffffffffe0000000000000001");
47fd5c32 Poul Sander 2024-10-05 08:44 101
47fd5c32 Poul Sander 2024-10-05 08:44 102
  const auto max128 = (fmt::detail::uint128_t(max64) << 64) | max64;
47fd5c32 Poul Sander 2024-10-05 08:44 103
  bigmax = max128;
47fd5c32 Poul Sander 2024-10-05 08:44 104
  bigmax *= max128;
47fd5c32 Poul Sander 2024-10-05 08:44 105
  EXPECT_EQ(fmt::to_string(bigmax),
47fd5c32 Poul Sander 2024-10-05 08:44 106
            "fffffffffffffffffffffffffffffffe00000000000000000000000000000001");
47fd5c32 Poul Sander 2024-10-05 08:44 107
}
47fd5c32 Poul Sander 2024-10-05 08:44 108
47fd5c32 Poul Sander 2024-10-05 08:44 109
TEST(bigint_test, square) {
47fd5c32 Poul Sander 2024-10-05 08:44 110
  bigint n0(0);
47fd5c32 Poul Sander 2024-10-05 08:44 111
  n0.square();
47fd5c32 Poul Sander 2024-10-05 08:44 112
  EXPECT_EQ(fmt::to_string(n0), "0");
47fd5c32 Poul Sander 2024-10-05 08:44 113
  bigint n1(0x100);
47fd5c32 Poul Sander 2024-10-05 08:44 114
  n1.square();
47fd5c32 Poul Sander 2024-10-05 08:44 115
  EXPECT_EQ(fmt::to_string(n1), "10000");
47fd5c32 Poul Sander 2024-10-05 08:44 116
  bigint n2(0xfffffffff);
47fd5c32 Poul Sander 2024-10-05 08:44 117
  n2.square();
47fd5c32 Poul Sander 2024-10-05 08:44 118
  EXPECT_EQ(fmt::to_string(n2), "ffffffffe000000001");
47fd5c32 Poul Sander 2024-10-05 08:44 119
  bigint n3(max_value<uint64_t>());
47fd5c32 Poul Sander 2024-10-05 08:44 120
  n3.square();
47fd5c32 Poul Sander 2024-10-05 08:44 121
  EXPECT_EQ(fmt::to_string(n3), "fffffffffffffffe0000000000000001");
47fd5c32 Poul Sander 2024-10-05 08:44 122
  bigint n4;
47fd5c32 Poul Sander 2024-10-05 08:44 123
  n4.assign_pow10(10);
47fd5c32 Poul Sander 2024-10-05 08:44 124
  EXPECT_EQ(fmt::to_string(n4), "2540be400");
47fd5c32 Poul Sander 2024-10-05 08:44 125
}
47fd5c32 Poul Sander 2024-10-05 08:44 126
47fd5c32 Poul Sander 2024-10-05 08:44 127
TEST(bigint_test, divmod_assign_zero_divisor) {
47fd5c32 Poul Sander 2024-10-05 08:44 128
  bigint zero(0);
47fd5c32 Poul Sander 2024-10-05 08:44 129
  EXPECT_THROW(bigint(0).divmod_assign(zero), assertion_failure);
47fd5c32 Poul Sander 2024-10-05 08:44 130
  EXPECT_THROW(bigint(42).divmod_assign(zero), assertion_failure);
47fd5c32 Poul Sander 2024-10-05 08:44 131
}
47fd5c32 Poul Sander 2024-10-05 08:44 132
47fd5c32 Poul Sander 2024-10-05 08:44 133
TEST(bigint_test, divmod_assign_self) {
47fd5c32 Poul Sander 2024-10-05 08:44 134
  bigint n(100);
47fd5c32 Poul Sander 2024-10-05 08:44 135
  EXPECT_THROW(n.divmod_assign(n), assertion_failure);
47fd5c32 Poul Sander 2024-10-05 08:44 136
}
47fd5c32 Poul Sander 2024-10-05 08:44 137
47fd5c32 Poul Sander 2024-10-05 08:44 138
TEST(bigint_test, divmod_assign_unaligned) {
47fd5c32 Poul Sander 2024-10-05 08:44 139
  // (42 << 340) / pow(10, 100):
47fd5c32 Poul Sander 2024-10-05 08:44 140
  bigint n1(42);
47fd5c32 Poul Sander 2024-10-05 08:44 141
  n1 <<= 340;
47fd5c32 Poul Sander 2024-10-05 08:44 142
  bigint n2;
47fd5c32 Poul Sander 2024-10-05 08:44 143
  n2.assign_pow10(100);
47fd5c32 Poul Sander 2024-10-05 08:44 144
  int result = n1.divmod_assign(n2);
47fd5c32 Poul Sander 2024-10-05 08:44 145
  EXPECT_EQ(result, 9406);
47fd5c32 Poul Sander 2024-10-05 08:44 146
  EXPECT_EQ(fmt::to_string(n1),
47fd5c32 Poul Sander 2024-10-05 08:44 147
            "10f8353019583bfc29ffc8f564e1b9f9d819dbb4cf783e4507eca1539220p96");
47fd5c32 Poul Sander 2024-10-05 08:44 148
}
47fd5c32 Poul Sander 2024-10-05 08:44 149
47fd5c32 Poul Sander 2024-10-05 08:44 150
TEST(bigint_test, divmod_assign) {
47fd5c32 Poul Sander 2024-10-05 08:44 151
  // 100 / 10:
47fd5c32 Poul Sander 2024-10-05 08:44 152
  bigint n1(100);
47fd5c32 Poul Sander 2024-10-05 08:44 153
  int result = n1.divmod_assign(bigint(10));
47fd5c32 Poul Sander 2024-10-05 08:44 154
  EXPECT_EQ(result, 10);
47fd5c32 Poul Sander 2024-10-05 08:44 155
  EXPECT_EQ(fmt::to_string(n1), "0");
47fd5c32 Poul Sander 2024-10-05 08:44 156
  // pow(10, 100) / (42 << 320):
47fd5c32 Poul Sander 2024-10-05 08:44 157
  n1.assign_pow10(100);
47fd5c32 Poul Sander 2024-10-05 08:44 158
  result = n1.divmod_assign(bigint(42) <<= 320);
47fd5c32 Poul Sander 2024-10-05 08:44 159
  EXPECT_EQ(result, 111);
47fd5c32 Poul Sander 2024-10-05 08:44 160
  EXPECT_EQ(fmt::to_string(n1),
47fd5c32 Poul Sander 2024-10-05 08:44 161
            "13ad2594c37ceb0b2784c4ce0bf38ace408e211a7caab24308a82e8f10p96");
47fd5c32 Poul Sander 2024-10-05 08:44 162
  // 42 / 100:
47fd5c32 Poul Sander 2024-10-05 08:44 163
  bigint n2(42);
47fd5c32 Poul Sander 2024-10-05 08:44 164
  n1.assign_pow10(2);
47fd5c32 Poul Sander 2024-10-05 08:44 165
  result = n2.divmod_assign(n1);
47fd5c32 Poul Sander 2024-10-05 08:44 166
  EXPECT_EQ(result, 0);
47fd5c32 Poul Sander 2024-10-05 08:44 167
  EXPECT_EQ(fmt::to_string(n2), "2a");
47fd5c32 Poul Sander 2024-10-05 08:44 168
}
47fd5c32 Poul Sander 2024-10-05 08:44 169
47fd5c32 Poul Sander 2024-10-05 08:44 170
template <bool is_iec559> void run_double_tests() {
47fd5c32 Poul Sander 2024-10-05 08:44 171
  fmt::print("warning: double is not IEC559, skipping FP tests\n");
47fd5c32 Poul Sander 2024-10-05 08:44 172
}
47fd5c32 Poul Sander 2024-10-05 08:44 173
47fd5c32 Poul Sander 2024-10-05 08:44 174
template <> void run_double_tests<true>() {
47fd5c32 Poul Sander 2024-10-05 08:44 175
  // Construct from double.
47fd5c32 Poul Sander 2024-10-05 08:44 176
  EXPECT_EQ(fp(1.23), fp(0x13ae147ae147aeu, -52));
47fd5c32 Poul Sander 2024-10-05 08:44 177
}
47fd5c32 Poul Sander 2024-10-05 08:44 178
47fd5c32 Poul Sander 2024-10-05 08:44 179
TEST(fp_test, double_tests) {
47fd5c32 Poul Sander 2024-10-05 08:44 180
  run_double_tests<std::numeric_limits<double>::is_iec559>();
47fd5c32 Poul Sander 2024-10-05 08:44 181
}
47fd5c32 Poul Sander 2024-10-05 08:44 182
47fd5c32 Poul Sander 2024-10-05 08:44 183
TEST(fp_test, normalize) {
47fd5c32 Poul Sander 2024-10-05 08:44 184
  const auto v = fp(0xbeef, 42);
47fd5c32 Poul Sander 2024-10-05 08:44 185
  auto normalized = normalize(v);
47fd5c32 Poul Sander 2024-10-05 08:44 186
  EXPECT_EQ(normalized.f, 0xbeef000000000000);
47fd5c32 Poul Sander 2024-10-05 08:44 187
  EXPECT_EQ(normalized.e, -6);
47fd5c32 Poul Sander 2024-10-05 08:44 188
}
47fd5c32 Poul Sander 2024-10-05 08:44 189
47fd5c32 Poul Sander 2024-10-05 08:44 190
TEST(fp_test, multiply) {
47fd5c32 Poul Sander 2024-10-05 08:44 191
  auto v = fp(123ULL << 32, 4) * fp(56ULL << 32, 7);
47fd5c32 Poul Sander 2024-10-05 08:44 192
  EXPECT_EQ(v.f, 123u * 56u);
47fd5c32 Poul Sander 2024-10-05 08:44 193
  EXPECT_EQ(v.e, 4 + 7 + 64);
47fd5c32 Poul Sander 2024-10-05 08:44 194
  v = fp(123ULL << 32, 4) * fp(567ULL << 31, 8);
47fd5c32 Poul Sander 2024-10-05 08:44 195
  EXPECT_EQ(v.f, (123 * 567 + 1u) / 2);
47fd5c32 Poul Sander 2024-10-05 08:44 196
  EXPECT_EQ(v.e, 4 + 8 + 64);
47fd5c32 Poul Sander 2024-10-05 08:44 197
}
47fd5c32 Poul Sander 2024-10-05 08:44 198
47fd5c32 Poul Sander 2024-10-05 08:44 199
TEST(fp_test, dragonbox_max_k) {
47fd5c32 Poul Sander 2024-10-05 08:44 200
  using fmt::detail::dragonbox::floor_log10_pow2;
47fd5c32 Poul Sander 2024-10-05 08:44 201
  using float_info = fmt::detail::dragonbox::float_info<float>;
47fd5c32 Poul Sander 2024-10-05 08:44 202
  EXPECT_EQ(
47fd5c32 Poul Sander 2024-10-05 08:44 203
      fmt::detail::const_check(float_info::max_k),
47fd5c32 Poul Sander 2024-10-05 08:44 204
      float_info::kappa -
47fd5c32 Poul Sander 2024-10-05 08:44 205
          floor_log10_pow2(std::numeric_limits<float>::min_exponent -
47fd5c32 Poul Sander 2024-10-05 08:44 206
                           fmt::detail::num_significand_bits<float>() - 1));
47fd5c32 Poul Sander 2024-10-05 08:44 207
  using double_info = fmt::detail::dragonbox::float_info<double>;
47fd5c32 Poul Sander 2024-10-05 08:44 208
  EXPECT_EQ(fmt::detail::const_check(double_info::max_k),
47fd5c32 Poul Sander 2024-10-05 08:44 209
            double_info::kappa -
47fd5c32 Poul Sander 2024-10-05 08:44 210
                floor_log10_pow2(
47fd5c32 Poul Sander 2024-10-05 08:44 211
                    std::numeric_limits<double>::min_exponent -
47fd5c32 Poul Sander 2024-10-05 08:44 212
                    2 * fmt::detail::num_significand_bits<double>() - 1));
47fd5c32 Poul Sander 2024-10-05 08:44 213
}
47fd5c32 Poul Sander 2024-10-05 08:44 214
47fd5c32 Poul Sander 2024-10-05 08:44 215
TEST(format_impl_test, format_error_code) {
47fd5c32 Poul Sander 2024-10-05 08:44 216
  std::string msg = "error 42", sep = ": ";
47fd5c32 Poul Sander 2024-10-05 08:44 217
  {
47fd5c32 Poul Sander 2024-10-05 08:44 218
    auto buffer = fmt::memory_buffer();
47fd5c32 Poul Sander 2024-10-05 08:44 219
    fmt::format_to(fmt::appender(buffer), "garbage");
47fd5c32 Poul Sander 2024-10-05 08:44 220
    fmt::detail::format_error_code(buffer, 42, "test");
47fd5c32 Poul Sander 2024-10-05 08:44 221
    EXPECT_EQ(to_string(buffer), "test: " + msg);
47fd5c32 Poul Sander 2024-10-05 08:44 222
  }
47fd5c32 Poul Sander 2024-10-05 08:44 223
  {
47fd5c32 Poul Sander 2024-10-05 08:44 224
    auto buffer = fmt::memory_buffer();
47fd5c32 Poul Sander 2024-10-05 08:44 225
    auto prefix =
47fd5c32 Poul Sander 2024-10-05 08:44 226
        std::string(fmt::inline_buffer_size - msg.size() - sep.size() + 1, 'x');
47fd5c32 Poul Sander 2024-10-05 08:44 227
    fmt::detail::format_error_code(buffer, 42, prefix);
47fd5c32 Poul Sander 2024-10-05 08:44 228
    EXPECT_EQ(msg, to_string(buffer));
47fd5c32 Poul Sander 2024-10-05 08:44 229
  }
47fd5c32 Poul Sander 2024-10-05 08:44 230
  int codes[] = {42, -1};
47fd5c32 Poul Sander 2024-10-05 08:44 231
  for (size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) {
47fd5c32 Poul Sander 2024-10-05 08:44 232
    // Test maximum buffer size.
47fd5c32 Poul Sander 2024-10-05 08:44 233
    msg = fmt::format("error {}", codes[i]);
47fd5c32 Poul Sander 2024-10-05 08:44 234
    fmt::memory_buffer buffer;
47fd5c32 Poul Sander 2024-10-05 08:44 235
    auto prefix =
47fd5c32 Poul Sander 2024-10-05 08:44 236
        std::string(fmt::inline_buffer_size - msg.size() - sep.size(), 'x');
47fd5c32 Poul Sander 2024-10-05 08:44 237
    fmt::detail::format_error_code(buffer, codes[i], prefix);
47fd5c32 Poul Sander 2024-10-05 08:44 238
    EXPECT_EQ(prefix + sep + msg, to_string(buffer));
47fd5c32 Poul Sander 2024-10-05 08:44 239
    size_t size = fmt::inline_buffer_size;
47fd5c32 Poul Sander 2024-10-05 08:44 240
    EXPECT_EQ(size, buffer.size());
47fd5c32 Poul Sander 2024-10-05 08:44 241
    buffer.resize(0);
47fd5c32 Poul Sander 2024-10-05 08:44 242
    // Test with a message that doesn't fit into the buffer.
47fd5c32 Poul Sander 2024-10-05 08:44 243
    prefix += 'x';
47fd5c32 Poul Sander 2024-10-05 08:44 244
    fmt::detail::format_error_code(buffer, codes[i], prefix);
47fd5c32 Poul Sander 2024-10-05 08:44 245
    EXPECT_EQ(to_string(buffer), msg);
47fd5c32 Poul Sander 2024-10-05 08:44 246
  }
47fd5c32 Poul Sander 2024-10-05 08:44 247
}
47fd5c32 Poul Sander 2024-10-05 08:44 248
47fd5c32 Poul Sander 2024-10-05 08:44 249
// Tests fmt::detail::count_digits for integer type Int.
47fd5c32 Poul Sander 2024-10-05 08:44 250
template <typename Int> void test_count_digits() {
47fd5c32 Poul Sander 2024-10-05 08:44 251
  for (Int i = 0; i < 10; ++i) EXPECT_EQ(1u, fmt::detail::count_digits(i));
47fd5c32 Poul Sander 2024-10-05 08:44 252
  for (Int i = 1, n = 1, end = max_value<Int>() / 10; n <= end; ++i) {
47fd5c32 Poul Sander 2024-10-05 08:44 253
    n *= 10;
47fd5c32 Poul Sander 2024-10-05 08:44 254
    EXPECT_EQ(fmt::detail::count_digits(n - 1), i);
47fd5c32 Poul Sander 2024-10-05 08:44 255
    EXPECT_EQ(fmt::detail::count_digits(n), i + 1);
47fd5c32 Poul Sander 2024-10-05 08:44 256
  }
47fd5c32 Poul Sander 2024-10-05 08:44 257
}
47fd5c32 Poul Sander 2024-10-05 08:44 258
47fd5c32 Poul Sander 2024-10-05 08:44 259
TEST(format_impl_test, count_digits) {
47fd5c32 Poul Sander 2024-10-05 08:44 260
  test_count_digits<uint32_t>();
47fd5c32 Poul Sander 2024-10-05 08:44 261
  test_count_digits<uint64_t>();
47fd5c32 Poul Sander 2024-10-05 08:44 262
}
47fd5c32 Poul Sander 2024-10-05 08:44 263
47fd5c32 Poul Sander 2024-10-05 08:44 264
TEST(format_impl_test, countl_zero) {
47fd5c32 Poul Sander 2024-10-05 08:44 265
  constexpr auto num_bits = fmt::detail::num_bits<uint32_t>();
47fd5c32 Poul Sander 2024-10-05 08:44 266
  uint32_t n = 1u;
47fd5c32 Poul Sander 2024-10-05 08:44 267
  for (int i = 1; i < num_bits - 1; i++) {
47fd5c32 Poul Sander 2024-10-05 08:44 268
    n <<= 1;
47fd5c32 Poul Sander 2024-10-05 08:44 269
    EXPECT_EQ(fmt::detail::countl_zero(n - 1), num_bits - i);
47fd5c32 Poul Sander 2024-10-05 08:44 270
    EXPECT_EQ(fmt::detail::countl_zero(n), num_bits - i - 1);
47fd5c32 Poul Sander 2024-10-05 08:44 271
  }
47fd5c32 Poul Sander 2024-10-05 08:44 272
}
47fd5c32 Poul Sander 2024-10-05 08:44 273
47fd5c32 Poul Sander 2024-10-05 08:44 274
#if FMT_USE_FLOAT128
47fd5c32 Poul Sander 2024-10-05 08:44 275
TEST(format_impl_test, write_float128) {
47fd5c32 Poul Sander 2024-10-05 08:44 276
  auto s = std::string();
47fd5c32 Poul Sander 2024-10-05 08:44 277
  fmt::detail::write<char>(std::back_inserter(s), __float128(42));
47fd5c32 Poul Sander 2024-10-05 08:44 278
  EXPECT_EQ(s, "42");
47fd5c32 Poul Sander 2024-10-05 08:44 279
}
47fd5c32 Poul Sander 2024-10-05 08:44 280
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 281
47fd5c32 Poul Sander 2024-10-05 08:44 282
struct double_double {
47fd5c32 Poul Sander 2024-10-05 08:44 283
  double a;
47fd5c32 Poul Sander 2024-10-05 08:44 284
  double b;
47fd5c32 Poul Sander 2024-10-05 08:44 285
47fd5c32 Poul Sander 2024-10-05 08:44 286
  explicit constexpr double_double(double a_val = 0, double b_val = 0)
47fd5c32 Poul Sander 2024-10-05 08:44 287
      : a(a_val), b(b_val) {}
47fd5c32 Poul Sander 2024-10-05 08:44 288
47fd5c32 Poul Sander 2024-10-05 08:44 289
  operator double() const { return a + b; }
47fd5c32 Poul Sander 2024-10-05 08:44 290
  auto operator-() const -> double_double { return double_double(-a, -b); }
47fd5c32 Poul Sander 2024-10-05 08:44 291
};
47fd5c32 Poul Sander 2024-10-05 08:44 292
47fd5c32 Poul Sander 2024-10-05 08:44 293
auto format_as(double_double d) -> double { return d; }
47fd5c32 Poul Sander 2024-10-05 08:44 294
47fd5c32 Poul Sander 2024-10-05 08:44 295
bool operator>=(const double_double& lhs, const double_double& rhs) {
47fd5c32 Poul Sander 2024-10-05 08:44 296
  return lhs.a + lhs.b >= rhs.a + rhs.b;
47fd5c32 Poul Sander 2024-10-05 08:44 297
}
47fd5c32 Poul Sander 2024-10-05 08:44 298
47fd5c32 Poul Sander 2024-10-05 08:44 299
struct slow_float {
47fd5c32 Poul Sander 2024-10-05 08:44 300
  float value;
47fd5c32 Poul Sander 2024-10-05 08:44 301
47fd5c32 Poul Sander 2024-10-05 08:44 302
  explicit constexpr slow_float(float val = 0) : value(val) {}
47fd5c32 Poul Sander 2024-10-05 08:44 303
  operator float() const { return value; }
47fd5c32 Poul Sander 2024-10-05 08:44 304
  auto operator-() const -> slow_float { return slow_float(-value); }
47fd5c32 Poul Sander 2024-10-05 08:44 305
};
47fd5c32 Poul Sander 2024-10-05 08:44 306
47fd5c32 Poul Sander 2024-10-05 08:44 307
auto format_as(slow_float f) -> float { return f; }
47fd5c32 Poul Sander 2024-10-05 08:44 308
47fd5c32 Poul Sander 2024-10-05 08:44 309
namespace std {
47fd5c32 Poul Sander 2024-10-05 08:44 310
template <> struct is_floating_point<double_double> : std::true_type {};
47fd5c32 Poul Sander 2024-10-05 08:44 311
template <> struct numeric_limits<double_double> {
47fd5c32 Poul Sander 2024-10-05 08:44 312
  // is_iec559 is true for double-double in libstdc++.
47fd5c32 Poul Sander 2024-10-05 08:44 313
  static constexpr bool is_iec559 = true;
47fd5c32 Poul Sander 2024-10-05 08:44 314
  static constexpr int digits = 106;
47fd5c32 Poul Sander 2024-10-05 08:44 315
};
47fd5c32 Poul Sander 2024-10-05 08:44 316
47fd5c32 Poul Sander 2024-10-05 08:44 317
template <> struct is_floating_point<slow_float> : std::true_type {};
47fd5c32 Poul Sander 2024-10-05 08:44 318
template <> struct numeric_limits<slow_float> : numeric_limits<float> {};
47fd5c32 Poul Sander 2024-10-05 08:44 319
}  // namespace std
47fd5c32 Poul Sander 2024-10-05 08:44 320
47fd5c32 Poul Sander 2024-10-05 08:44 321
FMT_BEGIN_NAMESPACE
47fd5c32 Poul Sander 2024-10-05 08:44 322
namespace detail {
47fd5c32 Poul Sander 2024-10-05 08:44 323
template <> struct is_fast_float<slow_float> : std::false_type {};
47fd5c32 Poul Sander 2024-10-05 08:44 324
namespace dragonbox {
47fd5c32 Poul Sander 2024-10-05 08:44 325
template <> struct float_info<slow_float> {
47fd5c32 Poul Sander 2024-10-05 08:44 326
  using carrier_uint = uint32_t;
47fd5c32 Poul Sander 2024-10-05 08:44 327
  static const int exponent_bits = 8;
47fd5c32 Poul Sander 2024-10-05 08:44 328
};
47fd5c32 Poul Sander 2024-10-05 08:44 329
}  // namespace dragonbox
47fd5c32 Poul Sander 2024-10-05 08:44 330
}  // namespace detail
47fd5c32 Poul Sander 2024-10-05 08:44 331
FMT_END_NAMESPACE
47fd5c32 Poul Sander 2024-10-05 08:44 332
47fd5c32 Poul Sander 2024-10-05 08:44 333
TEST(format_impl_test, write_double_double) {
47fd5c32 Poul Sander 2024-10-05 08:44 334
  auto s = std::string();
47fd5c32 Poul Sander 2024-10-05 08:44 335
  fmt::detail::write<char>(std::back_inserter(s), double_double(42), {});
47fd5c32 Poul Sander 2024-10-05 08:44 336
  // Specializing is_floating_point is broken in MSVC.
47fd5c32 Poul Sander 2024-10-05 08:44 337
  if (!FMT_MSC_VERSION) EXPECT_EQ(s, "42");
47fd5c32 Poul Sander 2024-10-05 08:44 338
}
47fd5c32 Poul Sander 2024-10-05 08:44 339
47fd5c32 Poul Sander 2024-10-05 08:44 340
TEST(format_impl_test, write_dragon_even) {
47fd5c32 Poul Sander 2024-10-05 08:44 341
  auto s = std::string();
47fd5c32 Poul Sander 2024-10-05 08:44 342
  fmt::detail::write<char>(std::back_inserter(s), slow_float(33554450.0f), {});
47fd5c32 Poul Sander 2024-10-05 08:44 343
  // Specializing is_floating_point is broken in MSVC.
47fd5c32 Poul Sander 2024-10-05 08:44 344
  if (!FMT_MSC_VERSION) EXPECT_EQ(s, "33554450");
47fd5c32 Poul Sander 2024-10-05 08:44 345
}
47fd5c32 Poul Sander 2024-10-05 08:44 346
47fd5c32 Poul Sander 2024-10-05 08:44 347
#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)
47fd5c32 Poul Sander 2024-10-05 08:44 348
#  include <windows.h>
47fd5c32 Poul Sander 2024-10-05 08:44 349
47fd5c32 Poul Sander 2024-10-05 08:44 350
TEST(format_impl_test, write_console_signature) {
47fd5c32 Poul Sander 2024-10-05 08:44 351
  decltype(::WriteConsoleW)* p = fmt::detail::WriteConsoleW;
47fd5c32 Poul Sander 2024-10-05 08:44 352
  (void)p;
47fd5c32 Poul Sander 2024-10-05 08:44 353
}
47fd5c32 Poul Sander 2024-10-05 08:44 354
#endif
47fd5c32 Poul Sander 2024-10-05 08:44 355
47fd5c32 Poul Sander 2024-10-05 08:44 356
// A public domain branchless UTF-8 decoder by Christopher Wellons:
47fd5c32 Poul Sander 2024-10-05 08:44 357
// https://github.com/skeeto/branchless-utf8
47fd5c32 Poul Sander 2024-10-05 08:44 358
constexpr bool unicode_is_surrogate(uint32_t c) {
47fd5c32 Poul Sander 2024-10-05 08:44 359
  return c >= 0xD800U && c <= 0xDFFFU;
47fd5c32 Poul Sander 2024-10-05 08:44 360
}
47fd5c32 Poul Sander 2024-10-05 08:44 361
47fd5c32 Poul Sander 2024-10-05 08:44 362
FMT_CONSTEXPR char* utf8_encode(char* s, uint32_t c) {
47fd5c32 Poul Sander 2024-10-05 08:44 363
  if (c >= (1UL << 16)) {
47fd5c32 Poul Sander 2024-10-05 08:44 364
    s[0] = static_cast<char>(0xf0 | (c >> 18));
47fd5c32 Poul Sander 2024-10-05 08:44 365
    s[1] = static_cast<char>(0x80 | ((c >> 12) & 0x3f));
47fd5c32 Poul Sander 2024-10-05 08:44 366
    s[2] = static_cast<char>(0x80 | ((c >> 6) & 0x3f));
47fd5c32 Poul Sander 2024-10-05 08:44 367
    s[3] = static_cast<char>(0x80 | ((c >> 0) & 0x3f));
47fd5c32 Poul Sander 2024-10-05 08:44 368
    return s + 4;
47fd5c32 Poul Sander 2024-10-05 08:44 369
  } else if (c >= (1UL << 11)) {
47fd5c32 Poul Sander 2024-10-05 08:44 370
    s[0] = static_cast<char>(0xe0 | (c >> 12));
47fd5c32 Poul Sander 2024-10-05 08:44 371
    s[1] = static_cast<char>(0x80 | ((c >> 6) & 0x3f));
47fd5c32 Poul Sander 2024-10-05 08:44 372
    s[2] = static_cast<char>(0x80 | ((c >> 0) & 0x3f));
47fd5c32 Poul Sander 2024-10-05 08:44 373
    return s + 3;
47fd5c32 Poul Sander 2024-10-05 08:44 374
  } else if (c >= (1UL << 7)) {
47fd5c32 Poul Sander 2024-10-05 08:44 375
    s[0] = static_cast<char>(0xc0 | (c >> 6));
47fd5c32 Poul Sander 2024-10-05 08:44 376
    s[1] = static_cast<char>(0x80 | ((c >> 0) & 0x3f));
47fd5c32 Poul Sander 2024-10-05 08:44 377
    return s + 2;
47fd5c32 Poul Sander 2024-10-05 08:44 378
  } else {
47fd5c32 Poul Sander 2024-10-05 08:44 379
    s[0] = static_cast<char>(c);
47fd5c32 Poul Sander 2024-10-05 08:44 380
    return s + 1;
47fd5c32 Poul Sander 2024-10-05 08:44 381
  }
47fd5c32 Poul Sander 2024-10-05 08:44 382
}
47fd5c32 Poul Sander 2024-10-05 08:44 383
47fd5c32 Poul Sander 2024-10-05 08:44 384
// Make sure it can decode every character
47fd5c32 Poul Sander 2024-10-05 08:44 385
TEST(format_impl_test, utf8_decode_decode_all) {
47fd5c32 Poul Sander 2024-10-05 08:44 386
  for (uint32_t i = 0; i < 0x10ffff; i++) {
47fd5c32 Poul Sander 2024-10-05 08:44 387
    if (!unicode_is_surrogate(i)) {
47fd5c32 Poul Sander 2024-10-05 08:44 388
      int e;
47fd5c32 Poul Sander 2024-10-05 08:44 389
      uint32_t c;
47fd5c32 Poul Sander 2024-10-05 08:44 390
      char buf[8] = {0};
47fd5c32 Poul Sander 2024-10-05 08:44 391
      char* end = utf8_encode(buf, i);
47fd5c32 Poul Sander 2024-10-05 08:44 392
      const char* res = fmt::detail::utf8_decode(buf, &c, &e);
47fd5c32 Poul Sander 2024-10-05 08:44 393
      EXPECT_EQ(end, res);
47fd5c32 Poul Sander 2024-10-05 08:44 394
      EXPECT_EQ(c, i);
47fd5c32 Poul Sander 2024-10-05 08:44 395
      EXPECT_EQ(e, 0);
47fd5c32 Poul Sander 2024-10-05 08:44 396
    }
47fd5c32 Poul Sander 2024-10-05 08:44 397
  }
47fd5c32 Poul Sander 2024-10-05 08:44 398
}
47fd5c32 Poul Sander 2024-10-05 08:44 399
47fd5c32 Poul Sander 2024-10-05 08:44 400
// Reject everything outside of U+0000..U+10FFFF
47fd5c32 Poul Sander 2024-10-05 08:44 401
TEST(format_impl_test, utf8_decode_out_of_range) {
47fd5c32 Poul Sander 2024-10-05 08:44 402
  for (uint32_t i = 0x110000; i < 0x1fffff; i++) {
47fd5c32 Poul Sander 2024-10-05 08:44 403
    int e;
47fd5c32 Poul Sander 2024-10-05 08:44 404
    uint32_t c;
47fd5c32 Poul Sander 2024-10-05 08:44 405
    char buf[8] = {0};
47fd5c32 Poul Sander 2024-10-05 08:44 406
    utf8_encode(buf, i);
47fd5c32 Poul Sander 2024-10-05 08:44 407
    const char* end = fmt::detail::utf8_decode(buf, &c, &e);
47fd5c32 Poul Sander 2024-10-05 08:44 408
    EXPECT_NE(e, 0);
47fd5c32 Poul Sander 2024-10-05 08:44 409
    EXPECT_EQ(end - buf, 4);
47fd5c32 Poul Sander 2024-10-05 08:44 410
  }
47fd5c32 Poul Sander 2024-10-05 08:44 411
}
47fd5c32 Poul Sander 2024-10-05 08:44 412
47fd5c32 Poul Sander 2024-10-05 08:44 413
// Does it reject all surrogate halves?
47fd5c32 Poul Sander 2024-10-05 08:44 414
TEST(format_impl_test, utf8_decode_surrogate_halves) {
47fd5c32 Poul Sander 2024-10-05 08:44 415
  for (uint32_t i = 0xd800; i <= 0xdfff; i++) {
47fd5c32 Poul Sander 2024-10-05 08:44 416
    int e;
47fd5c32 Poul Sander 2024-10-05 08:44 417
    uint32_t c;
47fd5c32 Poul Sander 2024-10-05 08:44 418
    char buf[8] = {0};
47fd5c32 Poul Sander 2024-10-05 08:44 419
    utf8_encode(buf, i);
47fd5c32 Poul Sander 2024-10-05 08:44 420
    fmt::detail::utf8_decode(buf, &c, &e);
47fd5c32 Poul Sander 2024-10-05 08:44 421
    EXPECT_NE(e, 0);
47fd5c32 Poul Sander 2024-10-05 08:44 422
  }
47fd5c32 Poul Sander 2024-10-05 08:44 423
}
47fd5c32 Poul Sander 2024-10-05 08:44 424
47fd5c32 Poul Sander 2024-10-05 08:44 425
// How about non-canonical encodings?
47fd5c32 Poul Sander 2024-10-05 08:44 426
TEST(format_impl_test, utf8_decode_non_canonical_encodings) {
47fd5c32 Poul Sander 2024-10-05 08:44 427
  int e;
47fd5c32 Poul Sander 2024-10-05 08:44 428
  uint32_t c;
47fd5c32 Poul Sander 2024-10-05 08:44 429
  const char* end;
47fd5c32 Poul Sander 2024-10-05 08:44 430
47fd5c32 Poul Sander 2024-10-05 08:44 431
  char buf2[8] = {char(0xc0), char(0xA4)};
47fd5c32 Poul Sander 2024-10-05 08:44 432
  end = fmt::detail::utf8_decode(buf2, &c, &e);
47fd5c32 Poul Sander 2024-10-05 08:44 433
  EXPECT_NE(e, 0);           // non-canonical len 2
47fd5c32 Poul Sander 2024-10-05 08:44 434
  EXPECT_EQ(end, buf2 + 2);  // non-canonical recover 2
47fd5c32 Poul Sander 2024-10-05 08:44 435
47fd5c32 Poul Sander 2024-10-05 08:44 436
  char buf3[8] = {char(0xe0), char(0x80), char(0xA4)};
47fd5c32 Poul Sander 2024-10-05 08:44 437
  end = fmt::detail::utf8_decode(buf3, &c, &e);
47fd5c32 Poul Sander 2024-10-05 08:44 438
  EXPECT_NE(e, 0);           // non-canonical len 3
47fd5c32 Poul Sander 2024-10-05 08:44 439
  EXPECT_EQ(end, buf3 + 3);  // non-canonical recover 3
47fd5c32 Poul Sander 2024-10-05 08:44 440
47fd5c32 Poul Sander 2024-10-05 08:44 441
  char buf4[8] = {char(0xf0), char(0x80), char(0x80), char(0xA4)};
47fd5c32 Poul Sander 2024-10-05 08:44 442
  end = fmt::detail::utf8_decode(buf4, &c, &e);
47fd5c32 Poul Sander 2024-10-05 08:44 443
  EXPECT_NE(e, 0);           // non-canonical encoding len 4
47fd5c32 Poul Sander 2024-10-05 08:44 444
  EXPECT_EQ(end, buf4 + 4);  // non-canonical recover 4
47fd5c32 Poul Sander 2024-10-05 08:44 445
}
47fd5c32 Poul Sander 2024-10-05 08:44 446
47fd5c32 Poul Sander 2024-10-05 08:44 447
// Let's try some bogus byte sequences
47fd5c32 Poul Sander 2024-10-05 08:44 448
TEST(format_impl_test, utf8_decode_bogus_byte_sequences) {
47fd5c32 Poul Sander 2024-10-05 08:44 449
  int e;
47fd5c32 Poul Sander 2024-10-05 08:44 450
  uint32_t c;
47fd5c32 Poul Sander 2024-10-05 08:44 451
47fd5c32 Poul Sander 2024-10-05 08:44 452
  // Invalid first byte
47fd5c32 Poul Sander 2024-10-05 08:44 453
  char buf0[4] = {char(0xff)};
47fd5c32 Poul Sander 2024-10-05 08:44 454
  auto len = fmt::detail::utf8_decode(buf0, &c, &e) - buf0;
47fd5c32 Poul Sander 2024-10-05 08:44 455
  EXPECT_NE(e, 0);    // "bogus [ff] 0x%02x U+%04lx", e, (unsigned long)c);
47fd5c32 Poul Sander 2024-10-05 08:44 456
  EXPECT_EQ(len, 1);  // "bogus [ff] recovery %d", len);
47fd5c32 Poul Sander 2024-10-05 08:44 457
47fd5c32 Poul Sander 2024-10-05 08:44 458
  // Invalid first byte
47fd5c32 Poul Sander 2024-10-05 08:44 459
  char buf1[4] = {char(0x80)};
47fd5c32 Poul Sander 2024-10-05 08:44 460
  len = fmt::detail::utf8_decode(buf1, &c, &e) - buf1;
47fd5c32 Poul Sander 2024-10-05 08:44 461
  EXPECT_NE(e, 0);    // "bogus [80] 0x%02x U+%04lx", e, (unsigned long)c);
47fd5c32 Poul Sander 2024-10-05 08:44 462
  EXPECT_EQ(len, 1);  // "bogus [80] recovery %d", len);
47fd5c32 Poul Sander 2024-10-05 08:44 463
47fd5c32 Poul Sander 2024-10-05 08:44 464
  // Looks like a two-byte sequence but second byte is wrong
47fd5c32 Poul Sander 2024-10-05 08:44 465
  char buf2[4] = {char(0xc0), char(0x0a)};
47fd5c32 Poul Sander 2024-10-05 08:44 466
  len = fmt::detail::utf8_decode(buf2, &c, &e) - buf2;
47fd5c32 Poul Sander 2024-10-05 08:44 467
  EXPECT_NE(e, 0);    // "bogus [c0 0a] 0x%02x U+%04lx", e, (unsigned long)c
47fd5c32 Poul Sander 2024-10-05 08:44 468
  EXPECT_EQ(len, 2);  // "bogus [c0 0a] recovery %d", len);
47fd5c32 Poul Sander 2024-10-05 08:44 469
}
47fd5c32 Poul Sander 2024-10-05 08:44 470
47fd5c32 Poul Sander 2024-10-05 08:44 471
TEST(format_impl_test, to_utf8) {
47fd5c32 Poul Sander 2024-10-05 08:44 472
  auto s = std::string("ёжик");
47fd5c32 Poul Sander 2024-10-05 08:44 473
  auto u = fmt::detail::to_utf8<wchar_t>(L"\x0451\x0436\x0438\x043A");
47fd5c32 Poul Sander 2024-10-05 08:44 474
  EXPECT_EQ(s, u.str());
47fd5c32 Poul Sander 2024-10-05 08:44 475
  EXPECT_EQ(s.size(), u.size());
47fd5c32 Poul Sander 2024-10-05 08:44 476
}
1970-01-01 00:00 477