Skip to content

Commit 32feb3a

Browse files
Parsing tools: added ParseInteger function
1 parent d86fa2d commit 32feb3a

2 files changed

Lines changed: 85 additions & 17 deletions

File tree

Common/interface/ParsingTools.hpp

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ inline bool IsDigit(Char Symbol) noexcept
7575

7676
/// Skips all characters until the end of the line.
7777

78-
/// \param[inout] Pos - starting position.
79-
/// \param[in] End - end of the input string.
80-
/// \param[in] GoToNextLine - whether to go to the next line.
78+
/// \param[in] Start - starting position.
79+
/// \param[in] End - end of the input string.
80+
/// \param[in] GoToNextLine - whether to go to the next line.
8181
///
8282
/// \return If GoToNextLine is true, the position following the
8383
/// new line character at the end of the string.
@@ -124,9 +124,9 @@ DEFINE_FLAG_ENUM_OPERATORS(SKIP_COMMENT_FLAGS)
124124

125125
/// Skips single-line and multi-line comments starting from the given position.
126126

127-
/// \param[inout] Start - starting position.
128-
/// \param[in] End - end of the input string.
129-
/// \param[in] Flags - flags controlling what kind of comments to skip.
127+
/// \param[in] Start - starting position.
128+
/// \param[in] End - end of the input string.
129+
/// \param[in] Flags - flags controlling what kind of comments to skip.
130130
///
131131
/// \return if the comment is found, the position immediately following
132132
/// the end of the comment; starting position otherwise.
@@ -211,9 +211,9 @@ InteratorType SkipComment(const InteratorType& Start, const InteratorType& End,
211211

212212
/// Skips all delimiters starting from the given position.
213213

214-
/// \param[inout] Pos - starting position.
215-
/// \param[in] End - end of the input string.
216-
/// \param[in] Delimiters - optional string containing custom delimiters.
214+
/// \param[in] Start - starting position.
215+
/// \param[in] End - end of the input string.
216+
/// \param[in] Delimiters - optional string containing custom delimiters.
217217
///
218218
/// \return position of the first non-delimiter character.
219219
template <typename InteratorType>
@@ -236,10 +236,10 @@ InteratorType SkipDelimiters(const InteratorType& Start, const InteratorType& En
236236

237237
/// Skips all comments and all delimiters starting from the given position.
238238

239-
/// \param[inout] Pos - starting position.
240-
/// \param[in] End - end of the input string.
241-
/// \param[in] Delimiters - optional string containing custom delimiters.
242-
/// \param[in] CommentFlags - optional flags controlling what kind of comments to skip.
239+
/// \param[in] Start - starting position.
240+
/// \param[in] End - end of the input string.
241+
/// \param[in] Delimiters - optional string containing custom delimiters.
242+
/// \param[in] CommentFlags - optional flags controlling what kind of comments to skip.
243243
///
244244
/// \return true position of the first non-comment non-delimiter character.
245245
///
@@ -270,8 +270,8 @@ IteratorType SkipDelimitersAndComments(const IteratorType& Start,
270270

271271
/// Skips one identifier starting from the given position.
272272

273-
/// \param[inout] Pos - starting position.
274-
/// \param[in] End - end of the input string.
273+
/// \param[in] Start - starting position.
274+
/// \param[in] End - end of the input string.
275275
///
276276
/// \return position immediately following the last character of identifier.
277277
template <typename IteratorType>
@@ -295,8 +295,8 @@ IteratorType SkipIdentifier(const IteratorType& Start, const IteratorType& End)
295295

296296
/// Skips a floating point number starting from the given position.
297297

298-
/// \param[inout] Pos - starting position.
299-
/// \param[in] End - end of the input string.
298+
/// \param[in] Start - starting position.
299+
/// \param[in] End - end of the input string.
300300
///
301301
/// \return position immediately following the last character of the number.
302302
template <typename IteratorType>
@@ -385,6 +385,38 @@ IteratorType SkipFloatNumber(const IteratorType& Start, const IteratorType& End)
385385
return Pos;
386386
}
387387

388+
/// Parses an integer starting from the given position.
389+
///
390+
/// \param[in] Start - starting position.
391+
/// \param[in] End - end of the input string
392+
/// \param[out] Value - parsed integer value.
393+
/// \return position immediately following the last character of the number.
394+
template <typename IteratorType, typename ValueType>
395+
IteratorType ParseInteger(const IteratorType& Start, const IteratorType& End, ValueType& Value) noexcept
396+
{
397+
auto Pos = Start;
398+
if (Pos == End)
399+
return Pos;
400+
401+
const bool IsNegative = *Pos == '-';
402+
if (*Pos == '+' || *Pos == '-')
403+
++Pos;
404+
405+
if (Pos == End || !IsNum(*Pos))
406+
return Start;
407+
408+
Value = 0;
409+
while (Pos != End && IsNum(*Pos))
410+
{
411+
Value = Value * 10 + (*Pos - '0');
412+
++Pos;
413+
}
414+
415+
if (IsNegative)
416+
Value = -Value;
417+
418+
return Pos;
419+
}
388420

389421
/// Splits string into chunks separated by comments and delimiters.
390422
///

Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#include "ParsingTools.hpp"
2828

29+
#include <limits.h>
30+
2931
#include "gtest/gtest.h"
3032

3133
#include "TestingEnvironment.hpp"
@@ -1369,4 +1371,38 @@ TEST(Common_ParsingTools, RefinePreprocessorDirective)
13691371
TestRefine("# \t /* Comment*/ define", "define");
13701372
}
13711373

1374+
1375+
TEST(Common_ParsingTools, ParseInteger)
1376+
{
1377+
auto Test = [](const std::string Str, size_t RefPos, int RefValue) {
1378+
int Value = INT_MAX;
1379+
auto Pos = ParseInteger(Str.begin(), Str.end(), Value);
1380+
EXPECT_EQ(Pos, Str.begin() + RefPos);
1381+
EXPECT_EQ(Value, RefValue);
1382+
};
1383+
1384+
Test("", 0, INT_MAX);
1385+
Test(" ", 0, INT_MAX);
1386+
Test("+", 0, INT_MAX);
1387+
Test("-", 0, INT_MAX);
1388+
Test("x", 0, INT_MAX);
1389+
Test("abcd", 0, INT_MAX);
1390+
Test("+x", 0, INT_MAX);
1391+
Test("-y", 0, INT_MAX);
1392+
Test("x123", 0, INT_MAX);
1393+
Test("+0", 2, 0);
1394+
Test("-0", 2, 0);
1395+
Test("234", 3, 234);
1396+
Test("+468", 4, 468);
1397+
Test("-135", 4, -135);
1398+
Test("234x567", 3, 234);
1399+
Test("+468x087", 4, 468);
1400+
Test("-135x124", 4, -135);
1401+
for (int i = -100; i <= 100; ++i)
1402+
{
1403+
std::string Str = std::to_string(i);
1404+
Test(Str, Str.length(), i);
1405+
}
1406+
};
1407+
13721408
} // namespace

0 commit comments

Comments
 (0)