| 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 |
|