Horizon
Loading...
Searching...
No Matches
stream_iterators.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2014-present
5// Copyright Google LLC 2020-present
6//
7// Use, modification and distribution is subject to the
8// Boost Software License, Version 1.0. (See accompanying
9// file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11//
12// Project home: https://github.com/ericniebler/range-v3
13//
14#ifndef RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
15#define RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
16
17#include <cstddef>
18#include <iosfwd>
19#include <iterator>
20#include <string>
21#include <type_traits>
22#include <utility>
23
25
27
28#include <range/v3/detail/prologue.hpp>
29
30namespace ranges
31{
34 template<typename T = void, typename Char = char,
35 typename Traits = std::char_traits<Char>>
37 {
38 private:
39 template<class U>
40 using value_t = meta::if_<std::is_void<T>, U, T>;
41
42 public:
43 using difference_type = std::ptrdiff_t;
44 using char_type = Char;
45 using traits_type = Traits;
46 using ostream_type = std::basic_ostream<Char, Traits>;
47
48 constexpr ostream_iterator() = default;
49 ostream_iterator(ostream_type & s, Char const * d = nullptr) noexcept
50 : sout_(&s)
51 , delim_(d)
52 {}
53 template(typename U)(
54 requires convertible_to<U, value_t<U> const &>)
55 ostream_iterator & operator=(U && value)
56 {
57 RANGES_EXPECT(sout_);
58 *sout_ << static_cast<value_t<U> const &>(static_cast<U &&>(value));
59 if(delim_)
60 *sout_ << delim_;
61 return *this;
62 }
63 ostream_iterator & operator*()
64 {
65 return *this;
66 }
67 ostream_iterator & operator++()
68 {
69 return *this;
70 }
71 ostream_iterator & operator++(int)
72 {
73 return *this;
74 }
75
76 private:
77 ostream_type * sout_;
78 Char const * delim_;
79 };
80
81 template<typename Delim, typename Char = char,
82 typename Traits = std::char_traits<Char>>
84 {
85 CPP_assert(semiregular<Delim>);
86 using difference_type = std::ptrdiff_t;
87 using char_type = Char;
88 using traits_type = Traits;
89 using ostream_type = std::basic_ostream<Char, Traits>;
90
91 constexpr ostream_joiner() = default;
92 ostream_joiner(ostream_type & s, Delim const & d)
93 : delim_(d)
94 , sout_(std::addressof(s))
95 , first_(true)
96 {}
97 ostream_joiner(ostream_type & s, Delim && d)
98 : delim_(std::move(d))
99 , sout_(std::addressof(s))
100 , first_(true)
101 {}
102 template<typename T>
103 ostream_joiner & operator=(T const & value)
104 {
105 RANGES_EXPECT(sout_);
106 if(!first_)
107 *sout_ << delim_;
108 first_ = false;
109 *sout_ << value;
110 return *this;
111 }
112 ostream_joiner & operator*() noexcept
113 {
114 return *this;
115 }
116 ostream_joiner & operator++() noexcept
117 {
118 return *this;
119 }
120 ostream_joiner & operator++(int) noexcept
121 {
122 return *this;
123 }
124
125 private:
126 Delim delim_;
127 ostream_type * sout_;
128 bool first_;
129 };
130
132 {
133 template(typename Delim, typename Char, typename Traits)(
134 requires semiregular<detail::decay_t<Delim>>)
136 operator()(std::basic_ostream<Char, Traits> & s, Delim && d) const
137 {
138 return {s, std::forward<Delim>(d)};
139 }
140 };
141
143 RANGES_INLINE_VARIABLE(make_ostream_joiner_fn, make_ostream_joiner)
144
145 template<typename Char, typename Traits = std::char_traits<Char>>
147 {
148 public:
149 typedef ptrdiff_t difference_type;
150 typedef Char char_type;
151 typedef Traits traits_type;
152 typedef std::basic_streambuf<Char, Traits> streambuf_type;
153 typedef std::basic_ostream<Char, Traits> ostream_type;
154
155 constexpr ostreambuf_iterator() = default;
156 ostreambuf_iterator(ostream_type & s) noexcept
157 : ostreambuf_iterator(s.rdbuf())
158 {}
159 ostreambuf_iterator(streambuf_type * s) noexcept
160 : sbuf_(s)
161 {
162 RANGES_ASSERT(s != nullptr);
163 }
164 ostreambuf_iterator & operator=(Char c)
165 {
166 RANGES_ASSERT(sbuf_ != nullptr);
167 if(!failed_)
168 failed_ = (sbuf_->sputc(c) == Traits::eof());
169 return *this;
170 }
171 ostreambuf_iterator & operator*()
172 {
173 return *this;
174 }
175 ostreambuf_iterator & operator++()
176 {
177 return *this;
178 }
179 ostreambuf_iterator & operator++(int)
180 {
181 return *this;
182 }
183 bool failed() const noexcept
184 {
185 return failed_;
186 }
187
188 private:
189 streambuf_type * sbuf_ = nullptr;
190 bool failed_ = false;
191 };
192
193 namespace cpp20
194 {
195 template<typename T, typename Char = char,
196 typename Traits = std::char_traits<Char>>
198
200 } // namespace cpp20
201
206 template<typename CharT = char, typename Traits = std::char_traits<CharT>>
208 {
209 public:
210 using iterator_category = std::output_iterator_tag;
211 using difference_type = std::ptrdiff_t;
212 using char_type = CharT;
213 using traits_type = Traits;
214 using ostream_type = std::basic_ostream<CharT, Traits>;
215
217
218 explicit unformatted_ostream_iterator(ostream_type & out) noexcept
219 : out_(&out)
220 {}
221
222 template<typename T>
223 // requires stream_insertible<T, ostream_type>
224 unformatted_ostream_iterator & operator=(T const & t)
225 {
226 RANGES_EXPECT(out_);
227 out_->write(reinterpret_cast<char const *>(std::addressof(t)), sizeof(T));
228 return *this;
229 }
230
231 unformatted_ostream_iterator & operator*() noexcept
232 {
233 return *this;
234 }
235 unformatted_ostream_iterator & operator++() noexcept
236 {
237 return *this;
238 }
239 unformatted_ostream_iterator & operator++(int) noexcept
240 {
241 return *this;
242 }
243
244 private:
245 ostream_type * out_ = nullptr;
246 };
248} // namespace ranges
249
251RANGES_DIAGNOSTIC_PUSH
252RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
253
254namespace std
255{
256 template<typename T, typename Char, typename Traits>
257 struct iterator_traits<::ranges::ostream_iterator<T, Char, Traits>>
258 : ::ranges::detail::std_output_iterator_traits<>
259 {};
260
261 template<typename Char, typename Traits>
262 struct iterator_traits<::ranges::ostreambuf_iterator<Char, Traits>>
263 : ::ranges::detail::std_output_iterator_traits<>
264 {};
265} // namespace std
266
267RANGES_DIAGNOSTIC_POP
269
270#include <range/v3/detail/epilogue.hpp>
271
272#endif // RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
Writes to an ostream object using the unformatted std::basic_ostream::write operation.
Definition stream_iterators.hpp:208
_t< detail::_if_< list< Args... > > > if_
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1247
Definition stream_iterators.hpp:132
Definition stream_iterators.hpp:37
Definition stream_iterators.hpp:84
Definition stream_iterators.hpp:147