VirtualBox

source: vbox/trunk/include/iprt/nocrt/ostream

Last change on this file was 99828, checked in by vboxsync, 13 months ago

*: A bunch of adjustments that allows using /permissive- with Visual C++ (qt 6.x necessity).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1/** @file
2 * IPRT / No-CRT - Minimal C++ ostream header.
3 */
4
5/*
6 * Copyright (C) 2022-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_SRC_nocrt_ostream
37#define VBOX_INCLUDED_SRC_nocrt_ostream
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42/* Currently all in the ios header. */
43#include <iprt/nocrt/ios>
44
45namespace std
46{
47 /**
48 * Basic output stream.
49 */
50 template<typename a_CharType, typename a_CharTraits /*= std::char_traits<a_CharType>*/ >
51 class basic_ostream : public basic_ios<a_CharType, a_CharTraits>
52 {
53 public:
54 typedef a_CharType char_type;
55 typedef a_CharTraits traits_type;
56 typedef typename a_CharTraits::int_type int_type;
57 typedef typename a_CharTraits::pos_type pos_type;
58 typedef typename a_CharTraits::off_type off_type;
59
60 protected:
61 /** Sentry class that performs pre and post output work. */
62 class sentry
63 {
64 private:
65 basic_ostream &m_rParent;
66
67 public:
68 explicit sentry(basic_ostream &a_rParent)
69 : m_rParent(a_rParent)
70 {
71 if (a_rParent.good())
72 {
73 basic_ostream *pTiedStream = a_rParent.tie();
74 if (!pTiedStream)
75 { /* likely? */ }
76 else
77 {
78 pTiedStream->flush();
79 if (!pTiedStream->good())
80 a_rParent.setstate(ios::failbit);
81 }
82 }
83 }
84
85 explicit operator bool() const
86 {
87 return m_rParent.good();
88 }
89
90 ~sentry()
91 {
92 if ( (m_rParent.flags() & std::ios_base::unitbuf)
93 && m_rParent.good())
94 m_rParent.rdbuf()->pubsync();
95 }
96 };
97
98 public:
99 explicit basic_ostream(std::basic_streambuf<a_CharType,a_CharTraits> *a_pBuf)
100 : basic_ios<a_CharType, a_CharTraits>(a_pBuf)
101 { }
102
103 /** For cerr initialization.
104 * @internal */
105 explicit basic_ostream(std::basic_streambuf<a_CharType,a_CharTraits> *a_pBuf,
106 std::basic_ostream<a_CharType, a_CharTraits> *a_pTiedStream,
107 bool a_fUnbuffered)
108 : basic_ios<a_CharType, a_CharTraits>(a_pBuf)
109 {
110 this->m_pTiedStream = a_pTiedStream;
111 if (!a_fUnbuffered)
112 this->setf(std::ios_base::unitbuf);
113 }
114
115 private:
116 basic_ostream(basic_ostream const &a_rSrc); /* not copyable */
117 basic_ostream &operator=(basic_ostream const &a_rSrc); /* not copyable */
118
119 public:
120 virtual ~basic_ostream()
121 {
122 }
123
124 public:
125 basic_ostream &put(a_CharType a_ch)
126 {
127 sentry PrePost(*this);
128 if (PrePost)
129 {
130 if (this->m_pBuf->sputc(a_ch) == traits_type::eof())
131 this->m_fState |= ios::badbit;
132 }
133 return *this;
134 }
135
136 basic_ostream &write(const a_CharType *a_pchSrc, std::streamsize a_cchToWrite)
137 {
138 sentry PrePost(*this);
139 if (PrePost)
140 {
141 std::streamsize cchWritten = this->m_pBuf->sputn(a_pchSrc, a_cchToWrite);
142 if (cchWritten != a_cchToWrite)
143 this->m_fState |= ios::badbit;
144 }
145 return *this;
146 }
147
148 basic_ostream &flush()
149 {
150 if (this->m_pBuf)
151 this->m_pBuf->pubsync();
152 return *this;
153 }
154
155 pos_type tellp() RT_NOEXCEPT;
156 basic_ostream &seekp(pos_type a_off) RT_NOEXCEPT;
157 basic_ostream &seekp(off_type a_off, ios::seekdir enmDir) RT_NOEXCEPT;
158
159 /** @name Internal support methods
160 * @{ */
161 inline basic_ostream &intWrite(const char *a_pchSrc, std::streamsize a_cchToWrite); /**< Internal method outputting char buffers. */
162
163 /** @returns 8, 10 or 16. */
164 inline unsigned intGetIntegerBase() const RT_NOEXCEPT
165 {
166 switch (this->m_fFlags & ios::basefield)
167 {
168 default:
169 case ios::dec: return 10;
170 case ios::hex: return 16;
171 case ios::oct: return 8;
172 }
173 }
174
175 /** @returns RTSTR_F_XXX . */
176 inline unsigned intGetIntegerFlags() const RT_NOEXCEPT
177 {
178 unsigned fFlags = 0;
179 if (this->m_fFlags & ios::uppercase)
180 fFlags |= RTSTR_F_CAPITAL;
181 if (this->m_fFlags & ios::showbase)
182 fFlags |= RTSTR_F_SPECIAL;
183 if (this->m_fFlags & ios::showpos)
184 fFlags |= RTSTR_F_PLUS;
185 return fFlags;
186 }
187
188 basic_ostream &formatInteger(uint64_t a_uValue, uint32_t a_fFlags, unsigned a_uBase = 0)
189 {
190 a_fFlags |= intGetIntegerFlags();
191 char szTmp[72];
192 int cchTmp = RTStrFormatNumber(szTmp, a_uValue, !a_uBase ? intGetIntegerBase() : a_uBase, 0, 0, a_fFlags);
193
194 /** @todo apply cchWidth and padding. */
195
196 return intWrite(szTmp, cchTmp);
197 }
198
199 /** @} */
200 };
201
202 /** @name Character and string output.
203 * @{ */
204 /** @todo not sure if this really works... */
205 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
206 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, char a_ch)
207 {
208 return a_rDst.put(a_ch);
209 }
210
211 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
212 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, const char *a_psz)
213 {
214 return a_rDst.intWrite(a_psz, strlen(a_psz));
215 }
216 /** @} */
217
218 /** @name Integer formatting.
219 * @{ */
220 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
221 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, signed char a_iValue)
222 {
223 return a_rDst.formatInteger(a_iValue, RTSTR_F_8BIT | RTSTR_F_VALSIGNED);
224 }
225
226 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
227 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned char a_uValue)
228 {
229 return a_rDst.formatInteger(a_uValue, RTSTR_F_8BIT);
230 }
231
232 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
233 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, short a_iValue)
234 {
235 return a_rDst.formatInteger(a_iValue, RTSTR_F_16BIT | RTSTR_F_VALSIGNED);
236 }
237
238 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
239 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned short a_uValue)
240 {
241 return a_rDst.formatInteger(a_uValue, RTSTR_F_16BIT);
242 }
243
244 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
245 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, int a_iValue)
246 {
247 return a_rDst.formatInteger(a_iValue, RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
248 }
249
250 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
251 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned int a_uValue)
252 {
253 return a_rDst.formatInteger(a_uValue, RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
254 }
255
256 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
257 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, long a_iValue)
258 {
259 return a_rDst.formatInteger(a_iValue, (sizeof(a_iValue) > sizeof(int32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT));
260 }
261
262 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
263 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, unsigned long a_uValue)
264 {
265 return a_rDst.formatInteger(a_uValue,
266 RTSTR_F_VALSIGNED | (sizeof(a_uValue) > sizeof(uint32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT));
267 }
268
269 template<typename a_CharType, typename a_CharTraits = std::char_traits<a_CharType> >
270 basic_ostream<a_CharType, a_CharTraits> &operator<<(basic_ostream<a_CharType, a_CharTraits> &a_rDst, void const *a_pvValue)
271 {
272 return a_rDst.formatInteger((uintptr_t)a_pvValue,
273 (sizeof(a_pvValue) > sizeof(uint32_t) ? RTSTR_F_64BIT : RTSTR_F_32BIT), 16);
274 }
275 /** @} */
276
277 template<>
278 inline basic_ostream<char> &basic_ostream<char>::intWrite(const char *a_pchSrc, std::streamsize a_cchToWrite)
279 {
280 return write(a_pchSrc, a_cchToWrite);
281 }
282
283
284}
285
286#endif /* !VBOX_INCLUDED_SRC_nocrt_ostream */
287
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use