VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1/** @file
2 * IPRT / No-CRT - Minimal C++ string header.
3 */
4
5/*
6 * Copyright (C) 2022-2024 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_string
37#define VBOX_INCLUDED_SRC_nocrt_string
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/nocrt/string.h>
43#include <iprt/nocrt/cstddef> /* for std::size_t */
44#include <iprt/cpp/ministring.h>
45
46#ifndef RT_NOCRT_EOF /* also in stdio.h */
47# define RT_NOCRT_EOF (-1)
48#endif
49
50namespace std
51{
52 using streamoff = ::RTFOFF;
53
54 /**
55 * @note This should be in iosfwd, not string.
56 */
57 template<typename a_MbStateType>
58 class fpos
59 {
60 protected:
61 std::streamoff m_off;
62 a_MbStateType m_MbState;
63
64 public:
65 fpos()
66 : m_off(0)
67 , m_MbState()
68 { }
69
70 fpos(std::streamoff a_off)
71 : m_off(a_off)
72 , m_MbState()
73 { }
74
75 a_MbStateType state() const RT_NOEXCEPT
76 {
77 return m_MbState;
78 }
79
80 void state(a_MbStateType a_NewMbState) const RT_NOEXCEPT
81 {
82 m_MbState = a_NewMbState;
83 }
84 };
85 using mbstate_t = ::RT_NOCRT(mbstate_t);
86 using streampos = fpos<std::mbstate_t>;
87
88 /* Use RTCString as std::string, it should be a reasonable match. */
89 typedef ::RTCString string;
90
91 /**
92 * Character traits.
93 */
94 template<typename a_CharType>
95 struct char_traits
96 {
97 /** @name Types
98 * @{ */
99 typedef a_CharType char_type;
100 typedef unsigned long int_type;
101 typedef std::streamoff off_type;
102 typedef std::streampos pos_type;
103 typedef std::mbstate_t state_type;
104 /** @} */
105
106 static void assign(char_type &a_rchDst, const char_type &a_rchSrc) RT_NOEXCEPT
107 {
108 a_rchDst = a_rchSrc;
109 }
110
111 static bool eq(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
112 {
113 return a_rchLeft == a_rchRight;
114 }
115
116 static bool lt(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
117 {
118 return a_rchLeft < a_rchRight;
119 }
120
121 static std::size_t length(const char_type *a_psz) RT_NOEXCEPT;
122 static int compare(const char_type *a_pchLeft, const char_type *a_pchRight, std::size_t a_cch) RT_NOEXCEPT;
123 static const char_type *find(const char_type *a_pchHaystack, std::size_t a_cchHaystack, const char_type &a_rchNeedle) RT_NOEXCEPT;
124 static char_type *assign(char_type *a_pchDst, std::size_t a_cchDst, char_type a_chFill) RT_NOEXCEPT;
125 static char_type *copy(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT;
126 static char_type *move(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT;
127
128 static char_type to_char_type(const int_type &a_riChar)
129 {
130 return static_cast<char_type>(a_riChar);
131 }
132
133 static int_type to_int_type(const char_type &a_rch)
134 {
135 return static_cast<int_type>(a_rch);
136 }
137
138 static bool eq_int_type(const int_type &a_riLeft, const int_type &a_riRight) RT_NOEXCEPT
139 {
140 return a_riLeft == a_riRight;
141 }
142
143 static int_type eof() RT_NOEXCEPT
144 {
145 return static_cast<int_type>(RT_NOCRT_EOF);
146 }
147
148 static int_type not_eof(const int_type &a_riChar) RT_NOEXCEPT
149 {
150 if (!eq_int_type(a_riChar, eof()))
151 return a_riChar;
152 return to_int_type(char_type());
153 }
154 };
155
156 template<typename a_CharType>
157 /*static*/ std::size_t char_traits<a_CharType>::length(const char_type *a_psz) RT_NOEXCEPT
158 {
159 const char_type * const pszStart = a_psz;
160 while (!eq(*a_psz, char_type()))
161 a_psz++;
162 return static_cast<std::size_t>(a_psz - pszStart);
163 }
164
165 template<typename a_CharType>
166 /*static*/ int char_traits<a_CharType>::compare(const char_type *a_pchLeft, const char_type *a_pchRight,
167 std::size_t a_cch) RT_NOEXCEPT
168 {
169 for (std::size_t off = 0; off < a_cch; off++)
170 if (eq(a_pchLeft[off], a_pchRight[off]))
171 { /* likely? */ }
172 else
173 return lt(a_pchLeft[off], a_pchRight[off]) ? -1 : 1;
174 return 0;
175 }
176
177 template<typename a_CharType>
178 /*static*/ const typename char_traits<a_CharType>::char_type *
179 char_traits<a_CharType>::find(const char_type *a_pchHaystack, std::size_t a_cchHaystack,
180 const char_type &a_rchNeedle) RT_NOEXCEPT
181 {
182 while (a_cchHaystack-- > 0)
183 {
184 if (eq(*a_pchHaystack, a_rchNeedle))
185 return a_pchHaystack;
186 a_pchHaystack++;
187 }
188 return NULL;
189 }
190
191 template<typename a_CharType>
192 /*static*/ typename char_traits<a_CharType>::char_type *
193 char_traits<a_CharType>::assign(char_type *a_pchDst, std::size_t a_cchDst, char_type a_chFill) RT_NOEXCEPT
194 {
195 char_type * const pchRet = a_pchDst;
196 while (a_cchDst-- > 0)
197 *a_pchDst++ = a_chFill;
198 return pchRet;
199 }
200
201 template<typename a_CharType>
202 /*static*/ typename char_traits<a_CharType>::char_type *
203 char_traits<a_CharType>::copy(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 while (a_cch-- > 0)
207 *a_pchDst++ = *a_pchSrc++;
208 return pchRet;
209 }
210
211 template<typename a_CharType>
212 /*static*/ typename char_traits<a_CharType>::char_type *
213 char_traits<a_CharType>::move(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
214 {
215 char_type * const pchRet = a_pchDst;
216 char_type volatile *pchDstV = static_cast<char_type const volatile *>(a_pchDst);
217 char_type const volatile *pchSrcV = static_cast<char_type const volatile *>(a_pchSrc);
218 if ((uintptr_t)pchDstV < (uintptr_t)pchSrcV)
219 {
220 /* forward copy */
221 while (a_cch-- > 0)
222 *pchDstV++ = *pchSrcV++;
223 }
224 else
225 {
226 /* reverse copy */
227 pchSrcV += a_cch;
228 pchDstV += a_cch;
229 while (a_cch-- > 0)
230 *pchDstV-- = *pchSrcV--;
231 }
232 return pchRet;
233 }
234
235 /*
236 * Character train specializations.
237 */
238 template <>
239 struct char_traits<char>
240 {
241 typedef char char_type;
242 typedef int int_type;
243 typedef std::streamoff off_type;
244 typedef std::streampos pos_type;
245 typedef std::mbstate_t state_type;
246
247 static void assign(char_type &a_rchDst, const char_type &a_rchSrc) RT_NOEXCEPT
248 {
249 a_rchDst = a_rchSrc;
250 }
251
252 static bool eq(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
253 {
254 return a_rchLeft == a_rchRight;
255 }
256
257 static bool lt(const char_type &a_rchLeft, const char_type &a_rchRight) RT_NOEXCEPT
258 {
259 return a_rchLeft < a_rchRight;
260 }
261
262 static std::size_t length(const char_type *a_psz) RT_NOEXCEPT
263 {
264 return ::RT_NOCRT(strlen)(a_psz);
265 }
266
267 static int compare(const char_type *a_pchLeft, const char_type *a_pchRight, std::size_t a_cch) RT_NOEXCEPT
268 {
269 return ::RT_NOCRT(memcmp)(a_pchLeft, a_pchRight, a_cch);
270 }
271
272 static const char_type *find(const char_type *a_pchHaystack, std::size_t a_cchHaystack, const char_type &a_rchNeedle) RT_NOEXCEPT
273 {
274 return static_cast<const char_type *>(::RT_NOCRT(memchr)(a_pchHaystack, a_rchNeedle, a_cchHaystack));
275 }
276
277 static char_type *assign(char_type *a_pchDst, std::size_t a_cchDst, char_type a_chFill) RT_NOEXCEPT
278 {
279 return static_cast<char_type *>(::RT_NOCRT(memset)(a_pchDst, a_chFill, a_cchDst));
280 }
281
282 static char_type *copy(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
283 {
284 return static_cast<char_type *>(::RT_NOCRT(memcpy)(a_pchDst, a_pchSrc, a_cch));
285 }
286
287 static char_type *move(char_type *a_pchDst, const char_type *a_pchSrc, std::size_t a_cch) RT_NOEXCEPT
288 {
289 return static_cast<char_type *>(::RT_NOCRT(memmove)(a_pchDst, a_pchSrc, a_cch));
290 }
291
292 static char_type to_char_type(const int_type &a_riChar)
293 {
294 return static_cast<char_type>(a_riChar);
295 }
296
297 static int_type to_int_type(const char_type &a_rch)
298 {
299 return static_cast<int_type>(a_rch);
300 }
301
302 static bool eq_int_type(const int_type &a_riLeft, const int_type &a_riRight) RT_NOEXCEPT
303 {
304 return a_riLeft == a_riRight;
305 }
306
307 static int_type eof() RT_NOEXCEPT
308 {
309 return static_cast<int_type>(RT_NOCRT_EOF);
310 }
311
312 static int_type not_eof(const int_type &a_riChar) RT_NOEXCEPT
313 {
314 if (!eq_int_type(a_riChar, eof()))
315 return a_riChar;
316 return 0;
317 }
318 };
319}
320
321
322#endif /* !VBOX_INCLUDED_SRC_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