Skip to content

Commit 2e6e90b

Browse files
Parsing tools: added GetArrayIndex function
1 parent 32feb3a commit 2e6e90b

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

Common/interface/ParsingTools.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <cstring>
3333
#include <sstream>
34+
#include <limits>
3435

3536
#include "../../Primitives/interface/BasicTypes.h"
3637
#include "../../Primitives/interface/FlagEnum.h"
@@ -1155,6 +1156,75 @@ inline std::string RefinePreprocessorDirective(const char* Str, size_t Len = 0)
11551156
return RefinePreprocessorDirective(Str, Str + Len);
11561157
}
11571158

1159+
static constexpr int InvalidArrayIndex = std::numeric_limits<int>::min();
1160+
1161+
/// Returns the array index if the given variable name is an indexed array element.
1162+
///
1163+
/// \param [in] Start - starting position.
1164+
/// \param [in] End - end of the input string.
1165+
/// \param [out] NameEnd - ending position of the variable name.
1166+
///
1167+
/// \return - Array index if the given variable name is an array element.
1168+
/// - -1 if the given variable name is a valid identifier and is not an array element.
1169+
/// - INT_MIN if the array index is invalid.
1170+
template <typename InteratorType>
1171+
inline int GetArrayIndex(const InteratorType& Start, const InteratorType& End, InteratorType& NameEnd)
1172+
{
1173+
NameEnd = SkipIdentifier(Start, End);
1174+
// Empty name is not a valid identifier
1175+
if (NameEnd == Start)
1176+
{
1177+
//
1178+
// ^
1179+
return InvalidArrayIndex;
1180+
}
1181+
1182+
if (NameEnd == End)
1183+
{
1184+
// MyArray
1185+
// ^
1186+
return -1;
1187+
}
1188+
// MyArray [ 16 ]
1189+
// ^
1190+
1191+
auto Pos = SkipDelimiters(NameEnd, End, " \t");
1192+
// MyArray [ 16 ]
1193+
// ^
1194+
if (Pos == End || *Pos != '[')
1195+
return InvalidArrayIndex;
1196+
1197+
Pos = SkipDelimiters(Pos + 1, End, " \t");
1198+
// MyArray [ 16 ]
1199+
// ^
1200+
if (Pos == End)
1201+
return InvalidArrayIndex;
1202+
1203+
int Index = InvalidArrayIndex;
1204+
Pos = ParseInteger(Pos, End, Index);
1205+
// MyArray [ 16 ]
1206+
// ^
1207+
1208+
Pos = SkipDelimiters(Pos, End, " \t");
1209+
// MyArray [ 16 ]
1210+
// ^
1211+
return (Pos != End && *Pos == ']') ? Index : InvalidArrayIndex;
1212+
}
1213+
1214+
template <typename InteratorType>
1215+
inline int GetArrayIndex(const InteratorType& Start, const InteratorType& End, std::string& NameWithoutBrackets)
1216+
{
1217+
InteratorType NameEnd = End;
1218+
const auto Index = GetArrayIndex(Start, End, NameEnd);
1219+
NameWithoutBrackets.assign(Start, NameEnd);
1220+
return Index;
1221+
}
1222+
1223+
inline int GetArrayIndex(const std::string& Var, std::string& NameWithoutBrackets)
1224+
{
1225+
return GetArrayIndex(Var.begin(), Var.end(), NameWithoutBrackets);
1226+
}
1227+
11581228
} // namespace Parsing
11591229

11601230
} // namespace Diligent

Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,4 +1405,41 @@ TEST(Common_ParsingTools, ParseInteger)
14051405
}
14061406
};
14071407

1408+
1409+
TEST(Common_ParsingTools, GetArrayIndex)
1410+
{
1411+
auto Test = [](const std::string Var, size_t RefNameEndPos, int RefIndex) {
1412+
std::string NameWOBrackets;
1413+
int Index = GetArrayIndex(Var, NameWOBrackets);
1414+
1415+
EXPECT_EQ(NameWOBrackets, Var.substr(0, RefNameEndPos));
1416+
EXPECT_EQ(Index, RefIndex);
1417+
};
1418+
1419+
Test("", 0, InvalidArrayIndex);
1420+
Test(" ", 0, InvalidArrayIndex);
1421+
Test("1", 0, InvalidArrayIndex);
1422+
Test("?", 0, InvalidArrayIndex);
1423+
Test("x", 1, -1);
1424+
Test("abc", 3, -1);
1425+
Test("xy1 ", 3, InvalidArrayIndex);
1426+
Test("xy2[", 3, InvalidArrayIndex);
1427+
Test("xy3 [", 3, InvalidArrayIndex);
1428+
Test("xy4[ ", 3, InvalidArrayIndex);
1429+
Test("xy5 [ ", 3, InvalidArrayIndex);
1430+
Test("xy6[10]", 3, 10);
1431+
Test("xy7[11 ]", 3, 11);
1432+
Test("xy8[ 12]", 3, 12);
1433+
Test("xy9[ 13 ]", 3, 13);
1434+
Test("xy0 [14]", 3, 14);
1435+
Test("xy1 [ 15]", 3, 15);
1436+
Test("xy2 [16 ]", 3, 16);
1437+
Test("xy3 [ 18 ]", 3, 18);
1438+
Test("xy4[x]", 3, INT_MIN);
1439+
Test("xy5 [ x ] ", 3, INT_MIN);
1440+
Test("xy6[12x]", 3, INT_MIN);
1441+
Test("xy7[12", 3, INT_MIN);
1442+
Test("xy7[12 ", 3, INT_MIN);
1443+
}
1444+
14081445
} // namespace

0 commit comments

Comments
 (0)