1 | // Standard stream manipulators -*- C++ -*- |
2 | |
3 | // Copyright (C) 1997-2024 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file include/iomanip |
26 | * This is a Standard C++ Library header. |
27 | */ |
28 | |
29 | // |
30 | // ISO C++ 14882: 27.6.3 Standard manipulators |
31 | // |
32 | |
33 | #ifndef _GLIBCXX_IOMANIP |
34 | #define _GLIBCXX_IOMANIP 1 |
35 | |
36 | #pragma GCC system_header |
37 | |
38 | #include <bits/requires_hosted.h> // iostreams |
39 | |
40 | #include <bits/c++config.h> |
41 | #include <iosfwd> |
42 | #include <bits/ios_base.h> |
43 | |
44 | #define __glibcxx_want_quoted_string_io |
45 | #include <bits/version.h> |
46 | |
47 | #if __cplusplus >= 201103L |
48 | #include <locale> |
49 | #if __cplusplus > 201103L |
50 | #include <bits/quoted_string.h> |
51 | #endif |
52 | #endif |
53 | |
54 | namespace std _GLIBCXX_VISIBILITY(default) |
55 | { |
56 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
57 | |
58 | // [27.6.3] standard manipulators |
59 | // Also see DR 183. |
60 | |
61 | struct _Resetiosflags { ios_base::fmtflags _M_mask; }; |
62 | |
63 | /** |
64 | * @brief Manipulator for @c setf. |
65 | * @param __mask A format flags mask. |
66 | * |
67 | * Sent to a stream object, this manipulator resets the specified flags, |
68 | * via @e stream.setf(0,__mask). |
69 | */ |
70 | inline _Resetiosflags |
71 | resetiosflags(ios_base::fmtflags __mask) |
72 | { return { ._M_mask: __mask }; } |
73 | |
74 | template<typename _CharT, typename _Traits> |
75 | inline basic_istream<_CharT, _Traits>& |
76 | operator>>(basic_istream<_CharT, _Traits>& __is, _Resetiosflags __f) |
77 | { |
78 | __is.setf(ios_base::fmtflags(0), __f._M_mask); |
79 | return __is; |
80 | } |
81 | |
82 | template<typename _CharT, typename _Traits> |
83 | inline basic_ostream<_CharT, _Traits>& |
84 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Resetiosflags __f) |
85 | { |
86 | __os.setf(ios_base::fmtflags(0), __f._M_mask); |
87 | return __os; |
88 | } |
89 | |
90 | |
91 | struct _Setiosflags { ios_base::fmtflags _M_mask; }; |
92 | |
93 | /** |
94 | * @brief Manipulator for @c setf. |
95 | * @param __mask A format flags mask. |
96 | * |
97 | * Sent to a stream object, this manipulator sets the format flags |
98 | * to @a __mask. |
99 | */ |
100 | inline _Setiosflags |
101 | setiosflags(ios_base::fmtflags __mask) |
102 | { return { ._M_mask: __mask }; } |
103 | |
104 | template<typename _CharT, typename _Traits> |
105 | inline basic_istream<_CharT, _Traits>& |
106 | operator>>(basic_istream<_CharT, _Traits>& __is, _Setiosflags __f) |
107 | { |
108 | __is.setf(__f._M_mask); |
109 | return __is; |
110 | } |
111 | |
112 | template<typename _CharT, typename _Traits> |
113 | inline basic_ostream<_CharT, _Traits>& |
114 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Setiosflags __f) |
115 | { |
116 | __os.setf(__f._M_mask); |
117 | return __os; |
118 | } |
119 | |
120 | |
121 | struct _Setbase { int _M_base; }; |
122 | |
123 | /** |
124 | * @brief Manipulator for @c setf. |
125 | * @param __base A numeric base. |
126 | * |
127 | * Sent to a stream object, this manipulator changes the |
128 | * @c ios_base::basefield flags to @c oct, @c dec, or @c hex when @a base |
129 | * is 8, 10, or 16, accordingly, and to 0 if @a __base is any other value. |
130 | */ |
131 | inline _Setbase |
132 | setbase(int __base) |
133 | { return { ._M_base: __base }; } |
134 | |
135 | template<typename _CharT, typename _Traits> |
136 | inline basic_istream<_CharT, _Traits>& |
137 | operator>>(basic_istream<_CharT, _Traits>& __is, _Setbase __f) |
138 | { |
139 | __is.setf(__f._M_base == 8 ? ios_base::oct : |
140 | __f._M_base == 10 ? ios_base::dec : |
141 | __f._M_base == 16 ? ios_base::hex : |
142 | ios_base::fmtflags(0), ios_base::basefield); |
143 | return __is; |
144 | } |
145 | |
146 | template<typename _CharT, typename _Traits> |
147 | inline basic_ostream<_CharT, _Traits>& |
148 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Setbase __f) |
149 | { |
150 | __os.setf(__f._M_base == 8 ? ios_base::oct : |
151 | __f._M_base == 10 ? ios_base::dec : |
152 | __f._M_base == 16 ? ios_base::hex : |
153 | ios_base::fmtflags(0), ios_base::basefield); |
154 | return __os; |
155 | } |
156 | |
157 | |
158 | template<typename _CharT> |
159 | struct _Setfill { _CharT _M_c; }; |
160 | |
161 | /** |
162 | * @brief Manipulator for @c fill. |
163 | * @param __c The new fill character. |
164 | * |
165 | * Sent to a stream object, this manipulator calls @c fill(__c) for that |
166 | * object. |
167 | */ |
168 | template<typename _CharT> |
169 | inline _Setfill<_CharT> |
170 | setfill(_CharT __c) |
171 | { return { __c }; } |
172 | |
173 | template<typename _CharT, typename _Traits> |
174 | __attribute__((__deprecated__("'std::setfill' should only be used with " |
175 | "output streams" ))) |
176 | inline basic_istream<_CharT, _Traits>& |
177 | operator>>(basic_istream<_CharT, _Traits>& __is, _Setfill<_CharT> __f) |
178 | { |
179 | __is.fill(__f._M_c); |
180 | return __is; |
181 | } |
182 | |
183 | template<typename _CharT, typename _Traits> |
184 | inline basic_ostream<_CharT, _Traits>& |
185 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Setfill<_CharT> __f) |
186 | { |
187 | __os.fill(__f._M_c); |
188 | return __os; |
189 | } |
190 | |
191 | |
192 | struct _Setprecision { int _M_n; }; |
193 | |
194 | /** |
195 | * @brief Manipulator for @c precision. |
196 | * @param __n The new precision. |
197 | * |
198 | * Sent to a stream object, this manipulator calls @c precision(__n) for |
199 | * that object. |
200 | */ |
201 | inline _Setprecision |
202 | setprecision(int __n) |
203 | { return { ._M_n: __n }; } |
204 | |
205 | template<typename _CharT, typename _Traits> |
206 | inline basic_istream<_CharT, _Traits>& |
207 | operator>>(basic_istream<_CharT, _Traits>& __is, _Setprecision __f) |
208 | { |
209 | __is.precision(__f._M_n); |
210 | return __is; |
211 | } |
212 | |
213 | template<typename _CharT, typename _Traits> |
214 | inline basic_ostream<_CharT, _Traits>& |
215 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Setprecision __f) |
216 | { |
217 | __os.precision(__f._M_n); |
218 | return __os; |
219 | } |
220 | |
221 | |
222 | struct _Setw { int _M_n; }; |
223 | |
224 | /** |
225 | * @brief Manipulator for @c width. |
226 | * @param __n The new width. |
227 | * |
228 | * Sent to a stream object, this manipulator calls @c width(__n) for |
229 | * that object. |
230 | */ |
231 | inline _Setw |
232 | setw(int __n) |
233 | { return { ._M_n: __n }; } |
234 | |
235 | template<typename _CharT, typename _Traits> |
236 | inline basic_istream<_CharT, _Traits>& |
237 | operator>>(basic_istream<_CharT, _Traits>& __is, _Setw __f) |
238 | { |
239 | __is.width(__f._M_n); |
240 | return __is; |
241 | } |
242 | |
243 | template<typename _CharT, typename _Traits> |
244 | inline basic_ostream<_CharT, _Traits>& |
245 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f) |
246 | { |
247 | __os.width(__f._M_n); |
248 | return __os; |
249 | } |
250 | |
251 | #if __cplusplus >= 201103L |
252 | |
253 | template<typename _MoneyT> |
254 | struct _Get_money { _MoneyT& _M_mon; bool _M_intl; }; |
255 | |
256 | /** |
257 | * @brief Extended manipulator for extracting money. |
258 | * @param __mon Either long double or a specialization of @c basic_string. |
259 | * @param __intl A bool indicating whether international format |
260 | * is to be used. |
261 | * |
262 | * Sent to a stream object, this manipulator extracts @a __mon. |
263 | */ |
264 | template<typename _MoneyT> |
265 | inline _Get_money<_MoneyT> |
266 | get_money(_MoneyT& __mon, bool __intl = false) |
267 | { return { __mon, __intl }; } |
268 | |
269 | template<typename _CharT, typename _Traits, typename _MoneyT> |
270 | basic_istream<_CharT, _Traits>& |
271 | operator>>(basic_istream<_CharT, _Traits>& __is, _Get_money<_MoneyT> __f) |
272 | { |
273 | typename basic_istream<_CharT, _Traits>::sentry __cerb(__is, false); |
274 | if (__cerb) |
275 | { |
276 | ios_base::iostate __err = ios_base::goodbit; |
277 | __try |
278 | { |
279 | typedef istreambuf_iterator<_CharT, _Traits> _Iter; |
280 | typedef money_get<_CharT, _Iter> _MoneyGet; |
281 | |
282 | const _MoneyGet& __mg = use_facet<_MoneyGet>(__is.getloc()); |
283 | __mg.get(_Iter(__is.rdbuf()), _Iter(), __f._M_intl, |
284 | __is, __err, __f._M_mon); |
285 | } |
286 | __catch(__cxxabiv1::__forced_unwind&) |
287 | { |
288 | __is._M_setstate(ios_base::badbit); |
289 | __throw_exception_again; |
290 | } |
291 | __catch(...) |
292 | { __is._M_setstate(ios_base::badbit); } |
293 | if (__err) |
294 | __is.setstate(__err); |
295 | } |
296 | return __is; |
297 | } |
298 | |
299 | |
300 | template<typename _MoneyT> |
301 | struct _Put_money { const _MoneyT& _M_mon; bool _M_intl; }; |
302 | |
303 | /** |
304 | * @brief Extended manipulator for inserting money. |
305 | * @param __mon Either long double or a specialization of @c basic_string. |
306 | * @param __intl A bool indicating whether international format |
307 | * is to be used. |
308 | * |
309 | * Sent to a stream object, this manipulator inserts @a __mon. |
310 | */ |
311 | template<typename _MoneyT> |
312 | inline _Put_money<_MoneyT> |
313 | put_money(const _MoneyT& __mon, bool __intl = false) |
314 | { return { __mon, __intl }; } |
315 | |
316 | template<typename _CharT, typename _Traits, typename _MoneyT> |
317 | basic_ostream<_CharT, _Traits>& |
318 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Put_money<_MoneyT> __f) |
319 | { |
320 | typename basic_ostream<_CharT, _Traits>::sentry __cerb(__os); |
321 | if (__cerb) |
322 | { |
323 | ios_base::iostate __err = ios_base::goodbit; |
324 | __try |
325 | { |
326 | typedef ostreambuf_iterator<_CharT, _Traits> _Iter; |
327 | typedef money_put<_CharT, _Iter> _MoneyPut; |
328 | |
329 | const _MoneyPut& __mp = use_facet<_MoneyPut>(__os.getloc()); |
330 | if (__mp.put(_Iter(__os.rdbuf()), __f._M_intl, __os, |
331 | __os.fill(), __f._M_mon).failed()) |
332 | __err |= ios_base::badbit; |
333 | } |
334 | __catch(__cxxabiv1::__forced_unwind&) |
335 | { |
336 | __os._M_setstate(ios_base::badbit); |
337 | __throw_exception_again; |
338 | } |
339 | __catch(...) |
340 | { __os._M_setstate(ios_base::badbit); } |
341 | if (__err) |
342 | __os.setstate(__err); |
343 | } |
344 | return __os; |
345 | } |
346 | |
347 | template<typename _CharT> |
348 | struct _Put_time |
349 | { |
350 | const std::tm* _M_tmb; |
351 | const _CharT* _M_fmt; |
352 | }; |
353 | |
354 | /** |
355 | * @brief Extended manipulator for formatting time. |
356 | * |
357 | * This manipulator uses time_put::put to format time. |
358 | * [ext.manip] |
359 | * |
360 | * @param __tmb struct tm time data to format. |
361 | * @param __fmt format string. |
362 | */ |
363 | template<typename _CharT> |
364 | inline _Put_time<_CharT> |
365 | put_time(const std::tm* __tmb, const _CharT* __fmt) |
366 | { return { __tmb, __fmt }; } |
367 | |
368 | template<typename _CharT, typename _Traits> |
369 | basic_ostream<_CharT, _Traits>& |
370 | operator<<(basic_ostream<_CharT, _Traits>& __os, _Put_time<_CharT> __f) |
371 | { |
372 | typename basic_ostream<_CharT, _Traits>::sentry __cerb(__os); |
373 | if (__cerb) |
374 | { |
375 | ios_base::iostate __err = ios_base::goodbit; |
376 | __try |
377 | { |
378 | typedef ostreambuf_iterator<_CharT, _Traits> _Iter; |
379 | typedef time_put<_CharT, _Iter> _TimePut; |
380 | |
381 | const _CharT* const __fmt_end = __f._M_fmt + |
382 | _Traits::length(__f._M_fmt); |
383 | |
384 | const _TimePut& __mp = use_facet<_TimePut>(__os.getloc()); |
385 | if (__mp.put(_Iter(__os.rdbuf()), __os, __os.fill(), |
386 | __f._M_tmb, __f._M_fmt, __fmt_end).failed()) |
387 | __err |= ios_base::badbit; |
388 | } |
389 | __catch(__cxxabiv1::__forced_unwind&) |
390 | { |
391 | __os._M_setstate(ios_base::badbit); |
392 | __throw_exception_again; |
393 | } |
394 | __catch(...) |
395 | { __os._M_setstate(ios_base::badbit); } |
396 | if (__err) |
397 | __os.setstate(__err); |
398 | } |
399 | return __os; |
400 | } |
401 | |
402 | template<typename _CharT> |
403 | struct _Get_time |
404 | { |
405 | std::tm* _M_tmb; |
406 | const _CharT* _M_fmt; |
407 | }; |
408 | |
409 | /** |
410 | * @brief Extended manipulator for extracting time. |
411 | * |
412 | * This manipulator uses time_get::get to extract time. |
413 | * [ext.manip] |
414 | * |
415 | * @param __tmb struct to extract the time data to. |
416 | * @param __fmt format string. |
417 | */ |
418 | template<typename _CharT> |
419 | inline _Get_time<_CharT> |
420 | get_time(std::tm* __tmb, const _CharT* __fmt) |
421 | { return { __tmb, __fmt }; } |
422 | |
423 | template<typename _CharT, typename _Traits> |
424 | basic_istream<_CharT, _Traits>& |
425 | operator>>(basic_istream<_CharT, _Traits>& __is, _Get_time<_CharT> __f) |
426 | { |
427 | typename basic_istream<_CharT, _Traits>::sentry __cerb(__is, false); |
428 | if (__cerb) |
429 | { |
430 | ios_base::iostate __err = ios_base::goodbit; |
431 | __try |
432 | { |
433 | typedef istreambuf_iterator<_CharT, _Traits> _Iter; |
434 | typedef time_get<_CharT, _Iter> _TimeGet; |
435 | |
436 | const _CharT* const __fmt_end = __f._M_fmt + |
437 | _Traits::length(__f._M_fmt); |
438 | |
439 | const _TimeGet& __mg = use_facet<_TimeGet>(__is.getloc()); |
440 | __mg.get(_Iter(__is.rdbuf()), _Iter(), __is, |
441 | __err, __f._M_tmb, __f._M_fmt, __fmt_end); |
442 | } |
443 | __catch(__cxxabiv1::__forced_unwind&) |
444 | { |
445 | __is._M_setstate(ios_base::badbit); |
446 | __throw_exception_again; |
447 | } |
448 | __catch(...) |
449 | { __is._M_setstate(ios_base::badbit); } |
450 | if (__err) |
451 | __is.setstate(__err); |
452 | } |
453 | return __is; |
454 | } |
455 | |
456 | #ifdef __cpp_lib_quoted_string_io // C++ >= 14 && HOSTED |
457 | |
458 | /** |
459 | * @brief Manipulator for quoted strings. |
460 | * @param __string String to quote. |
461 | * @param __delim Character to quote string with. |
462 | * @param __escape Escape character to escape itself or quote character. |
463 | * @since C++14 |
464 | */ |
465 | template<typename _CharT> |
466 | inline auto |
467 | quoted(const _CharT* __string, |
468 | _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) |
469 | { |
470 | return __detail::_Quoted_string<const _CharT*, _CharT>(__string, __delim, |
471 | __escape); |
472 | } |
473 | |
474 | template<typename _CharT, typename _Traits, typename _Alloc> |
475 | inline auto |
476 | quoted(const basic_string<_CharT, _Traits, _Alloc>& __string, |
477 | _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) |
478 | { |
479 | return __detail::_Quoted_string< |
480 | const basic_string<_CharT, _Traits, _Alloc>&, _CharT>( |
481 | __string, __delim, __escape); |
482 | } |
483 | |
484 | template<typename _CharT, typename _Traits, typename _Alloc> |
485 | inline auto |
486 | quoted(basic_string<_CharT, _Traits, _Alloc>& __string, |
487 | _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) |
488 | { |
489 | return __detail::_Quoted_string< |
490 | basic_string<_CharT, _Traits, _Alloc>&, _CharT>( |
491 | __string, __delim, __escape); |
492 | } |
493 | |
494 | #if __cplusplus >= 201703L |
495 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
496 | // 2785. quoted should work with basic_string_view |
497 | template<typename _CharT, typename _Traits> |
498 | inline auto |
499 | quoted(basic_string_view<_CharT, _Traits> __sv, |
500 | _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) |
501 | { |
502 | return __detail::_Quoted_string< |
503 | basic_string_view<_CharT, _Traits>, _CharT>(__sv, __delim, __escape); |
504 | } |
505 | #endif // C++17 |
506 | #endif // __cpp_lib_quoted_string_io |
507 | |
508 | #endif // __cplusplus >= 201103L |
509 | |
510 | // Inhibit implicit instantiations for required instantiations, |
511 | // which are defined via explicit instantiations elsewhere. |
512 | // NB: This syntax is a GNU extension. |
513 | #if _GLIBCXX_EXTERN_TEMPLATE |
514 | extern template ostream& operator<<(ostream&, _Setfill<char>); |
515 | extern template ostream& operator<<(ostream&, _Setiosflags); |
516 | extern template ostream& operator<<(ostream&, _Resetiosflags); |
517 | extern template ostream& operator<<(ostream&, _Setbase); |
518 | extern template ostream& operator<<(ostream&, _Setprecision); |
519 | extern template ostream& operator<<(ostream&, _Setw); |
520 | extern template istream& operator>>(istream&, _Setfill<char>); |
521 | extern template istream& operator>>(istream&, _Setiosflags); |
522 | extern template istream& operator>>(istream&, _Resetiosflags); |
523 | extern template istream& operator>>(istream&, _Setbase); |
524 | extern template istream& operator>>(istream&, _Setprecision); |
525 | extern template istream& operator>>(istream&, _Setw); |
526 | |
527 | #ifdef _GLIBCXX_USE_WCHAR_T |
528 | extern template wostream& operator<<(wostream&, _Setfill<wchar_t>); |
529 | extern template wostream& operator<<(wostream&, _Setiosflags); |
530 | extern template wostream& operator<<(wostream&, _Resetiosflags); |
531 | extern template wostream& operator<<(wostream&, _Setbase); |
532 | extern template wostream& operator<<(wostream&, _Setprecision); |
533 | extern template wostream& operator<<(wostream&, _Setw); |
534 | extern template wistream& operator>>(wistream&, _Setfill<wchar_t>); |
535 | extern template wistream& operator>>(wistream&, _Setiosflags); |
536 | extern template wistream& operator>>(wistream&, _Resetiosflags); |
537 | extern template wistream& operator>>(wistream&, _Setbase); |
538 | extern template wistream& operator>>(wistream&, _Setprecision); |
539 | extern template wistream& operator>>(wistream&, _Setw); |
540 | #endif |
541 | #endif |
542 | |
543 | _GLIBCXX_END_NAMESPACE_VERSION |
544 | } // namespace |
545 | |
546 | #endif /* _GLIBCXX_IOMANIP */ |
547 | |