source: mainline/uspace/lib/cpp/include/impl/ostream.hpp@ 91ba048

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 91ba048 was 91ba048, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added basic unformatted output to std::ostream

  • Property mode set to 100644
File size: 10.2 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_OSTREAM
30#define LIBCPP_OSTREAM
31
32#include <ios>
33#include <iosfwd>
34#include <locale>
35
36namespace std
37{
38 /**
39 * 27.7.3.1, class template basic_ostream:
40 */
41
42 template<class Char, class Traits>
43 class basic_ostream: virtual public basic_ios<Char, Traits>
44 {
45 public:
46 using char_type = Char;
47 using traits_type = Traits;
48 using int_type = typename traits_type::int_type;
49 using pos_type = typename traits_type::pos_type;
50 using off_type = typename traits_type::off_type;
51
52 /**
53 * 27.7.3.2, constructor/destructor:
54 */
55
56 explicit basic_ostream(basic_streambuf<char_type, traits_type>* sb)
57 {
58 basic_ios<Char, Traits>::init(sb);
59 }
60
61 virtual ~basic_ostream()
62 { /* DUMMY BODY */ }
63
64 /**
65 * 27.7.3.4, prefix/suffix:
66 */
67
68 class sentry
69 {
70 public:
71 explicit sentry(basic_ostream<Char, Traits>& os)
72 : os_{os}, ok_{false}
73 {
74 if (os.good())
75 {
76 if (os.tie())
77 os.tie()->flush();
78 }
79
80 ok_ = os.good();
81 }
82
83 ~sentry()
84 {
85 if ((os_.flags() & ios_base::unitbuf) && os_.good())
86 {
87 auto ret = os_.rdbuf()->pubsync();
88 (void)ret;
89 // TODO: if ret == -1, set badbit in rdstate
90 }
91 }
92
93 explicit operator bool() const
94 {
95 return ok_;
96 }
97
98 sentry(const sentry&) = delete;
99 sentry& operator=(const sentry&) = delete;
100
101 private:
102 basic_ostream<Char, Traits>& os_;
103 bool ok_;
104 };
105
106 /**
107 * 27.7.3.6, formatted output:
108 */
109
110 basic_ostream<Char, Traits>& operator<<(
111 basic_ostream<Char, Traits>& (*pf)(basic_ostream<Char, Traits>&)
112 )
113 {
114 return pf(*this);
115 }
116
117 basic_ostream<Char, Traits>& operator<<(
118 basic_ios<Char, Traits>& (*pf)(basic_ios<Char, Traits>&)
119 )
120 {
121 pf(*this);
122
123 return *this;
124 }
125
126 basic_ostream<Char, Traits>& operator<<(
127 ios_base& (*pf)(ios_base&)
128 )
129 {
130 pf(*this);
131
132 return *this;
133 }
134
135 basic_ostream<Char, Traits>& operator<<(bool x)
136 {
137 // TODO: sentry etc
138 /* bool failed = use_facet< */
139 /* num_put<char_type, ostreambuf_iterator<char_type, traits_type>> */
140 /* >(this->getloc()).put(*this, *this, this->fill(), x).failed(); */
141
142 /* if (failed) */
143 /* this->setstate(ios_base::badbit); */
144
145 return *this;
146 }
147
148 basic_ostream<Char, Traits>& operator<<(short x)
149 {
150 // TODO: implement
151 return *this;
152 }
153
154 basic_ostream<Char, Traits>& operator<<(unsigned short x)
155 {
156 // TODO: implement
157 return *this;
158 }
159
160 basic_ostream<Char, Traits>& operator<<(int x)
161 {
162 // TODO: implement
163 return *this;
164 }
165
166 basic_ostream<Char, Traits>& operator<<(unsigned int x)
167 {
168 // TODO: implement
169 return *this;
170 }
171
172 basic_ostream<Char, Traits>& operator<<(long x)
173 {
174 // TODO: implement
175 return *this;
176 }
177
178 basic_ostream<Char, Traits>& operator<<(unsigned long x)
179 {
180 // TODO: implement
181 return *this;
182 }
183
184 basic_ostream<Char, Traits>& operator<<(long long x)
185 {
186 // TODO: implement
187 return *this;
188 }
189
190 basic_ostream<Char, Traits>& operator<<(unsigned long long x)
191 {
192 // TODO: implement
193 return *this;
194 }
195
196 basic_ostream<Char, Traits>& operator<<(float x)
197 {
198 // TODO: implement
199 return *this;
200 }
201
202 basic_ostream<Char, Traits>& operator<<(double x)
203 {
204 // TODO: implement
205 return *this;
206 }
207
208 basic_ostream<Char, Traits>& operator<<(long double x)
209 {
210 // TODO: implement
211 return *this;
212 }
213
214 basic_ostream<Char, Traits>& operator<<(const void* p)
215 {
216 // TODO: implement
217 return *this;
218 }
219
220 basic_ostream<Char, Traits>& operator<<(basic_streambuf<Char, Traits>* sb)
221 {
222 // TODO: implement
223 return *this;
224 }
225
226 /**
227 * 27.7.3.7, unformatted output:
228 * TODO: when we have exceptions, complete these
229 */
230
231 basic_ostream<Char, Traits>& put(char_type c)
232 {
233 sentry sen{*this};
234
235 if (sen)
236 {
237 auto ret = this->rdbuf()->sputc(c);
238 if (traits_type::eq_int_type(ret, traits_type::eof()))
239 this->setstate(ios_base::badbit);
240 }
241
242 return *this;
243 }
244
245 basic_ostream<Char, Traits>& write(const char_type* s, streamsize n)
246 {
247 sentry sen{*this};
248
249 if (sen)
250 {
251 for (streamsize i = 0; i < n; ++i)
252 {
253 auto ret = this->rdbuf()->sputc(s[i]);
254 if (traits_type::eq_int_type(ret, traits_type::eof()))
255 {
256 this->setstate(ios_base::badbit);
257 break;
258 }
259 }
260 }
261
262 return *this;
263 }
264
265 basic_ostream<Char, Traits>& flush()
266 {
267 if (this->rdbuf())
268 {
269 sentry sen{*this};
270
271 if (sen)
272 {
273 auto ret = this->rdbuf()->pubsync();
274 if (ret == -1)
275 this->setstate(ios_base::badbit);
276 }
277 }
278
279 return *this;
280 }
281
282 /**
283 * 27.7.3.5, seeks:
284 */
285
286 pos_type tellp()
287 {
288 // TODO: implement
289 return pos_type{};
290 }
291
292 basic_ostream<Char, Traits>& seekp(pos_type pos)
293 {
294 // TODO: implement
295 return *this;
296 }
297
298 basic_ostream<Char, Traits>& seekp(off_type off, ios_base::seekdir dir)
299 {
300 // TODO: implement
301 return *this;
302 }
303
304 protected:
305 basic_ostream(const basic_ostream&) = delete;
306
307 basic_ostream(basic_ostream&& other)
308 {
309 basic_ios<Char, Traits>::move(other);
310 }
311
312 /**
313 * 27.7.3.3, assign/swap:
314 */
315
316 basic_ostream& operator=(const basic_ostream&) = delete;
317
318 basic_ostream& operator=(basic_ostream&& other)
319 {
320 swap(other);
321
322 return *this;
323 }
324
325 void swap(basic_ostream& rhs)
326 {
327 basic_ios<Char, Traits>::swap(rhs);
328 }
329 };
330
331 using ostream = basic_ostream<char>;
332 using wostream = basic_ostream<wchar_t>;
333
334 template<class Char, class Traits = char_traits<Char>>
335 basic_ostream<Char, Traits>& endl(basic_ostream<Char, Traits>& os)
336 {
337 os.put('\n');
338 os.flush();
339
340 return os;
341 }
342
343 template<class Char, class Traits = char_traits<Char>>
344 basic_ostream<Char, Traits>& ends(basic_ostream<Char, Traits>& os);
345
346 template<class Char, class Traits = char_traits<Char>>
347 basic_ostream<Char, Traits>& flush(basic_ostream<Char, Traits>& os);
348
349 template<class Char, class Traits = char_traits<Char>, class T>
350 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os, const T& x);
351}
352
353#endif
354
Note: See TracBrowser for help on using the repository browser.