From Jason Turner

[iostream.format]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwo0e7b8y/{from.md → to.md} +173 -97
tmp/tmpwo0e7b8y/{from.md → to.md} RENAMED
@@ -2,40 +2,46 @@
2
 
3
  ### Header `<istream>` synopsis <a id="istream.syn">[[istream.syn]]</a>
4
 
5
  ``` cpp
6
  namespace std {
 
7
  template<class charT, class traits = char_traits<charT>>
8
  class basic_istream;
9
 
10
  using istream = basic_istream<char>;
11
  using wistream = basic_istream<wchar_t>;
12
 
 
13
  template<class charT, class traits = char_traits<charT>>
14
  class basic_iostream;
15
 
16
  using iostream = basic_iostream<char>;
17
  using wiostream = basic_iostream<wchar_t>;
18
 
 
19
  template<class charT, class traits>
20
  basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);
21
 
 
22
  template<class Istream, class T>
23
  Istream&& operator>>(Istream&& is, T&& x);
24
  }
25
  ```
26
 
27
  ### Header `<ostream>` synopsis <a id="ostream.syn">[[ostream.syn]]</a>
28
 
29
  ``` cpp
30
  namespace std {
 
31
  template<class charT, class traits = char_traits<charT>>
32
  class basic_ostream;
33
 
34
  using ostream = basic_ostream<char>;
35
  using wostream = basic_ostream<wchar_t>;
36
 
 
37
  template<class charT, class traits>
38
  basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& os);
39
  template<class charT, class traits>
40
  basic_ostream<charT, traits>& ends(basic_ostream<charT, traits>& os);
41
  template<class charT, class traits>
@@ -46,39 +52,45 @@ namespace std {
46
  template<class charT, class traits>
47
  basic_ostream<charT, traits>& noemit_on_flush(basic_ostream<charT, traits>& os);
48
  template<class charT, class traits>
49
  basic_ostream<charT, traits>& flush_emit(basic_ostream<charT, traits>& os);
50
 
 
51
  template<class Ostream, class T>
52
  Ostream&& operator<<(Ostream&& os, const T& x);
53
 
54
  // [ostream.formatted.print], print functions
55
  template<class... Args>
56
  void print(ostream& os, format_string<Args...> fmt, Args&&... args);
57
  template<class... Args>
58
  void println(ostream& os, format_string<Args...> fmt, Args&&... args);
 
59
 
60
  void vprint_unicode(ostream& os, string_view fmt, format_args args);
61
  void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
62
  }
63
  ```
64
 
65
  ### Header `<iomanip>` synopsis <a id="iomanip.syn">[[iomanip.syn]]</a>
66
 
67
  ``` cpp
68
  namespace std {
 
69
  unspecified resetiosflags(ios_base::fmtflags mask);
70
  unspecified setiosflags (ios_base::fmtflags mask);
71
  unspecified setbase(int base);
72
  template<class charT> unspecified setfill(charT c);
73
  unspecified setprecision(int n);
74
  unspecified setw(int n);
 
 
75
  template<class moneyT> unspecified get_money(moneyT& mon, bool intl = false);
76
  template<class moneyT> unspecified put_money(const moneyT& mon, bool intl = false);
77
  template<class charT> unspecified get_time(tm* tmb, const charT* fmt);
78
  template<class charT> unspecified put_time(const tm* tmb, const charT* fmt);
79
 
 
80
  template<class charT>
81
  unspecified quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\'));
82
 
83
  template<class charT, class traits, class Allocator>
84
  unspecified quoted(const basic_string<charT, traits, Allocator>& s,
@@ -104,18 +116,22 @@ namespace std {
104
  template<class... Args>
105
  void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
106
 
107
  template<class... Args>
108
  void println(format_string<Args...> fmt, Args&&... args);
 
109
  template<class... Args>
110
  void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
 
111
 
112
  void vprint_unicode(string_view fmt, format_args args);
113
  void vprint_unicode(FILE* stream, string_view fmt, format_args args);
 
114
 
115
  void vprint_nonunicode(string_view fmt, format_args args);
116
  void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
 
117
  }
118
  ```
119
 
120
  ### Input streams <a id="input.streams">[[input.streams]]</a>
121
 
@@ -139,13 +155,13 @@ namespace std {
139
  template<class charT, class traits = char_traits<charT>>
140
  class basic_istream : virtual public basic_ios<charT, traits> {
141
  public:
142
  // types (inherited from basic_ios[ios])
143
  using char_type = charT;
144
- using int_type = typename traits::int_type;
145
- using pos_type = typename traits::pos_type;
146
- using off_type = typename traits::off_type;
147
  using traits_type = traits;
148
 
149
  // [istream.cons], constructor/destructor
150
  explicit basic_istream(basic_streambuf<charT, traits>* sb);
151
  virtual ~basic_istream();
@@ -186,10 +202,11 @@ namespace std {
186
 
187
  basic_istream& getline(char_type* s, streamsize n);
188
  basic_istream& getline(char_type* s, streamsize n, char_type delim);
189
 
190
  basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof());
 
191
  int_type peek();
192
  basic_istream& read (char_type* s, streamsize n);
193
  streamsize readsome(char_type* s, streamsize n);
194
 
195
  basic_istream& putback(char_type c);
@@ -267,11 +284,11 @@ virtual ~basic_istream();
267
 
268
  ``` cpp
269
  basic_istream& operator=(basic_istream&& rhs);
270
  ```
271
 
272
- *Effects:* Equivalent to: `swap(rhs)`.
273
 
274
  *Returns:* `*this`.
275
 
276
  ``` cpp
277
  void swap(basic_istream& rhs);
@@ -339,12 +356,12 @@ const ctype<charT>& ctype = use_facet<ctype<charT>>(is.getloc());
339
  if (ctype.is(ctype.space, c) != 0)
340
  // c is a whitespace character.
341
  ```
342
 
343
  If, after any preparation is completed, `is.good()` is `true`,
344
- `ok_ != false` otherwise, `ok_ == false`. During preparation, the
345
- constructor may call `setstate(failbit)` (which may throw
346
  `ios_base::failure` [[iostate.flags]]).[^19]
347
 
348
  ``` cpp
349
  ~sentry();
350
  ```
@@ -353,11 +370,11 @@ constructor may call `setstate(failbit)` (which may throw
353
 
354
  ``` cpp
355
  explicit operator bool() const;
356
  ```
357
 
358
- *Returns:* `ok_`.
359
 
360
  #### Formatted input functions <a id="istream.formatted">[[istream.formatted]]</a>
361
 
362
  ##### Common requirements <a id="istream.formatted.reqmts">[[istream.formatted.reqmts]]</a>
363
 
@@ -791,11 +808,11 @@ int main() {
791
 
792
  ``` cpp
793
  basic_istream& getline(char_type* s, streamsize n);
794
  ```
795
 
796
- *Returns:* `getline(s, n, widen(’\n’))`
797
 
798
  ``` cpp
799
  basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof());
800
  ```
801
 
@@ -803,11 +820,11 @@ basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof());
803
  above). After constructing a `sentry` object, extracts characters and
804
  discards them. Characters are extracted until any of the following
805
  occurs:
806
 
807
  - `n != numeric_limits<streamsize>::max()` [[numeric.limits]] and `n`
808
- characters have been extracted so far
809
  - end-of-file occurs on the input sequence (in which case the function
810
  calls `setstate(eofbit)`, which may throw `ios_base::failure`
811
  [[iostate.flags]]);
812
  - `traits::eq_int_type(traits::to_int_type(c), delim)` for the next
813
  available input character `c` (in which case `c` is extracted).
@@ -815,10 +832,19 @@ occurs:
815
  [*Note 1*: The last condition will never occur if
816
  `traits::eq_int_type(delim, traits::eof())`. — *end note*]
817
 
818
  *Returns:* `*this`.
819
 
 
 
 
 
 
 
 
 
 
820
  ``` cpp
821
  int_type peek();
822
  ```
823
 
824
  *Effects:* Behaves as an unformatted input function (as described
@@ -1006,13 +1032,13 @@ namespace std {
1006
  class basic_iostream
1007
  : public basic_istream<charT, traits>,
1008
  public basic_ostream<charT, traits> {
1009
  public:
1010
  using char_type = charT;
1011
- using int_type = typename traits::int_type;
1012
- using pos_type = typename traits::pos_type;
1013
- using off_type = typename traits::off_type;
1014
  using traits_type = traits;
1015
 
1016
  // [iostream.cons], constructor
1017
  explicit basic_iostream(basic_streambuf<charT, traits>* sb);
1018
 
@@ -1067,11 +1093,11 @@ virtual ~basic_iostream();
1067
 
1068
  ``` cpp
1069
  basic_iostream& operator=(basic_iostream&& rhs);
1070
  ```
1071
 
1072
- *Effects:* Equivalent to: `swap(rhs)`.
1073
 
1074
  ``` cpp
1075
  void swap(basic_iostream& rhs);
1076
  ```
1077
 
@@ -1098,13 +1124,13 @@ namespace std {
1098
  template<class charT, class traits = char_traits<charT>>
1099
  class basic_ostream : virtual public basic_ios<charT, traits> {
1100
  public:
1101
  // types (inherited from basic_ios[ios])
1102
  using char_type = charT;
1103
- using int_type = typename traits::int_type;
1104
- using pos_type = typename traits::pos_type;
1105
- using off_type = typename traits::off_type;
1106
  using traits_type = traits;
1107
 
1108
  // [ostream.cons], constructor/destructor
1109
  explicit basic_ostream(basic_streambuf<char_type, traits>* sb);
1110
  virtual ~basic_ostream();
@@ -1276,11 +1302,11 @@ virtual ~basic_ostream();
1276
 
1277
  ``` cpp
1278
  basic_ostream& operator=(basic_ostream&& rhs);
1279
  ```
1280
 
1281
- *Effects:* Equivalent to: `swap(rhs)`.
1282
 
1283
  *Returns:* `*this`.
1284
 
1285
  ``` cpp
1286
  void swap(basic_ostream& rhs);
@@ -1316,28 +1342,29 @@ explicit sentry(basic_ostream& os);
1316
 
1317
  If `os.good()` is nonzero, prepares for formatted or unformatted output.
1318
  If `os.tie()` is not a null pointer, calls `os.tie()->flush()`.[^29]
1319
 
1320
  If, after any preparation is completed, `os.good()` is `true`,
1321
- `ok_ == true` otherwise, `ok_ == false`. During preparation, the
1322
  constructor may call `setstate(failbit)` (which may throw
1323
  `ios_base::failure` [[iostate.flags]]).[^30]
1324
 
1325
  ``` cpp
1326
  ~sentry();
1327
  ```
1328
 
1329
  If
1330
  `(os.flags() & ios_base::unitbuf) && !uncaught_exceptions() && os.good()`
1331
- is `true`, calls `os.rdbuf()->pubsync()`. If that function returns -1,
1332
- sets `badbit` in `os.rdstate()` without propagating an exception.
 
1333
 
1334
  ``` cpp
1335
  explicit operator bool() const;
1336
  ```
1337
 
1338
- *Effects:* Returns `ok_`.
1339
 
1340
  ##### Seek members <a id="ostream.seeks">[[ostream.seeks]]</a>
1341
 
1342
  Each seek member function begins execution by constructing an object of
1343
  class `sentry`. It returns by destroying the `sentry` object.
@@ -1392,16 +1419,16 @@ function is `*this`.
1392
  The descriptions of the individual formatted output functions describe
1393
  how they perform output and do not mention the `sentry` object.
1394
 
1395
  If a formatted output function of a stream `os` determines padding, it
1396
  does so as follows. Given a `charT` character sequence `seq` where
1397
- `charT` is the character type of the stream, if the length of `seq` is
1398
- less than `os.width()`, then enough copies of `os.fill()` are added to
1399
- this sequence as necessary to pad to a width of `os.width()` characters.
1400
- If `(os.flags() & ios_base::adjustfield) == ios_base::left` is `true`,
1401
- the fill characters are placed after the character sequence; otherwise,
1402
- they are placed before the character sequence.
1403
 
1404
  ##### Arithmetic inserters <a id="ostream.inserters.arithmetic">[[ostream.inserters.arithmetic]]</a>
1405
 
1406
  ``` cpp
1407
  basic_ostream& operator<<(bool val);
@@ -1426,59 +1453,52 @@ When `val` is of type `bool`, `long`, `unsigned long`, `long long`,
1426
  `unsigned long long`, `double`, `long double`, or `const void*`, the
1427
  formatting conversion occurs as if it performed the following code
1428
  fragment:
1429
 
1430
  ``` cpp
1431
- bool failed = use_facet<
1432
- num_put<charT, ostreambuf_iterator<charT, traits>>
1433
- >(getloc()).put(*this, *this, fill(), val).failed();
1434
  ```
1435
 
1436
  When `val` is of type `short` the formatting conversion occurs as if it
1437
  performed the following code fragment:
1438
 
1439
  ``` cpp
1440
  ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
1441
- bool failed = use_facet<
1442
- num_put<charT, ostreambuf_iterator<charT, traits>>
1443
- >(getloc()).put(*this, *this, fill(),
1444
  baseflags == ios_base::oct || baseflags == ios_base::hex
1445
  ? static_cast<long>(static_cast<unsigned short>(val))
1446
  : static_cast<long>(val)).failed();
1447
  ```
1448
 
1449
  When `val` is of type `int` the formatting conversion occurs as if it
1450
  performed the following code fragment:
1451
 
1452
  ``` cpp
1453
  ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
1454
- bool failed = use_facet<
1455
- num_put<charT, ostreambuf_iterator<charT, traits>>
1456
- >(getloc()).put(*this, *this, fill(),
1457
  baseflags == ios_base::oct || baseflags == ios_base::hex
1458
  ? static_cast<long>(static_cast<unsigned int>(val))
1459
  : static_cast<long>(val)).failed();
1460
  ```
1461
 
1462
  When `val` is of type `unsigned short` or `unsigned int` the formatting
1463
  conversion occurs as if it performed the following code fragment:
1464
 
1465
  ``` cpp
1466
- bool failed = use_facet<
1467
- num_put<charT, ostreambuf_iterator<charT, traits>>
1468
- >(getloc()).put(*this, *this, fill(),
1469
- static_cast<unsigned long>(val)).failed();
1470
  ```
1471
 
1472
  When `val` is of type `float` the formatting conversion occurs as if it
1473
  performed the following code fragment:
1474
 
1475
  ``` cpp
1476
- bool failed = use_facet<
1477
- num_put<charT, ostreambuf_iterator<charT, traits>>
1478
- >(getloc()).put(*this, *this, fill(),
1479
- static_cast<double>(val)).failed();
1480
  ```
1481
 
1482
  The first argument provides an object of the `ostreambuf_iterator<>`
1483
  class which is an iterator for class `basic_ostream<>`. It bypasses
1484
  `ostream`s and uses `streambuf`s directly. Class `locale` relies on
@@ -1506,26 +1526,22 @@ basic_ostream& operator<<(extended-floating-point-type val);
1506
  *`extended-floating-point-type`* is less than or equal to that of
1507
  `double`, the formatting conversion occurs as if it performed the
1508
  following code fragment:
1509
 
1510
  ``` cpp
1511
- bool failed = use_facet<
1512
- num_put<charT, ostreambuf_iterator<charT, traits>>
1513
- >(getloc()).put(*this, *this, fill(),
1514
- static_cast<double>(val)).failed();
1515
  ```
1516
 
1517
  Otherwise, if the floating-point conversion rank of
1518
  *`extended-floating-point-type`* is less than or equal to that of
1519
  `long double`, the formatting conversion occurs as if it performed the
1520
  following code fragment:
1521
 
1522
  ``` cpp
1523
- bool failed = use_facet<
1524
- num_put<charT, ostreambuf_iterator<charT, traits>>
1525
- >(getloc()).put(*this, *this, fill(),
1526
- static_cast<long double>(val)).failed();
1527
  ```
1528
 
1529
  Otherwise, an invocation of the operator function is conditionally
1530
  supported with *implementation-defined* semantics.
1531
 
@@ -1619,15 +1635,15 @@ template<class traits>
1619
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, unsigned char c);
1620
  ```
1621
 
1622
  *Effects:* Behaves as a formatted output
1623
  function [[ostream.formatted.reqmts]] of `out`. Constructs a character
1624
- sequence `seq`. If `c` has type `char` and the character type of the
1625
- stream is not `char`, then `seq` consists of `out.widen(c)`; otherwise
1626
- `seq` consists of `c`. Determines padding for `seq` as described
1627
- in  [[ostream.formatted.reqmts]]. Inserts `seq` into `out`. Calls
1628
- `os.width(0)`.
1629
 
1630
  *Returns:* `out`.
1631
 
1632
  ``` cpp
1633
  template<class charT, class traits>
@@ -1677,28 +1693,38 @@ template<class... Args>
1677
 
1678
  *Effects:* If the ordinary literal encoding [[lex.charset]] is UTF-8,
1679
  equivalent to:
1680
 
1681
  ``` cpp
1682
- vprint_unicode(os, fmt.str, make_format_args(std::forward<Args>(args)...));
1683
  ```
1684
 
1685
  Otherwise, equivalent to:
1686
 
1687
  ``` cpp
1688
- vprint_nonunicode(os, fmt.str, make_format_args(std::forward<Args>(args)...));
1689
  ```
1690
 
1691
  ``` cpp
1692
  template<class... Args>
1693
  void println(ostream& os, format_string<Args...> fmt, Args&&... args);
1694
  ```
1695
 
1696
  *Effects:* Equivalent to:
1697
 
1698
  ``` cpp
1699
- print(os, "{}\n", format(fmt, std::forward<Args>(args)...));
 
 
 
 
 
 
 
 
 
 
1700
  ```
1701
 
1702
  ``` cpp
1703
  void vprint_unicode(ostream& os, string_view fmt, format_args args);
1704
  void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
@@ -1710,28 +1736,29 @@ function [[ostream.formatted.reqmts]] of `os`, except that:
1710
  - failure to generate output is reported as specified below, and
1711
  - any exception thrown by the call to `vformat` is propagated without
1712
  regard to the value of `os.exceptions()` and without turning on
1713
  `ios_base::badbit` in the error state of `os`.
1714
 
1715
- After constructing a `sentry` object, the function initializes an
1716
- automatic variable via
1717
 
1718
  ``` cpp
1719
  string out = vformat(os.getloc(), fmt, args);
1720
  ```
1721
 
1722
- If the function is `vprint_unicode` and `os` is a stream that refers to
1723
- a terminal capable of displaying Unicode which is determined in an
1724
- implementation-defined manner, writes `out` to the terminal using the
1725
- native Unicode API; if `out` contains invalid code units, the behavior
1726
- is undefined and implementations are encouraged to diagnose it. If the
1727
- native Unicode API is used, the function flushes `os` before writing
1728
- `out`. Otherwise (if `os` is not such a stream or the function is
1729
- `vprint_nonunicode`), inserts the character sequence \[`out.begin()`,
1730
- `out.end()`) into `os`. If writing to the terminal or inserting into
1731
- `os` fails, calls `os.setstate(ios_base::badbit)` (which may throw
1732
- `ios_base::failure`).
 
1733
 
1734
  *Recommended practice:* For `vprint_unicode`, if invoking the native
1735
  Unicode API requires transcoding, implementations should substitute
1736
  invalid code units with U+fffd (replacement character) per the Unicode
1737
  Standard, Chapter 3.9 ‘U+fffd‘ Substitution in Conversion.
@@ -1792,11 +1819,11 @@ object. If that object returns `true` when converted to a value of type
1792
  [[iostate.flags]]). Otherwise, if the `sentry` object returns `false`,
1793
  does nothing.
1794
 
1795
  *Returns:* `*this`.
1796
 
1797
- #### Standard manipulators <a id="ostream.manip">[[ostream.manip]]</a>
1798
 
1799
  Each instantiation of any of the function templates specified in this
1800
  subclause is a designated addressable function [[namespace.std]].
1801
 
1802
  ``` cpp
@@ -1838,11 +1865,11 @@ of exposition, calls `buf->set_emit_on_sync(true)`. Otherwise this
1838
  manipulator has no effect.
1839
 
1840
  [*Note 1*: To work around the issue that the `Allocator` template
1841
  argument cannot be deduced, implementations can introduce an
1842
  intermediate base class to `basic_syncbuf` that manages its
1843
- `emit_on_sync` flag. — *end note*]
1844
 
1845
  *Returns:* `os`.
1846
 
1847
  ``` cpp
1848
  template<class charT, class traits>
@@ -2255,21 +2282,27 @@ print(stdout, fmt, std::forward<Args>(args)...);
2255
  ``` cpp
2256
  template<class... Args>
2257
  void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
2258
  ```
2259
 
2260
- *Effects:* If the ordinary literal encoding [[lex.charset]] is UTF-8,
2261
- equivalent to:
 
 
2262
 
2263
  ``` cpp
2264
- vprint_unicode(stream, fmt.str, make_format_args(std::forward<Args>(args)...));
 
 
2265
  ```
2266
 
2267
  Otherwise, equivalent to:
2268
 
2269
  ``` cpp
2270
- vprint_nonunicode(stream, fmt.str, make_format_args(std::forward<Args>(args)...));
 
 
2271
  ```
2272
 
2273
  ``` cpp
2274
  template<class... Args>
2275
  void println(format_string<Args...> fmt, Args&&... args);
@@ -2279,19 +2312,39 @@ template<class... Args>
2279
 
2280
  ``` cpp
2281
  println(stdout, fmt, std::forward<Args>(args)...);
2282
  ```
2283
 
 
 
 
 
 
 
 
 
 
 
2284
  ``` cpp
2285
  template<class... Args>
2286
  void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
2287
  ```
2288
 
2289
  *Effects:* Equivalent to:
2290
 
2291
  ``` cpp
2292
- print(stream, "{}\n", format(fmt, std::forward<Args>(args)...));
 
 
 
 
 
 
 
 
 
 
2293
  ```
2294
 
2295
  ``` cpp
2296
  void vprint_unicode(string_view fmt, format_args args);
2297
  ```
@@ -2300,37 +2353,47 @@ void vprint_unicode(string_view fmt, format_args args);
2300
 
2301
  ``` cpp
2302
  vprint_unicode(stdout, fmt, args);
2303
  ```
2304
 
 
 
 
 
 
 
 
 
 
 
 
2305
  ``` cpp
2306
  void vprint_unicode(FILE* stream, string_view fmt, format_args args);
2307
  ```
2308
 
2309
  *Preconditions:* `stream` is a valid pointer to an output C stream.
2310
 
2311
- *Effects:* The function initializes an automatic variable via
 
 
2312
 
2313
- ``` cpp
2314
- string out = vformat(fmt, args);
2315
- ```
 
 
 
2316
 
2317
- If `stream` refers to a terminal capable of displaying Unicode, writes
2318
- `out` to the terminal using the native Unicode API; if `out` contains
2319
- invalid code units, the behavior is undefined and implementations are
2320
- encouraged to diagnose it. Otherwise writes `out` to `stream` unchanged.
2321
- If the native Unicode API is used, the function flushes `stream` before
2322
- writing `out`.
2323
 
2324
- [*Note 1*: On POSIX and Windows, `stream` referring to a terminal means
2325
- that, respectively, `isatty(fileno(stream))` and
2326
- `GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)` return
 
 
2327
  nonzero. — *end note*]
2328
 
2329
- [*Note 2*: On Windows, the native Unicode API is
2330
- `WriteConsoleW`. — *end note*]
2331
-
2332
  *Throws:* Any exception thrown by the call to `vformat`
2333
  [[format.err.report]]. `system_error` if writing to the terminal or
2334
  `stream` fails. May throw `bad_alloc`.
2335
 
2336
  *Recommended practice:* If invoking the native Unicode API requires
@@ -2346,17 +2409,30 @@ void vprint_nonunicode(string_view fmt, format_args args);
2346
 
2347
  ``` cpp
2348
  vprint_nonunicode(stdout, fmt, args);
2349
  ```
2350
 
 
 
 
 
 
 
 
 
 
 
 
2351
  ``` cpp
2352
  void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
2353
  ```
2354
 
2355
  *Preconditions:* `stream` is a valid pointer to an output C stream.
2356
 
2357
- *Effects:* Writes the result of `vformat(fmt, args)` to `stream`.
 
 
2358
 
2359
  *Throws:* Any exception thrown by the call to `vformat`
2360
  [[format.err.report]]. `system_error` if writing to `stream` fails. May
2361
  throw `bad_alloc`.
2362
 
 
2
 
3
  ### Header `<istream>` synopsis <a id="istream.syn">[[istream.syn]]</a>
4
 
5
  ``` cpp
6
  namespace std {
7
+ // [istream], class template basic_istream
8
  template<class charT, class traits = char_traits<charT>>
9
  class basic_istream;
10
 
11
  using istream = basic_istream<char>;
12
  using wistream = basic_istream<wchar_t>;
13
 
14
+ // [iostreamclass], class template basic_iostream
15
  template<class charT, class traits = char_traits<charT>>
16
  class basic_iostream;
17
 
18
  using iostream = basic_iostream<char>;
19
  using wiostream = basic_iostream<wchar_t>;
20
 
21
+ // [istream.manip], standard basic_istream manipulators
22
  template<class charT, class traits>
23
  basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);
24
 
25
+ // [istream.rvalue], rvalue stream extraction
26
  template<class Istream, class T>
27
  Istream&& operator>>(Istream&& is, T&& x);
28
  }
29
  ```
30
 
31
  ### Header `<ostream>` synopsis <a id="ostream.syn">[[ostream.syn]]</a>
32
 
33
  ``` cpp
34
  namespace std {
35
+ // [ostream], class template basic_ostream
36
  template<class charT, class traits = char_traits<charT>>
37
  class basic_ostream;
38
 
39
  using ostream = basic_ostream<char>;
40
  using wostream = basic_ostream<wchar_t>;
41
 
42
+ // [ostream.manip], standard basic_ostream manipulators
43
  template<class charT, class traits>
44
  basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& os);
45
  template<class charT, class traits>
46
  basic_ostream<charT, traits>& ends(basic_ostream<charT, traits>& os);
47
  template<class charT, class traits>
 
52
  template<class charT, class traits>
53
  basic_ostream<charT, traits>& noemit_on_flush(basic_ostream<charT, traits>& os);
54
  template<class charT, class traits>
55
  basic_ostream<charT, traits>& flush_emit(basic_ostream<charT, traits>& os);
56
 
57
+ // [ostream.rvalue], rvalue stream insertion
58
  template<class Ostream, class T>
59
  Ostream&& operator<<(Ostream&& os, const T& x);
60
 
61
  // [ostream.formatted.print], print functions
62
  template<class... Args>
63
  void print(ostream& os, format_string<Args...> fmt, Args&&... args);
64
  template<class... Args>
65
  void println(ostream& os, format_string<Args...> fmt, Args&&... args);
66
+ void println(ostream& os);
67
 
68
  void vprint_unicode(ostream& os, string_view fmt, format_args args);
69
  void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
70
  }
71
  ```
72
 
73
  ### Header `<iomanip>` synopsis <a id="iomanip.syn">[[iomanip.syn]]</a>
74
 
75
  ``` cpp
76
  namespace std {
77
+ // [std.manip], standard manipulators
78
  unspecified resetiosflags(ios_base::fmtflags mask);
79
  unspecified setiosflags (ios_base::fmtflags mask);
80
  unspecified setbase(int base);
81
  template<class charT> unspecified setfill(charT c);
82
  unspecified setprecision(int n);
83
  unspecified setw(int n);
84
+
85
+ // [ext.manip], extended manipulators
86
  template<class moneyT> unspecified get_money(moneyT& mon, bool intl = false);
87
  template<class moneyT> unspecified put_money(const moneyT& mon, bool intl = false);
88
  template<class charT> unspecified get_time(tm* tmb, const charT* fmt);
89
  template<class charT> unspecified put_time(const tm* tmb, const charT* fmt);
90
 
91
+ // [quoted.manip], quoted manipulators
92
  template<class charT>
93
  unspecified quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\'));
94
 
95
  template<class charT, class traits, class Allocator>
96
  unspecified quoted(const basic_string<charT, traits, Allocator>& s,
 
116
  template<class... Args>
117
  void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
118
 
119
  template<class... Args>
120
  void println(format_string<Args...> fmt, Args&&... args);
121
+ void println();
122
  template<class... Args>
123
  void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
124
+ void println(FILE* stream);
125
 
126
  void vprint_unicode(string_view fmt, format_args args);
127
  void vprint_unicode(FILE* stream, string_view fmt, format_args args);
128
+ void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args);
129
 
130
  void vprint_nonunicode(string_view fmt, format_args args);
131
  void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
132
+ void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args);
133
  }
134
  ```
135
 
136
  ### Input streams <a id="input.streams">[[input.streams]]</a>
137
 
 
155
  template<class charT, class traits = char_traits<charT>>
156
  class basic_istream : virtual public basic_ios<charT, traits> {
157
  public:
158
  // types (inherited from basic_ios[ios])
159
  using char_type = charT;
160
+ using int_type = traits::int_type;
161
+ using pos_type = traits::pos_type;
162
+ using off_type = traits::off_type;
163
  using traits_type = traits;
164
 
165
  // [istream.cons], constructor/destructor
166
  explicit basic_istream(basic_streambuf<charT, traits>* sb);
167
  virtual ~basic_istream();
 
202
 
203
  basic_istream& getline(char_type* s, streamsize n);
204
  basic_istream& getline(char_type* s, streamsize n, char_type delim);
205
 
206
  basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof());
207
+ basic_istream& ignore(streamsize n, char_type delim);
208
  int_type peek();
209
  basic_istream& read (char_type* s, streamsize n);
210
  streamsize readsome(char_type* s, streamsize n);
211
 
212
  basic_istream& putback(char_type c);
 
284
 
285
  ``` cpp
286
  basic_istream& operator=(basic_istream&& rhs);
287
  ```
288
 
289
+ *Effects:* Equivalent to `swap(rhs)`.
290
 
291
  *Returns:* `*this`.
292
 
293
  ``` cpp
294
  void swap(basic_istream& rhs);
 
356
  if (ctype.is(ctype.space, c) != 0)
357
  // c is a whitespace character.
358
  ```
359
 
360
  If, after any preparation is completed, `is.good()` is `true`,
361
+ *`ok_`*` != false` otherwise, *`ok_`*` == false`. During preparation,
362
+ the constructor may call `setstate(failbit)` (which may throw
363
  `ios_base::failure` [[iostate.flags]]).[^19]
364
 
365
  ``` cpp
366
  ~sentry();
367
  ```
 
370
 
371
  ``` cpp
372
  explicit operator bool() const;
373
  ```
374
 
375
+ *Returns:* *ok\_*.
376
 
377
  #### Formatted input functions <a id="istream.formatted">[[istream.formatted]]</a>
378
 
379
  ##### Common requirements <a id="istream.formatted.reqmts">[[istream.formatted.reqmts]]</a>
380
 
 
808
 
809
  ``` cpp
810
  basic_istream& getline(char_type* s, streamsize n);
811
  ```
812
 
813
+ *Returns:* `getline(s, n, widen(’\n’))`.
814
 
815
  ``` cpp
816
  basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof());
817
  ```
818
 
 
820
  above). After constructing a `sentry` object, extracts characters and
821
  discards them. Characters are extracted until any of the following
822
  occurs:
823
 
824
  - `n != numeric_limits<streamsize>::max()` [[numeric.limits]] and `n`
825
+ characters have been extracted so far;
826
  - end-of-file occurs on the input sequence (in which case the function
827
  calls `setstate(eofbit)`, which may throw `ios_base::failure`
828
  [[iostate.flags]]);
829
  - `traits::eq_int_type(traits::to_int_type(c), delim)` for the next
830
  available input character `c` (in which case `c` is extracted).
 
832
  [*Note 1*: The last condition will never occur if
833
  `traits::eq_int_type(delim, traits::eof())`. — *end note*]
834
 
835
  *Returns:* `*this`.
836
 
837
+ ``` cpp
838
+ basic_istream& ignore(streamsize n, char_type delim);
839
+ ```
840
+
841
+ *Constraints:* `is_same_v<char_type, char>` is `true`.
842
+
843
+ *Effects:* Equivalent to:
844
+ `return ignore(n, traits::to_int_type(delim));`
845
+
846
  ``` cpp
847
  int_type peek();
848
  ```
849
 
850
  *Effects:* Behaves as an unformatted input function (as described
 
1032
  class basic_iostream
1033
  : public basic_istream<charT, traits>,
1034
  public basic_ostream<charT, traits> {
1035
  public:
1036
  using char_type = charT;
1037
+ using int_type = traits::int_type;
1038
+ using pos_type = traits::pos_type;
1039
+ using off_type = traits::off_type;
1040
  using traits_type = traits;
1041
 
1042
  // [iostream.cons], constructor
1043
  explicit basic_iostream(basic_streambuf<charT, traits>* sb);
1044
 
 
1093
 
1094
  ``` cpp
1095
  basic_iostream& operator=(basic_iostream&& rhs);
1096
  ```
1097
 
1098
+ *Effects:* Equivalent to `swap(rhs)`.
1099
 
1100
  ``` cpp
1101
  void swap(basic_iostream& rhs);
1102
  ```
1103
 
 
1124
  template<class charT, class traits = char_traits<charT>>
1125
  class basic_ostream : virtual public basic_ios<charT, traits> {
1126
  public:
1127
  // types (inherited from basic_ios[ios])
1128
  using char_type = charT;
1129
+ using int_type = traits::int_type;
1130
+ using pos_type = traits::pos_type;
1131
+ using off_type = traits::off_type;
1132
  using traits_type = traits;
1133
 
1134
  // [ostream.cons], constructor/destructor
1135
  explicit basic_ostream(basic_streambuf<char_type, traits>* sb);
1136
  virtual ~basic_ostream();
 
1302
 
1303
  ``` cpp
1304
  basic_ostream& operator=(basic_ostream&& rhs);
1305
  ```
1306
 
1307
+ *Effects:* Equivalent to `swap(rhs)`.
1308
 
1309
  *Returns:* `*this`.
1310
 
1311
  ``` cpp
1312
  void swap(basic_ostream& rhs);
 
1342
 
1343
  If `os.good()` is nonzero, prepares for formatted or unformatted output.
1344
  If `os.tie()` is not a null pointer, calls `os.tie()->flush()`.[^29]
1345
 
1346
  If, after any preparation is completed, `os.good()` is `true`,
1347
+ *`ok_`*` == true` otherwise, *`ok_`*` == false`. During preparation, the
1348
  constructor may call `setstate(failbit)` (which may throw
1349
  `ios_base::failure` [[iostate.flags]]).[^30]
1350
 
1351
  ``` cpp
1352
  ~sentry();
1353
  ```
1354
 
1355
  If
1356
  `(os.flags() & ios_base::unitbuf) && !uncaught_exceptions() && os.good()`
1357
+ is `true`, calls `os.rdbuf()->pubsync()`. If that function returns -1 or
1358
+ exits via an exception, sets `badbit` in `os.rdstate()` without
1359
+ propagating an exception.
1360
 
1361
  ``` cpp
1362
  explicit operator bool() const;
1363
  ```
1364
 
1365
+ *Effects:* Returns *ok\_*.
1366
 
1367
  ##### Seek members <a id="ostream.seeks">[[ostream.seeks]]</a>
1368
 
1369
  Each seek member function begins execution by constructing an object of
1370
  class `sentry`. It returns by destroying the `sentry` object.
 
1419
  The descriptions of the individual formatted output functions describe
1420
  how they perform output and do not mention the `sentry` object.
1421
 
1422
  If a formatted output function of a stream `os` determines padding, it
1423
  does so as follows. Given a `charT` character sequence `seq` where
1424
+ `charT` is the character container type of the stream, if the length of
1425
+ `seq` is less than `os.width()`, then enough copies of `os.fill()` are
1426
+ added to this sequence as necessary to pad to a width of `os.width()`
1427
+ characters. If `(os.flags() & ios_base::adjustfield) == ios_base::left`
1428
+ is `true`, the fill characters are placed after the character sequence;
1429
+ otherwise, they are placed before the character sequence.
1430
 
1431
  ##### Arithmetic inserters <a id="ostream.inserters.arithmetic">[[ostream.inserters.arithmetic]]</a>
1432
 
1433
  ``` cpp
1434
  basic_ostream& operator<<(bool val);
 
1453
  `unsigned long long`, `double`, `long double`, or `const void*`, the
1454
  formatting conversion occurs as if it performed the following code
1455
  fragment:
1456
 
1457
  ``` cpp
1458
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1459
+ getloc()).put(*this, *this, fill(), val).failed();
 
1460
  ```
1461
 
1462
  When `val` is of type `short` the formatting conversion occurs as if it
1463
  performed the following code fragment:
1464
 
1465
  ``` cpp
1466
  ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
1467
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1468
+ getloc()).put(*this, *this, fill(),
 
1469
  baseflags == ios_base::oct || baseflags == ios_base::hex
1470
  ? static_cast<long>(static_cast<unsigned short>(val))
1471
  : static_cast<long>(val)).failed();
1472
  ```
1473
 
1474
  When `val` is of type `int` the formatting conversion occurs as if it
1475
  performed the following code fragment:
1476
 
1477
  ``` cpp
1478
  ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
1479
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1480
+ getloc()).put(*this, *this, fill(),
 
1481
  baseflags == ios_base::oct || baseflags == ios_base::hex
1482
  ? static_cast<long>(static_cast<unsigned int>(val))
1483
  : static_cast<long>(val)).failed();
1484
  ```
1485
 
1486
  When `val` is of type `unsigned short` or `unsigned int` the formatting
1487
  conversion occurs as if it performed the following code fragment:
1488
 
1489
  ``` cpp
1490
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1491
+ getloc()).put(*this, *this, fill(), static_cast<unsigned long>(val)).failed();
 
 
1492
  ```
1493
 
1494
  When `val` is of type `float` the formatting conversion occurs as if it
1495
  performed the following code fragment:
1496
 
1497
  ``` cpp
1498
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1499
+ getloc()).put(*this, *this, fill(), static_cast<double>(val)).failed();
 
 
1500
  ```
1501
 
1502
  The first argument provides an object of the `ostreambuf_iterator<>`
1503
  class which is an iterator for class `basic_ostream<>`. It bypasses
1504
  `ostream`s and uses `streambuf`s directly. Class `locale` relies on
 
1526
  *`extended-floating-point-type`* is less than or equal to that of
1527
  `double`, the formatting conversion occurs as if it performed the
1528
  following code fragment:
1529
 
1530
  ``` cpp
1531
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1532
+ getloc()).put(*this, *this, fill(), static_cast<double>(val)).failed();
 
 
1533
  ```
1534
 
1535
  Otherwise, if the floating-point conversion rank of
1536
  *`extended-floating-point-type`* is less than or equal to that of
1537
  `long double`, the formatting conversion occurs as if it performed the
1538
  following code fragment:
1539
 
1540
  ``` cpp
1541
+ bool failed = use_facet<num_put<charT, ostreambuf_iterator<charT, traits>>>(
1542
+ getloc()).put(*this, *this, fill(), static_cast<long double>(val)).failed();
 
 
1543
  ```
1544
 
1545
  Otherwise, an invocation of the operator function is conditionally
1546
  supported with *implementation-defined* semantics.
1547
 
 
1635
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, unsigned char c);
1636
  ```
1637
 
1638
  *Effects:* Behaves as a formatted output
1639
  function [[ostream.formatted.reqmts]] of `out`. Constructs a character
1640
+ sequence `seq`. If `c` has type `char` and the character container type
1641
+ of the stream is not `char`, then `seq` consists of `out.widen(c)`;
1642
+ otherwise `seq` consists of `c`. Determines padding for `seq` as
1643
+ described in  [[ostream.formatted.reqmts]]. Inserts `seq` into `out`.
1644
+ Calls `os.width(0)`.
1645
 
1646
  *Returns:* `out`.
1647
 
1648
  ``` cpp
1649
  template<class charT, class traits>
 
1693
 
1694
  *Effects:* If the ordinary literal encoding [[lex.charset]] is UTF-8,
1695
  equivalent to:
1696
 
1697
  ``` cpp
1698
+ vprint_unicode(os, fmt.str, make_format_args(args...));
1699
  ```
1700
 
1701
  Otherwise, equivalent to:
1702
 
1703
  ``` cpp
1704
+ vprint_nonunicode(os, fmt.str, make_format_args(args...));
1705
  ```
1706
 
1707
  ``` cpp
1708
  template<class... Args>
1709
  void println(ostream& os, format_string<Args...> fmt, Args&&... args);
1710
  ```
1711
 
1712
  *Effects:* Equivalent to:
1713
 
1714
  ``` cpp
1715
+ print(os, "{}\n", format(os.getloc(), fmt, std::forward<Args>(args)...));
1716
+ ```
1717
+
1718
+ ``` cpp
1719
+ void println(ostream& os);
1720
+ ```
1721
+
1722
+ *Effects:* Equivalent to:
1723
+
1724
+ ``` cpp
1725
+ print(os, "\n");
1726
  ```
1727
 
1728
  ``` cpp
1729
  void vprint_unicode(ostream& os, string_view fmt, format_args args);
1730
  void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
 
1736
  - failure to generate output is reported as specified below, and
1737
  - any exception thrown by the call to `vformat` is propagated without
1738
  regard to the value of `os.exceptions()` and without turning on
1739
  `ios_base::badbit` in the error state of `os`.
1740
 
1741
+ After constructing a `sentry` object, the function initializes a
1742
+ variable with automatic storage duration via
1743
 
1744
  ``` cpp
1745
  string out = vformat(os.getloc(), fmt, args);
1746
  ```
1747
 
1748
+ - If the function is `vprint_unicode` and `os` is a stream that refers
1749
+ to a terminal that is capable of displaying Unicode only via a native
1750
+ Unicode API, which is determined in an implementation-defined manner,
1751
+ flushes `os` and then writes `out` to the terminal using the native
1752
+ Unicode API; if `out` contains invalid code units, the behavior is
1753
+ undefined. Then establishes an observable
1754
+ checkpoint [[intro.abstract]].
1755
+ - Otherwise inserts the character sequence \[`out.begin()`, `out.end()`)
1756
+ into `os`.
1757
+
1758
+ If writing to the terminal or inserting into `os` fails, calls
1759
+ `os.setstate(ios_base::badbit)` (which may throw `ios_base::failure`).
1760
 
1761
  *Recommended practice:* For `vprint_unicode`, if invoking the native
1762
  Unicode API requires transcoding, implementations should substitute
1763
  invalid code units with U+fffd (replacement character) per the Unicode
1764
  Standard, Chapter 3.9 ‘U+fffd‘ Substitution in Conversion.
 
1819
  [[iostate.flags]]). Otherwise, if the `sentry` object returns `false`,
1820
  does nothing.
1821
 
1822
  *Returns:* `*this`.
1823
 
1824
+ #### Standard `basic_ostream` manipulators <a id="ostream.manip">[[ostream.manip]]</a>
1825
 
1826
  Each instantiation of any of the function templates specified in this
1827
  subclause is a designated addressable function [[namespace.std]].
1828
 
1829
  ``` cpp
 
1865
  manipulator has no effect.
1866
 
1867
  [*Note 1*: To work around the issue that the `Allocator` template
1868
  argument cannot be deduced, implementations can introduce an
1869
  intermediate base class to `basic_syncbuf` that manages its
1870
+ *emit-on-sync* flag. — *end note*]
1871
 
1872
  *Returns:* `os`.
1873
 
1874
  ``` cpp
1875
  template<class charT, class traits>
 
2282
  ``` cpp
2283
  template<class... Args>
2284
  void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
2285
  ```
2286
 
2287
+ *Effects:* Let `locksafe` be
2288
+ `(enable_nonlocking_formatter_optimization<remove_cvref_t<Args>> && ...)`.
2289
+ If the ordinary literal encoding [[lex.charset]] is UTF-8, equivalent
2290
+ to:
2291
 
2292
  ``` cpp
2293
+ locksafe
2294
+ ? vprint_unicode(stream, fmt.str, make_format_args(args...))
2295
+ : vprint_unicode_buffered(stream, fmt.str, make_format_args(args...));
2296
  ```
2297
 
2298
  Otherwise, equivalent to:
2299
 
2300
  ``` cpp
2301
+ locksafe
2302
+ ? vprint_nonunicode(stream, fmt.str, make_format_args(args...))
2303
+ : vprint_nonunicode_buffered(stream, fmt.str, make_format_args(args...));
2304
  ```
2305
 
2306
  ``` cpp
2307
  template<class... Args>
2308
  void println(format_string<Args...> fmt, Args&&... args);
 
2312
 
2313
  ``` cpp
2314
  println(stdout, fmt, std::forward<Args>(args)...);
2315
  ```
2316
 
2317
+ ``` cpp
2318
+ void println();
2319
+ ```
2320
+
2321
+ *Effects:* Equivalent to:
2322
+
2323
+ ``` cpp
2324
+ println(stdout);
2325
+ ```
2326
+
2327
  ``` cpp
2328
  template<class... Args>
2329
  void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
2330
  ```
2331
 
2332
  *Effects:* Equivalent to:
2333
 
2334
  ``` cpp
2335
+ print(stream, runtime_format(string(fmt.get()) + '\n'), std::forward<Args>(args)...);
2336
+ ```
2337
+
2338
+ ``` cpp
2339
+ void println(FILE* stream);
2340
+ ```
2341
+
2342
+ *Effects:* Equivalent to:
2343
+
2344
+ ``` cpp
2345
+ print(stream, "\n");
2346
  ```
2347
 
2348
  ``` cpp
2349
  void vprint_unicode(string_view fmt, format_args args);
2350
  ```
 
2353
 
2354
  ``` cpp
2355
  vprint_unicode(stdout, fmt, args);
2356
  ```
2357
 
2358
+ ``` cpp
2359
+ void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args);
2360
+ ```
2361
+
2362
+ *Effects:* Equivalent to:
2363
+
2364
+ ``` cpp
2365
+ string out = vformat(fmt, args);
2366
+ vprint_unicode(stream, "{}", make_format_args(out));
2367
+ ```
2368
+
2369
  ``` cpp
2370
  void vprint_unicode(FILE* stream, string_view fmt, format_args args);
2371
  ```
2372
 
2373
  *Preconditions:* `stream` is a valid pointer to an output C stream.
2374
 
2375
+ *Effects:* Locks `stream`. Let `out` denote the character representation
2376
+ of formatting arguments provided by `args` formatted according to
2377
+ specifications given in `fmt`.
2378
 
2379
+ - If `stream` refers to a terminal that is capable of displaying Unicode
2380
+ only via a native Unicode API, flushes `stream` and then writes `out`
2381
+ to the terminal using the native Unicode API; if `out` contains
2382
+ invalid code units, the behavior is undefined. Then establishes an
2383
+ observable checkpoint [[intro.abstract]].
2384
+ - Otherwise writes `out` to `stream` unchanged.
2385
 
2386
+ Unconditionally unlocks `stream` on function exit.
 
 
 
 
 
2387
 
2388
+ See also: ISO C 7.23.2.
2389
+
2390
+ [*Note 1*: On Windows the native Unicode API is `WriteConsoleW` and
2391
+ `stream` referring to a terminal means that
2392
+ `GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)` returns
2393
  nonzero. — *end note*]
2394
 
 
 
 
2395
  *Throws:* Any exception thrown by the call to `vformat`
2396
  [[format.err.report]]. `system_error` if writing to the terminal or
2397
  `stream` fails. May throw `bad_alloc`.
2398
 
2399
  *Recommended practice:* If invoking the native Unicode API requires
 
2409
 
2410
  ``` cpp
2411
  vprint_nonunicode(stdout, fmt, args);
2412
  ```
2413
 
2414
+ ``` cpp
2415
+ void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args);
2416
+ ```
2417
+
2418
+ *Effects:* Equivalent to:
2419
+
2420
+ ``` cpp
2421
+ string out = vformat(fmt, args);
2422
+ vprint_nonunicode("{}", make_format_args(out));
2423
+ ```
2424
+
2425
  ``` cpp
2426
  void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
2427
  ```
2428
 
2429
  *Preconditions:* `stream` is a valid pointer to an output C stream.
2430
 
2431
+ *Effects:* While holding the lock on `stream`, writes the character
2432
+ representation of formatting arguments provided by `args` formatted
2433
+ according to specifications given in `fmt` to `stream`.
2434
 
2435
  *Throws:* Any exception thrown by the call to `vformat`
2436
  [[format.err.report]]. `system_error` if writing to `stream` fails. May
2437
  throw `bad_alloc`.
2438