1385913859 // \ref {format.formatter }, formatter
1386013860 template<class T, class charT = char> struct formatter;
1386113861
13862- // \ref {format.range.formatter }, class template \tcode {range_formatter}
13862+ // \ref {format.formattable }, concept \libconcept {formattable}
13863+ template<class T, class charT>
13864+ concept formattable = @\seebelow@ ;
13865+
13866+ template<class R, class charT>
13867+ concept @\defexposconcept {const-formattable-range}@ = // \expos
13868+ ranges::@\libconcept {input_range}@<const R> &&
13869+ @\libconcept {formattable}@<ranges::range_reference_t<const R>, charT>;
13870+
13871+ template<class R, class charT>
13872+ using @\exposid {fmt-maybe-const}@ = // \expos
13873+ conditional_t<@\exposconcept {const-formattable-range}@<R, charT>, const R, R>;
13874+
13875+ // \ref {format.parse.ctx }, class template \tcode {basic_format_parse_context}
13876+ template<class charT> class basic_format_parse_context;
13877+ using format_parse_context = basic_format_parse_context<char>;
13878+ using wformat_parse_context = basic_format_parse_context<wchar_t>;
13879+
13880+ // \ref {format.range }, formatting of ranges
13881+ // \ref {format.range.fmtkind }, variable template \tcode {format_kind}
1386313882 enum class range_format {
1386413883 disabled,
1386513884 map,
@@ -13876,37 +13895,21 @@
1387613895 requires @\libconcept {same_as}@<R, remove_cvref_t<R>>
1387713896 constexpr range_format format_kind<R> = @\seebelow@ ;
1387813897
13898+ // \ref {format.range.formatter }, class template \tcode {range_formatter}
1387913899 template<class T, class charT = char>
1388013900 requires @\libconcept {same_as}@<remove_cvref_t<T>, T> && @\libconcept {formattable}@<T, charT>
1388113901 class range_formatter;
1388213902
13903+ // \ref {format.range.fmtdef }, class template \tcode {\exposid {range-default-formatter}}
1388313904 template<range_format K, ranges::@\libconcept {input_range}@ R, class charT>
1388413905 struct @\exposid {range-default-formatter}@; // \expos
1388513906
13886- // \ref {format.formatter.spec }, formatter specializations
13907+ // \ref {format.range.fmtmap }, \ref { format.range.fmtset }, \ref { format.range.fmtstr }, specializations for maps, sets, and strings
1388713908 template<ranges::@\libconcept {input_range}@ R, class charT>
1388813909 requires (format_kind<R> != range_format::disabled) &&
1388913910 @\libconcept {formattable}@<ranges::range_reference_t<R>, charT>
1389013911 struct formatter<R, charT> : @\exposid {range-default-formatter}@<format_kind<R>, R, charT> { };
1389113912
13892- // \ref {format.parse.ctx }, class template \tcode {basic_format_parse_context}
13893- template<class charT> class basic_format_parse_context;
13894- using format_parse_context = basic_format_parse_context<char>;
13895- using wformat_parse_context = basic_format_parse_context<wchar_t>;
13896-
13897- // \ref {format.formattable }, concept \libconcept {formattable}
13898- template<class T, class charT>
13899- concept formattable = @\seebelow@ ;
13900-
13901- template<class R, class charT>
13902- concept @\defexposconcept {const-formattable-range}@ = // \expos
13903- ranges::@\libconcept {input_range}@<const R> &&
13904- @\libconcept {formattable}@<ranges::range_reference_t<const R>, charT>;
13905-
13906- template<class R, class charT>
13907- using @\exposid {fmt-maybe-const}@ = // \expos
13908- conditional_t<@\exposconcept {const-formattable-range}@<R, charT>, const R, R>;
13909-
1391013913 // \ref {format.arguments }, arguments
1391113914 // \ref {format.arg }, class template \tcode {basic_format_arg}
1391213915 template<class Context> class basic_format_arg;
1566815671\end {codeblock }
1566915672\end {example }
1567015673
15671- \rSec 2[format.range.formatter]{Class template \tcode {range_formatter}}
15674+ \rSec 2[format.range]{Formatting of ranges}
15675+
15676+ \rSec 3[format.range.fmtkind]{Variable template \tcode {format_kind}}
15677+
15678+ \indexlibraryglobal {format_kind}
15679+ \begin {itemdecl }
15680+ template<ranges::@\libconcept {input_range}@ R>
15681+ requires @\libconcept {same_as}@<R, remove_cvref_t<R>>
15682+ constexpr range_format format_kind<R> = @\seebelow@ ;
15683+ \end {itemdecl }
15684+
15685+ \begin {itemdescr }
15686+ \pnum
15687+ A program that instantiates the primary template of \tcode {format_kind}
15688+ is ill-formed.
15689+
15690+ \pnum
15691+ For a type \tcode {R}, \tcode {format_kind<R>} is defined as follows:
15692+ \begin {itemize }
15693+ \item
15694+ If \tcode {\libconcept {same_as}<remove_cvref_t<ranges::range_reference_t<R>>, R>}
15695+ is \tcode {true},
15696+ \tcode {format_kind<R>} is \tcode {range_format::disabled}.
15697+ \begin {note }
15698+ This prevents constraint recursion for ranges whose
15699+ reference type is the same range type.
15700+ For example,
15701+ \tcode {std::filesystem::path} is a range of \tcode {std::filesystem::path}.
15702+ \end {note }
15703+
15704+ \item
15705+ Otherwise, if the \grammarterm {qualified-id} \tcode {R::key_type}
15706+ is valid and denotes a type:
15707+ \begin {itemize }
15708+ \item
15709+ If the \grammarterm {qualified-id} \tcode {R::mapped_type}
15710+ is valid and denotes a type,
15711+ let \tcode {U} be \tcode {remove_cvref_t<ranges::range_reference_t<R>>}.
15712+ If either \tcode {U} is a specialization of \tcode {pair} or
15713+ \tcode {U} is a specialization of \tcode {tuple} and
15714+ \tcode {tuple_size_v<U> == 2},
15715+ \tcode {format_kind<R>} is \tcode {range_format::map}.
15716+ \item
15717+ Otherwise, \tcode {format_kind<R>} is \tcode {range_format::set}.
15718+ \end {itemize }
15719+
15720+ \item
15721+ Otherwise, \tcode {format_kind<R>} is \tcode {range_format::sequence}.
15722+ \end {itemize }
15723+
15724+ \pnum
15725+ \remarks
15726+ Pursuant to \ref {namespace.std }, users may specialize \tcode {format_kind}
15727+ for cv-unqualified program-defined types
15728+ that model \tcode {ranges::\libconcept {input_range}}.
15729+ Such specializations shall be usable in constant expressions\iref {expr.const }
15730+ and have type \tcode {const range_format}.
15731+ \end {itemdescr }
15732+
15733+ \rSec 3[format.range.formatter]{Class template \tcode {range_formatter}}
15734+
15735+ \indexlibraryglobal {range_formatter}%
15736+ \begin {codeblock }
15737+ namespace std {
15738+ template<class T, class charT = char>
15739+ requires @\libconcept {same_as}@<remove_cvref_t<T>, T> && @\libconcept {formattable}@<T, charT>
15740+ class range_formatter {
15741+ formatter<T, charT> @\exposid {underlying_}@; // \expos
15742+ basic_string_view<charT> @\exposid {separator_}@ = @\exposid {STATICALLY-WIDEN}@<charT>(", "); // \expos
15743+ basic_string_view<charT> @\exposid {opening-bracket_}@ = @\exposid {STATICALLY-WIDEN}@<charT>("["); // \expos
15744+ basic_string_view<charT> @\exposid {closing-bracket_}@ = @\exposid {STATICALLY-WIDEN}@<charT>("]"); // \expos
15745+
15746+ public:
15747+ constexpr void set_separator(basic_string_view<charT> sep);
15748+ constexpr void set_brackets(basic_string_view<charT> opening,
15749+ basic_string_view<charT> closing);
15750+ constexpr formatter<T, charT>& underlying() { return @\exposid {underlying_}@; }
15751+ constexpr const formatter<T, charT>& underlying() const { return @\exposid {underlying_}@; }
15752+
15753+ template<class ParseContext>
15754+ constexpr typename ParseContext::iterator
15755+ parse(ParseContext& ctx);
15756+
15757+ template<ranges::@\libconcept {input_range}@ R, class FormatContext>
15758+ requires @\libconcept {formattable}@<ranges::range_reference_t<R>, charT> &&
15759+ @\libconcept {same_as}@<remove_cvref_t<ranges::range_reference_t<R>>, T>
15760+ typename FormatContext::iterator
15761+ format(R&& r, FormatContext& ctx) const;
15762+ };
15763+ }
15764+ \end {codeblock }
1567215765
1567315766\pnum
1567415767The class template \tcode {range_formatter} is a utility
1576815861then there shall be
1576915862no \tcode {n} option and no \fmtgrammarterm {range-underlying-spec}.
1577015863
15771- \indexlibraryglobal {format_kind}
15772- \begin {itemdecl }
15773- template<ranges::@\libconcept {input_range}@ R>
15774- requires @\libconcept {same_as}@<R, remove_cvref_t<R>>
15775- constexpr range_format format_kind<R> = @\seebelow@ ;
15776- \end {itemdecl }
15777-
15778- \begin {itemdescr }
15779- \pnum
15780- A program that instantiates the primary template of \tcode {format_kind}
15781- is ill-formed.
15782-
15783- \pnum
15784- For a type \tcode {R}, \tcode {format_kind<R>} is defined as follows:
15785- \begin {itemize }
15786- \item
15787- If \tcode {\libconcept {same_as}<remove_cvref_t<ranges::range_reference_t<R>>, R>}
15788- is \tcode {true},
15789- \tcode {format_kind<R>} is \tcode {range_format::disabled}.
15790- \begin {note }
15791- This prevents constraint recursion for ranges whose
15792- reference type is the same range type.
15793- For example,
15794- \tcode {std::filesystem::path} is a range of \tcode {std::filesystem::path}.
15795- \end {note }
15796-
15797- \item
15798- Otherwise, if the \grammarterm {qualified-id} \tcode {R::key_type}
15799- is valid and denotes a type:
15800- \begin {itemize }
15801- \item
15802- If the \grammarterm {qualified-id} \tcode {R::mapped_type}
15803- is valid and denotes a type,
15804- let \tcode {U} be \tcode {remove_cvref_t<ranges::range_reference_t<R>>}.
15805- If either \tcode {U} is a specialization of \tcode {pair} or
15806- \tcode {U} is a specialization of \tcode {tuple} and
15807- \tcode {tuple_size_v<U> == 2},
15808- \tcode {format_kind<R>} is \tcode {range_format::map}.
15809- \item
15810- Otherwise, \tcode {format_kind<R>} is \tcode {range_format::set}.
15811- \end {itemize }
15812-
15813- \item
15814- Otherwise, \tcode {format_kind<R>} is \tcode {range_format::sequence}.
15815- \end {itemize }
15816-
15817- \pnum
15818- \remarks
15819- Pursuant to \ref {namespace.std }, users may specialize \tcode {format_kind}
15820- for cv-unqualified program-defined types
15821- that model \tcode {ranges::\libconcept {input_range}}.
15822- Such specializations shall be usable in constant expressions\iref {expr.const }
15823- and have type \tcode {const range_format}.
15824- \end {itemdescr }
15825-
15826- \indexlibraryglobal {range_formatter}%
15827- \begin {codeblock }
15828- namespace std {
15829- template<class T, class charT = char>
15830- requires @\libconcept {same_as}@<remove_cvref_t<T>, T> && @\libconcept {formattable}@<T, charT>
15831- class range_formatter {
15832- formatter<T, charT> @\exposid {underlying_}@; // \expos
15833- basic_string_view<charT> @\exposid {separator_}@ = @\exposid {STATICALLY-WIDEN}@<charT>(", "); // \expos
15834- basic_string_view<charT> @\exposid {opening-bracket_}@ = @\exposid {STATICALLY-WIDEN}@<charT>("["); // \expos
15835- basic_string_view<charT> @\exposid {closing-bracket_}@ = @\exposid {STATICALLY-WIDEN}@<charT>("]"); // \expos
15836-
15837- public:
15838- constexpr void set_separator(basic_string_view<charT> sep);
15839- constexpr void set_brackets(basic_string_view<charT> opening,
15840- basic_string_view<charT> closing);
15841- constexpr formatter<T, charT>& underlying() { return @\exposid {underlying_}@; }
15842- constexpr const formatter<T, charT>& underlying() const { return @\exposid {underlying_}@; }
15843-
15844- template<class ParseContext>
15845- constexpr typename ParseContext::iterator
15846- parse(ParseContext& ctx);
15847-
15848- template<ranges::@\libconcept {input_range}@ R, class FormatContext>
15849- requires @\libconcept {formattable}@<ranges::range_reference_t<R>, charT> &&
15850- @\libconcept {same_as}@<remove_cvref_t<ranges::range_reference_t<R>>, T>
15851- typename FormatContext::iterator
15852- format(R&& r, FormatContext& ctx) const;
15853- };
15854- }
15855- \end {codeblock }
15856-
1585715864\indexlibrarymember {set_separator}{range_formatter}%
1585815865\begin {itemdecl }
1585915866constexpr void set_separator(basic_string_view<charT> sep);
1595815965An iterator past the end of the output range.
1595915966\end {itemdescr }
1596015967
15968+ \rSec 3[format.range.fmtdef]{Class template \tcode {\exposid {range-default-formatter}}}
15969+
1596115970\indexlibraryglobal {\exposid {range-default-formatter}}%
1596215971\begin {codeblock }
1596315972namespace std {
1603216041Equivalent to: \tcode {return \exposid {underlying_}.format(elems, ctx);}
1603316042\end {itemdescr }
1603416043
16044+ \rSec 3[format.range.fmtmap]{Specialization of \tcode {\exposid {range-default-formatter}} for maps}
16045+
1603516046\indexlibraryglobal {\exposid {range-default-formatter}}%
1603616047\begin {codeblock }
1603716048namespace std {
1610916120Equivalent to: \tcode {return \exposid {underlying_}.format(r, ctx);}
1611016121\end {itemdescr }
1611116122
16123+ \rSec 3[format.range.fmtset]{Specialization of \tcode {\exposid {range-default-formatter}} for sets}
16124+
1611216125\indexlibraryglobal {\exposid {range-default-formatter}}%
1611316126\begin {codeblock }
1611416127namespace std {
@@ -16173,12 +16186,13 @@
1617316186Equivalent to: \tcode {return \exposid {underlying_}.format(r, ctx);}
1617416187\end {itemdescr }
1617516188
16189+ \rSec 3[format.range.fmtstr]{Specialization of \tcode {\exposid {range-default-formatter}} for strings}
16190+
1617616191\indexlibraryglobal {\exposid {range-default-formatter}}%
1617716192\begin {codeblock }
1617816193namespace std {
1617916194 template<range_format K, ranges::@\libconcept {input_range}@ R, class charT>
16180- requires (K == range_format::string ||
16181- K == range_format::debug_string)
16195+ requires (K == range_format::string || K == range_format::debug_string)
1618216196 struct @\exposid {range-default-formatter}@<K, R, charT> {
1618316197 private:
1618416198 formatter<basic_string<charT>, charT> @\exposid {underlying_}@; // \expos
0 commit comments