| 452 | template <typename OutputIt, typename Char> |
| 453 | template <typename ArgFormatter> |
| 454 | OutputIt basic_printf_context<OutputIt, Char>::format() { |
| 455 | auto out = this->out(); |
| 456 | const Char* start = parse_ctx_.begin(); |
| 457 | const Char* end = parse_ctx_.end(); |
| 458 | auto it = start; |
| 459 | while (it != end) { |
| 460 | char_type c = *it++; |
| 461 | if (c != '%') continue; |
| 462 | if (it != end && *it == c) { |
| 463 | out = std::copy(start, it, out); |
| 464 | start = ++it; |
| 465 | continue; |
| 466 | } |
| 467 | out = std::copy(start, it - 1, out); |
| 468 | |
| 469 | format_specs specs; |
| 470 | specs.align = align::right; |
| 471 | |
| 472 | // Parse argument index, flags and width. |
| 473 | int arg_index = parse_header(it, end, specs); |
| 474 | if (arg_index == 0) on_error("argument index out of range"); |
| 475 | |
| 476 | // Parse precision. |
| 477 | if (it != end && *it == '.') { |
| 478 | ++it; |
| 479 | c = it != end ? *it : 0; |
| 480 | if ('0' <= c && c <= '9') { |
| 481 | internal::error_handler eh; |
| 482 | specs.precision = parse_nonnegative_int(it, end, eh); |
| 483 | } else if (c == '*') { |
| 484 | ++it; |
| 485 | specs.precision = static_cast<int>( |
| 486 | visit_format_arg(internal::printf_precision_handler(), get_arg())); |
| 487 | } else { |
| 488 | specs.precision = 0; |
| 489 | } |
| 490 | } |
| 491 | |
| 492 | format_arg arg = get_arg(arg_index); |
| 493 | if (specs.alt && visit_format_arg(internal::is_zero_int(), arg)) |
| 494 | specs.alt = false; |
| 495 | if (specs.fill[0] == '0') { |
| 496 | if (arg.is_arithmetic()) |
| 497 | specs.align = align::numeric; |
| 498 | else |
| 499 | specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types. |
| 500 | } |
| 501 | |
| 502 | // Parse length and convert the argument to the required type. |
| 503 | c = it != end ? *it++ : 0; |
| 504 | char_type t = it != end ? *it : 0; |
| 505 | using internal::convert_arg; |
| 506 | switch (c) { |
| 507 | case 'h': |
| 508 | if (t == 'h') { |
| 509 | ++it; |
| 510 | t = it != end ? *it : 0; |
| 511 | convert_arg<signed char>(arg, t); |
no test coverage detected