28 auto [
fill, align_char] = result;
52 switch (ch.value_or(U
'-')) {
125 return (-
parser::match_one(
'b'_m ||
'B'_m ||
'c'_m ||
'd'_m ||
'o'_m ||
'x'_m ||
'X'_m)) %
127 switch (ch.value_or(U
'd')) {
152 return (
parser::match_one(
'b'_m ||
'B'_m ||
'c'_m ||
'd'_m ||
'o'_m ||
'x'_m ||
'X'_m ||
'?'_m)) %
181 return (-
parser::match_one(
'b'_m ||
'B'_m ||
'd'_m ||
'o'_m ||
's'_m ||
'x'_m ||
'X'_m)) %
183 switch (ch.value_or(U
's')) {
209 switch (ch.value_or(U
'p')) {
292 template<concepts::Encoding Enc>
304 (void) result.push_back(
c32(p));
307 if (
c32(p) ==
'\0') {
308 (void) result.push_back(U
'\\');
309 (void) result.push_back(U
'0');
310 }
else if (
c32(p) ==
'\a') {
311 (void) result.push_back(U
'\\');
312 (void) result.push_back(U
'a');
313 }
else if (
c32(p) ==
'\b') {
314 (void) result.push_back(U
'\\');
315 (void) result.push_back(U
'b');
316 }
else if (
c32(p) ==
'\f') {
317 (void) result.push_back(U
'\\');
318 (void) result.push_back(U
'f');
319 }
else if (
c32(p) ==
'\n') {
320 (void) result.push_back(U
'\\');
321 (void) result.push_back(U
'n');
322 }
else if (
c32(p) ==
'\r') {
323 (void) result.push_back(U
'\\');
324 (void) result.push_back(U
'r');
325 }
else if (
c32(p) ==
'\t') {
326 (void) result.push_back(U
'\\');
327 (void) result.push_back(U
't');
328 }
else if (
c32(p) ==
'\v') {
329 (void) result.push_back(U
'\\');
330 (void) result.push_back(U
'v');
331 }
else if (
c32(p) ==
'\\') {
332 (void) result.push_back(U
'\\');
333 (void) result.push_back(U
'\\');
336 else if (
c32(p) == delimit_code_point) {
337 (void) result.push_back(U
'\\');
338 (void) result.push_back(delimit_code_point);
342 else if (p <= 31 || p == 127 || (p >= 0x80 && p <= 0x9F)) {
343 auto v1 = (
u8(p) / 16) & 0xF;
344 auto v2 = (
u8(p) % 16);
346 (void) result.push_back(U
'\\');
347 (void) result.push_back(U
'x');
348 (void) result.push_back((v1 >= 10) ? (
'a' + (v1 - 10)) : (
'0' + v1));
349 (void) result.push_back((v2 >= 10) ? (
'a' + (v2 - 10)) : (
'0' + v2));
351 (void) result.push_back(
c32(p));
357 auto view = view::concat(delimit, view::join(view::transform(view_in, map_to_debug_char)), delimit);
359 auto measure_code_point = [&](CodePoint) ->
size_t {
365 auto do_output_char = [&](CodePoint code_point) ->
Result<void> {
366 (void) context.output(code_point);
370 size_t width_printed_so_far = 0;
372 auto output_char = [&](CodePoint code_point) ->
Result<void> {
375 return do_output_char(code_point);
379 auto code_point_width = measure_code_point(code_point);
380 if (width_printed_so_far + code_point_width > *precision) {
384 auto result = do_output_char(code_point);
385 width_printed_so_far += code_point_width;
393 auto total_width = view | view::transform(measure_code_point) |
container::sum;
394 if (total_width >= *
width) {
401 auto chars_to_pad = (*
width - total_width) / measure_code_point(fill_code_point);
405 return { 0, chars_to_pad };
409 return { chars_to_pad, 0 };
415 auto do_pad = [&](
auto) {
416 return output_char(fill_code_point);
424 template<concepts::Encoding Enc>
427 auto encoding = context.encoding();
435 template<concepts::Encoding Enc, concepts::Integral T>
453 auto const negative = [&] {
464 (void) buffer.push_back(CodePoint(
'-'));
469 (void) buffer.push_back(CodePoint(
'-'));
471 (void) buffer.push_back(CodePoint(
'+'));
476 (void) buffer.push_back(CodePoint(
'-'));
478 (void) buffer.push_back(CodePoint(
' '));
484 auto do_prefix = [&] {
490 (void) buffer.push_back(CodePoint(
'0'));
491 (void) buffer.push_back(CodePoint(
'b'));
494 (void) buffer.push_back(CodePoint(
'0'));
495 (void) buffer.push_back(CodePoint(
'B'));
498 (void) buffer.push_back(CodePoint(
'0'));
501 (void) buffer.push_back(CodePoint(
'0'));
502 (void) buffer.push_back(CodePoint(
'x'));
505 (void) buffer.push_back(CodePoint(
'0'));
506 (void) buffer.push_back(CodePoint(
'X'));
513 bool zero_pad = zero ==
Zero::Yes && !fill_and_align;
519 for (
auto ch : buffer) {
524 *
width -= code_points;
529 auto const radix = [&] -> UnsignedType {
547 return (value >= 10) ? (
'a' + (value - 10)) : (
'0' + value);
549 return (value >= 10) ? (
'A' + (value - 10)) : (
'0' + value);
551 return (
'0' + value);
555 UnsignedType strength = 1;
556 for (
auto x = as_unsigned; x / strength >= radix; strength *= radix) {}
558 for (; strength; strength /= radix) {
559 (void) buffer.push_back(to_digit((as_unsigned / strength) % radix));
567 template<concepts::Encoding Enc>
590 (void) fill_and_align;
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition static_vector.h:17
Definition string_impl_forward_declaration.h:9
Definition string_view_impl_forward_declaration.h:7
Definition optional_forward_declaration.h:5
Definition tuple_forward_declaration.h:5
Definition format_context.h:9
Definition language.h:238
Definition tuple_like.h:38
constexpr usize width
Definition gfx_test.cpp:21
#define DI_TRY(...)
Definition monad_try.h:13
constexpr auto convert_to_code_units
Definition encoding.h:139
constexpr auto code_point_view
Definition encoding.h:159
constexpr auto sequence
Definition sequence.h:34
constexpr auto distance
Definition distance.h:44
constexpr auto sum
Definition sum.h:26
constexpr auto value
Definition value.h:34
Definition integral_set.h:125
constexpr auto to_unsigned
Definition to_unsigned.h:16
constexpr auto divide_round_up
Definition divide_round_up.h:17
constexpr auto abs_unsigned
Definition abs_unsigned.h:26
constexpr auto match_one
Definition match_one.h:27
constexpr auto integer
Definition integer.h:212
__UINT8_TYPE__ u8
Definition integers.h:9
char32_t c32
Definition char.h:6
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
void unreachable()
Definition unreachable.h:4
Expected< T, Error > Result
Definition result.h:8
constexpr auto create_parser
Definition create_parser.h:55
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
constexpr auto make_from_tuple
Definition make_from_tuple.h:31
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto lift_bool
Definition lift_bool.h:13
Definition in_place_type.h:5