Standardize iFindFirst
iFindFirst was added in the previous commit. Move it to using
std::ranges::subrange, withi is a direct replacement for boost, rather
than inventing a new type.
Tested: Unit tests pass.
Change-Id: I6d88fc90f34ee0748b52e9fb6438635f9cdbd0a9
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/src/entity_manager/utils.cpp b/src/entity_manager/utils.cpp
index 14f3c79..9e379e9 100644
--- a/src/entity_manager/utils.cpp
+++ b/src/entity_manager/utils.cpp
@@ -91,31 +91,38 @@
// Walking through the string to find $<templateVar>
while (true)
{
- auto [firstIndex, lastIndex] = iFindFirst(*strPtr, templateChar);
- if (firstIndex == std::string_view::npos)
+ std::ranges::subrange<std::string::const_iterator> findStart =
+ iFindFirst(*strPtr, std::string_view(templateChar));
+
+ if (!findStart)
{
break;
}
- size_t templateVarEndIndex = 0;
- auto [firstSpaceIndex, _] = iFindFirst(strPtr->substr(lastIndex), " ");
- if (firstSpaceIndex == std::string_view::npos)
+ std::ranges::subrange<std::string::iterator> searchRange(
+ strPtr->begin() + (findStart.end() - strPtr->begin()),
+ strPtr->end());
+ std::ranges::subrange<std::string::const_iterator> findSpace =
+ iFindFirst(searchRange, " ");
+
+ std::string::const_iterator templateVarEnd;
+
+ if (!findSpace)
{
// No space means the template var spans to the end of
// of the keyPair value
- templateVarEndIndex = strPtr->size();
+ templateVarEnd = strPtr->end();
}
else
{
// A space marks the end of a template var
- templateVarEndIndex = lastIndex + firstSpaceIndex;
+ templateVarEnd = findSpace.begin();
}
lg2::error(
"There's still template variable {VAR} un-replaced. Removing it from the string.\n",
- "VAR",
- strPtr->substr(firstIndex, templateVarEndIndex - firstIndex));
- strPtr->erase(firstIndex, templateVarEndIndex - firstIndex);
+ "VAR", std::string(findStart.begin(), templateVarEnd));
+ strPtr->erase(findStart.begin(), templateVarEnd);
}
}
@@ -175,14 +182,17 @@
for (const auto& [propName, propValue] : interface)
{
std::string templateName = templateChar + propName;
- auto [start, endIdx] = iFindFirst(*strPtr, templateName);
- if (start == std::string::npos)
+ std::ranges::subrange<std::string::const_iterator> find =
+ iFindFirst(*strPtr, templateName);
+ if (!find)
{
continue;
}
+ size_t start = find.begin() - strPtr->begin();
+
// check for additional operations
- if ((start == 0U) && endIdx == strPtr->size())
+ if ((start == 0U) && find.end() == strPtr->end())
{
std::visit([&](auto&& val) { keyPair.value() = val; }, propValue);
return ret;
@@ -232,7 +242,7 @@
number = expression::evaluate(number, exprBegin, exprEnd);
- std::string replaced(strPtr->begin() + start, strPtr->begin() + endIdx);
+ std::string replaced(find.begin(), find.end());
while (exprBegin != exprEnd)
{
replaced.append(" ").append(*exprBegin++);
diff --git a/src/utils.cpp b/src/utils.cpp
index d5eb30b..0650a01 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -180,34 +180,3 @@
{
return std::visit(MatchProbeForwarder(probe), dbusValue);
}
-
-inline char asciiToLower(char c)
-{
- // Converts a character to lower case without relying on std::locale
- if ('A' <= c && c <= 'Z')
- {
- c -= static_cast<char>('A' - 'a');
- }
- return c;
-}
-
-std::pair<FirstIndex, LastIndex> iFindFirst(std::string_view str,
- std::string_view sub)
-{
- if (sub.empty())
- {
- return {std::string_view::npos, std::string_view::npos};
- }
- auto result = std::ranges::search(str, sub, [](char a, char b) {
- return asciiToLower(a) == asciiToLower(b);
- });
-
- if (!result.empty())
- {
- size_t start = static_cast<size_t>(
- std::ranges::distance(str.begin(), result.begin()));
- return {start, start + sub.size()};
- }
-
- return {std::string_view::npos, std::string_view::npos};
-}
diff --git a/src/utils.hpp b/src/utils.hpp
index e51ed1e..4565db0 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -77,8 +77,23 @@
/// \return true if the dbusValue matched the probe otherwise false.
bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue);
-std::pair<FirstIndex, LastIndex> iFindFirst(std::string_view str,
- std::string_view sub);
+inline char asciiToLower(char c)
+{
+ // Converts a character to lower case without relying on std::locale
+ if ('A' <= c && c <= 'Z')
+ {
+ c -= static_cast<char>('A' - 'a');
+ }
+ return c;
+}
+
+template <typename T>
+auto iFindFirst(T&& str, std::string_view sub)
+{
+ return std::ranges::search(str, sub, [](char a, char b) {
+ return asciiToLower(a) == asciiToLower(b);
+ });
+}
template <typename T>
std::from_chars_result fromCharsWrapper(const std::string_view& str, T& out,
diff --git a/test/meson.build b/test/meson.build
index 50f0901..adb6097 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -62,6 +62,6 @@
'test_utils.cpp',
'../src/utils.cpp',
include_directories: test_include_dir,
- dependencies: [gtest, phosphor_logging_dep],
+ dependencies: [gtest, phosphor_logging_dep, sdbusplus],
),
)
diff --git a/test/test_utils.cpp b/test/test_utils.cpp
index 76570df..7c67e9b 100644
--- a/test/test_utils.cpp
+++ b/test/test_utils.cpp
@@ -2,51 +2,54 @@
#include <gtest/gtest.h>
+constexpr std::string_view helloWorld = "Hello World";
+
TEST(IfindFirstTest, BasicMatch)
{
- auto [firstIndex, lastIndex] = iFindFirst("Hello World", "World");
- EXPECT_EQ(firstIndex, 6);
- EXPECT_EQ(lastIndex, 11);
+ auto match = iFindFirst(helloWorld, "World");
+ EXPECT_TRUE(match);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.begin()), 6);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.end()), 11);
}
TEST(IfindFirstTest, CaseInsensitiveMatch)
{
- auto [firstIndex, lastIndex] = iFindFirst("Hello World", "world");
- EXPECT_EQ(firstIndex, 6);
- EXPECT_EQ(lastIndex, 11);
+ auto match = iFindFirst(helloWorld, "world");
+ EXPECT_TRUE(match);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.begin()), 6);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.end()), 11);
}
TEST(IfindFirstTest, NoMatch)
{
- auto [firstIndex, lastIndex] = iFindFirst("Hello World", "Planet");
- EXPECT_EQ(firstIndex, std::string_view::npos);
- EXPECT_EQ(lastIndex, std::string_view::npos);
+ auto match = iFindFirst(helloWorld, "Planet");
+ EXPECT_FALSE(match);
}
TEST(IfindFirstTest, MatchAtStart)
{
- auto [firstIndex, lastIndex] = iFindFirst("Hello World", "HeLLo");
- EXPECT_EQ(firstIndex, 0);
- EXPECT_EQ(lastIndex, 5);
+ auto match = iFindFirst(helloWorld, "HeLLo");
+ EXPECT_TRUE(match);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.begin()), 0);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.end()), 5);
}
TEST(IfindFirstTest, MatchAtEnd)
{
- auto [firstIndex, lastIndex] = iFindFirst("Hello World", "LD");
- EXPECT_EQ(firstIndex, 9);
- EXPECT_EQ(lastIndex, 11);
+ auto match = iFindFirst(helloWorld, "LD");
+ EXPECT_TRUE(match);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.begin()), 9);
+ EXPECT_EQ(std::distance(helloWorld.begin(), match.end()), 11);
}
TEST(IfindFirstTest, EmptySubstring)
{
- auto [firstIndex, lastIndex] = iFindFirst("Hello", "");
- EXPECT_EQ(firstIndex, std::string_view::npos);
- EXPECT_EQ(lastIndex, std::string_view::npos);
+ auto match = iFindFirst(helloWorld, "");
+ EXPECT_FALSE(match);
}
TEST(IfindFirstTest, EmptyString)
{
- auto [firstIndex, lastIndex] = iFindFirst("", "Hello");
- EXPECT_EQ(firstIndex, std::string_view::npos);
- EXPECT_EQ(lastIndex, std::string_view::npos);
+ auto match = iFindFirst("", "Hello");
+ EXPECT_FALSE(match);
}