[libcxx-commits] [libcxx] 3fca07d - [libc++] [P0458] Add map::contains and set::contains for heterogenous lookup missed in a17b1aed.

Marek Kurdej via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 13 08:16:05 PDT 2021


Author: Marek Kurdej
Date: 2021-04-13T17:15:58+02:00
New Revision: 3fca07d7b9a29fe829c8f04642d35a3bbb94d4d1

URL: https://github.com/llvm/llvm-project/commit/3fca07d7b9a29fe829c8f04642d35a3bbb94d4d1
DIFF: https://github.com/llvm/llvm-project/commit/3fca07d7b9a29fe829c8f04642d35a3bbb94d4d1.diff

LOG: [libc++] [P0458] Add map::contains and set::contains for heterogenous lookup missed in a17b1aed.

Commit rGa17b1aed added `bool contains(const key_type& x) const;` methods to associative containers, but didn't add `template<class K> bool contains(const K& x) const;` for heterogenous lookup.

Reviewed By: #libc, Quuxplusone, ldionne

Differential Revision: https://reviews.llvm.org/D100369

Added: 
    libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
    libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
    libcxx/test/std/containers/associative/set/contains_transparent.pass.cpp

Modified: 
    libcxx/docs/Cxx2aStatusPaperStatus.csv
    libcxx/include/map
    libcxx/include/set

Removed: 
    libcxx/test/std/containers/associative/map/contains.pass.cpp


################################################################################
diff  --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv
index 2e36ab1e8d26b..f478f31d162b9 100644
--- a/libcxx/docs/Cxx2aStatusPaperStatus.csv
+++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv
@@ -27,7 +27,7 @@
 "`P0966R1 <https://wg21.link/P0966R1>`__","LWG","``string::reserve``\  Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0"
 "","","","","",""
 "`P0019R8 <https://wg21.link/P0019R8>`__","LWG","Atomic Ref","Rapperswil","",""
-"`P0458R2 <https://wg21.link/P0458R2>`__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|",""
+"`P0458R2 <https://wg21.link/P0458R2>`__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0"
 "`P0475R1 <https://wg21.link/P0475R1>`__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|",""
 "`P0476R2 <https://wg21.link/P0476R2>`__","LWG","Bit-casting object representations","Rapperswil","",""
 "`P0528R3 <https://wg21.link/P0528R3>`__","CWG","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","Rapperswil","",""

diff  --git a/libcxx/include/map b/libcxx/include/map
index ddb596f8f6317..688e068574858 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -191,10 +191,14 @@ public:
         iterator find(const K& x);              // C++14
     template<typename K>
         const_iterator find(const K& x) const;  // C++14
+
     template<typename K>
       size_type count(const K& x) const;        // C++14
     size_type      count(const key_type& k) const;
-        bool contains(const key_type& x) const; // C++20
+
+    bool           contains(const key_type& x) const;  // C++20
+    template<class K> bool contains(const K& x) const; // C++20
+
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
     template<typename K>
@@ -406,10 +410,14 @@ public:
         iterator find(const K& x);              // C++14
     template<typename K>
         const_iterator find(const K& x) const;  // C++14
+
     template<typename K>
       size_type count(const K& x) const;        // C++14
     size_type      count(const key_type& k) const;
-        bool contains(const key_type& x) const; // C++20
+
+    bool           contains(const key_type& x) const;  // C++20
+    template<class K> bool contains(const K& x) const; // C++20
+
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
     template<typename K>
@@ -1406,6 +1414,10 @@ public:
 #if _LIBCPP_STD_VER > 17
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    contains(const _K2& __k) const { return find(__k) != end(); }
 #endif // _LIBCPP_STD_VER > 17
 
     _LIBCPP_INLINE_VISIBILITY
@@ -2072,6 +2084,10 @@ public:
 #if _LIBCPP_STD_VER > 17
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    contains(const _K2& __k) const { return find(__k) != end(); }
 #endif // _LIBCPP_STD_VER > 17
 
     _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/include/set b/libcxx/include/set
index 11991affb66e0..5c5bcf3617fac 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -154,10 +154,14 @@ public:
         iterator find(const K& x);
     template<typename K>
         const_iterator find(const K& x) const;  // C++14
+
     template<typename K>
         size_type count(const K& x) const;        // C++14
     size_type      count(const key_type& k) const;
-        bool contains(const key_type& x) const; // C++20
+
+    bool           contains(const key_type& x) const;  // C++20
+    template<class K> bool contains(const K& x) const; // C++20
+
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
     template<typename K>
@@ -355,10 +359,14 @@ public:
         iterator find(const K& x);
     template<typename K>
         const_iterator find(const K& x) const;  // C++14
+
     template<typename K>
         size_type count(const K& x) const;      // C++14
     size_type      count(const key_type& k) const;
-        bool contains(const key_type& x) const; // C++20
+
+    bool           contains(const key_type& x) const;  // C++20
+    template<class K> bool contains(const K& x) const; // C++20
+
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
     template<typename K>
@@ -798,6 +806,10 @@ public:
 #if _LIBCPP_STD_VER > 17
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    contains(const _K2& __k) const { return find(__k) != end(); }
 #endif // _LIBCPP_STD_VER > 17
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1325,6 +1337,10 @@ public:
 #if _LIBCPP_STD_VER > 17
     _LIBCPP_INLINE_VISIBILITY
     bool contains(const key_type& __k) const {return find(__k) != end();}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    contains(const _K2& __k) const { return find(__k) != end(); }
 #endif // _LIBCPP_STD_VER > 17
 
     _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/test/std/containers/associative/map/contains.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
similarity index 100%
rename from libcxx/test/std/containers/associative/map/contains.pass.cpp
rename to libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp

diff  --git a/libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
new file mode 100644
index 0000000000000..c5543a6eee3d3
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <cassert>
+#include <map>
+
+// <map>
+
+// template<class K> bool contains(const K& x) const; // C++20
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair<int, int>& lhs,
+                  const std::pair<int, int>& rhs) const {
+    return lhs < rhs;
+  }
+
+  bool operator()(const std::pair<int, int>& lhs, int rhs) const {
+    return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair<int, int>& rhs) const {
+    return lhs < rhs.first;
+  }
+};
+
+template <typename Container>
+void test() {
+  Container s{{{2, 1}, 1}, {{1, 2}, 2}, {{1, 3}, 3}, {{1, 4}, 4}, {{2, 2}, 5}};
+
+  assert(s.contains(1));
+  assert(!s.contains(-1));
+}
+
+int main(int, char**) {
+  test<std::map<std::pair<int, int>, int, Comp> >();
+  test<std::multimap<std::pair<int, int>, int, Comp> >();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/containers/associative/set/contains_transparent.pass.cpp b/libcxx/test/std/containers/associative/set/contains_transparent.pass.cpp
new file mode 100644
index 0000000000000..e4caa0b7128b4
--- /dev/null
+++ b/libcxx/test/std/containers/associative/set/contains_transparent.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <set>
+
+// class set
+
+// template<typename K> bool contains(const K& x) const; // C++20
+
+#include <cassert>
+#include <set>
+#include <utility>
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair<int, int>& lhs,
+                  const std::pair<int, int>& rhs) const {
+    return lhs < rhs;
+  }
+
+  bool operator()(const std::pair<int, int>& lhs, int rhs) const {
+    return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair<int, int>& rhs) const {
+    return lhs < rhs.first;
+  }
+};
+
+template <typename Container>
+void test() {
+  Container s{{2, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 2}};
+
+  assert(s.contains(1));
+  assert(!s.contains(-1));
+}
+
+int main(int, char**) {
+  test<std::set<std::pair<int, int>, Comp> >();
+  test<std::multiset<std::pair<int, int>, Comp> >();
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list