This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.

### 2344. `quoted()`'s interaction with padding is unclear

Section: 29.7.8 [quoted.manip] Status: C++14 Submitter: Stephan T. Lavavej Opened: 2013-11-01 Last modified: 2016-01-28

Priority: 1

View all other issues in [quoted.manip].

View all issues with C++14 status.

Discussion:

Given this code:

>     cout << "[" << left << setfill('x') << setw(20) << R"("AB \"CD\" EF")" << "]" << endl;
>     cout << "[" << left << setfill('y') << setw(20) << quoted(R"(GH "IJ" KL)") << "]" << endl;

The first line prints `["AB \"CD\" EF"xxxxxx]`. The second line should probably print `["GH \"IJ\" KL"yyyyyy]`, but 29.7.8 [quoted.manip]/2 doesn't say whether or how `quoted()` should interact with padding. All it says is that

> "`out << quoted(s, delim, escape)` behaves as if it inserts the following characters into out using character inserter function templates (27.7.3.6.4)".

29.7.5.3.4 [ostream.inserters.character] specifies both single-character and null-terminated inserters, both referring to 29.7.5.3.1 [ostream.formatted.reqmts]/3 for padding. Literally implementing `quoted()` with single-character inserters would result in padding being emitted after the first character, with undesirable effects for `ios_base::left`.

It appears that 21.3.4.4 [string.io]/5 has the appropriate incantations to follow here. It says that `os << str`

> "Behaves as a formatted output function (27.7.3.6.1) of `os`. Forms a character sequence `seq`, initially consisting of the elements defined by the range `[str.begin(), str.end())`. Determines padding for `seq` as described in 27.7.3.6.1. Then inserts `seq` as if by calling `os.rdbuf()->sputn(seq, n)`, where `n` is the larger of `os.width()` and `str.size();` then calls `os.width(0)`."

Additionally, saying that it's a "formatted output function" activates 29.7.5.3.1 [ostream.formatted.reqmts]/1's wording for sentry objects.

[2014-02-14 Issaquah meeting: Move to Immediate]

Proposed resolution:

This wording is relative to N3797.

1. Edit 29.7.8 [quoted.manip] as follows:

   >     template <class charT>
   >       unspecified quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\'));
   >     template <class charT, class traits, class Allocator>
   >       unspecified quoted(const basic_string<charT, traits, Allocator>& s,
   >                          charT delim=charT('"'), charT escape=charT('\\'));

   > > -2- Returns: An object of unspecified type such that if `out` is an instance of `basic_ostream` with member type `char_type` the same as `charT`, then the expression `out << quoted(s, delim, escape)` behaves as if it inserts the following characters into `out` using character inserter function templates (27.7.3.6.4), which may throw `ios_base::failure` (27.5.3.1.1)a formatted output function (29.7.5.3.1 [ostream.formatted.reqmts]) of `out`. This forms a character sequence `seq`, initially consisting of the following elements:

   > > - `delim`.

   > > - Each character in `s`. If the character to be output is equal to escape or `delim`, as determined by `operator==`, first output `escape`.

   > > - `delim`.

   > > Let `x` be the number of elements initially in `seq`. Then padding is determined for `seq` as described in 29.7.5.3.1 [ostream.formatted.reqmts], `seq` is inserted as if by calling `out.rdbuf()->sputn(seq, n)`, where `n` is the larger of `out.width()` and `x`, and `out.width(0)` is called. The expression `out << quoted(s, delim, escape)` shall have type `basic_ostream<charT, traits>&` and value `out`.