| 1580 | |
| 1581 | template <typename Char, typename Handler> |
| 1582 | FMT_CONSTEXPR FMT_INLINE auto parse_replacement_field(const Char* begin, |
| 1583 | const Char* end, |
| 1584 | Handler&& handler) |
| 1585 | -> const Char* { |
| 1586 | ++begin; |
| 1587 | if (begin == end) { |
| 1588 | handler.on_error("invalid format string"); |
| 1589 | return end; |
| 1590 | } |
| 1591 | int arg_id = 0; |
| 1592 | switch (*begin) { |
| 1593 | case '}': |
| 1594 | handler.on_replacement_field(handler.on_arg_id(), begin); |
| 1595 | return begin + 1; |
| 1596 | case '{': handler.on_text(begin, begin + 1); return begin + 1; |
| 1597 | case ':': arg_id = handler.on_arg_id(); break; |
| 1598 | default: { |
| 1599 | struct id_adapter { |
| 1600 | Handler& handler; |
| 1601 | int arg_id; |
| 1602 | |
| 1603 | FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); } |
| 1604 | FMT_CONSTEXPR void on_name(basic_string_view<Char> id) { |
| 1605 | arg_id = handler.on_arg_id(id); |
| 1606 | } |
| 1607 | } adapter = {handler, 0}; |
| 1608 | begin = parse_arg_id(begin, end, adapter); |
| 1609 | arg_id = adapter.arg_id; |
| 1610 | Char c = begin != end ? *begin : Char(); |
| 1611 | if (c == '}') { |
| 1612 | handler.on_replacement_field(arg_id, begin); |
| 1613 | return begin + 1; |
| 1614 | } |
| 1615 | if (c != ':') { |
| 1616 | handler.on_error("missing '}' in format string"); |
| 1617 | return end; |
| 1618 | } |
| 1619 | break; |
| 1620 | } |
| 1621 | } |
| 1622 | begin = handler.on_format_specs(arg_id, begin + 1, end); |
| 1623 | if (begin == end || *begin != '}') |
| 1624 | return handler.on_error("unknown format specifier"), end; |
| 1625 | return begin + 1; |
| 1626 | } |
| 1627 | |
| 1628 | template <typename Char, typename Handler> |
| 1629 | FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> fmt, |
no test coverage detected