OpenTTD Source 20250522-master-g467f832c2f
string_consumer.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "../stdafx.h"
11
12#include <iostream>
13
14#include "../3rdparty/catch2/catch.hpp"
15
16#include "../core/string_consumer.hpp"
17
18#include "../safeguards.h"
19
20TEST_CASE("StringConsumer - basic")
21{
22 StringConsumer consumer("ab"sv);
23 CHECK(!consumer.AnyBytesRead());
24 CHECK(consumer.GetBytesRead() == 0);
25 CHECK(consumer.AnyBytesLeft());
26 CHECK(consumer.GetBytesLeft() == 2);
27 CHECK(consumer.GetOrigData() == "ab");
28 CHECK(consumer.GetReadData() == "");
29 CHECK(consumer.GetLeftData() == "ab");
30 consumer.Skip(1);
31 CHECK(consumer.AnyBytesRead());
32 CHECK(consumer.GetBytesRead() == 1);
33 CHECK(consumer.AnyBytesLeft());
34 CHECK(consumer.GetBytesLeft() == 1);
35 CHECK(consumer.GetOrigData() == "ab");
36 CHECK(consumer.GetReadData() == "a");
37 CHECK(consumer.GetLeftData() == "b");
38 consumer.SkipAll();
39 CHECK(consumer.AnyBytesRead());
40 CHECK(consumer.GetBytesRead() == 2);
41 CHECK(!consumer.AnyBytesLeft());
42 CHECK(consumer.GetBytesLeft() == 0);
43 CHECK(consumer.GetOrigData() == "ab");
44 CHECK(consumer.GetReadData() == "ab");
45 CHECK(consumer.GetLeftData() == "");
46 consumer.Skip(1);
47 CHECK(consumer.AnyBytesRead());
48 CHECK(consumer.GetBytesRead() == 2);
49 CHECK(!consumer.AnyBytesLeft());
50 CHECK(consumer.GetBytesLeft() == 0);
51 CHECK(consumer.GetOrigData() == "ab");
52 CHECK(consumer.GetReadData() == "ab");
53 CHECK(consumer.GetLeftData() == "");
54}
55
56TEST_CASE("StringConsumer - binary8")
57{
58 StringConsumer consumer("\xFF\xFE\xFD\0"sv);
59 CHECK(consumer.PeekUint8() == 0xFF);
60 CHECK(consumer.PeekSint8() == -1);
61 CHECK(consumer.PeekChar() == static_cast<char>(-1));
62 consumer.SkipUint8();
63 CHECK(consumer.PeekUint8() == 0xFE);
64 CHECK(consumer.PeekSint8() == -2);
65 CHECK(consumer.PeekChar() == static_cast<char>(-2));
66 CHECK(consumer.ReadUint8() == 0xFE);
67 CHECK(consumer.PeekUint8() == 0xFD);
68 CHECK(consumer.PeekSint8() == -3);
69 CHECK(consumer.PeekChar() == static_cast<char>(-3));
70 CHECK(consumer.ReadSint8() == -3);
71 CHECK(consumer.PeekUint8() == 0);
72 CHECK(consumer.PeekSint8() == 0);
73 CHECK(consumer.PeekChar() == 0);
74 CHECK(consumer.ReadChar() == 0);
75 CHECK(consumer.PeekUint8() == std::nullopt);
76 CHECK(consumer.PeekSint8() == std::nullopt);
77 CHECK(consumer.PeekChar() == std::nullopt);
78 CHECK(consumer.ReadUint8(42) == 42);
79 consumer.SkipSint8();
80 CHECK(consumer.ReadSint8(42) == 42);
81 CHECK(consumer.ReadChar(42) == 42);
82}
83
84TEST_CASE("StringConsumer - binary16")
85{
86 StringConsumer consumer("\xFF\xFF\xFE\xFF\xFD\xFF"sv);
87 CHECK(consumer.PeekUint16LE() == 0xFFFF);
88 CHECK(consumer.PeekSint16LE() == -1);
89 consumer.SkipUint16LE();
90 CHECK(consumer.PeekUint16LE() == 0xFFFE);
91 CHECK(consumer.PeekSint16LE() == -2);
92 CHECK(consumer.ReadUint16LE() == 0xFFFE);
93 CHECK(consumer.PeekUint16LE() == 0xFFFD);
94 CHECK(consumer.PeekSint16LE() == -3);
95 CHECK(consumer.ReadSint16LE() == -3);
96 CHECK(consumer.PeekUint16LE() == std::nullopt);
97 CHECK(consumer.PeekSint16LE() == std::nullopt);
98 CHECK(consumer.ReadUint16LE(42) == 42);
99 consumer.SkipSint16LE();
100 CHECK(consumer.ReadSint16LE(42) == 42);
101}
102
103TEST_CASE("StringConsumer - binary32")
104{
105 StringConsumer consumer("\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFD\xFF\xFF\xFF"sv);
106 CHECK(consumer.PeekUint32LE() == 0xFFFFFFFF);
107 CHECK(consumer.PeekSint32LE() == -1);
108 consumer.SkipUint32LE();
109 CHECK(consumer.PeekUint32LE() == 0xFFFFFFFE);
110 CHECK(consumer.PeekSint32LE() == -2);
111 CHECK(consumer.ReadUint32LE() == 0xFFFFFFFE);
112 CHECK(consumer.PeekUint32LE() == 0xFFFFFFFD);
113 CHECK(consumer.PeekSint32LE() == -3);
114 CHECK(consumer.ReadSint32LE() == -3);
115 CHECK(consumer.PeekUint32LE() == std::nullopt);
116 CHECK(consumer.PeekSint32LE() == std::nullopt);
117 CHECK(consumer.ReadUint32LE(42) == 42);
118 consumer.SkipSint32LE();
119 CHECK(consumer.ReadSint32LE(42) == 42);
120}
121
122TEST_CASE("StringConsumer - binary64")
123{
124 StringConsumer consumer("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF"sv);
125 CHECK(consumer.PeekUint64LE() == 0xFFFFFFFF'FFFFFFFF);
126 CHECK(consumer.PeekSint64LE() == -1);
127 consumer.SkipUint64LE();
128 CHECK(consumer.PeekUint64LE() == 0xFFFFFFFF'FFFFFFFE);
129 CHECK(consumer.PeekSint64LE() == -2);
130 CHECK(consumer.ReadUint64LE() == 0xFFFFFFFF'FFFFFFFE);
131 CHECK(consumer.PeekUint64LE() == 0xFFFFFFFF'FFFFFFFD);
132 CHECK(consumer.PeekSint64LE() == -3);
133 CHECK(consumer.ReadSint64LE() == -3);
134 CHECK(consumer.PeekUint64LE() == std::nullopt);
135 CHECK(consumer.PeekSint64LE() == std::nullopt);
136 CHECK(consumer.ReadUint64LE(42) == 42);
137 consumer.SkipSint64LE();
138 CHECK(consumer.ReadSint64LE(42) == 42);
139}
140
141TEST_CASE("StringConsumer - utf8")
142{
143 StringConsumer consumer("a\u1234\xFF\xFE""b"sv);
144 CHECK(consumer.PeekUtf8() == std::pair<StringConsumer::size_type, char32_t>(1, 'a'));
145 consumer.SkipUtf8();
146 CHECK(consumer.PeekUtf8() == std::pair<StringConsumer::size_type, char32_t>(3, 0x1234));
147 CHECK(consumer.ReadUtf8() == 0x1234);
148 CHECK(consumer.PeekUint8() == 0xFF);
149 CHECK(consumer.PeekUtf8() == std::pair<StringConsumer::size_type, char32_t>(0, 0));
150 CHECK(consumer.ReadUtf8() == '?');
151 CHECK(consumer.PeekUint8() == 0xFE);
152 CHECK(consumer.PeekUtf8() == std::pair<StringConsumer::size_type, char32_t>(0, 0));
153 consumer.SkipUtf8();
154 CHECK(consumer.PeekUtf8() == std::pair<StringConsumer::size_type, char32_t>(1, 'b'));
155 CHECK(consumer.ReadUtf8() == 'b');
156 CHECK(!consumer.AnyBytesLeft());
157 CHECK(consumer.PeekUtf8() == std::pair<StringConsumer::size_type, char32_t>(0, 0));
158 CHECK(consumer.ReadUtf8() == '?');
159}
160
161TEST_CASE("StringConsumer - conditions")
162{
163 StringConsumer consumer("ABCDabcde\u0234@@@gh\0\0\0ij\0\0\0kl"sv);
164 CHECK(consumer.PeekIf("AB"));
165 CHECK(consumer.PeekCharIf('A'));
166 CHECK(consumer.PeekUtf8If('A'));
167 CHECK(!consumer.PeekIf("CD"));
168 CHECK(!consumer.ReadIf("CD"));
169 consumer.SkipIf("CD");
170 CHECK(consumer.ReadIf("AB"));
171 CHECK(consumer.PeekIf("CD"));
172 consumer.SkipIf("CD");
173 CHECK(consumer.Peek(2) == "ab");
174 CHECK(consumer.Read(2) == "ab");
175 CHECK(consumer.Peek(2) == "cd");
176 CHECK(consumer.Find("e\u0234") == 2);
177 CHECK(consumer.Find("ab") == StringConsumer::npos);
178 CHECK(consumer.FindChar('e') == 2);
179 CHECK(consumer.FindChar('a') == StringConsumer::npos);
180 CHECK(consumer.FindUtf8(0x234) == 3);
181 CHECK(consumer.FindUtf8(0x1234) == StringConsumer::npos);
182 consumer.Skip(2);
183 CHECK(consumer.Peek(3) == "e\u0234");
184 CHECK(consumer.PeekUntil("e", StringConsumer::READ_ALL_SEPARATORS) == "e");
185 CHECK(consumer.PeekUntil("e", StringConsumer::READ_ONE_SEPARATOR) == "e");
186 CHECK(consumer.PeekUntil("e", StringConsumer::KEEP_SEPARATOR) == "");
187 CHECK(consumer.PeekUntil("e", StringConsumer::SKIP_ONE_SEPARATOR) == "");
188 CHECK(consumer.PeekUntil("e", StringConsumer::SKIP_ALL_SEPARATORS) == "");
189 CHECK(consumer.PeekUntil("@", StringConsumer::READ_ALL_SEPARATORS) == "e\u0234@@@");
190 CHECK(consumer.PeekUntil("@", StringConsumer::READ_ONE_SEPARATOR) == "e\u0234@");
191 CHECK(consumer.PeekUntil("@", StringConsumer::KEEP_SEPARATOR) == "e\u0234");
192 CHECK(consumer.PeekUntil("@", StringConsumer::SKIP_ONE_SEPARATOR) == "e\u0234");
193 CHECK(consumer.PeekUntil("@", StringConsumer::SKIP_ALL_SEPARATORS) == "e\u0234");
194 CHECK(consumer.ReadUntil("@", StringConsumer::KEEP_SEPARATOR) == "e\u0234");
195 CHECK(consumer.ReadUntil("@", StringConsumer::READ_ONE_SEPARATOR) == "@");
196 CHECK(consumer.ReadUntil("@", StringConsumer::READ_ALL_SEPARATORS) == "@@");
197 CHECK(consumer.PeekUntilChar('\0', StringConsumer::READ_ALL_SEPARATORS) == "gh\0\0\0"sv);
198 CHECK(consumer.PeekUntilChar('\0', StringConsumer::READ_ONE_SEPARATOR) == "gh\0"sv);
199 CHECK(consumer.PeekUntilChar('\0', StringConsumer::KEEP_SEPARATOR) == "gh");
200 CHECK(consumer.PeekUntilChar('\0', StringConsumer::SKIP_ONE_SEPARATOR) == "gh");
201 CHECK(consumer.PeekUntilChar('\0', StringConsumer::SKIP_ALL_SEPARATORS) == "gh");
202 CHECK(consumer.ReadUntilChar('\0', StringConsumer::READ_ONE_SEPARATOR) == "gh\0"sv);
203 CHECK(consumer.PeekUntilChar('\0', StringConsumer::READ_ALL_SEPARATORS) == "\0\0"sv);
204 CHECK(consumer.ReadUntilChar('\0', StringConsumer::SKIP_ONE_SEPARATOR) == "");
205 CHECK(consumer.PeekUntilChar('\0', StringConsumer::READ_ALL_SEPARATORS) == "\0"sv);
206 consumer.SkipUntilUtf8(0, StringConsumer::READ_ALL_SEPARATORS);
207 CHECK(consumer.PeekUntilUtf8(0, StringConsumer::KEEP_SEPARATOR) == "ij");
208 consumer.SkipUntilUtf8(0, StringConsumer::SKIP_ALL_SEPARATORS);
209 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::READ_ALL_SEPARATORS) == "kl");
210 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::READ_ONE_SEPARATOR) == "kl");
211 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::KEEP_SEPARATOR) == "kl");
212 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::SKIP_ONE_SEPARATOR) == "kl");
213 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::SKIP_ALL_SEPARATORS) == "kl");
214 CHECK(consumer.ReadUntilUtf8(0x234, StringConsumer::READ_ALL_SEPARATORS) == "kl");
215 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::READ_ALL_SEPARATORS) == "");
216 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::READ_ONE_SEPARATOR) == "");
217 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::KEEP_SEPARATOR) == "");
218 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::SKIP_ONE_SEPARATOR) == "");
219 CHECK(consumer.PeekUntilUtf8(0x234, StringConsumer::SKIP_ALL_SEPARATORS) == "");
220 CHECK(consumer.ReadUntilUtf8(0x234, StringConsumer::READ_ALL_SEPARATORS) == "");
221 CHECK(consumer.ReadUntilUtf8(0x234, StringConsumer::READ_ONE_SEPARATOR) == "");
222 CHECK(consumer.ReadUntilUtf8(0x234, StringConsumer::KEEP_SEPARATOR) == "");
223 CHECK(consumer.ReadUntilUtf8(0x234, StringConsumer::SKIP_ONE_SEPARATOR) == "");
224 CHECK(consumer.ReadUntilUtf8(0x234, StringConsumer::SKIP_ALL_SEPARATORS) == "");
225 CHECK(consumer.Peek(2) == "");
226 CHECK(consumer.Read(2) == "");
227}
228
229TEST_CASE("StringConsumer - ascii")
230{
231 StringConsumer consumer("abcdefgh \r\n\tAB \r\n\t"sv);
232 CHECK(consumer.FindCharIn("dc") == 2);
233 CHECK(consumer.FindCharIn("xy") == StringConsumer::npos);
234 CHECK(consumer.FindCharNotIn("ba") == 2);
235 CHECK(consumer.PeekUntilCharNotIn("ba") == "ab");
236 CHECK(consumer.PeekUntilCharNotIn("dc") == "");
237 CHECK(consumer.PeekUntilCharIn("ba") == "");
238 CHECK(consumer.PeekUntilCharIn("dc") == "ab");
239 CHECK(consumer.ReadUntilCharNotIn("dc") == "");
240 CHECK(consumer.ReadUntilCharNotIn("ba") == "ab");
241 CHECK(consumer.ReadUntilCharIn("dc") == "");
242 CHECK(consumer.ReadUntilCharIn("fe") == "cd");
243 CHECK(consumer.PeekIf("ef"));
244 consumer.SkipUntilCharNotIn("ji");
245 CHECK(consumer.PeekIf("ef"));
246 consumer.SkipUntilCharNotIn("fe");
247 CHECK(consumer.PeekIf("gh"));
248 consumer.SkipUntilCharIn("hg");
249 CHECK(consumer.PeekIf("gh"));
250 consumer.SkipUntilCharIn(StringConsumer::WHITESPACE_OR_NEWLINE);
251 CHECK(consumer.PeekCharIfIn(StringConsumer::WHITESPACE_OR_NEWLINE) == ' ');
252 CHECK(consumer.ReadCharIfIn(StringConsumer::WHITESPACE_OR_NEWLINE) == ' ');
253 consumer.SkipCharIfIn(StringConsumer::WHITESPACE_OR_NEWLINE);
254 CHECK(consumer.PeekUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE) == "\r");
255 CHECK(consumer.ReadUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE) == "\r");
256 consumer.SkipUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE);
257 CHECK(consumer.PeekCharIfIn(StringConsumer::WHITESPACE_OR_NEWLINE) == '\n');
258 CHECK(consumer.ReadCharIfIn(StringConsumer::WHITESPACE_OR_NEWLINE) == '\n');
259 CHECK(consumer.PeekUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE) == "\t");
260 CHECK(consumer.ReadUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE) == "\t");
261 consumer.SkipUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE);
262 CHECK(consumer.PeekUntilCharIn(StringConsumer::WHITESPACE_OR_NEWLINE) == "AB");
263 CHECK(consumer.ReadUntilCharIn(StringConsumer::WHITESPACE_OR_NEWLINE) == "AB");
264 CHECK(consumer.PeekUntilCharNotIn(StringConsumer::WHITESPACE_OR_NEWLINE) == " \r\n\t");
265 consumer.SkipUntilCharNotIn(StringConsumer::WHITESPACE_OR_NEWLINE);
266 CHECK(!consumer.AnyBytesLeft());
267}
268
269TEST_CASE("StringConsumer - parse int")
270{
271 StringConsumer consumer("1 a -a -2 -8 ffffFFFF ffffFFFF -1aaaAAAA -1aaaAAAA +3 1234567890123 1234567890123 1234567890123 ffffFFFFffffFFFE ffffFFFFffffFFFE ffffFFFFffffFFFE ffffFFFFffffFFFE -0x1aaaAAAAaaaaAAAA -1234567890123 "sv);
272 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(1, 1));
273 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(1, 1));
274 CHECK(consumer.PeekIntegerBase<uint32_t>(8) == std::pair<StringConsumer::size_type, uint32_t>(1, 1));
275 CHECK(consumer.PeekIntegerBase<int32_t>(8) == std::pair<StringConsumer::size_type, int32_t>(1, 1));
276 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(1, 1));
277 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(1, 1));
278 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(1, 1));
279 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(1, 1));
280 CHECK(consumer.TryReadIntegerBase<uint32_t>(10) == 1);
281 CHECK(consumer.ReadUtf8() == ' ');
282 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
283 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
284 CHECK(consumer.PeekIntegerBase<uint32_t>(8) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
285 CHECK(consumer.PeekIntegerBase<int32_t>(8) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
286 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
287 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
288 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(1, 0xa));
289 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(1, 0xa));
290 CHECK(consumer.ReadIntegerBase<uint32_t>(16) == 0xa);
291 CHECK(consumer.ReadUtf8() == ' ');
292 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
293 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
294 CHECK(consumer.PeekIntegerBase<uint32_t>(8) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
295 CHECK(consumer.PeekIntegerBase<int32_t>(8) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
296 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
297 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
298 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
299 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(2, -0xa));
300 CHECK(consumer.ReadIntegerBase<int32_t>(16) == -0xa);
301 CHECK(consumer.ReadUtf8() == ' ');
302 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
303 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(2, -2));
304 CHECK(consumer.PeekIntegerBase<uint32_t>(8) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
305 CHECK(consumer.PeekIntegerBase<int32_t>(8) == std::pair<StringConsumer::size_type, int32_t>(2, -2));
306 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
307 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(2, -2));
308 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
309 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(2, -2));
310 CHECK(consumer.TryReadIntegerBase<uint32_t>(10) == std::nullopt);
311 CHECK(consumer.ReadIntegerBase<uint32_t>(10) == 0);
312 CHECK(consumer.ReadUtf8() == ' ');
313 CHECK(consumer.PeekIntegerBase<uint32_t>(8) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
314 CHECK(consumer.PeekIntegerBase<int32_t>(8) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
315 CHECK(consumer.TryReadIntegerBase<uint32_t>(8) == std::nullopt);
316 CHECK(consumer.TryReadIntegerBase<int32_t>(8) == std::nullopt);
317 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
318 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(2, -8));
319 CHECK(consumer.TryReadIntegerBase<uint32_t>(10) == std::nullopt);
320 CHECK(consumer.ReadIntegerBase<int32_t>(10) == -8);
321 CHECK(consumer.ReadUtf8() == ' ');
322 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(8, 0xffffffff));
323 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
324 CHECK(consumer.PeekIntegerBase<uint32_t>(16, true) == std::pair<StringConsumer::size_type, uint32_t>(8, 0xffffffff));
325 CHECK(consumer.PeekIntegerBase<int32_t>(16, true) == std::pair<StringConsumer::size_type, int32_t>(8, 0x7fffffff));
326 CHECK(consumer.TryReadIntegerBase<int32_t>(16) == std::nullopt);
327 CHECK(consumer.ReadIntegerBase<int32_t>(16) == 0);
328 CHECK(consumer.ReadUtf8() == ' ');
329 CHECK(consumer.TryReadIntegerBase<uint32_t>(16) == 0xffffffff);
330 CHECK(consumer.ReadUtf8() == ' ');
331 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
332 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(9, -0x1aaaaaaa));
333 CHECK(consumer.PeekIntegerBase<uint32_t>(16, true) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
334 CHECK(consumer.PeekIntegerBase<int32_t>(16, true) == std::pair<StringConsumer::size_type, int32_t>(9, -0x1aaaaaaa));
335 CHECK(consumer.TryReadIntegerBase<uint32_t>(16) == std::nullopt);
336 CHECK(consumer.ReadIntegerBase<uint32_t>(16) == 0);
337 CHECK(consumer.ReadUtf8() == ' ');
338 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
339 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(9, -0x1aaaaaaa));
340 CHECK(consumer.TryReadIntegerBase<uint32_t>(16) == std::nullopt);
341 CHECK(consumer.ReadIntegerBase<int32_t>(16) == -0x1aaaaaaa);
342 CHECK(consumer.ReadUtf8() == ' ');
343 CHECK(consumer.PeekIntegerBase<uint32_t>(8) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
344 CHECK(consumer.PeekIntegerBase<int32_t>(8) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
345 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
346 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
347 consumer.SkipIntegerBase(10);
348 CHECK(consumer.ReadUtf8() == '+');
349 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(1, 3));
350 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(1, 3));
351 consumer.SkipIntegerBase(10);
352 CHECK(consumer.ReadUtf8() == ' ');
353 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
354 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
355 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(13, 1234567890123));
356 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(13, 1234567890123));
357 CHECK(consumer.PeekIntegerBase<uint32_t>(10, true) == std::pair<StringConsumer::size_type, uint32_t>(13, 0xffffffff));
358 CHECK(consumer.PeekIntegerBase<int32_t>(10, true) == std::pair<StringConsumer::size_type, int32_t>(13, 0x7fffffff));
359 CHECK(consumer.PeekIntegerBase<uint64_t>(10, true) == std::pair<StringConsumer::size_type, uint64_t>(13, 1234567890123));
360 CHECK(consumer.PeekIntegerBase<int64_t>(10, true) == std::pair<StringConsumer::size_type, int64_t>(13, 1234567890123));
361 CHECK(consumer.TryReadIntegerBase<uint32_t>(10) == std::nullopt);
362 CHECK(consumer.ReadIntegerBase<uint32_t>(10) == 0);
363 CHECK(consumer.ReadUtf8() == ' ');
364 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
365 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
366 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(13, 1234567890123));
367 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(13, 1234567890123));
368 CHECK(consumer.TryReadIntegerBase<int32_t>(10) == std::nullopt);
369 CHECK(consumer.ReadIntegerBase<int32_t>(10) == 0);
370 CHECK(consumer.ReadUtf8() == ' ');
371 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
372 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
373 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(13, 1234567890123));
374 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(13, 1234567890123));
375 CHECK(consumer.ReadIntegerBase<uint64_t>(10) == 1234567890123);
376 CHECK(consumer.ReadUtf8() == ' ');
377 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
378 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
379 CHECK(consumer.PeekIntegerBase<uint64_t>(16) == std::pair<StringConsumer::size_type, uint64_t>(16, 0xffffffff'fffffffe));
380 CHECK(consumer.PeekIntegerBase<int64_t>(16) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
381 CHECK(consumer.PeekIntegerBase<uint32_t>(16, true) == std::pair<StringConsumer::size_type, uint32_t>(16, 0xffffffff));
382 CHECK(consumer.PeekIntegerBase<int32_t>(16, true) == std::pair<StringConsumer::size_type, int32_t>(16, 0x7fffffff));
383 CHECK(consumer.PeekIntegerBase<uint64_t>(16, true) == std::pair<StringConsumer::size_type, uint64_t>(16, 0xffffffff'fffffffe));
384 CHECK(consumer.PeekIntegerBase<int64_t>(16, true) == std::pair<StringConsumer::size_type, int64_t>(16, 0x7fffffff'ffffffff));
385 CHECK(consumer.ReadIntegerBase<uint32_t>(16) == 0);
386 CHECK(consumer.ReadUtf8() == ' ');
387 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
388 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
389 CHECK(consumer.PeekIntegerBase<uint64_t>(16) == std::pair<StringConsumer::size_type, uint64_t>(16, 0xffffffff'fffffffe));
390 CHECK(consumer.PeekIntegerBase<int64_t>(16) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
391 CHECK(consumer.ReadIntegerBase<int32_t>(16) == 0);
392 CHECK(consumer.ReadUtf8() == ' ');
393 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
394 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
395 CHECK(consumer.PeekIntegerBase<uint64_t>(16) == std::pair<StringConsumer::size_type, uint64_t>(16, 0xffffffff'fffffffe));
396 CHECK(consumer.PeekIntegerBase<int64_t>(16) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
397 CHECK(consumer.ReadIntegerBase<int64_t>(16) == 0);
398 CHECK(consumer.ReadUtf8() == ' ');
399 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
400 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
401 CHECK(consumer.PeekIntegerBase<uint64_t>(16) == std::pair<StringConsumer::size_type, uint64_t>(16, 0xffffffff'fffffffe));
402 CHECK(consumer.PeekIntegerBase<int64_t>(16) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
403 CHECK(consumer.ReadIntegerBase<uint64_t>(16) == 0xffffffff'fffffffe);
404 CHECK(consumer.ReadUtf8() == ' ');
405 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
406 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(2, 0));
407 CHECK(consumer.PeekIntegerBase<uint64_t>(16) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
408 CHECK(consumer.PeekIntegerBase<int64_t>(16) == std::pair<StringConsumer::size_type, int64_t>(2, 0));
409 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
410 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
411 CHECK(consumer.PeekIntegerBase<uint64_t>(0) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
412 CHECK(consumer.PeekIntegerBase<int64_t>(0) == std::pair<StringConsumer::size_type, int64_t>(19, -0x1aaaaaaa'aaaaaaaa));
413 CHECK(consumer.ReadIntegerBase<int64_t>(0) == -0x1aaaaaaa'aaaaaaaa);
414 CHECK(consumer.ReadUtf8() == ' ');
415 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
416 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
417 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
418 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(14, -1234567890123));
419 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
420 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
421 CHECK(consumer.PeekIntegerBase<uint64_t>(0) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
422 CHECK(consumer.PeekIntegerBase<int64_t>(0) == std::pair<StringConsumer::size_type, int64_t>(14, -1234567890123));
423 CHECK(consumer.ReadIntegerBase<int64_t>(0) == -1234567890123);
424 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
425 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
426 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
427 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
428 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
429 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
430 CHECK(consumer.PeekIntegerBase<uint64_t>(0) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
431 CHECK(consumer.PeekIntegerBase<int64_t>(0) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
432 consumer.SkipIntegerBase(10);
433 consumer.SkipIntegerBase(10);
434 consumer.SkipIntegerBase(0);
435 consumer.SkipIntegerBase(0);
436 CHECK(consumer.ReadIntegerBase<uint32_t>(10, 42) == 42);
437 CHECK(consumer.ReadIntegerBase<int32_t>(10, 42) == 42);
438 CHECK(consumer.ReadIntegerBase<uint64_t>(10, 42) == 42);
439 CHECK(consumer.ReadIntegerBase<int64_t>(10, 42) == 42);
440 CHECK(consumer.ReadIntegerBase<uint32_t>(0, 42) == 42);
441 CHECK(consumer.ReadIntegerBase<int32_t>(0, 42) == 42);
442 CHECK(consumer.ReadIntegerBase<uint64_t>(0, 42) == 42);
443 CHECK(consumer.ReadIntegerBase<int64_t>(0, 42) == 42);
444 CHECK(consumer.ReadUtf8() == ' ');
445 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
446 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
447 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
448 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
449 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
450 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
451 CHECK(consumer.PeekIntegerBase<uint64_t>(0) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
452 CHECK(consumer.PeekIntegerBase<int64_t>(0) == std::pair<StringConsumer::size_type, int64_t>(0, 0));
453 consumer.SkipIntegerBase(10);
454 consumer.SkipIntegerBase(10);
455 CHECK(consumer.ReadIntegerBase<uint32_t>(10, 42) == 42);
456 CHECK(consumer.ReadIntegerBase<int32_t>(10, 42) == 42);
457 CHECK(consumer.ReadIntegerBase<uint64_t>(10, 42) == 42);
458 CHECK(consumer.ReadIntegerBase<int64_t>(10, 42) == 42);
459 CHECK(consumer.ReadIntegerBase<uint32_t>(0, 42) == 42);
460 CHECK(consumer.ReadIntegerBase<int32_t>(0, 42) == 42);
461 CHECK(consumer.ReadIntegerBase<uint64_t>(0, 42) == 42);
462 CHECK(consumer.ReadIntegerBase<int64_t>(0, 42) == 42);
463}
464
465TEST_CASE("StringConsumer - invalid int")
466{
467 StringConsumer consumer("x 0x - -0x 0y"sv);
468 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
469 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
470 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
471 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
472 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
473 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
474 consumer.SkipIntegerBase(0);
475 consumer.SkipIntegerBase(10);
476 consumer.SkipIntegerBase(16);
477 CHECK(consumer.ReadUtf8() == 'x');
478 CHECK(consumer.ReadUtf8() == ' ');
479 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
480 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
481 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(1, 0));
482 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(1, 0));
483 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(1, 0));
484 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(1, 0));
485 consumer.SkipIntegerBase(0);
486 CHECK(consumer.ReadUtf8() == ' ');
487 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
488 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
489 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
490 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
491 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
492 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
493 consumer.SkipIntegerBase(0);
494 CHECK(consumer.ReadUtf8() == ' ');
495 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
496 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
497 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
498 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(2, 0));
499 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
500 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(2, 0));
501 consumer.SkipIntegerBase(0);
502 CHECK(consumer.ReadUtf8() == ' ');
503 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(1, 0));
504 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(1, 0));
505 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(1, 0));
506 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(1, 0));
507 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(1, 0));
508 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(1, 0));
509 consumer.SkipIntegerBase(0);
510 CHECK(consumer.ReadUtf8() == 'y');
511}
512
513TEST_CASE("StringConsumer - most negative")
514{
515 StringConsumer consumer("-80000000 -0x80000000 -2147483648 -9223372036854775808"sv);
516 CHECK(consumer.PeekIntegerBase<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
517 CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(9, 0x80000000));
518 CHECK(consumer.PeekIntegerBase<uint32_t>(16, true) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
519 CHECK(consumer.PeekIntegerBase<int32_t>(16, true) == std::pair<StringConsumer::size_type, int32_t>(9, 0x80000000));
520 consumer.SkipIntegerBase(16);
521 CHECK(consumer.ReadUtf8() == ' ');
522 CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
523 CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(11, 0x80000000));
524 consumer.SkipIntegerBase(0);
525 CHECK(consumer.ReadUtf8() == ' ');
526 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
527 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(11, 0x80000000));
528 consumer.SkipIntegerBase(0);
529 CHECK(consumer.ReadUtf8() == ' ');
530 CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
531 CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(0, 0));
532 CHECK(consumer.PeekIntegerBase<uint64_t>(10) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
533 CHECK(consumer.PeekIntegerBase<int64_t>(10) == std::pair<StringConsumer::size_type, int64_t>(20, 0x80000000'00000000));
534 CHECK(consumer.PeekIntegerBase<uint32_t>(10, true) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
535 CHECK(consumer.PeekIntegerBase<int32_t>(10, true) == std::pair<StringConsumer::size_type, int32_t>(20, 0x80000000));
536 CHECK(consumer.PeekIntegerBase<uint64_t>(10, true) == std::pair<StringConsumer::size_type, uint64_t>(0, 0));
537 CHECK(consumer.PeekIntegerBase<int64_t>(10, true) == std::pair<StringConsumer::size_type, int64_t>(20, 0x80000000'00000000));
538}
Parse data from a string / buffer.
@ READ_ALL_SEPARATORS
Read all consecutive separators, and include them all in the result.
@ READ_ONE_SEPARATOR
Read one separator, and include it in the result.
@ SKIP_ALL_SEPARATORS
Read and discard all consecutive separators, do not include any in the result.
@ SKIP_ONE_SEPARATOR
Read and discard one separator, do not include it in the result.
@ KEEP_SEPARATOR
Keep the separator in the data as next value to be read.
static const std::string_view WHITESPACE_OR_NEWLINE
ASCII whitespace characters, including new-line.
static const std::string_view WHITESPACE_NO_NEWLINE
ASCII whitespace characters, excluding new-line.
static constexpr size_type npos
Special value for "end of data".