[format.range.formatter] # 28 Text processing library [[text]](./#text) ## 28.5 Formatting [[format]](format#range.formatter) ### 28.5.7 Formatting of ranges [[format.range]](format.range#formatter) #### 28.5.7.2 Class template range_formatter [format.range.formatter] [🔗](#lib:range_formatter) namespace std {templaterequires [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"), T> && [formattable](format.formattable#concept:formattable "28.5.6.3 Concept formattable [format.formattable]")class range_formatter { formatter *underlying_*; // *exposition only* basic_string_view *separator_* = *STATICALLY-WIDEN*(", "); // *exposition only* basic_string_view *opening-bracket_* = *STATICALLY-WIDEN*("["); // *exposition only* basic_string_view *closing-bracket_* = *STATICALLY-WIDEN*("]"); // *exposition only*public:constexpr void set_separator(basic_string_view sep) noexcept; constexpr void set_brackets(basic_string_view opening, basic_string_view closing) noexcept; constexpr formatter& underlying() noexcept { return *underlying_*; }constexpr const formatter& underlying() const noexcept { return *underlying_*; }templateconstexpr typename ParseContext::iterator parse(ParseContext& ctx); templaterequires [formattable](format.formattable#concept:formattable "28.5.6.3 Concept formattable [format.formattable]"), charT> &&[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>, T>typename FormatContext::iterator format(R&& r, FormatContext& ctx) const; };} [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7921) The class template range_formatter is a utility for implementing formatter specializations for range types[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7925) range_formatter interprets *format-spec* as a *range-format-spec*[.](#2.sentence-1) The syntax of format specifications is as follows: range-format-spec : range-fill-and-alignopt widthopt nopt range-typeopt range-underlying-specopt range-fill-and-align : range-fillopt align range-fill : any character other than { or } or : range-type : m s ?s range-underlying-spec : : format-spec [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7957) For range_formatter, the *format-spec* in a *range-underlying-spec*, if any, is interpreted by formatter[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7963) The *range-fill-and-align* is interpreted the same way as a *fill-and-align* ([[format.string.std]](format.string.std "28.5.2.2 Standard format specifiers"))[.](#4.sentence-1) The productions *align* and *width* are described in [[format.string]](format.string "28.5.2 Format string")[.](#4.sentence-2) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7969) The n option causes the range to be formatted without the opening and closing brackets[.](#5.sentence-1) [*Note [1](#note-1)*: This is equivalent to invoking set_brackets({}, {})[.](#5.sentence-2) — *end note*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L7976) The *range-type* specifier changes the way a range is formatted, with certain options only valid with certain argument types[.](#6.sentence-1) The meaning of the various type options is as specified in Table [115](#tab:formatter.range.type "Table 115: Meaning of range-type options")[.](#6.sentence-2) Table [115](#tab:formatter.range.type) — Meaning of *range-type* options [[tab:formatter.range.type]](./tab:formatter.range.type) | [🔗](#tab:formatter.range.type-row-1)
**Option** | **Requirements** | **Meaning** | | --- | --- | --- | | [🔗](#tab:formatter.range.type-row-2)
m | T shall be either a specialization of pair or a specialization of tuple such that tuple_size_v is 2[.](#tab:formatter.range.type-row-2-column-2-sentence-1) | Indicates that the opening bracket should be "{", the closing bracket should be "}", the separator should be ", ", and each range element should be formatted as if m were specified for its *tuple-type*[.](#tab:formatter.range.type-row-2-column-3-sentence-1)
[*Note [2](#tab:formatter.range.type-row-2-column-3-note-2)*:
If the n option is provided in addition to the m option, both the opening and closing brackets are still empty[.](#tab:formatter.range.type-row-2-column-3-sentence-2) — *end note*] | | [🔗](#tab:formatter.range.type-row-3)
s | T shall be charT[.](#tab:formatter.range.type-row-3-column-2-sentence-1) | Indicates that the range should be formatted as a string[.](#tab:formatter.range.type-row-3-column-3-sentence-1) | | [🔗](#tab:formatter.range.type-row-4)
?s | T shall be charT[.](#tab:formatter.range.type-row-4-column-2-sentence-1) | Indicates that the range should be formatted as an escaped string ([[format.string.escaped]](format.string.escaped "28.5.6.5 Formatting escaped characters and strings"))[.](#tab:formatter.range.type-row-4-column-3-sentence-1) | If the *range-type* is s or ?s, then there shall be no n option and no *range-underlying-spec*[.](#6.sentence-3) [🔗](#lib:set_separator,range_formatter) `constexpr void set_separator(basic_string_view sep) noexcept; ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8025) *Effects*: Equivalent to: *separator_* = sep; [🔗](#lib:set_brackets,range_formatter) `constexpr void set_brackets(basic_string_view opening, basic_string_view closing) noexcept; ` [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8037) *Effects*: Equivalent to:*opening-bracket_* = opening;*closing-bracket_* = closing; [🔗](#lib:parse,range_formatter) `template constexpr typename ParseContext::iterator parse(ParseContext& ctx); ` [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8054) *Effects*: Parses the format specifiers as a *range-format-spec* and stores the parsed specifiers in *this[.](#9.sentence-1) Calls *underlying_*.parse(ctx) to parse*format-spec* in *range-format-spec* or, if the latter is not present, an empty *format-spec*[.](#9.sentence-2) The values of*opening-bracket_*, *closing-bracket_*, and *separator_* are modified if and only if required by the *range-type* or the n option, if present[.](#9.sentence-3) If: - [(9.1)](#9.1) the *range-type* is neither s nor ?s, - [(9.2)](#9.2) *underlying_*.set_debug_format() is a valid expression, and - [(9.3)](#9.3) there is no *range-underlying-spec*, then calls *underlying_*.set_debug_format()[.](#9.sentence-4) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8076) *Returns*: An iterator past the end of the *range-format-spec*[.](#10.sentence-1) [🔗](#lib:format,range_formatter) `template requires [formattable](format.formattable#concept:formattable "28.5.6.3 Concept formattable [format.formattable]"), charT> && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>, T> typename FormatContext::iterator format(R&& r, FormatContext& ctx) const; ` [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8091) *Effects*: Writes the following into ctx.out(), adjusted according to the *range-format-spec*: - [(11.1)](#11.1) If the *range-type* was s, then as if by formatting basic_string(from_range, r)[.](#11.1.sentence-1) - [(11.2)](#11.2) Otherwise, if the *range-type* was ?s, then as if by formatting basic_string(from_range, r) as an escaped string ([[format.string.escaped]](format.string.escaped "28.5.6.5 Formatting escaped characters and strings"))[.](#11.2.sentence-1) - [(11.3)](#11.3) Otherwise, * [(11.3.1)](#11.3.1) *opening-bracket_*, * [(11.3.2)](#11.3.2) for each element e of the range r: + [(11.3.2.1)](#11.3.2.1) the result of writing e via *underlying_* and + [(11.3.2.2)](#11.3.2.2) *separator_*, unless e is the last element of r, and * [(11.3.3)](#11.3.3) *closing-bracket_*[.](#11.3.sentence-1) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8122) *Returns*: An iterator past the end of the output range[.](#12.sentence-1)