1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
11#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
12
13#include <__algorithm/specialized_algorithms.h>
14#include <__config>
15#include <__cstddef/ptrdiff_t.h>
16#include <__fwd/ios.h>
17#include <__fwd/ostream.h>
18#include <__fwd/streambuf.h>
19#include <__iterator/iterator.h>
20#include <__iterator/iterator_traits.h>
21#include <__type_traits/is_same.h>
22#include <__utility/pair.h>
23#include <iosfwd> // for forward declaration of ostreambuf_iterator
24
25#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26# pragma GCC system_header
27#endif
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31template <class _CharT, class _Traits>
32class ostreambuf_iterator
33 : public __iterator_base<ostreambuf_iterator<_CharT, _Traits>, output_iterator_tag, void, void, void, void> {
34public:
35 typedef output_iterator_tag iterator_category;
36 typedef void value_type;
37#if _LIBCPP_STD_VER >= 20
38 typedef ptrdiff_t difference_type;
39#else
40 typedef void difference_type;
41#endif
42 typedef void pointer;
43 typedef void reference;
44 typedef _CharT char_type;
45 typedef _Traits traits_type;
46 typedef basic_streambuf<_CharT, _Traits> streambuf_type;
47 typedef basic_ostream<_CharT, _Traits> ostream_type;
48
49private:
50 streambuf_type* __sbuf_;
51
52public:
53 _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(ostream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {}
54 _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT : __sbuf_(__s) {}
55 _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator=(_CharT __c) {
56 if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
57 __sbuf_ = nullptr;
58 return *this;
59 }
60 _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator*() { return *this; }
61 _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++() { return *this; }
62 _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++(int) { return *this; }
63 _LIBCPP_HIDE_FROM_ABI bool failed() const _NOEXCEPT { return __sbuf_ == nullptr; }
64
65#if _LIBCPP_HAS_LOCALIZATION
66 template <class _Ch, class _Tr>
67 friend _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator<_Ch, _Tr> __pad_and_output(
68 ostreambuf_iterator<_Ch, _Tr> __s, const _Ch* __ob, const _Ch* __op, const _Ch* __oe, ios_base& __iob, _Ch __fl);
69#endif // _LIBCPP_HAS_LOCALIZATION
70
71 template <class, class...>
72 friend struct __specialized_algorithm;
73};
74
75template <class _InCharT, class _CharT, class _Traits>
76struct __specialized_algorithm<_Algorithm::__copy,
77 __iterator_pair<_InCharT*, _InCharT*>,
78 __single_iterator<ostreambuf_iterator<_CharT, _Traits> > > {
79 static const bool __has_algorithm = is_same<const _CharT, const _InCharT>::value;
80
81 _LIBCPP_HIDE_FROM_ABI static pair<_InCharT*, ostreambuf_iterator<_CharT, _Traits> >
82 operator()(_InCharT* __first, _InCharT* __last, ostreambuf_iterator<_CharT, _Traits> __result) {
83 auto __size = __last - __first;
84 if (__result.__sbuf_ && __size > 0) {
85 if (__result.__sbuf_->sputn(__first, __last - __first) != __size)
86 __result.__sbuf_ = nullptr;
87 }
88 return pair<_InCharT*, ostreambuf_iterator<_CharT, _Traits> >(__last, __result);
89 }
90};
91
92_LIBCPP_END_NAMESPACE_STD
93
94#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H
95