master
  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
 45template <class _CharT, class _Traits>
 46class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
 47public:
 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:
 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
 64protected:
 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
 70  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_ostream& __rhs) {
 71    basic_ios<char_type, traits_type>::swap(__rhs);
 72  }
 73
 74public:
 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>
 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>
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
181protected:
182  _LIBCPP_HIDE_FROM_ABI basic_ostream() {} // extension, intentially does not initialize
183};
184
185template <class _CharT, class _Traits>
186class basic_ostream<_CharT, _Traits>::sentry {
187  bool __ok_;
188  basic_ostream<_CharT, _Traits>& __os_;
189
190public:
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
199template <class _CharT, class _Traits>
200basic_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
208template <class _CharT, class _Traits>
209basic_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
223template <class _CharT, class _Traits>
224basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs) {
225  this->move(__rhs);
226}
227
228template <class _CharT, class _Traits>
229basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs) {
230  swap(__rhs);
231  return *this;
232}
233
234template <class _CharT, class _Traits>
235basic_ostream<_CharT, _Traits>::~basic_ostream() {}
236
237template <class _CharT, class _Traits>
238basic_ostream<_CharT, _Traits>&
239basic_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
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
271  } catch (...) {
272    this->__set_badbit_and_consider_rethrow();
273  }
274#  endif // _LIBCPP_HAS_EXCEPTIONS
275  return *this;
276}
277
278template <class _CharT, class _Traits>
279basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(bool __n) {
280  return __put_num(__n);
281}
282
283template <class _CharT, class _Traits>
284basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(short __n) {
285  return __put_num_integer_promote(__n);
286}
287
288template <class _CharT, class _Traits>
289basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n) {
290  return __put_num_integer_promote(__n);
291}
292
293template <class _CharT, class _Traits>
294basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(int __n) {
295  return __put_num_integer_promote(__n);
296}
297
298template <class _CharT, class _Traits>
299basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n) {
300  return __put_num_integer_promote(__n);
301}
302
303template <class _CharT, class _Traits>
304basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long __n) {
305  return __put_num(__n);
306}
307
308template <class _CharT, class _Traits>
309basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) {
310  return __put_num(__n);
311}
312
313template <class _CharT, class _Traits>
314basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long long __n) {
315  return __put_num(__n);
316}
317
318template <class _CharT, class _Traits>
319basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) {
320  return __put_num(__n);
321}
322
323template <class _CharT, class _Traits>
324basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(float __n) {
325  return *this << static_cast<double>(__n);
326}
327
328template <class _CharT, class _Traits>
329basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(double __n) {
330  return __put_num(__n);
331}
332
333template <class _CharT, class _Traits>
334basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(long double __n) {
335  return __put_num(__n);
336}
337
338template <class _CharT, class _Traits>
339basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(const void* __n) {
340  return __put_num(__n);
341}
342
343template <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
348template <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
368  } catch (...) {
369    __os.__set_badbit_and_consider_rethrow();
370  }
371#  endif // _LIBCPP_HAS_EXCEPTIONS
372  return __os;
373}
374
375template <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
380template <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
385template <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
390template <class _CharT, class _Traits>
391_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
392operator<<(basic_ostream<_CharT, _Traits>& __os, const _CharT* __str) {
393  return std::__put_character_sequence(__os, __str, _Traits::length(__str));
394}
395
396template <class _CharT, class _Traits>
397_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
398operator<<(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
429  } catch (...) {
430    __os.__set_badbit_and_consider_rethrow();
431  }
432#  endif // _LIBCPP_HAS_EXCEPTIONS
433  return __os;
434}
435
436template <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
441template <class _Traits>
442_LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>&
443operator<<(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
448template <class _Traits>
449_LIBCPP_HIDE_FROM_ABI basic_ostream<char, _Traits>&
450operator<<(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
455template <class _CharT, class _Traits>
456basic_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
476template <class _CharT, class _Traits>
477basic_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
494template <class _CharT, class _Traits>
495basic_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
514template <class _CharT, class _Traits>
515typename 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
521template <class _CharT, class _Traits>
522basic_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
531template <class _CharT, class _Traits>
532basic_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
541template <class _CharT, class _Traits>
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
548template <class _CharT, class _Traits>
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
554template <class _CharT, class _Traits>
555_LIBCPP_HIDE_FROM_ABI inline basic_ostream<_CharT, _Traits>& flush(basic_ostream<_CharT, _Traits>& __os) {
556  __os.flush();
557  return __os;
558}
559
560template <class _Stream, class _Tp, class = void>
561struct __is_ostreamable : false_type {};
562
563template <class _Stream, class _Tp>
564struct __is_ostreamable<_Stream, _Tp, decltype(std::declval<_Stream>() << std::declval<_Tp>(), void())> : true_type {};
565
566template <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
574template <class _CharT, class _Traits, class _Allocator>
575basic_ostream<_CharT, _Traits>&
576operator<<(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
580template <class _CharT, class _Traits>
581_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
582operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv) {
583  return std::__put_character_sequence(__os, __sv.data(), __sv.size());
584}
585
586template <class _CharT, class _Traits>
587inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
588operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __ec) {
589  return __os << __ec.category().name() << ':' << __ec.value();
590}
591
592template <class _CharT, class _Traits, class _Yp>
593inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
594operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p) {
595  return __os << __p.get();
596}
597
598template <
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>
607inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
608operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p) {
609  return __os << __p.get();
610}
611
612template <class _CharT, class _Traits, size_t _Size>
613_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
614operator<<(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
622template <class _Traits>
623basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, wchar_t) = delete;
624
625template <class _Traits>
626basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const wchar_t*) = delete;
627
628template <class _Traits>
629basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char16_t) = delete;
630
631template <class _Traits>
632basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char32_t) = delete;
633
634template <class _Traits>
635basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char16_t*) = delete;
636
637template <class _Traits>
638basic_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
643template <class _Traits>
644basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char8_t) = delete;
645
646template <class _Traits>
647basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, char8_t) = delete;
648
649template <class _Traits>
650basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char8_t*) = delete;
651
652template <class _Traits>
653basic_ostream<wchar_t, _Traits>& operator<<(basic_ostream<wchar_t, _Traits>&, const char8_t*) = delete;
654#    endif
655
656template <class _Traits>
657basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char16_t) = delete;
658
659template <class _Traits>
660basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, char32_t) = delete;
661
662template <class _Traits>
663basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char16_t*) = delete;
664
665template <class _Traits>
666basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete;
667
668#  endif // _LIBCPP_STD_VER >= 20
669
670extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>;
671#  if _LIBCPP_HAS_WIDE_CHARACTERS
672extern 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