diff --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv --- a/libcxx/docs/Cxx2aStatusPaperStatus.csv +++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv @@ -27,7 +27,7 @@ "`P0966R1 `__","LWG","``string::reserve``\ Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0" "","","","","","" "`P0019R8 `__","LWG","Atomic Ref","Rapperswil","","" -"`P0458R2 `__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","" +"`P0458R2 `__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0" "`P0475R1 `__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|","" "`P0476R2 `__","LWG","Bit-casting object representations","Rapperswil","","" "`P0528R3 `__","CWG","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","Rapperswil","","" diff --git a/libcxx/include/map b/libcxx/include/map --- a/libcxx/include/map +++ b/libcxx/include/map @@ -191,10 +191,14 @@ iterator find(const K& x); // C++14 template const_iterator find(const K& x) const; // C++14 + template 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 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 @@ -406,10 +410,14 @@ iterator find(const K& x); // C++14 template const_iterator find(const K& x) const; // C++14 + template 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 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 @@ -1406,6 +1414,12 @@ #if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY bool contains(const key_type& __k) const {return find(__k) != end();} + template + _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 +2086,12 @@ #if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY bool contains(const key_type& __k) const {return find(__k) != end();} + template + _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 --- a/libcxx/include/set +++ b/libcxx/include/set @@ -154,10 +154,14 @@ iterator find(const K& x); template const_iterator find(const K& x) const; // C++14 + template 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 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 @@ -355,10 +359,14 @@ iterator find(const K& x); template const_iterator find(const K& x) const; // C++14 + template 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 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 @@ -798,6 +806,12 @@ #if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY bool contains(const key_type& __k) const {return find(__k) != end();} + template + _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 +1339,12 @@ #if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY bool contains(const key_type& __k) const {return find(__k) != end();} + template + _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 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 --- /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 +#include + +// + +// template bool contains(const K& x) const; // C++20 + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair& lhs, + const std::pair& rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair& lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair& rhs) const { + return lhs < rhs.first; + } +}; + +template +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, int, Comp> >(); + test, 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 --- /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 + +// + +// class set + +// template bool contains(const K& x) const; // C++20 + +#include +#include +#include + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair& lhs, + const std::pair& rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair& lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair& rhs) const { + return lhs < rhs.first; + } +}; + +template +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, Comp> >(); + test, Comp> >(); + + return 0; +}