@@ -631,33 +631,75 @@ struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
631631#endif // __cpp_lib_atomic_flag_test
632632
633633FMT_EXPORT
634- template <typename F, typename Char>
635- struct formatter <std::complex <F>, Char> : nested_formatter<F, Char> {
634+ template <typename T, typename Char> struct formatter <std::complex <T>, Char> {
636635 private:
636+ detail::dynamic_format_specs<Char> specs_;
637+
638+ template <typename FormatContext, typename F>
639+ auto write_padded (detail::dynamic_format_specs<Char>& specs,
640+ FormatContext& ctx, F write) const -> decltype(ctx.out()) {
641+ if (specs.width == 0 ) return write (specs, ctx, ctx.out ());
642+ auto buf = basic_memory_buffer<Char>();
643+
644+ auto complex_specs = format_specs ();
645+ complex_specs.width = specs.width ;
646+ complex_specs.fill = specs.fill ;
647+ complex_specs.align = specs.align ;
648+
649+ specs.width = 0 ;
650+ specs.fill = {};
651+ specs.align = align::none;
652+ write (specs, ctx, basic_appender<Char>(buf));
653+ return detail::write<Char>(ctx.out (),
654+ basic_string_view<Char>(buf.data (), buf.size ()),
655+ complex_specs);
656+ }
657+
637658 // Functor because C++11 doesn't support generic lambdas.
638659 struct writer {
639- const formatter<std::complex <F>, Char>* f;
640- const std::complex <F>& c;
660+ const std::complex <T>& c;
641661
642- template <typename OutputIt>
643- FMT_CONSTEXPR auto operator ()(OutputIt out) -> OutputIt {
662+ template <typename FormatContext, typename OutputIt>
663+ FMT_CONSTEXPR auto operator ()(detail::dynamic_format_specs<Char>& specs,
664+ FormatContext& ctx,
665+ OutputIt out) -> OutputIt {
644666 if (c.real () != 0 ) {
645- auto format_full = detail::string_literal<Char, ' (' , ' {' , ' }' , ' +' , ' {' ,
646- ' }' , ' i' , ' )' >{};
647- return fmt::format_to (out, basic_string_view<Char>(format_full),
648- f->nested (c.real ()), f->nested (c.imag ()));
667+ *out++ = Char (' (' );
668+ out = detail::write<Char>(out, c.real (), specs, ctx.locale ());
669+ specs.sign = sign::plus;
670+ out = detail::write<Char>(out, c.imag (), specs, ctx.locale ());
671+ if (!detail::isfinite (c.imag ())) *out++ = Char (' ' );
672+ *out++ = Char (' i' );
673+ *out++ = Char (' )' );
674+ return out;
649675 }
650- auto format_imag = detail::string_literal<Char, ' {' , ' }' , ' i' >{};
651- return fmt::format_to (out, basic_string_view<Char>(format_imag),
652- f->nested (c.imag ()));
676+ out = detail::write<Char>(out, c.imag (), specs, ctx.locale ());
677+ if (!detail::isfinite (c.imag ())) *out++ = Char (' ' );
678+ *out++ = Char (' i' );
679+ return out;
653680 }
654681 };
655682
656683 public:
684+ FMT_CONSTEXPR auto parse (basic_format_parse_context<Char>& ctx)
685+ -> decltype(ctx.begin()) {
686+ if (ctx.begin () == ctx.end () || *ctx.begin () == ' }' ) return ctx.begin ();
687+ return parse_format_specs (ctx.begin (), ctx.end (), specs_, ctx,
688+ detail::type_constant<T, Char>::value);
689+ }
690+
657691 template <typename FormatContext>
658- auto format (const std::complex <F >& c, FormatContext& ctx) const
692+ auto format (const std::complex <T >& c, FormatContext& ctx) const
659693 -> decltype(ctx.out()) {
660- return this ->write_padded (ctx, writer{this , c});
694+ auto specs = specs_;
695+ if (specs.width_ref .kind != detail::arg_id_kind::none ||
696+ specs.precision_ref .kind != detail::arg_id_kind::none) {
697+ detail::handle_dynamic_spec<detail::width_checker>(specs.width ,
698+ specs.width_ref , ctx);
699+ detail::handle_dynamic_spec<detail::precision_checker>(
700+ specs.precision , specs.precision_ref , ctx);
701+ }
702+ return this ->write_padded (specs, ctx, writer{c});
661703 }
662704};
663705
0 commit comments