| 172 | namespace cf { |
| 173 | template <typename Context, typename Range, typename CompiledFormat> |
| 174 | auto vformat_to(Range out, CompiledFormat& cf, basic_format_args<Context> args) |
| 175 | -> typename Context::iterator { |
| 176 | using char_type = typename Context::char_type; |
| 177 | basic_format_parse_context<char_type> parse_ctx( |
| 178 | to_string_view(cf.format_str_)); |
| 179 | Context ctx(out.begin(), args); |
| 180 | |
| 181 | const auto& parts = cf.parts(); |
| 182 | for (auto part_it = std::begin(parts); part_it != std::end(parts); |
| 183 | ++part_it) { |
| 184 | const auto& part = *part_it; |
| 185 | const auto& value = part.val; |
| 186 | |
| 187 | using format_part_t = format_part<char_type>; |
| 188 | switch (part.part_kind) { |
| 189 | case format_part_t::kind::text: { |
| 190 | const auto text = value.str; |
| 191 | auto output = ctx.out(); |
| 192 | auto&& it = reserve(output, text.size()); |
| 193 | it = std::copy_n(text.begin(), text.size(), it); |
| 194 | ctx.advance_to(output); |
| 195 | break; |
| 196 | } |
| 197 | |
| 198 | case format_part_t::kind::arg_index: |
| 199 | advance_to(parse_ctx, part.arg_id_end); |
| 200 | internal::format_arg<Range>(parse_ctx, ctx, value.arg_index); |
| 201 | break; |
| 202 | |
| 203 | case format_part_t::kind::arg_name: |
| 204 | advance_to(parse_ctx, part.arg_id_end); |
| 205 | internal::format_arg<Range>(parse_ctx, ctx, value.str); |
| 206 | break; |
| 207 | |
| 208 | case format_part_t::kind::replacement: { |
| 209 | const auto& arg_id_value = value.repl.arg_id.val; |
| 210 | const auto arg = value.repl.arg_id.kind == arg_id_kind::index |
| 211 | ? ctx.arg(arg_id_value.index) |
| 212 | : ctx.arg(arg_id_value.name); |
| 213 | |
| 214 | auto specs = value.repl.specs; |
| 215 | |
| 216 | handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx); |
| 217 | handle_dynamic_spec<precision_checker>(specs.precision, |
| 218 | specs.precision_ref, ctx); |
| 219 | |
| 220 | error_handler h; |
| 221 | numeric_specs_checker<error_handler> checker(h, arg.type()); |
| 222 | if (specs.align == align::numeric) checker.require_numeric_argument(); |
| 223 | if (specs.sign != sign::none) checker.check_sign(); |
| 224 | if (specs.alt) checker.require_numeric_argument(); |
| 225 | if (specs.precision >= 0) checker.check_precision(); |
| 226 | |
| 227 | advance_to(parse_ctx, part.arg_id_end); |
| 228 | ctx.advance_to( |
| 229 | visit_format_arg(arg_formatter<Range>(ctx, nullptr, &specs), arg)); |
| 230 | break; |
| 231 | } |
nothing calls this directly
no test coverage detected