1 // Formatting library for C++ - formatting library implementation tests
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
6 // For the license information refer to format.h.
12 #include "test-assert.h"
15 #include "fmt/format.h"
16 #include "gmock/gmock.h"
19 using fmt::detail::bigint
;
20 using fmt::detail::fp
;
21 using fmt::detail::max_value
;
23 static_assert(!std::is_copy_constructible
<bigint
>::value
, "");
24 static_assert(!std::is_copy_assignable
<bigint
>::value
, "");
26 TEST(bigint_test
, construct
) {
27 EXPECT_EQ("", fmt::format("{}", bigint()));
28 EXPECT_EQ("42", fmt::format("{}", bigint(0x42)));
29 EXPECT_EQ("123456789abcedf0", fmt::format("{}", bigint(0x123456789abcedf0)));
32 TEST(bigint_test
, compare
) {
35 EXPECT_EQ(compare(n1
, n2
), 0);
37 EXPECT_LT(compare(n1
, n2
), 0);
39 EXPECT_LT(compare(n1
, n3
), 0);
40 EXPECT_GT(compare(n3
, n1
), 0);
41 bigint
n4(42 * 0x100000001);
42 EXPECT_LT(compare(n2
, n4
), 0);
43 EXPECT_GT(compare(n4
, n2
), 0);
46 TEST(bigint_test
, add_compare
) {
48 add_compare(bigint(0xffffffff), bigint(0xffffffff), bigint(1) <<= 64), 0);
49 EXPECT_LT(add_compare(bigint(1) <<= 32, bigint(1), bigint(1) <<= 96), 0);
50 EXPECT_GT(add_compare(bigint(1) <<= 32, bigint(0), bigint(0xffffffff)), 0);
51 EXPECT_GT(add_compare(bigint(0), bigint(1) <<= 32, bigint(0xffffffff)), 0);
52 EXPECT_GT(add_compare(bigint(42), bigint(1), bigint(42)), 0);
53 EXPECT_GT(add_compare(bigint(0xffffffff), bigint(1), bigint(0xffffffff)), 0);
54 EXPECT_LT(add_compare(bigint(10), bigint(10), bigint(22)), 0);
55 EXPECT_LT(add_compare(bigint(0x100000010), bigint(0x100000010),
58 EXPECT_GT(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
61 EXPECT_EQ(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
64 EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
67 EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002),
72 TEST(bigint_test
, shift_left
) {
75 EXPECT_EQ("42", fmt::format("{}", n
));
77 EXPECT_EQ("84", fmt::format("{}", n
));
79 EXPECT_EQ("108000000", fmt::format("{}", n
));
82 TEST(bigint_test
, multiply
) {
84 EXPECT_THROW(n
*= 0, assertion_failure
);
86 EXPECT_EQ("42", fmt::format("{}", n
));
88 EXPECT_EQ("84", fmt::format("{}", n
));
90 EXPECT_EQ("962fc95e0", fmt::format("{}", n
));
91 bigint
bigmax(max_value
<uint32_t>());
92 bigmax
*= max_value
<uint32_t>();
93 EXPECT_EQ("fffffffe00000001", fmt::format("{}", bigmax
));
94 bigmax
.assign(max_value
<uint64_t>());
95 bigmax
*= max_value
<uint64_t>();
96 EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", bigmax
));
99 TEST(bigint_test
, accumulator
) {
100 fmt::detail::accumulator acc
;
101 EXPECT_EQ(acc
.lower
, 0);
102 EXPECT_EQ(acc
.upper
, 0);
105 EXPECT_EQ(static_cast<uint32_t>(acc
), 34);
107 EXPECT_EQ(acc
.lower
, 90);
108 acc
+= max_value
<uint64_t>();
109 EXPECT_EQ(acc
.upper
, 13);
110 EXPECT_EQ(acc
.lower
, 89);
112 EXPECT_EQ(acc
.upper
, 0);
113 EXPECT_EQ(acc
.lower
, 13 * 0x100000000);
116 TEST(bigint_test
, square
) {
119 EXPECT_EQ("0", fmt::format("{}", n0
));
122 EXPECT_EQ("10000", fmt::format("{}", n1
));
123 bigint
n2(0xfffffffff);
125 EXPECT_EQ("ffffffffe000000001", fmt::format("{}", n2
));
126 bigint
n3(max_value
<uint64_t>());
128 EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", n3
));
131 EXPECT_EQ("2540be400", fmt::format("{}", n4
));
134 TEST(bigint_test
, divmod_assign_zero_divisor
) {
136 EXPECT_THROW(bigint(0).divmod_assign(zero
), assertion_failure
);
137 EXPECT_THROW(bigint(42).divmod_assign(zero
), assertion_failure
);
140 TEST(bigint_test
, divmod_assign_self
) {
142 EXPECT_THROW(n
.divmod_assign(n
), assertion_failure
);
145 TEST(bigint_test
, divmod_assign_unaligned
) {
146 // (42 << 340) / pow(10, 100):
150 n2
.assign_pow10(100);
151 int result
= n1
.divmod_assign(n2
);
152 EXPECT_EQ(result
, 9406);
153 EXPECT_EQ("10f8353019583bfc29ffc8f564e1b9f9d819dbb4cf783e4507eca1539220p96",
154 fmt::format("{}", n1
));
157 TEST(bigint_test
, divmod_assign
) {
160 int result
= n1
.divmod_assign(bigint(10));
161 EXPECT_EQ(result
, 10);
162 EXPECT_EQ("0", fmt::format("{}", n1
));
163 // pow(10, 100) / (42 << 320):
164 n1
.assign_pow10(100);
165 result
= n1
.divmod_assign(bigint(42) <<= 320);
166 EXPECT_EQ(result
, 111);
167 EXPECT_EQ("13ad2594c37ceb0b2784c4ce0bf38ace408e211a7caab24308a82e8f10p96",
168 fmt::format("{}", n1
));
172 result
= n2
.divmod_assign(n1
);
173 EXPECT_EQ(result
, 0);
174 EXPECT_EQ("2a", fmt::format("{}", n2
));
177 template <bool is_iec559
> void run_double_tests() {
178 fmt::print("warning: double is not IEC559, skipping FP tests\n");
181 template <> void run_double_tests
<true>() {
182 // Construct from double.
183 EXPECT_EQ(fp(1.23), fp(0x13ae147ae147aeu
, -52));
186 TEST(fp_test
, double_tests
) {
187 run_double_tests
<std::numeric_limits
<double>::is_iec559
>();
190 TEST(fp_test
, normalize
) {
191 const auto v
= fp(0xbeef, 42);
192 auto normalized
= normalize(v
);
193 EXPECT_EQ(0xbeef000000000000, normalized
.f
);
194 EXPECT_EQ(-6, normalized
.e
);
197 TEST(fp_test
, multiply
) {
198 auto v
= fp(123ULL << 32, 4) * fp(56ULL << 32, 7);
199 EXPECT_EQ(v
.f
, 123u * 56u);
200 EXPECT_EQ(v
.e
, 4 + 7 + 64);
201 v
= fp(123ULL << 32, 4) * fp(567ULL << 31, 8);
202 EXPECT_EQ(v
.f
, (123 * 567 + 1u) / 2);
203 EXPECT_EQ(v
.e
, 4 + 8 + 64);
206 TEST(fp_test
, get_cached_power
) {
207 using limits
= std::numeric_limits
<double>;
208 for (auto exp
= limits::min_exponent
; exp
<= limits::max_exponent
; ++exp
) {
210 auto fp
= fmt::detail::get_cached_power(exp
, dec_exp
);
211 bigint exact
, cache(fp
.f
);
213 exact
.assign_pow10(dec_exp
);
220 auto exact_str
= fmt::format("{}", exact
);
221 auto cache_str
= fmt::format("{}", cache
);
222 EXPECT_EQ(exact_str
.size(), cache_str
.size());
223 EXPECT_EQ(exact_str
.substr(0, 15), cache_str
.substr(0, 15));
224 int diff
= cache_str
[15] - exact_str
[15];
226 EXPECT_GT(exact_str
[16], '8');
230 cache
.assign_pow10(-dec_exp
);
231 cache
*= fp
.f
+ 1; // Inexact check.
235 auto exact_str
= fmt::format("{}", exact
);
236 auto cache_str
= fmt::format("{}", cache
);
237 EXPECT_EQ(exact_str
.size(), cache_str
.size());
238 EXPECT_EQ(exact_str
.substr(0, 16), cache_str
.substr(0, 16));
243 TEST(fp_test
, dragonbox_max_k
) {
244 using fmt::detail::dragonbox::floor_log10_pow2
;
245 using float_info
= fmt::detail::dragonbox::float_info
<float>;
246 EXPECT_EQ(fmt::detail::const_check(float_info::max_k
),
247 float_info::kappa
- floor_log10_pow2(float_info::min_exponent
-
248 float_info::significand_bits
));
249 using double_info
= fmt::detail::dragonbox::float_info
<double>;
251 fmt::detail::const_check(double_info::max_k
),
252 double_info::kappa
- floor_log10_pow2(double_info::min_exponent
-
253 double_info::significand_bits
));
256 TEST(fp_test
, get_round_direction
) {
257 using fmt::detail::get_round_direction
;
258 using fmt::detail::round_direction
;
259 EXPECT_EQ(round_direction::down
, get_round_direction(100, 50, 0));
260 EXPECT_EQ(round_direction::up
, get_round_direction(100, 51, 0));
261 EXPECT_EQ(round_direction::down
, get_round_direction(100, 40, 10));
262 EXPECT_EQ(round_direction::up
, get_round_direction(100, 60, 10));
263 for (size_t i
= 41; i
< 60; ++i
)
264 EXPECT_EQ(round_direction::unknown
, get_round_direction(100, i
, 10));
265 uint64_t max
= max_value
<uint64_t>();
266 EXPECT_THROW(get_round_direction(100, 100, 0), assertion_failure
);
267 EXPECT_THROW(get_round_direction(100, 0, 100), assertion_failure
);
268 EXPECT_THROW(get_round_direction(100, 0, 50), assertion_failure
);
269 // Check that remainder + error doesn't overflow.
270 EXPECT_EQ(round_direction::up
, get_round_direction(max
, max
- 1, 2));
271 // Check that 2 * (remainder + error) doesn't overflow.
272 EXPECT_EQ(round_direction::unknown
,
273 get_round_direction(max
, max
/ 2 + 1, max
/ 2));
274 // Check that remainder - error doesn't overflow.
275 EXPECT_EQ(round_direction::unknown
, get_round_direction(100, 40, 41));
276 // Check that 2 * (remainder - error) doesn't overflow.
277 EXPECT_EQ(round_direction::up
, get_round_direction(max
, max
- 1, 1));
280 TEST(fp_test
, fixed_handler
) {
281 struct handler
: fmt::detail::fixed_handler
{
283 handler(int prec
= 0) : fmt::detail::fixed_handler() {
289 handler().on_digit('0', 100, 99, 0, exp
, false);
290 EXPECT_THROW(handler().on_digit('0', 100, 100, 0, exp
, false),
292 namespace digits
= fmt::detail::digits
;
293 EXPECT_EQ(handler(1).on_digit('0', 100, 10, 10, exp
, false), digits::error
);
294 // Check that divisor - error doesn't overflow.
295 EXPECT_EQ(handler(1).on_digit('0', 100, 10, 101, exp
, false), digits::error
);
296 // Check that 2 * error doesn't overflow.
297 uint64_t max
= max_value
<uint64_t>();
298 EXPECT_EQ(handler(1).on_digit('0', max
, 10, max
- 1, exp
, false),
302 TEST(fp_test
, grisu_format_compiles_with_on_ieee_double
) {
303 fmt::memory_buffer buf
;
304 format_float(0.42, -1, fmt::detail::float_specs(), buf
);
307 TEST(format_impl_test
, format_error_code
) {
308 std::string msg
= "error 42", sep
= ": ";
310 fmt::memory_buffer buffer
;
311 format_to(fmt::appender(buffer
), "garbage");
312 fmt::detail::format_error_code(buffer
, 42, "test");
313 EXPECT_EQ("test: " + msg
, to_string(buffer
));
316 fmt::memory_buffer buffer
;
318 std::string(fmt::inline_buffer_size
- msg
.size() - sep
.size() + 1, 'x');
319 fmt::detail::format_error_code(buffer
, 42, prefix
);
320 EXPECT_EQ(msg
, to_string(buffer
));
322 int codes
[] = {42, -1};
323 for (size_t i
= 0, n
= sizeof(codes
) / sizeof(*codes
); i
< n
; ++i
) {
324 // Test maximum buffer size.
325 msg
= fmt::format("error {}", codes
[i
]);
326 fmt::memory_buffer buffer
;
328 std::string(fmt::inline_buffer_size
- msg
.size() - sep
.size(), 'x');
329 fmt::detail::format_error_code(buffer
, codes
[i
], prefix
);
330 EXPECT_EQ(prefix
+ sep
+ msg
, to_string(buffer
));
331 size_t size
= fmt::inline_buffer_size
;
332 EXPECT_EQ(size
, buffer
.size());
334 // Test with a message that doesn't fit into the buffer.
336 fmt::detail::format_error_code(buffer
, codes
[i
], prefix
);
337 EXPECT_EQ(msg
, to_string(buffer
));
341 TEST(format_impl_test
, compute_width
) {
343 fmt::detail::compute_width(
344 fmt::basic_string_view
<fmt::detail::char8_type
>(
345 reinterpret_cast<const fmt::detail::char8_type
*>("ёжик"))));
348 // Tests fmt::detail::count_digits for integer type Int.
349 template <typename Int
> void test_count_digits() {
350 for (Int i
= 0; i
< 10; ++i
) EXPECT_EQ(1u, fmt::detail::count_digits(i
));
351 for (Int i
= 1, n
= 1, end
= max_value
<Int
>() / 10; n
<= end
; ++i
) {
353 EXPECT_EQ(i
, fmt::detail::count_digits(n
- 1));
354 EXPECT_EQ(i
+ 1, fmt::detail::count_digits(n
));
358 TEST(format_impl_test
, count_digits
) {
359 test_count_digits
<uint32_t>();
360 test_count_digits
<uint64_t>();
363 TEST(format_impl_test
, write_fallback_uintptr
) {
365 fmt::detail::write_ptr
<char>(
366 std::back_inserter(s
),
367 fmt::detail::fallback_uintptr(reinterpret_cast<void*>(0xface)), nullptr);
368 EXPECT_EQ(s
, "0xface");
372 # include <windows.h>
376 TEST(format_impl_test
, write_console_signature
) {
377 decltype(WriteConsoleW
)* p
= fmt::detail::WriteConsoleW
;