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,