@@ -631,33 +631,67 @@ struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
631
631
#endif // __cpp_lib_atomic_flag_test
632
632
633
633
FMT_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> {
636
635
private:
637
- // Functor because C++11 doesn't support generic lambdas.
638
- struct writer {
639
- const formatter<std::complex<F>, Char>* f;
640
- const std::complex<F >& c;
641
-
642
- template < typename OutputIt>
643
- FMT_CONSTEXPR auto operator ()(OutputIt out) -> OutputIt {
644
- 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 () ));
649
- }
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 ())) ;
636
+ detail::dynamic_format_specs<Char> specs_;
637
+
638
+ template < typename FormatContext, typename OutputIt>
639
+ FMT_CONSTEXPR auto do_format ( const std::complex<T >& c,
640
+ detail::dynamic_format_specs<Char>& specs,
641
+ FormatContext& ctx, OutputIt out) const
642
+ -> OutputIt {
643
+ if (c.real () != 0 ) {
644
+ *out++ = Char ( ' (' );
645
+ out = detail:: write <Char>(out, c. real (), specs, ctx. locale ()) ;
646
+ specs. sign = sign::plus;
647
+ out = detail:: write <Char>(out, c. imag (), specs, ctx. locale ( ));
648
+ if (! detail::isfinite (c. imag ())) *out++ = Char ( ' ' );
649
+ *out++ = Char ( ' i ' ) ;
650
+ * out++ = Char ( ' ) ' );
651
+ return out ;
653
652
}
654
- };
653
+ out = detail::write <Char>(out, c.imag (), specs, ctx.locale ());
654
+ if (!detail::isfinite (c.imag ())) *out++ = Char (' ' );
655
+ *out++ = Char (' i' );
656
+ return out;
657
+ }
655
658
656
659
public:
660
+ FMT_CONSTEXPR auto parse (basic_format_parse_context<Char>& ctx)
661
+ -> decltype(ctx.begin()) {
662
+ if (ctx.begin () == ctx.end () || *ctx.begin () == ' }' ) return ctx.begin ();
663
+ return parse_format_specs (ctx.begin (), ctx.end (), specs_, ctx,
664
+ detail::type_constant<T, Char>::value);
665
+ }
666
+
657
667
template <typename FormatContext>
658
- auto format (const std::complex<F >& c, FormatContext& ctx) const
668
+ auto format (const std::complex<T >& c, FormatContext& ctx) const
659
669
-> decltype(ctx.out()) {
660
- return this ->write_padded (ctx, writer{this , c});
670
+ auto specs = specs_;
671
+ if (specs.width_ref .kind != detail::arg_id_kind::none ||
672
+ specs.precision_ref .kind != detail::arg_id_kind::none) {
673
+ detail::handle_dynamic_spec<detail::width_checker>(specs.width ,
674
+ specs.width_ref , ctx);
675
+ detail::handle_dynamic_spec<detail::precision_checker>(
676
+ specs.precision , specs.precision_ref , ctx);
677
+ }
678
+
679
+ if (specs.width == 0 ) return do_format (c, specs, ctx, ctx.out ());
680
+ auto buf = basic_memory_buffer<Char>();
681
+
682
+ auto outer_specs = format_specs ();
683
+ outer_specs.width = specs.width ;
684
+ outer_specs.fill = specs.fill ;
685
+ outer_specs.align = specs.align ;
686
+
687
+ specs.width = 0 ;
688
+ specs.fill = {};
689
+ specs.align = align::none;
690
+
691
+ do_format (c, specs, ctx, basic_appender<Char>(buf));
692
+ return detail::write <Char>(ctx.out (),
693
+ basic_string_view<Char>(buf.data (), buf.size ()),
694
+ outer_specs);
661
695
}
662
696
};
663
697
0 commit comments