Skip to content

Commit 5d9ed8e

Browse files
committed
Simplify range formatter
1 parent 13cfaa2 commit 5d9ed8e

File tree

3 files changed

+25
-35
lines changed

3 files changed

+25
-35
lines changed

include/fmt/base.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -2961,8 +2961,8 @@ template <typename OutputIt, typename Sentinel = OutputIt>
29612961
struct format_to_result {
29622962
/** Iterator pointing to just after the last successful write in the range. */
29632963
OutputIt out;
2964-
/** Sentinel indicating the end of the output range. */
2965-
Sentinel out_last;
2964+
/** Specifies if the output was truncated. */
2965+
bool truncated;
29662966

29672967
FMT_CONSTEXPR operator OutputIt&() & noexcept { return out; }
29682968
FMT_CONSTEXPR operator const OutputIt&() const& noexcept { return out; }
@@ -2974,13 +2974,15 @@ struct format_to_result {
29742974
template <size_t N>
29752975
auto vformat_to(char (&out)[N], string_view fmt, format_args args)
29762976
-> format_to_result<char*> {
2977-
return {vformat_to_n(out, N, fmt, args).out, out + N};
2977+
auto result = vformat_to_n(out, N, fmt, args);
2978+
return {result.out, result.size > N};
29782979
}
29792980

29802981
template <size_t N, typename... T>
29812982
FMT_INLINE auto format_to(char (&out)[N], format_string<T...> fmt, T&&... args)
29822983
-> format_to_result<char*> {
2983-
return vformat_to(out, fmt, fmt::make_format_args(args...));
2984+
auto result = format_to_n(out, N, fmt, args...);
2985+
return {result.out, result.size > N};
29842986
}
29852987

29862988
/** Returns the number of chars in the output of ``format(fmt, args...)``. */

include/fmt/ranges.h

+13-25
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,6 @@ struct range_formatter<
388388
detail::string_literal<Char, '['>{};
389389
basic_string_view<Char> closing_bracket_ =
390390
detail::string_literal<Char, ']'>{};
391-
bool is_string_format = false;
392391
bool is_debug = false;
393392

394393
public:
@@ -413,9 +412,7 @@ struct range_formatter<
413412
auto it = ctx.begin();
414413
auto end = ctx.end();
415414
detail::maybe_set_debug_format(underlying_, true);
416-
if (it == end) {
417-
return underlying_.parse(ctx);
418-
}
415+
if (it == end) return underlying_.parse(ctx);
419416

420417
switch (detail::to_ascii(*it)) {
421418
case 'n':
@@ -426,21 +423,17 @@ struct range_formatter<
426423
is_debug = true;
427424
set_brackets({}, {});
428425
++it;
429-
if (it == end || *it != 's') {
430-
report_error("invalid format specifier");
431-
}
426+
if (it == end || *it != 's') report_error("invalid format specifier");
432427
FMT_FALLTHROUGH;
433428
case 's':
434-
if (!std::is_same<T, Char>::value) {
429+
if (!std::is_same<T, Char>::value)
435430
report_error("invalid format specifier");
436-
}
437431
if (!is_debug) {
438432
set_brackets(detail::string_literal<Char, '"'>{},
439433
detail::string_literal<Char, '"'>{});
440434
set_separator({});
441435
detail::maybe_set_debug_format(underlying_, false);
442436
}
443-
is_string_format = true;
444437
++it;
445438
return it;
446439
}
@@ -455,21 +448,19 @@ struct range_formatter<
455448
return underlying_.parse(ctx);
456449
}
457450

458-
template <typename Output, typename Iter, typename IterEnd, typename U = T,
451+
template <typename Output, typename It, typename Sentinel, typename U = T,
459452
FMT_ENABLE_IF(std::is_same<U, Char>::value)>
460-
auto write_debug_string(Output& out, Iter& it, IterEnd& end) const -> Output {
453+
auto write_debug_string(Output& out, It it, Sentinel end) const -> Output {
461454
auto buf = basic_memory_buffer<Char>();
462-
for (; it != end; ++it) {
463-
buf.push_back(*it);
464-
}
465-
format_specs spec_str;
466-
spec_str.type = presentation_type::debug;
455+
for (; it != end; ++it) buf.push_back(*it);
456+
auto specs = format_specs();
457+
specs.type = presentation_type::debug;
467458
return detail::write<Char>(
468-
out, basic_string_view<Char>(buf.data(), buf.size()), spec_str);
459+
out, basic_string_view<Char>(buf.data(), buf.size()), specs);
469460
}
470-
template <typename Output, typename Iter, typename IterEnd, typename U = T,
461+
template <typename Output, typename It, typename Sentinel, typename U = T,
471462
FMT_ENABLE_IF(!std::is_same<U, Char>::value)>
472-
auto write_debug_string(Output& out, Iter&, IterEnd&) const -> Output {
463+
auto write_debug_string(Output& out, It, Sentinel) const -> Output {
473464
return out;
474465
}
475466

@@ -479,17 +470,14 @@ struct range_formatter<
479470
auto out = ctx.out();
480471
auto it = detail::range_begin(range);
481472
auto end = detail::range_end(range);
482-
if (is_debug) {
483-
return write_debug_string(out, it, end);
484-
}
473+
if (is_debug) return write_debug_string(out, it, end);
485474

486475
out = detail::copy<Char>(opening_bracket_, out);
487476
int i = 0;
488477
for (; it != end; ++it) {
489478
if (i > 0) out = detail::copy<Char>(separator_, out);
490479
ctx.advance_to(out);
491-
auto&& item = *it;
492-
out = underlying_.format(mapper.map(item), ctx);
480+
out = underlying_.format(mapper.map(*it), ctx);
493481
++i;
494482
}
495483
out = detail::copy<Char>(closing_bracket_, out);

test/base-test.cc

+6-6
Original file line numberDiff line numberDiff line change
@@ -697,13 +697,13 @@ TEST(core_test, format_to_c_array) {
697697
char buffer[4];
698698
auto result = fmt::format_to(buffer, "{}", 12345);
699699
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
700-
EXPECT_EQ(0, std::distance(result.out, result.out_last));
700+
EXPECT_TRUE(result.truncated);
701701
EXPECT_EQ(buffer + 4, result.out);
702702
EXPECT_EQ("1234", fmt::string_view(buffer, 4));
703703

704704
result = fmt::format_to(buffer, "{:s}", "foobar");
705705
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
706-
EXPECT_EQ(0, std::distance(result.out, result.out_last));
706+
EXPECT_TRUE(result.truncated);
707707
EXPECT_EQ(buffer + 4, result.out);
708708
EXPECT_EQ("foob", fmt::string_view(buffer, 4));
709709

@@ -713,24 +713,24 @@ TEST(core_test, format_to_c_array) {
713713
buffer[3] = 'x';
714714
result = fmt::format_to(buffer, "{}", 'A');
715715
EXPECT_EQ(1, std::distance(&buffer[0], result.out));
716-
EXPECT_EQ(3, std::distance(result.out, result.out_last));
716+
EXPECT_FALSE(result.truncated);
717717
EXPECT_EQ(buffer + 1, result.out);
718718
EXPECT_EQ("Axxx", fmt::string_view(buffer, 4));
719719

720720
result = fmt::format_to(buffer, "{}{} ", 'B', 'C');
721721
EXPECT_EQ(3, std::distance(&buffer[0], result.out));
722-
EXPECT_EQ(1, std::distance(result.out, result.out_last));
722+
EXPECT_FALSE(result.truncated);
723723
EXPECT_EQ(buffer + 3, result.out);
724724
EXPECT_EQ("BC x", fmt::string_view(buffer, 4));
725725

726726
result = fmt::format_to(buffer, "{}", "ABCDE");
727727
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
728-
EXPECT_EQ(0, std::distance(result.out, result.out_last));
728+
EXPECT_TRUE(result.truncated);
729729
EXPECT_EQ("ABCD", fmt::string_view(buffer, 4));
730730

731731
result = fmt::format_to(buffer, "{}", std::string(1000, '*'));
732732
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
733-
EXPECT_EQ(0, std::distance(result.out, result.out_last));
733+
EXPECT_TRUE(result.truncated);
734734
EXPECT_EQ("****", fmt::string_view(buffer, 4));
735735
}
736736

0 commit comments

Comments
 (0)