Fix Template Parameter List for Associative Containers in base::EraseIf

This change fixes the template parameter lists of associative containers for
base::EraseIf. For example, trying to use base::EraseIf with a std::map using a
custom comparator would have resulted in a compilation error before this change.

BUG=697235
[email protected], [email protected], [email protected]

Review-Url: https://codereview.chromium.org/2746053002
Cr-Commit-Position: refs/heads/master@{#456385}
diff --git a/base/stl_util.h b/base/stl_util.h
index 2cec11b..b0670b2 100644
--- a/base/stl_util.h
+++ b/base/stl_util.h
@@ -222,43 +222,68 @@
   container.remove_if(pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::map<T, Allocator>& container, Predicate pred) {
+template <class Key, class T, class Compare, class Allocator, class Predicate>
+void EraseIf(std::map<Key, T, Compare, Allocator>& container, Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::multimap<T, Allocator>& container, Predicate pred) {
+template <class Key, class T, class Compare, class Allocator, class Predicate>
+void EraseIf(std::multimap<Key, T, Compare, Allocator>& container,
+             Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::set<T, Allocator>& container, Predicate pred) {
+template <class Key, class Compare, class Allocator, class Predicate>
+void EraseIf(std::set<Key, Compare, Allocator>& container, Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::multiset<T, Allocator>& container, Predicate pred) {
+template <class Key, class Compare, class Allocator, class Predicate>
+void EraseIf(std::multiset<Key, Compare, Allocator>& container,
+             Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::unordered_map<T, Allocator>& container, Predicate pred) {
+template <class Key,
+          class T,
+          class Hash,
+          class KeyEqual,
+          class Allocator,
+          class Predicate>
+void EraseIf(std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& container,
+             Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::unordered_multimap<T, Allocator>& container, Predicate pred) {
+template <class Key,
+          class T,
+          class Hash,
+          class KeyEqual,
+          class Allocator,
+          class Predicate>
+void EraseIf(
+    std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>& container,
+    Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::unordered_set<T, Allocator>& container, Predicate pred) {
+template <class Key,
+          class Hash,
+          class KeyEqual,
+          class Allocator,
+          class Predicate>
+void EraseIf(std::unordered_set<Key, Hash, KeyEqual, Allocator>& container,
+             Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
-template <class T, class Allocator, class Predicate>
-void EraseIf(std::unordered_multiset<T, Allocator>& container, Predicate pred) {
+template <class Key,
+          class Hash,
+          class KeyEqual,
+          class Allocator,
+          class Predicate>
+void EraseIf(std::unordered_multiset<Key, Hash, KeyEqual, Allocator>& container,
+             Predicate pred) {
   internal::IterateAndEraseIf(container, pred);
 }
 
diff --git a/base/stl_util_unittest.cc b/base/stl_util_unittest.cc
index 34c5af81..48d0f66 100644
--- a/base/stl_util_unittest.cc
+++ b/base/stl_util_unittest.cc
@@ -79,6 +79,10 @@
   }
 }
 
+struct CustomIntHash {
+  size_t operator()(int elem) const { return std::hash<int>()(elem) + 1; }
+};
+
 struct HashByFirst {
   size_t operator()(const std::pair<int, int>& elem) const {
     return std::hash<int>()(elem.first);
@@ -377,26 +381,34 @@
 
 TEST(Erase, Map) {
   RunEraseIfTest<std::map<int, int>>();
+  RunEraseIfTest<std::map<int, int, std::greater<int>>>();
 }
 
 TEST(Erase, Multimap) {
   RunEraseIfTest<std::multimap<int, int>>();
+  RunEraseIfTest<std::multimap<int, int, std::greater<int>>>();
 }
 
 TEST(Erase, Set) {
   RunEraseIfTest<std::set<std::pair<int, int>>>();
+  RunEraseIfTest<
+      std::set<std::pair<int, int>, std::greater<std::pair<int, int>>>>();
 }
 
 TEST(Erase, Multiset) {
   RunEraseIfTest<std::multiset<std::pair<int, int>>>();
+  RunEraseIfTest<
+      std::multiset<std::pair<int, int>, std::greater<std::pair<int, int>>>>();
 }
 
 TEST(Erase, UnorderedMap) {
   RunEraseIfTest<std::unordered_map<int, int>>();
+  RunEraseIfTest<std::unordered_map<int, int, CustomIntHash>>();
 }
 
 TEST(Erase, UnorderedMultimap) {
   RunEraseIfTest<std::unordered_multimap<int, int>>();
+  RunEraseIfTest<std::unordered_multimap<int, int, CustomIntHash>>();
 }
 
 TEST(Erase, UnorderedSet) {