VirtualBox

source: vbox/trunk/include/iprt/nocrt/string@ 96354

Last change on this file since 96354 was 95985, checked in by vboxsync, 2 years ago

include/iprt/nocrt: Some early & incomplete ostream code. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 KB
Line 
1/** @file
2 * IPRT / No-CRT - Minimal C++ string header.
3 */
4
5/*
6 * Copyright (C) 2022 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_nocrt_string
27#define IPRT_INCLUDED_nocrt_string
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/nocrt/string.h>
33#include <iprt/nocrt/cstddef> /* for std::size_t */
34#include <iprt/cpp/ministring.h>
35
36#ifndef RT_NOCRT_EOF /* also in stdio.h */
37# define RT_NOCRT_EOF (-1)
38#endif
39
40namespace std
41{
42 using streamoff = ::RTFOFF;
43
44 /**
45 * @note This should be in iosfwd, not string.
46 */
47 template<typename a_MbStateType>
48 class fpos
49 {
50 protected:
51 std::streamoff m_off;
52 a_MbStateType m_MbState;
53
54 public:
55 fpos()
56 : m_off(0)
57 , m_MbState()
58 { }
59
60 fpos(std::streamoff a_off)
61 : m_off(a_off)
62 , m_MbState()
63 { }
64
65 a_MbStateType state() const RT_NOEXCEPT
66 {
67 return m_MbState;
68 }
69
70 void state(a_MbStateType a_NewMbState) const RT_NOEXCEPT
71 {
72 m_MbState = a_NewMbState;
73 }
74 };
75 using mbstate_t = ::RT_NOCRT(mbstate_t);
76 using streampos = fpos<std::mbstate_t>;
77
78 /* Use RTCString as std::string, it should be a reasonable match. */
79 typedef ::RTCString string;
80
81 /**
82 * Character traits.
83 */
84 template<typename a_CharType>
85 struct char_traits
86 {
87 /** @name Types
88 * @{ */
89 typedef a_CharType char_type;
90 typedef unsigned long int_type;
91 typedef std::streamoff off_type;
92 typedef std::streampos pos_type;
93 typedef std::mbstate_t state_type;
94 /** @} */
95
96 static void assign(char_type &a_rchDst, const char_type &a_rchSrc) RT_NOEXCEPT
97 {
98 a_rchDst = a_rchSrc;
99 }
100
101 static bool eq(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
102 {
103 return a_rchLeft == a_rchRight;
104 }
105
106 static bool lt(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
107 {
108 return a_rchLeft < a_rchRight;
109 }
110
111 static std::size_t length(const char_type *a_psz) RT_NOEXCEPT;
112 static int compare(const char_type *a_pchLeft, const char_type *a_pchRight, std::size_t a_cch) RT_NOEXCEPT;
113 static const char_type *find(const char_type *a_pchHaystack, std::size_t a_cchHaystack, const char_type &a_rchNeedle) RT_NOEXCEPT;
114 static char_type *assign(char_type *a_pchDst, std::size_t a_cchDst, char_type a_chFill) RT_NOEXCEPT;
115 static char_type *copy(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT;
116 static char_type *move(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT;
117
118 static char_type to_char_type(const int_type &a_riChar)
119 {
120 return static_cast<char_type>(a_riChar);
121 }
122
123 static int_type to_int_type(const char_type &a_rch)
124 {
125 return static_cast<int_type>(a_rch);
126 }
127
128 static bool eq_int_type(const int_type &a_riLeft, const int_type &a_riRight) RT_NOEXCEPT
129 {
130 return a_riLeft == a_riRight;
131 }
132
133 static int_type eof() RT_NOEXCEPT
134 {
135 return static_cast<int_type>(RT_NOCRT_EOF);
136 }
137
138 static int_type not_eof(const int_type &a_riChar) RT_NOEXCEPT
139 {
140 if (!eq_int_type(a_riChar, eof()))
141 return a_riChar;
142 return to_int_type(char_type());
143 }
144 };
145
146 template<typename a_CharType>
147 /*static*/ std::size_t char_traits<a_CharType>::length(const char_type *a_psz) RT_NOEXCEPT
148 {
149 const char_type * const pszStart = a_psz;
150 while (!eq(*a_pszLeft, char_type()))
151 a_psz++;
152 return static_cast<std::size_t>(a_psz - pszStart);
153 }
154
155 template<typename a_CharType>
156 /*static*/ int char_traits<a_CharType>::compare(const char_type *a_pchLeft, const char_type *a_pchRight,
157 std::size_t a_cch) RT_NOEXCEPT
158 {
159 for (std::size_t off = 0; off < a_cch; off++)
160 if (eq(a_pchLeft[off], a_pchRight[off]))
161 { /* likely? */ }
162 else
163 return lt(a_pchLeft[off], a_pchRight[off]) ? -1 : 1;
164 return 0;
165 }
166
167 template<typename a_CharType>
168 /*static*/ const typename char_traits<a_CharType>::char_type *
169 char_traits<a_CharType>::find(const char_type *a_pchHaystack, std::size_t a_cchHaystack,
170 const char_type &a_rchNeedle) RT_NOEXCEPT
171 {
172 while (a_cchHaystack-- > 0)
173 {
174 if (eq(*a_pchHaystack, a_rchNeedle))
175 return a_pchHaystack;
176 a_pchHaystack++;
177 }
178 return NULL;
179 }
180
181 template<typename a_CharType>
182 /*static*/ typename char_traits<a_CharType>::char_type *
183 char_traits<a_CharType>::assign(char_type *a_pchDst, std::size_t a_cchDst, char_type a_chFill) RT_NOEXCEPT
184 {
185 char_type * const pchRet = a_pchDst;
186 while (a_cchDst-- > 0)
187 *a_pchDst++ = a_chFill;
188 return pchRet;
189 }
190
191 template<typename a_CharType>
192 /*static*/ typename char_traits<a_CharType>::char_type *
193 char_traits<a_CharType>::copy(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
194 {
195 char_type * const pchRet = a_pchDst;
196 while (a_cch-- > 0)
197 *a_pchDst++ = *a_pchSrc++;
198 return pchRet;
199 }
200
201 template<typename a_CharType>
202 /*static*/ typename char_traits<a_CharType>::char_type *
203 char_traits<a_CharType>::move(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
204 {
205 char_type * const pchRet = a_pchDst;
206 char_type volatile *pchDstV = static_cast<char_type const volatile *>(a_pchDst);
207 char_type const volatile *pchSrcV = static_cast<char_type const volatile *>(a_pchSrc);
208 if ((uintptr_t)a_pchDst < (uintptr_t)a_pchSrc)
209 {
210 /* forward copy */
211 while (a_cch-- > 0)
212 *a_pchDstV++ = *a_pchSrcV++;
213 }
214 else
215 {
216 /* reverse copy */
217 a_pchSrcV += a_cch;
218 a_pchDstV += a_cch;
219 while (a_cchDst-- > 0)
220 *a_pchDstV-- = *a_pchSrcV--;
221 }
222 return pchRet;
223 }
224
225 /*
226 * Character train specializations.
227 */
228 template <>
229 struct char_traits<char>
230 {
231 typedef char char_type;
232 typedef int int_type;
233 typedef std::streamoff off_type;
234 typedef std::streampos pos_type;
235 typedef std::mbstate_t state_type;
236
237 static void assign(char_type &a_rchDst, const char_type &a_rchSrc) RT_NOEXCEPT
238 {
239 a_rchDst = a_rchSrc;
240 }
241
242 static bool eq(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
243 {
244 return a_rchLeft == a_rchRight;
245 }
246
247 static bool lt(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
248 {
249 return a_rchLeft < a_rchRight;
250 }
251
252 static std::size_t length(const char_type *a_psz) RT_NOEXCEPT
253 {
254 return ::RT_NOCRT(strlen)(a_psz);
255 }
256
257 static int compare(const char_type *a_pchLeft, const char_type *a_pchRight, std::size_t a_cch) RT_NOEXCEPT
258 {
259 return ::RT_NOCRT(memcmp)(a_pchLeft, a_pchRight, a_cch);
260 }
261
262 static const char_type *find(const char_type *a_pchHaystack, std::size_t a_cchHaystack, const char_type &a_rchNeedle) RT_NOEXCEPT
263 {
264 return static_cast<const char_type *>(::RT_NOCRT(memchr)(a_pchHaystack, a_rchNeedle, a_cchHaystack));
265 }
266
267 static char_type *assign(char_type *a_pchDst, std::size_t a_cchDst, char_type a_chFill) RT_NOEXCEPT
268 {
269 return static_cast<char_type *>(::RT_NOCRT(memset)(a_pchDst, a_chFill, a_cchDst));
270 }
271
272 static char_type *copy(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
273 {
274 return static_cast<char_type *>(::RT_NOCRT(memcpy)(a_pchDst, a_pchSrc, a_cch));
275 }
276
277 static char_type *move(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
278 {
279 return static_cast<char_type *>(::RT_NOCRT(memmove)(a_pchDst, a_pchSrc, a_cch));
280 }
281
282 static char_type to_char_type(const int_type &a_riChar)
283 {
284 return static_cast<char_type>(a_riChar);
285 }
286
287 static int_type to_int_type(const char_type &a_rch)
288 {
289 return static_cast<int_type>(a_rch);
290 }
291
292 static bool eq_int_type(const int_type &a_riLeft, const int_type &a_riRight) RT_NOEXCEPT
293 {
294 return a_riLeft == a_riRight;
295 }
296
297 static int_type eof() RT_NOEXCEPT
298 {
299 return static_cast<int_type>(RT_NOCRT_EOF);
300 }
301
302 static int_type not_eof(const int_type &a_riChar) RT_NOEXCEPT
303 {
304 if (!eq_int_type(a_riChar, eof()))
305 return a_riChar;
306 return 0;
307 }
308 };
309}
310
311
312#endif /* !IPRT_INCLUDED_nocrt_string */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette