On Wed, 16 Apr 2025 at 11:10, Jonathan Wakely <jwak...@redhat.com> wrote: > > On 16/04/25 11:45 +0200, Tomasz Kamiński wrote: > >This patch implements formatter specializations for pair and tuple form > >P2286R8. In addition using 'm` and range_format::map (from P2585R1) for > >ranges are now supported. > > > >The formatters for pairs and tuples whose corresponding elements are the same > >(after applying remove_cvref_t) derive from the same __tuple_formatter class. > >This reduce the code duplication, as most of the parsing and formatting is > >the > >same in such cases. We use a custom reduced implementation of the tuple > >(__formatters_storage) to store the elements formatters. > > > >Handling of the padding (width and fill) options, is extracted to > >__format::__format_padded function, that is used both by __tuple_formatter > >and > >range_formatter. To reduce number of instantations range_formatter::format > >triggers, we cast incoming range to __format::__maybe_const_range<_Rg, > >_CharT>&, > >before formatting it. > > > >As in the case of previous commits, the signatures of the user-facing parse > >and format methods of the provided formatters deviate from the standard by > >constraining types of parameters: > >* _CharT is constrained __formatter::__char > >* basic_format_parse_context<_CharT> for parse argument > >* basic_format_context<_Out, _CharT> for format second argument > >The standard specifies last three of above as unconstrained types. > > > >Finally, test for tuple-like std::array and std::ranges::subrange, > >that illustrate that they remain formatted as ranges. > > > > PR libstdc++/PR109162 > > > >libstdc++-v3/ChangeLog: > > > > * include/std/format (__formatter_int::_M_format_character_escaped) > > (__formatter_str::format): Use __sink.out() to produce _Sink_iter. > > (__format::__const_formattable_range): Moved closer to > > range_formatter. > > (__format::__maybe_const_range): Use `__conditional_t` and moved > > closer > > to range_formatter. > > (__format::__format_padded, __format::maybe_const) > > (__format::__indexed_formatter_storage, __format::__tuple_formatter) > > (std::formatter<pair<_Fp, _Sp>, _CharT>>) > > (std::formatter<tuple<_Tps...>, _CharT): Define. > > (std::formatter<_Rg, _CharT>::format): Cast incoming range to > > __format::__maybe_const_range<_Rg, _CharT>&. > > (std::formatter<_Rg, _CharT>::_M_format): Extracted from format, > > and use __format_padded. > > (std::formatter<_Rg, _CharT>::_M_format_no_padding): Rename... > > (std::formatter<_Rg, _CharT>::_M_format_elems): ...to this. > > (std::formatter<_Rg, _CharT>::_M_format_with_padding): Extracted as > > __format_padded. > > * testsuite/util/testsuite_iterators.h (test_input_range_nocopy): > > Define. > > * testsuite/std/format/ranges/formatter.cc: Tests for `m` specifier. > > * testsuite/std/format/ranges/sequence.cc: Tests for array and > > subrange. > > * testsuite/std/format/ranges/map.cc: New test. > > * testsuite/std/format/tuple.cc: New test. > >--- > >I doged the which is safe, static_cast or const_cast discussion by > >calling: > >+ using __maybe_const_range > >+ = __format::__maybe_const_range<_Rg, _CharT>; > >+ return _M_format<__maybe_const_range>(__rg, __fc); > > OK. > > >I have also applied the `__conditional_t` to __maybe_const_range, > >and moved this two helpers closer to range_formatter. > > Thanks. > > And addressof is qualified, and trigger is renamed to _M_trigger. > > >OK for trunk? > > OK, thanks.
(With the base class removed from __indexed_formatter_storage of course)