[format.tuple]

# 28 Text processing library [[text]](./#text)

## 28.5 Formatting [[format]](format#tuple)

### 28.5.9 Tuple formatter [format.tuple]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8755)

For each of pair and tuple,
the library provides the following formatter specialization
where *pair-or-tuple* is the name of the template:

[ð](#lib:formatter)

namespace std {template<class charT, [formattable](format.formattable#concept:formattable "28.5.6.3 Concept formattable [format.formattable]")<charT>... Ts>struct formatter<*pair-or-tuple*<Ts...>, charT> {private: tuple<formatter<remove_cvref_t<Ts>, charT>...> *underlying_*; // *exposition only* basic_string_view<charT> *separator_* = *STATICALLY-WIDEN*<charT>(", "); // *exposition only* basic_string_view<charT> *opening-bracket_* = *STATICALLY-WIDEN*<charT>("("); // *exposition only* basic_string_view<charT> *closing-bracket_* = *STATICALLY-WIDEN*<charT>(")"); // *exposition only*public:constexpr void set_separator(basic_string_view<charT> sep) noexcept; constexpr void set_brackets(basic_string_view<charT> opening,
 basic_string_view<charT> closing) noexcept; template<class ParseContext>constexpr typename ParseContext::iterator
 parse(ParseContext& ctx); template<class FormatContext>typename FormatContext::iterator
 format(*see below*& elems, FormatContext& ctx) const; }; template<class... Ts>constexpr bool enable_nonlocking_formatter_optimization<*pair-or-tuple*<Ts...>> =(enable_nonlocking_formatter_optimization<Ts> && ...);}

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8791)

The parse member functions of these formatters
interpret the format specification as
a *tuple-format-spec* according to the following syntax:

tuple-format-spec :  
tuple-fill-and-alignopt widthopt tuple-typeopt

tuple-fill-and-align :  
tuple-fillopt align

tuple-fill :  
any character other than { or } or :

tuple-type :  
m  
n

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8817)

The *tuple-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"))[.](#3.sentence-1)

The productions *align* and *width* are described in [[format.string]](format.string "28.5.2 Format string")[.](#3.sentence-2)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8823)

The *tuple-type* specifier
changes the way a pair or tuple is formatted,
with certain options only valid with certain argument types[.](#4.sentence-1)

The meaning of the various type options
is as specified in Table [116](#tab:formatter.tuple.type "Table 116: Meaning of tuple-type options")[.](#4.sentence-2)

Table [116](#tab:formatter.tuple.type) — Meaning of *tuple-type* options [[tab:formatter.tuple.type]](./tab:formatter.tuple.type)  

| [ð](#tab:formatter.tuple.type-row-1)<br>**Option** | **Requirements** | **Meaning** |
| --- | --- | --- |
| [ð](#tab:formatter.tuple.type-row-2)<br>m | sizeof...(Ts) == 2 | Equivalent to: set_separator(*STATICALLY-WIDEN*<charT>(": ")); set_brackets({}, {}); |
| [ð](#tab:formatter.tuple.type-row-3)<br>n | none | Equivalent to: set_brackets({}, {}); |
| [ð](#tab:formatter.tuple.type-row-4)<br>none | none | No effects |

[ð](#lib:set_separator,formatter)

`constexpr void set_separator(basic_string_view<charT> sep) noexcept;
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8861)

*Effects*: Equivalent to: *separator_* = sep;

[ð](#lib:set_brackets,formatter)

`constexpr void set_brackets(basic_string_view<charT> opening,
                            basic_string_view<charT> closing) noexcept;
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8873)

*Effects*: Equivalent to:*opening-bracket_* = opening;*closing-bracket_* = closing;

[ð](#lib:parse,formatter)

`template<class ParseContext>
  constexpr typename ParseContext::iterator
    parse(ParseContext& ctx);
`

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8890)

*Effects*: Parses the format specifiers as a *tuple-format-spec* and
stores the parsed specifiers in *this[.](#7.sentence-1)

The values of*opening-bracket_*,*closing-bracket_*, and*separator_* are modified if and only if
required by the *tuple-type*, if present[.](#7.sentence-2)

For each element *e* in *underlying_*,
calls *e*.parse(ctx) to parse
an empty *format-spec* and,
if *e*.set_debug_format() is a valid expression,
calls *e*.set_debug_format()[.](#7.sentence-3)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8906)

*Returns*: An iterator past the end of the *tuple-format-spec*[.](#8.sentence-1)

[ð](#lib:format,formatter)

`template<class FormatContext>
  typename FormatContext::iterator
    format(see below& elems, FormatContext& ctx) const;
`

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8919)

The type of elems is:

- [(9.1)](#9.1)

  If ([formattable](format.formattable#concept:formattable "28.5.6.3 Concept formattable [format.formattable]")<const Ts, charT> && ...) is true,const *pair-or-tuple*<Ts...>&[.](#9.1.sentence-1)

- [(9.2)](#9.2)

  Otherwise *pair-or-tuple*<Ts...>&[.](#9.2.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8929)

*Effects*: Writes the following into ctx.out(),
adjusted according to the *tuple-format-spec*:

- [(10.1)](#10.1)

*opening-bracket_*,

- [(10.2)](#10.2)

for each index I in the [0, sizeof...(Ts)):
  * [(10.2.1)](#10.2.1)

if I != 0, *separator_*,

  * [(10.2.2)](#10.2.2)

the result of writing get<I>(elems) via get<I>(*underlying_*), and

- [(10.3)](#10.3)

*closing-bracket_*[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L8949)

*Returns*: An iterator past the end of the output range[.](#11.sentence-1)
