[res] Simplify XmlPullParser::FindAttribute() and StringPool::Sort

1. FindAttribute used to do lots of work that C++17 does
   automatically

2. Use function_ref for a more efficient callback passing

Test: aapt2_tests
Flag: EXEMPT minor refactor
Change-Id: I4f172cca16c05422992b107e347ed01479fff898
diff --git a/tools/aapt2/xml/XmlPullParser.cpp b/tools/aapt2/xml/XmlPullParser.cpp
index 203832d..8abc26d 100644
--- a/tools/aapt2/xml/XmlPullParser.cpp
+++ b/tools/aapt2/xml/XmlPullParser.cpp
@@ -14,11 +14,13 @@
  * limitations under the License.
  */
 
-#include <iostream>
+#include "xml/XmlPullParser.h"
+
+#include <algorithm>
 #include <string>
+#include <tuple>
 
 #include "util/Util.h"
-#include "xml/XmlPullParser.h"
 #include "xml/XmlUtil.h"
 
 using ::android::InputStream;
@@ -325,5 +327,18 @@
   return {};
 }
 
+XmlPullParser::const_iterator XmlPullParser::FindAttribute(android::StringPiece namespace_uri,
+                                                           android::StringPiece name) const {
+  const auto end_iter = end_attributes();
+  const auto iter = std::lower_bound(begin_attributes(), end_iter, std::tuple(namespace_uri, name),
+                                     [](const Attribute& attr, const auto& rhs) {
+                                       return std::tie(attr.namespace_uri, attr.name) < rhs;
+                                     });
+  if (iter != end_iter && namespace_uri == iter->namespace_uri && name == iter->name) {
+    return iter;
+  }
+  return end_iter;
+}
+
 }  // namespace xml
 }  // namespace aapt
diff --git a/tools/aapt2/xml/XmlPullParser.h b/tools/aapt2/xml/XmlPullParser.h
index 655e6dc..64274d0 100644
--- a/tools/aapt2/xml/XmlPullParser.h
+++ b/tools/aapt2/xml/XmlPullParser.h
@@ -19,8 +19,7 @@
 
 #include <expat.h>
 
-#include <algorithm>
-#include <istream>
+#include <optional>
 #include <ostream>
 #include <queue>
 #include <stack>
@@ -302,31 +301,6 @@
   return compare(rhs) != 0;
 }
 
-inline XmlPullParser::const_iterator XmlPullParser::FindAttribute(
-    android::StringPiece namespace_uri, android::StringPiece name) const {
-  const auto end_iter = end_attributes();
-  const auto iter = std::lower_bound(
-      begin_attributes(), end_iter,
-      std::pair<android::StringPiece, android::StringPiece>(namespace_uri, name),
-      [](const Attribute& attr,
-         const std::pair<android::StringPiece, android::StringPiece>& rhs) -> bool {
-        int cmp = attr.namespace_uri.compare(
-            0, attr.namespace_uri.size(), rhs.first.data(), rhs.first.size());
-        if (cmp < 0) return true;
-        if (cmp > 0) return false;
-        cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(),
-                                rhs.second.size());
-        if (cmp < 0) return true;
-        return false;
-      });
-
-  if (iter != end_iter && namespace_uri == iter->namespace_uri &&
-      name == iter->name) {
-    return iter;
-  }
-  return end_iter;
-}
-
 }  // namespace xml
 }  // namespace aapt