1 //===---------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===---------------------------------------------------------------------===//
8
9 #ifndef _LIBCPP___OSTREAM_BASIC_OSTREAM_H
10 #define _LIBCPP___OSTREAM_BASIC_OSTREAM_H
11
12 #include <__config>
13
14 #if _LIBCPP_HAS_LOCALIZATION
15
16 # include <__exception/operations.h>
17 # include <__fwd/memory.h>
18 # include <__iterator/ostreambuf_iterator.h>
19 # include <__locale_dir/num.h>
20 # include <__locale_dir/pad_and_output.h>
21 # include <__memory/addressof.h>
22 # include <__memory/unique_ptr.h>
23 # include <__new/exceptions.h>
24 # include <__ostream/put_character_sequence.h>
25 # include <__system_error/error_code.h>
26 # include <__type_traits/conjunction.h>
27 # include <__type_traits/enable_if.h>
28 # include <__type_traits/is_base_of.h>
29 # include <__type_traits/void_t.h>
30 # include <__utility/declval.h>
31 # include <bitset>
32 # include <ios>
33 # include <streambuf>
34 # include <string_view>
35
36 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
37 # pragma GCC system_header
38 # endif
39
40 _LIBCPP_PUSH_MACROS
41 # include <__undef_macros>
42
43 _LIBCPP_BEGIN_NAMESPACE_STD
44
45 template <class _CharT, class _Traits>
46 class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
47 public:
48 // types (inherited from basic_ios (27.5.4)):
49 typedef _CharT char_type;
50 typedef _Traits traits_type;
51 typedef typename traits_type::int_type int_type;
52 typedef typename traits_type::pos_type pos_type;
53 typedef typename traits_type::off_type off_type;
54
55 // 27.7.2.2 Constructor/destructor:
basic_ostream(basic_streambuf<char_type,traits_type> * __sb)56 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) {
57 this->init(__sb);
58 }
59 ~basic_ostream() override;
60
61 basic_ostream(const basic_ostream& __rhs) = delete;
62 basic_ostream& operator=(const basic_ostream& __rhs) = delete;
63
64 protected:
65 inline _LIBCPP_HIDE_FROM_ABI basic_ostream(basic_ostream&& __rhs);
66
67 // 27.7.2.3 Assign/swap
68 inline _LIBCPP_HIDE_FROM_ABI basic_ostream& operator=(basic_ostream&& __rhs);
69
swap(basic_ostream & __rhs)70 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_ostream& __rhs) {
71 basic_ios<char_type, traits_type>::swap(__rhs);
72 }
73
74 public:
75 // 27.7.2.4 Prefix/suffix:
76 class sentry;
77
78 // 27.7.2.6 Formatted output:
79 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) {
80 return __pf(*this);
81 }
82
83 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream&
84 operator<<(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) {
85 __pf(*this);
86 return *this;
87 }
88
89 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) {
90 __pf(*this);
91 return *this;
92 }
93
94 template <class _Tp>
__put_num(_Tp __value)95 _LIBCPP_HIDE_FROM_ABI basic_ostream& __put_num(_Tp __value) {
96 # if _LIBCPP_HAS_EXCEPTIONS
97 try {
98 # endif // _LIBCPP_HAS_EXCEPTIONS
99 sentry __s(*this);
100 if (__s) {
101 using _Fp = num_put<char_type, ostreambuf_iterator<char_type, traits_type> >;
102 const _Fp& __facet = std::use_facet<_Fp>(this->getloc());
103 if (__facet.put(*this, *this, this->fill(), __value).failed())
104 this->setstate(ios_base::badbit | ios_base::failbit);
105 }
106 # if _LIBCPP_HAS_EXCEPTIONS
107 } catch (...) {
108 this->__set_badbit_and_consider_rethrow();
109 }
110 # endif // _LIBCPP_HAS_EXCEPTIONS
111 return *this;
112 }
113
114 template <class _Tp>
__put_num_integer_promote(_Tp __value)115 _LIBCPP_HIDE_FROM_ABI basic_ostream& __put_num_integer_promote(_Tp __value) {
116 # if _LIBCPP_HAS_EXCEPTIONS
117 try {
118 # endif // _LIBCPP_HAS_EXCEPTIONS
119 sentry __s(*this);
120 if (__s) {
121 ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;
122
123 using _Fp = num_put<char_type, ostreambuf_iterator<char_type, traits_type> >;
124 const _Fp& __facet = std::use_facet<_Fp>(this->getloc());
125 if (__facet
126 .put(*this,
127 *this,
128 this->fill(),
129 __flags == ios_base::oct || __flags == ios_base::hex
130 ? static_cast<__copy_unsigned_t<_Tp, long> >(std::__to_unsigned_like(__value))
131 : static_cast<__copy_unsigned_t<_Tp, long> >(__value))
132 .failed())
133 this->setstate(ios_base::badbit | ios_base::failbit);
134 }
135 # if _LIBCPP_HAS_EXCEPTIONS
136 } catch (...) {
137 this->__set_badbit_and_consider_rethrow();
138 }
139 # endif // _LIBCPP_HAS_EXCEPTIONS
140 return *this;
141 }
142
143 basic_ostream& operator<<(bool __n);
144 basic_ostream& operator<<(short __n);
145 basic_ostream& operator<<(unsigned short __n);
146 basic_ostream& operator<<(int __n);
147 basic_ostream& operator<<(unsigned int __n);
148 basic_ostream& operator<<(long __n);
149 basic_ostream& operator<<(unsigned long __n);
150 basic_ostream& operator<<(long long __n);
151 basic_ostream& operator<<(unsigned long long __n);
152 basic_ostream& operator<<(float __f);
153 basic_ostream& operator<<(double __f);
154 basic_ostream& operator<<(long double __f);
155 basic_ostream& operator<<(const void* __p);
156
157 # if _LIBCPP_STD_VER >= 23
158 _LIBCPP_HIDE_FROM_ABI basic_ostream& operator<<(const volatile void* __p) {
159 return operator<<(const_cast<const void*>(__p));
160 }
161 # endif
162
163 basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);
164
165 # if _LIBCPP_STD_VER >= 17
166 // LWG 2221 - nullptr. This is not backported to older standards modes.
167 // See https://reviews.llvm.org/D127033 for more info on the rationale.
168 _LIBCPP_HIDE_FROM_ABI basic_ostream& operator<<(nullptr_t) { return *this << "nullptr"; }
169 # endif
170
171 // 27.7.2.7 Unformatted output:
172 basic_ostream& put(char_type __c);
173 basic_ostream& write(const char_type* __s, streamsize __n);
174 basic_ostream& flush();
175
176 // 27.7.2.5 seeks:
177 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type tellp();
178 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(pos_type __pos);
179 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
180
181 protected:
basic_ostream()182 _LIBCPP_HIDE_FROM_ABI basic_ostream() {} // extension, intentially does not initialize
183 };
184
185 template <class _CharT, class _Traits>
186 class basic_ostream<_CharT, _Traits>::sentry {
187 bool __ok_;
188 basic_ostream<_CharT, _Traits>& __os_;
189
190 public:
191 explicit sentry(basic_ostream<_CharT, _Traits>& __os);
192 ~sentry();
193 sentry(const sentry&) = delete;
194 sentry& operator=(const sentry&) = delete;
195
196 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ok_; }
197 };
198
199 template <class _CharT, class _Traits>
sentry(basic_ostream<_CharT,_Traits> & __os)200 basic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& __os) : __ok_(false), __os_(__os) {
201 if (__os.good()) {
202 if (__os.tie())
203 __os.tie()->flush();
204 __ok_ = true;
205 }
206 }
207
208 template <class _CharT, class _Traits>
~sentry()209 basic_ostream<_CharT, _Traits>::sentry::~sentry() {
210 if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) {
211 # if _LIBCPP_HAS_EXCEPTIONS
212 try {
213 # endif // _LIBCPP_HAS_EXCEPTIONS
214 if (__os_.rdbuf()->pubsync() == -1)
215 __os_.setstate(ios_base::badbit);
216 # if _LIBCPP_HAS_EXCEPTIONS
217 } catch (...) {
218 }
219 # endif // _LIBCPP_HAS_EXCEPTIONS
220 }
221 }
222
223 template <class _CharT, class _Traits>
basic_ostream(basic_ostream && __rhs)224 basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs) {
225 this->move(__rhs);
226 }
227
228 template <class _CharT, class _Traits>
229 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs) {
230 swap(__rhs);
231 return *this;
232 }
233
234 template <class _CharT, class _Traits>
~basic_ostream()235 basic_ostream<_CharT, _Traits>::~basic_ostream() {}
236
237 template <class _CharT, class _Traits>
238 basic_ostream<_CharT, _Traits>&
239 basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb) {
240 # if _LIBCPP_HAS_EXCEPTIONS
241 try {
242 # endif // _LIBCPP_HAS_EXCEPTIONS
243 sentry __s(*this);
244 if (__s) {
245 if (__sb) {
246 # if _LIBCPP_HAS_EXCEPTIONS
247 try {
248 # endif // _LIBCPP_HAS_EXCEPTIONS
249 typedef istreambuf_iterator<_CharT, _Traits> _Ip;
250 typedef ostreambuf_iterator<_CharT, _Traits> _Op;
251 _Ip __i(__sb);
252 _Ip __eof;
253 _Op __o(*this);
254 size_t __c = 0;
255 for (; __i != __eof; ++__i, ++__o, ++__c) {
256 *__o = *__i;
257 if (__o.failed())
258 break;
259 }
260 if (__c == 0)
261 this->setstate(ios_base::failbit);
262 # if _LIBCPP_HAS_EXCEPTIONS
catch(...)263 } catch (...) {
264 this->__set_failbit_and_consider_rethrow();
265 }
266 # endif // _LIBCPP_HAS_EXCEPTIONS
267 } else
268 this->setstate(ios_base::badbit);
269 }
270 # if _LIBCPP_HAS_EXCEPTIONS
catch(...)271 } catch (...) {
272 this->__set_badbit_and_consider_rethrow();
273 }
274 # endif // _LIBCPP_HAS_EXCEPTIONS
275 return *this;
276 }
277
278 template <class _CharT, class _Traits>
279 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __n) {
280 return __put_num(__n);
281 }
282
283 template <class _CharT, class _Traits>
284 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(short __n) {
285 return __put_num_integer_promote(__n);
286 }
287
288 template <class _CharT, class _Traits>
289 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n) {
290 return __put_num_integer_promote(__n);
291 }
292
293 template <class _CharT, class _Traits>
294 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(int __n) {
295 return __put_num_integer_promote(__n);
296 }
297
298 template <class _CharT, class _Traits>
299 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n) {
300 return __put_num_integer_promote(__n);
301 }
302
303 template <class _CharT, class _Traits>
304 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __n) {
305 return __put_num(__n);
306 }
307
308 template <class _CharT, class _Traits>
309 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) {
310 return __put_num(__n);
311 }
312
313 template <class _CharT, class _Traits>
314 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long long __n) {
315 return __put_num(__n);
316 }
317
318 template <class _CharT, class _Traits>
319 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) {
320 return __put_num(__n);
321 }
322
323 template <class _CharT, class _Traits>
324 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __n) {
325 return *this << static_cast<double>(__n);
326 }
327
328 template <class _CharT, class _Traits>
329 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __n) {
330 return __put_num(__n);
331 }
332
333 template <class _CharT, class _Traits>
334 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __n) {
335 return __put_num(__n);
336 }
337
338 template <class _CharT, class _Traits>
339 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __n) {
340 return __put_num(__n);
341 }
342
343 template <class _CharT, class _Traits>
344 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, _CharT __c) {
345 return std::__put_character_sequence(__os, std::addressof(__c), 1);
346 }
347
348 template <class _CharT, class _Traits>
349 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn) {
350 # if _LIBCPP_HAS_EXCEPTIONS
351 try {
352 # endif // _LIBCPP_HAS_EXCEPTIONS
353 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
354 if (__s) {
355 _CharT __c = __os.widen(__cn);
356 typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
357 if (std::__pad_and_output(
358 _Ip(__os),
359 std::addressof(__c),
360 std::addressof(__c) + (((__os.flags() & ios_base::adjustfield) == ios_base::left) ? 1 : 0),
361 std::addressof(__c) + 1,
362 __os,
363 __os.fill())
364 .failed())
365 __os.setstate(ios_base::badbit | ios_base::failbit);
366 }
367 # if _LIBCPP_HAS_EXCEPTIONS
catch(...)368 } catch (...) {
369 __os.__set_badbit_and_consider_rethrow();
370 }
371 # endif // _LIBCPP_HAS_EXCEPTIONS
372 return __os;
373 }
374
375 template <class _Traits>
376 _LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __os, char __c) {
377 return std::__put_character_sequence(__os, &__c, 1);
378 }
379
380 template <class _Traits>
381 _LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __os, signed char __c) {
382 return std::__put_character_sequence(__os, (char*)&__c, 1);
383 }
384
385 template <class _Traits>
386 _LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __os, unsigned char __c) {
387 return std::__put_character_sequence(__os, (char*)&__c, 1);
388 }
389
390 template <class _CharT, class _Traits>
391 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
392 operator<<(basic_ostream<_CharT, _Traits>& __os, const _CharT* __str) {
393 return std::__put_character_sequence(__os, __str, _Traits::length(__str));
394 }
395
396 template <class _CharT, class _Traits>
397 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
398 operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn) {
399 # if _LIBCPP_HAS_EXCEPTIONS
400 try {
401 # endif // _LIBCPP_HAS_EXCEPTIONS
402 typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
403 if (__s) {
404 typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
405 size_t __len = char_traits<char>::length(__strn);
406 const int __bs = 100;
407 _CharT __wbb[__bs];
408 _CharT* __wb = __wbb;
409 unique_ptr<_CharT, void (*)(void*)> __h(0, free);
410 if (__len > __bs) {
411 __wb = (_CharT*)malloc(__len * sizeof(_CharT));
412 if (__wb == 0)
413 std::__throw_bad_alloc();
414 __h.reset(__wb);
415 }
416 for (_CharT* __p = __wb; *__strn != '\0'; ++__strn, ++__p)
417 *__p = __os.widen(*__strn);
418 if (std::__pad_and_output(
419 _Ip(__os),
420 __wb,
421 (__os.flags() & ios_base::adjustfield) == ios_base::left ? __wb + __len : __wb,
422 __wb + __len,
423 __os,
424 __os.fill())
425 .failed())
426 __os.setstate(ios_base::badbit | ios_base::failbit);
427 }
428 # if _LIBCPP_HAS_EXCEPTIONS
catch(...)429 } catch (...) {
430 __os.__set_badbit_and_consider_rethrow();
431 }
432 # endif // _LIBCPP_HAS_EXCEPTIONS
433 return __os;
434 }
435
436 template <class _Traits>
437 _LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __os, const char* __str) {
438 return std::__put_character_sequence(__os, __str, _Traits::length(__str));
439 }
440
441 template <class _Traits>
442 _LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>&
443 operator<<(basic_ostream<char, _Traits>& __os, const signed char* __str) {
444 const char* __s = (const char*)__str;
445 return std::__put_character_sequence(__os, __s, _Traits::length(__s));
446 }
447
448 template <class _Traits>
449 _LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>&
450 operator<<(basic_ostream<char, _Traits>& __os, const unsigned char* __str) {
451 const char* __s = (const char*)__str;
452 return std::__put_character_sequence(__os, __s, _Traits::length(__s));
453 }
454
455 template <class _CharT, class _Traits>
put(char_type __c)456 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::put(char_type __c) {
457 # if _LIBCPP_HAS_EXCEPTIONS
458 try {
459 # endif // _LIBCPP_HAS_EXCEPTIONS
460 sentry __s(*this);
461 if (__s) {
462 typedef ostreambuf_iterator<_CharT, _Traits> _Op;
463 _Op __o(*this);
464 *__o = __c;
465 if (__o.failed())
466 this->setstate(ios_base::badbit);
467 }
468 # if _LIBCPP_HAS_EXCEPTIONS
469 } catch (...) {
470 this->__set_badbit_and_consider_rethrow();
471 }
472 # endif // _LIBCPP_HAS_EXCEPTIONS
473 return *this;
474 }
475
476 template <class _CharT, class _Traits>
write(const char_type * __s,streamsize __n)477 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n) {
478 # if _LIBCPP_HAS_EXCEPTIONS
479 try {
480 # endif // _LIBCPP_HAS_EXCEPTIONS
481 sentry __sen(*this);
482 if (__sen && __n) {
483 if (this->rdbuf()->sputn(__s, __n) != __n)
484 this->setstate(ios_base::badbit);
485 }
486 # if _LIBCPP_HAS_EXCEPTIONS
487 } catch (...) {
488 this->__set_badbit_and_consider_rethrow();
489 }
490 # endif // _LIBCPP_HAS_EXCEPTIONS
491 return *this;
492 }
493
494 template <class _CharT, class _Traits>
flush()495 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::flush() {
496 # if _LIBCPP_HAS_EXCEPTIONS
497 try {
498 # endif // _LIBCPP_HAS_EXCEPTIONS
499 if (this->rdbuf()) {
500 sentry __s(*this);
501 if (__s) {
502 if (this->rdbuf()->pubsync() == -1)
503 this->setstate(ios_base::badbit);
504 }
505 }
506 # if _LIBCPP_HAS_EXCEPTIONS
507 } catch (...) {
508 this->__set_badbit_and_consider_rethrow();
509 }
510 # endif // _LIBCPP_HAS_EXCEPTIONS
511 return *this;
512 }
513
514 template <class _CharT, class _Traits>
tellp()515 typename basic_ostream<_CharT, _Traits>::pos_type basic_ostream<_CharT, _Traits>::tellp() {
516 if (this->fail())
517 return pos_type(-1);
518 return this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
519 }
520
521 template <class _CharT, class _Traits>
seekp(pos_type __pos)522 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) {
523 sentry __s(*this);
524 if (!this->fail()) {
525 if (this->rdbuf()->pubseekpos(__pos, ios_base::out) == pos_type(-1))
526 this->setstate(ios_base::failbit);
527 }
528 return *this;
529 }
530
531 template <class _CharT, class _Traits>
seekp(off_type __off,ios_base::seekdir __dir)532 basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir) {
533 sentry __s(*this);
534 if (!this->fail()) {
535 if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::out) == pos_type(-1))
536 this->setstate(ios_base::failbit);
537 }
538 return *this;
539 }
540
541 template <class _CharT, class _Traits>
endl(basic_ostream<_CharT,_Traits> & __os)542 _LIBCPP_HIDE_FROM_ABI inline basic_ostream<_CharT, _Traits>& endl(basic_ostream<_CharT, _Traits>& __os) {
543 __os.put(__os.widen('\n'));
544 __os.flush();
545 return __os;
546 }
547
548 template <class _CharT, class _Traits>
ends(basic_ostream<_CharT,_Traits> & __os)549 _LIBCPP_HIDE_FROM_ABI inline basic_ostream<_CharT, _Traits>& ends(basic_ostream<_CharT, _Traits>& __os) {
550 __os.put(_CharT());
551 return __os;
552 }
553
554 template <class _CharT, class _Traits>
flush(basic_ostream<_CharT,_Traits> & __os)555 _LIBCPP_HIDE_FROM_ABI inline basic_ostream<_CharT, _Traits>& flush(basic_ostream<_CharT, _Traits>& __os) {
556 __os.flush();
557 return __os;
558 }
559
560 template <class _Stream, class _Tp, class = void>
561 struct __is_ostreamable : false_type {};
562
563 template <class _Stream, class _Tp>
564 struct __is_ostreamable<_Stream, _Tp, decltype(std::declval<_Stream>() << std::declval<_Tp>(), void())> : true_type {};
565
566 template <class _Stream,
567 class _Tp,
568 __enable_if_t<_And<is_base_of<ios_base, _Stream>, __is_ostreamable<_Stream&, const _Tp&> >::value, int> = 0>
569 _LIBCPP_HIDE_FROM_ABI _Stream&& operator<<(_Stream&& __os, const _Tp& __x) {
570 __os << __x;
571 return std::move(__os);
572 }
573
574 template <class _CharT, class _Traits, class _Allocator>
575 basic_ostream<_CharT, _Traits>&
576 operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Allocator>& __str) {
577 return std::__put_character_sequence(__os, __str.data(), __str.size());
578 }
579
580 template <class _CharT, class _Traits>
581 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
582 operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv) {
583 return std::__put_character_sequence(__os, __sv.data(), __sv.size());
584 }
585
586 template <class _CharT, class _Traits>
587 inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
588 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __ec) {
589 return __os << __ec.category().name() << ':' << __ec.value();
590 }
591
592 template <class _CharT, class _Traits, class _Yp>
593 inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
594 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p) {
595 return __os << __p.get();
596 }
597
598 template <
599 class _CharT,
600 class _Traits,
601 class _Yp,
602 class _Dp,
603 __enable_if_t<is_same<void,
604 __void_t<decltype((std::declval<basic_ostream<_CharT, _Traits>&>()
605 << std::declval<typename unique_ptr<_Yp, _Dp>::pointer>()))> >::value,
606 int> = 0>
607 inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
608 operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p) {
609 return __os << __p.get();
610 }
611
612 template <class _CharT, class _Traits, size_t _Size>
613 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
614 operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) {
615 return __os << __x.template to_string<_CharT, _Traits>(std::use_facet<ctype<_CharT> >(__os.getloc()).widen('0'),
616 std::use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
617 }
618
619 # if _LIBCPP_STD_VER >= 20
620
621 # if _LIBCPP_HAS_WIDE_CHARACTERS
622 template <class _Traits>
623 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, wchar_t) = delete;
624
625 template <class _Traits>
626 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const wchar_t*) = delete;
627
628 template <class _Traits>
629 basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char16_t) = delete;
630
631 template <class _Traits>
632 basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char32_t) = delete;
633
634 template <class _Traits>
635 basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char16_t*) = delete;
636
637 template <class _Traits>
638 basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char32_t*) = delete;
639
640 # endif // _LIBCPP_HAS_WIDE_CHARACTERS
641
642 # if _LIBCPP_HAS_CHAR8_T
643 template <class _Traits>
644 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char8_t) = delete;
645
646 template <class _Traits>
647 basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char8_t) = delete;
648
649 template <class _Traits>
650 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char8_t*) = delete;
651
652 template <class _Traits>
653 basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char8_t*) = delete;
654 # endif
655
656 template <class _Traits>
657 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char16_t) = delete;
658
659 template <class _Traits>
660 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char32_t) = delete;
661
662 template <class _Traits>
663 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char16_t*) = delete;
664
665 template <class _Traits>
666 basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete;
667
668 # endif // _LIBCPP_STD_VER >= 20
669
670 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>;
671 # if _LIBCPP_HAS_WIDE_CHARACTERS
672 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>;
673 # endif
674
675 _LIBCPP_END_NAMESPACE_STD
676
677 _LIBCPP_POP_MACROS
678
679 #endif // _LIBCPP_HAS_LOCALIZATION
680
681 #endif // _LIBCPP___OSTREAM_BASIC_OSTREAM_H
682