From e5ec94a1a083e055ac2686ecc72fb4868dd7ce85 Mon Sep 17 00:00:00 2001 From: Ruslan Arutyunyan <ruslan.arutyunyan@intel.com> Date: Tue, 10 Nov 2020 07:49:55 -0500 Subject: [PATCH] [libc++] Implement P0919R3: heterogenous lookup for unordered containers Implement heterogenous lookup for unordered containers, including the refinement from P1690R1. Differential Revision: https://reviews.llvm.org/D87171 --- libcxx/docs/FeatureTestMacroTable.rst | 2 +- libcxx/include/unordered_map | 176 ++++++++++++++++-- libcxx/include/unordered_set | 86 +++++++++ libcxx/include/version | 2 +- .../unord.map/contains.transparent.pass.cpp | 62 ++++++ .../unord.map/count.transparent.pass.cpp | 63 +++++++ .../equal_range_const.transparent.pass.cpp | 65 +++++++ ...equal_range_non_const.transparent.pass.cpp | 65 +++++++ .../unord.map/find_const.transparent.pass.cpp | 65 +++++++ .../find_non_const.transparent.pass.cpp | 65 +++++++ .../contains.transparent.pass.cpp | 65 +++++++ .../unord.multimap/count.transparent.pass.cpp | 63 +++++++ .../equal_range_const.transparent.pass.cpp | 65 +++++++ ...equal_range_non_const.transparent.pass.cpp | 65 +++++++ .../find_const.transparent.pass.cpp | 65 +++++++ .../find_non_const.transparent.pass.cpp | 65 +++++++ .../contains.transparent.pass.cpp | 64 +++++++ .../unord.multiset/count.transparent.pass.cpp | 62 ++++++ .../equal_range_const.transparent.pass.cpp | 64 +++++++ ...equal_range_non_const.transparent.pass.cpp | 64 +++++++ .../find_const.transparent.pass.cpp | 64 +++++++ .../find_non_const.transparent.pass.cpp | 64 +++++++ .../unord.set/contains.transparent.pass.cpp | 61 ++++++ .../unord.set/count.transparent.pass.cpp | 62 ++++++ .../equal_range_const.transparent.pass.cpp | 64 +++++++ ...equal_range_non_const.transparent.pass.cpp | 64 +++++++ .../unord.set/find_const.transparent.pass.cpp | 64 +++++++ .../find_non_const.transparent.pass.cpp | 64 +++++++ .../unordered_map.version.pass.cpp | 16 +- .../unordered_set.version.pass.cpp | 16 +- .../version.version.pass.cpp | 16 +- libcxx/test/support/is_transparent.h | 85 ++++++++- .../test/support/test_transparent_unordered.h | 136 ++++++++++++++ .../generate_feature_test_macro_components.py | 1 - libcxx/www/cxx2a_status.html | 4 +- 35 files changed, 2015 insertions(+), 59 deletions(-) create mode 100644 libcxx/test/std/containers/unord/unord.map/contains.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.map/count.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.map/equal_range_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.map/equal_range_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.map/find_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.map/find_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multimap/contains.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multimap/count.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multimap/equal_range_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multimap/equal_range_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multimap/find_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multimap/find_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multiset/contains.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multiset/count.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multiset/equal_range_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multiset/equal_range_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multiset/find_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.multiset/find_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.set/contains.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.set/count.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.set/equal_range_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.set/equal_range_non_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.set/find_const.transparent.pass.cpp create mode 100644 libcxx/test/std/containers/unord/unord.set/find_non_const.transparent.pass.cpp create mode 100644 libcxx/test/support/test_transparent_unordered.h diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 0f17a3a1bd54..8d7bfd45fc56 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -206,7 +206,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_erase_if`` ``202002L`` ------------------------------------------------- ----------------- - ``__cpp_lib_generic_unordered_lookup`` *unimplemented* + ``__cpp_lib_generic_unordered_lookup`` ``201811L`` ------------------------------------------------- ----------------- ``__cpp_lib_interpolate`` ``201902L`` ------------------------------------------------- ----------------- diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index fcdb15b32b18..9a00fd76f28d 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -173,10 +173,22 @@ public: iterator find(const key_type& k); const_iterator find(const key_type& k) const; + template<typename K> + iterator find(const K& x); // C++20 + template<typename K> + const_iterator find(const K& x) const; // C++20 size_type count(const key_type& k) const; + template<typename K> + size_type count(const K& k) const; // C++20 bool contains(const key_type& k) const; // C++20 + template<typename K> + bool contains(const K& k) const; // C++20 pair<iterator, iterator> equal_range(const key_type& k); pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + template<typename K> + pair<iterator, iterator> equal_range(const K& k); // C++20 + template<typename K> + pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); @@ -355,10 +367,22 @@ public: iterator find(const key_type& k); const_iterator find(const key_type& k) const; + template<typename K> + iterator find(const K& x); // C++20 + template<typename K> + const_iterator find(const K& x) const; // C++20 size_type count(const key_type& k) const; + template<typename K> + size_type count(const K& k) const; // C++20 bool contains(const key_type& k) const; // C++20 + template<typename K> + bool contains(const K& k) const; // C++20 pair<iterator, iterator> equal_range(const key_type& k); pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + template<typename K> + pair<iterator, iterator> equal_range(const K& k); // C++20 + template<typename K> + pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; @@ -423,7 +447,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Key, class _Cp, class _Hash, +template <class _Key, class _Cp, class _Hash, class _Pred, bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> class __unordered_map_hasher : private _Hash @@ -445,6 +469,12 @@ public: _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return static_cast<const _Hash&>(*this)(__x);} +#if _LIBCPP_STD_VER > 17 + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const _K2& __x) const + {return static_cast<const _Hash&>(*this)(__x);} +#endif void swap(__unordered_map_hasher&__y) _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value) { @@ -453,8 +483,8 @@ public: } }; -template <class _Key, class _Cp, class _Hash> -class __unordered_map_hasher<_Key, _Cp, _Hash, false> +template <class _Key, class _Cp, class _Hash, class _Pred> +class __unordered_map_hasher<_Key, _Cp, _Hash, _Pred, false> { _Hash __hash_; public: @@ -474,6 +504,12 @@ public: _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return __hash_(__x);} +#if _LIBCPP_STD_VER > 17 + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const _K2& __x) const + {return __hash_(__x);} +#endif void swap(__unordered_map_hasher&__y) _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value) { @@ -482,17 +518,17 @@ public: } }; -template <class _Key, class _Cp, class _Hash, bool __b> +template <class _Key, class _Cp, class _Hash, class _Pred, bool __b> inline _LIBCPP_INLINE_VISIBILITY void -swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x, - __unordered_map_hasher<_Key, _Cp, _Hash, __b>& __y) +swap(__unordered_map_hasher<_Key, _Cp, _Hash, _Pred, __b>& __x, + __unordered_map_hasher<_Key, _Cp, _Hash, _Pred, __b>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } -template <class _Key, class _Cp, class _Pred, +template <class _Key, class _Cp, class _Pred, class _Hash, bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value> class __unordered_map_equal : private _Pred @@ -517,6 +553,24 @@ public: _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);} +#if _LIBCPP_STD_VER > 17 + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Cp& __x, const _K2& __y) const + {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y);} + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _K2& __x, const _Cp& __y) const + {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);} + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Key& __x, const _K2& __y) const + {return static_cast<const _Pred&>(*this)(__x, __y);} + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _K2& __x, const _Key& __y) const + {return static_cast<const _Pred&>(*this)(__x, __y);} +#endif void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { @@ -525,8 +579,8 @@ public: } }; -template <class _Key, class _Cp, class _Pred> -class __unordered_map_equal<_Key, _Cp, _Pred, false> +template <class _Key, class _Cp, class _Pred, class _Hash> +class __unordered_map_equal<_Key, _Cp, _Pred, _Hash, false> { _Pred __pred_; public: @@ -549,6 +603,24 @@ public: _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const {return __pred_(__x, __y.__get_value().first);} +#if _LIBCPP_STD_VER > 17 + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Cp& __x, const _K2& __y) const + {return __pred_(__x.__get_value().first, __y);} + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _K2& __x, const _Cp& __y) const + {return __pred_(__x, __y.__get_value().first);} + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _Key& __x, const _K2& __y) const + {return __pred_(__x, __y);} + template <typename _K2, typename = _EnableIf<__is_transparent<_Hash, _K2>::value && __is_transparent<_Pred, _K2>::value>> + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _K2& __x, const _Key& __y) const + {return __pred_(__x, __y);} +#endif void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { @@ -557,11 +629,11 @@ public: } }; -template <class _Key, class _Cp, class _Pred, bool __b> +template <class _Key, class _Cp, class _Pred, class _Hash, bool __b> inline _LIBCPP_INLINE_VISIBILITY void -swap(__unordered_map_equal<_Key, _Cp, _Pred, __b>& __x, - __unordered_map_equal<_Key, _Cp, _Pred, __b>& __y) +swap(__unordered_map_equal<_Key, _Cp, _Pred, _Hash, __b>& __x, + __unordered_map_equal<_Key, _Cp, _Pred, _Hash, __b>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); @@ -858,11 +930,11 @@ public: "Invalid allocator::value_type"); private: - typedef __hash_value_type<key_type, mapped_type> __value_type; - typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher; - typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal; + typedef __hash_value_type<key_type, mapped_type> __value_type; + typedef __unordered_map_hasher<key_type, __value_type, hasher, key_equal> __hasher; + typedef __unordered_map_equal<key_type, __value_type, key_equal, hasher> __key_equal; typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, - __value_type>::type __allocator_type; + __value_type>::type __allocator_type; typedef __hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table; @@ -1280,11 +1352,34 @@ public: iterator find(const key_type& __k) {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __table_.find(__k);} + + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, iterator> + find(const _K2& __k) {return __table_.find(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, const_iterator> + find(const _K2& __k) const {return __table_.find(__k);} + #endif // _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, size_type> + count(const _K2& __k) const {return __table_.__count_unique(__k);} + #endif // _LIBCPP_STD_VER > 17 #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 + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, bool> + contains(const _K2& __k) const {return find(__k) != end();} #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const key_type& __k) @@ -1292,6 +1387,16 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {return __table_.__equal_range_unique(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<iterator, iterator>> + equal_range(const _K2& __k) {return __table_.__equal_range_unique(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<const_iterator, const_iterator>> + equal_range(const _K2& __k) const {return __table_.__equal_range_unique(__k);} + #endif // _LIBCPP_STD_VER > 17 mapped_type& operator[](const key_type& __k); #ifndef _LIBCPP_CXX03_LANG @@ -1762,11 +1867,11 @@ public: "Invalid allocator::value_type"); private: - typedef __hash_value_type<key_type, mapped_type> __value_type; - typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher; - typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal; + typedef __hash_value_type<key_type, mapped_type> __value_type; + typedef __unordered_map_hasher<key_type, __value_type, hasher, key_equal> __hasher; + typedef __unordered_map_equal<key_type, __value_type, key_equal, hasher> __key_equal; typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, - __value_type>::type __allocator_type; + __value_type>::type __allocator_type; typedef __hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table; @@ -2059,11 +2164,32 @@ public: iterator find(const key_type& __k) {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __table_.find(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, iterator> + find(const _K2& __k) {return __table_.find(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, const_iterator> + find(const _K2& __k) const {return __table_.find(__k);} + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, size_type> + count(const _K2& __k) const {return __table_.__count_multi(__k);} + #endif // _LIBCPP_STD_VER > 17 #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 + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, bool> + contains(const _K2& __k) const {return find(__k) != end();} #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const key_type& __k) @@ -2071,6 +2197,16 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {return __table_.__equal_range_multi(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<iterator, iterator>> + equal_range(const _K2& __k) {return __table_.__equal_range_multi(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<const_iterator, const_iterator>> + equal_range(const _K2& __k) const {return __table_.__equal_range_multi(__k);} + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index da4beb176d2a..80f460d7edaa 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -145,10 +145,22 @@ public: iterator find(const key_type& k); const_iterator find(const key_type& k) const; + template<typename K> + iterator find(const K& x); // C++20 + template<typename K> + const_iterator find(const K& x) const; // C++20 size_type count(const key_type& k) const; + template<typename K> + size_type count(const K& k) const; // C++20 bool contains(const key_type& k) const; // C++20 + template<typename K> + bool contains(const K& k) const; // C++20 pair<iterator, iterator> equal_range(const key_type& k); pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + template<typename K> + pair<iterator, iterator> equal_range(const K& k); // C++20 + template<typename K> + pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; @@ -310,10 +322,22 @@ public: iterator find(const key_type& k); const_iterator find(const key_type& k) const; + template<typename K> + iterator find(const K& x); // C++20 + template<typename K> + const_iterator find(const K& x) const; // C++20 size_type count(const key_type& k) const; + template<typename K> + size_type count(const K& k) const; // C++20 bool contains(const key_type& k) const; // C++20 + template<typename K> + bool contains(const K& k) const; // C++20 pair<iterator, iterator> equal_range(const key_type& k); pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + template<typename K> + pair<iterator, iterator> equal_range(const K& k); // C++20 + template<typename K> + pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20 size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; @@ -679,11 +703,32 @@ public: iterator find(const key_type& __k) {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __table_.find(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, iterator> + find(const _K2& __k) {return __table_.find(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, const_iterator> + find(const _K2& __k) const {return __table_.find(__k);} + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, size_type> + count(const _K2& __k) const {return __table_.__count_unique(__k);} + #endif // _LIBCPP_STD_VER > 17 #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 + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, bool> + contains(const _K2& __k) const {return find(__k) != end();} #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const key_type& __k) @@ -691,6 +736,16 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {return __table_.__equal_range_unique(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<iterator, iterator>> + equal_range(const _K2& __k) {return __table_.__equal_range_unique(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<const_iterator, const_iterator>> + equal_range(const _K2& __k) const {return __table_.__equal_range_unique(__k);} + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} @@ -1314,11 +1369,32 @@ public: iterator find(const key_type& __k) {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __table_.find(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, iterator> + find(const _K2& __k) {return __table_.find(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, const_iterator> + find(const _K2& __k) const {return __table_.find(__k);} + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, size_type> + count(const _K2& __k) const {return __table_.__count_multi(__k);} + #endif // _LIBCPP_STD_VER > 17 #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 + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, bool> + contains(const _K2& __k) const {return find(__k) != end();} #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const key_type& __k) @@ -1326,6 +1402,16 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {return __table_.__equal_range_multi(__k);} + #if _LIBCPP_STD_VER > 17 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<iterator, iterator>> + equal_range(const _K2& __k) {return __table_.__equal_range_multi(__k);} + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<const_iterator, const_iterator>> + equal_range(const _K2& __k) const {return __table_.__equal_range_multi(__k);} + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} diff --git a/libcxx/include/version b/libcxx/include/version index 3355e2d18c56..1f05f3a851cc 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -260,7 +260,7 @@ __cpp_lib_void_t 201411L <type_traits> # endif # define __cpp_lib_endian 201907L # define __cpp_lib_erase_if 202002L -// # define __cpp_lib_generic_unordered_lookup 201811L +# define __cpp_lib_generic_unordered_lookup 201811L # define __cpp_lib_interpolate 201902L # if !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) # define __cpp_lib_is_constant_evaluated 201811L diff --git a/libcxx/test/std/containers/unord/unord.map/contains.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.map/contains.transparent.pass.cpp new file mode 100644 index 000000000000..5d3b5cecfbdf --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/contains.transparent.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_map + +// template <typename K> +// bool contains(const K& x) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, std::equal_to<> >; + test_transparent_contains<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash_final, transparent_equal_final>; + test_transparent_contains<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_contains<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/count.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.map/count.transparent.pass.cpp new file mode 100644 index 000000000000..07276c25fe7c --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/count.transparent.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_map + +// template <typename K> +// size_type count(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, std::equal_to<> >; + test_transparent_count<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = + const unord_map_type<std::unordered_map, transparent_hash_final, transparent_equal_final>; + test_transparent_count<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, std::equal_to<> >; + test_non_transparent_count<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = + const unord_map_type<std::unordered_map, transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = + const unord_map_type<std::unordered_map, non_transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/equal_range_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.map/equal_range_const.transparent.pass.cpp new file mode 100644 index 000000000000..9e76f72081ed --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/equal_range_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_map + +// template <typename K> +// pair<const_iterator, const_iterator> equal_range(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/equal_range_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.map/equal_range_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..97db1dcecc1e --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/equal_range_non_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_map + +// template <typename K> +// pair<iterator, iterator> equal_range(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = unord_map_type<std::unordered_map, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/find_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.map/find_const.transparent.pass.cpp new file mode 100644 index 000000000000..cc9324f28190 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/find_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_map + +// template <typename K> +// const_iterator find(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<> >; + test_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = const unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = const unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/find_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.map/find_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..b4233a8333d1 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/find_non_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_map + +// template <typename K> +// iterator find(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<> >; + test_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = unord_map_type<std::unordered_map, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = unord_map_type<std::unordered_map, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = unord_map_type<std::unordered_map, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/contains.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/contains.transparent.pass.cpp new file mode 100644 index 000000000000..2f07bcd37fa0 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/contains.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multimap + +// template <typename K> +// bool contains(const K& x) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<> >; + test_transparent_contains<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash_final, transparent_equal_final>; + test_transparent_contains<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_contains<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<map_type>( + ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<map_type>( + ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/count.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/count.transparent.pass.cpp new file mode 100644 index 000000000000..7abf662982f6 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/count.transparent.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multimap + +// template <typename K> +// size_type count(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash, std::equal_to<> >; + test_transparent_count<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = + const unord_map_type<std::unordered_multimap, transparent_hash_final, transparent_equal_final>; + test_transparent_count<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_multimap, non_transparent_hash, std::equal_to<> >; + test_non_transparent_count<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = + const unord_map_type<std::unordered_multimap, transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = + const unord_map_type<std::unordered_multimap, non_transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/equal_range_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/equal_range_const.transparent.pass.cpp new file mode 100644 index 000000000000..2444e9ca9dc4 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/equal_range_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multimap + +// template <typename K> +// pair<const_iterator, const_iterator> equal_range(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/equal_range_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/equal_range_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..a4c7730fd85f --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/equal_range_non_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multimap + +// template <typename K> +// pair<iterator, iterator> equal_range(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/find_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/find_const.transparent.pass.cpp new file mode 100644 index 000000000000..3737866cf4e0 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/find_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multimap + +// template <typename K> +// const_iterator find(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<> >; + test_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = const unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = const unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = const unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/find_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/find_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..676c82a3bab1 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/find_non_const.transparent.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_map> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multimap + +// template <typename K> +// iterator find(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_map> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + using ilist_type = std::initializer_list<std::pair<const key_type, int> >; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<> >; + test_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using map_type = unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using map_type = unord_map_type<std::unordered_multimap, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using map_type = unord_map_type<std::unordered_multimap, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<map_type>(ilist_type{{1, 2}, {1, 3}, {2, 3}}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/contains.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/contains.transparent.pass.cpp new file mode 100644 index 000000000000..0256d71c4690 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/contains.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_multiset + +// template <typename K> +// bool contains(const K& x) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<> >; + test_transparent_contains<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash_final, transparent_equal_final>; + test_transparent_contains<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_contains<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<set_type>( + key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<set_type>( + key_type{1}, key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/count.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/count.transparent.pass.cpp new file mode 100644 index 000000000000..a56a12a902c1 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/count.transparent.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multiset + +// template <typename K> +// size_type count(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash, std::equal_to<> >; + test_transparent_count<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = + const unord_set_type<std::unordered_multiset, transparent_hash_final, transparent_equal_final>; + test_transparent_count<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_multiset, non_transparent_hash, std::equal_to<> >; + test_non_transparent_count<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = + const unord_set_type<std::unordered_multiset, transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = + const unord_set_type<std::unordered_multiset, non_transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/equal_range_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/equal_range_const.transparent.pass.cpp new file mode 100644 index 000000000000..991ffcd30dee --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/equal_range_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multiset + +// template <typename K> +// pair<const_iterator, const_iterator> equal_range(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/equal_range_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/equal_range_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..dc84dc6a50c8 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/equal_range_non_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multiset + +// template <typename K> +// pair<iterator, iterator> equal_range(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/find_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/find_const.transparent.pass.cpp new file mode 100644 index 000000000000..c3a765462514 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/find_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multiset + +// template <typename K> +// const_iterator find(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<> >; + test_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = const unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = const unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/find_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/find_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..3255c8c6ab4f --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/find_non_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_multiset + +// template <typename K> +// iterator find(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<> >; + test_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = unord_set_type<std::unordered_multiset, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = unord_set_type<std::unordered_multiset, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.set/contains.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.set/contains.transparent.pass.cpp new file mode 100644 index 000000000000..6adf6ab4313e --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/contains.transparent.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_multiset + +// template <typename K> +// bool contains(const K& x) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, std::equal_to<> >; + test_transparent_contains<set_type>(key_type(1), key_type(2)); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash_final, transparent_equal_final>; + test_transparent_contains<set_type>(key_type(1), key_type(2)); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_contains<set_type>(key_type(1), key_type(2)); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<set_type>(key_type(1), key_type(2)); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_contains<set_type>(key_type(1), key_type(2)); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.set/count.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.set/count.transparent.pass.cpp new file mode 100644 index 000000000000..277308ea5323 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/count.transparent.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_set + +// template <typename K> +// size_type count(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, std::equal_to<> >; + test_transparent_count<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = + const unord_set_type<std::unordered_set, transparent_hash_final, transparent_equal_final>; + test_transparent_count<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, std::equal_to<> >; + test_non_transparent_count<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = + const unord_set_type<std::unordered_set, transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = + const unord_set_type<std::unordered_set, non_transparent_hash, std::equal_to<key_type> >; + test_non_transparent_count<set_type>(key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.set/equal_range_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.set/equal_range_const.transparent.pass.cpp new file mode 100644 index 000000000000..0c3f18bb4382 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/equal_range_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_set + +// template <typename K> +// pair<const_iterator, const_iterator> equal_range(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.set/equal_range_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.set/equal_range_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..452d15d7b0c9 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/equal_range_non_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_set + +// template <typename K> +// pair<iterator, iterator> equal_range(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<> >; + test_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = unord_set_type<std::unordered_set, transparent_hash_final, + transparent_equal_final>; + test_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_equal_range<set_type>(key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.set/find_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.set/find_const.transparent.pass.cpp new file mode 100644 index 000000000000..6256ef35f5a8 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/find_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_set + +// template <typename K> +// const_iterator find(const K& k) const; + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<> >; + test_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = const unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = const unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.set/find_non_const.transparent.pass.cpp b/libcxx/test/std/containers/unord/unord.set/find_non_const.transparent.pass.cpp new file mode 100644 index 000000000000..7fa3508ae09e --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/find_non_const.transparent.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, +// class Alloc = allocator<pair<const Key, T>>> +// class unordered_set + +// template <typename K> +// iterator find(const K& k); + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +#include <unordered_set> + +#include "test_transparent_unordered.h" + +int main(int, char**) +{ + using key_type = StoredType<int>; + + { + // Make sure conversions don't happen for transparent non-final hasher and key_equal + using set_type = unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<> >; + test_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions don't happen for transparent final hasher and key_equal + using set_type = unord_set_type<std::unordered_set, transparent_hash_final, + transparent_equal_final>; + test_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent hasher + using set_type = unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for non-transparent key_equal + using set_type = unord_set_type<std::unordered_set, transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + { + // Make sure conversions do happen for both non-transparent hasher and key_equal + using set_type = unord_set_type<std::unordered_set, non_transparent_hash, + std::equal_to<key_type> >; + test_non_transparent_find<set_type>(key_type{1}, key_type{2}); + } + + return 0; +} diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp index 62c974add1ba..a3365f40b9bb 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp @@ -131,17 +131,11 @@ # error "__cpp_lib_erase_if should have the value 202002L in c++2a" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a" # endif # ifndef __cpp_lib_node_extract diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp index 6fe59790857b..1cd59235ab82 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp @@ -115,17 +115,11 @@ # error "__cpp_lib_erase_if should have the value 202002L in c++2a" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a" # endif # ifndef __cpp_lib_node_extract diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index 86579298afdb..c625753ca2bd 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -1992,17 +1992,11 @@ # error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++2a" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a" # endif # if !defined(_LIBCPP_VERSION) diff --git a/libcxx/test/support/is_transparent.h b/libcxx/test/support/is_transparent.h index 667877526efe..9088ab67d31b 100644 --- a/libcxx/test/support/is_transparent.h +++ b/libcxx/test/support/is_transparent.h @@ -11,6 +11,8 @@ #include "test_macros.h" +#include <functional> // for std::equal_to + // testing transparent #if TEST_STD_VER > 11 @@ -79,6 +81,87 @@ bool operator <(int rhs, const C2Int& lhs) { return rhs < lhs.g bool operator <(const C2Int& rhs, const C2Int& lhs) { return rhs.get() < lhs.get(); } bool operator <(const C2Int& rhs, int lhs) { return rhs.get() < lhs; } -#endif +#endif // TEST_STD_VER > 11 + +#if TEST_STD_VER > 17 + +template <typename T> +struct StoredType; + +template <typename T> +struct SearchedType; + +struct hash_impl { + template <typename T> + constexpr std::size_t operator()(SearchedType<T> const& t) const { + return static_cast<std::size_t>(t.get_value()); + } + + template <typename T> + constexpr std::size_t operator()(StoredType<T> const& t) const { + return static_cast<std::size_t>(t.get_value()); + } +}; + +struct non_transparent_hash : hash_impl {}; + +struct transparent_hash : hash_impl { + using is_transparent = void; +}; + +struct transparent_hash_final final : transparent_hash {}; + +struct transparent_equal_final final : std::equal_to<> {}; + +template <typename T> +struct SearchedType { + SearchedType(T value, int* counter) : value_(value), conversions_(counter) { } + + // Whenever a conversion is performed, increment the counter to keep track + // of conversions. + operator StoredType<T>() const { + ++*conversions_; + return StoredType<T>{value_}; + } + + int get_value() const { + return value_; + } + +private: + T value_; + int* conversions_; +}; + +template <typename T> +struct StoredType { + StoredType() = default; + StoredType(T value) : value_(value) { } + + friend bool operator==(StoredType const& lhs, StoredType const& rhs) { + return lhs.value_ == rhs.value_; + } + + // If we're being passed a SearchedType<T> object, avoid the conversion + // to T. This allows testing that the transparent operations are correctly + // forwarding the SearchedType all the way to this comparison by checking + // that we didn't have a conversion when we search for a SearchedType<T> + // in a container full of StoredType<T>. + friend bool operator==(StoredType const& lhs, SearchedType<T> const& rhs) { + return lhs.value_ == rhs.get_value(); + } + friend bool operator==(SearchedType<T> const& lhs, StoredType<T> const& rhs) { + return lhs.get_value() == rhs.value_; + } + + int get_value() const { + return value_; + } + +private: + T value_; +}; + +#endif // TEST_STD_VER > 17 #endif // TRANSPARENT_H diff --git a/libcxx/test/support/test_transparent_unordered.h b/libcxx/test/support/test_transparent_unordered.h new file mode 100644 index 000000000000..7bcbc19c05a8 --- /dev/null +++ b/libcxx/test/support/test_transparent_unordered.h @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_TRANSPARENT_UNORDERED_H +#define TEST_TRANSPARENT_UNORDERED_H + +#include "test_macros.h" +#include "is_transparent.h" + +#include <cassert> + +// testing transparent unordered containers +#if TEST_STD_VER > 17 + +template <template <typename...> class UnorderedSet, typename Hash, + typename Equal> +using unord_set_type = UnorderedSet<StoredType<int>, Hash, Equal>; + +template <template <typename...> class UnorderedMap, typename Hash, + typename Equal> +using unord_map_type = UnorderedMap<StoredType<int>, int, Hash, Equal>; + +template <typename Container, typename... Args> +void test_transparent_find(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + assert(c.find(SearchedType<int>(1, &conversions)) != c.end()); + assert(c.find(SearchedType<int>(2, &conversions)) != c.end()); + assert(conversions == 0); + assert(c.find(SearchedType<int>(3, &conversions)) == c.end()); + assert(conversions == 0); +} + +template <typename Container, typename... Args> +void test_non_transparent_find(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + assert(c.find(SearchedType<int>(1, &conversions)) != c.end()); + assert(conversions > 0); + conversions = 0; + assert(c.find(SearchedType<int>(2, &conversions)) != c.end()); + assert(conversions > 0); + conversions = 0; + assert(c.find(SearchedType<int>(3, &conversions)) == c.end()); + assert(conversions > 0); +} + +template <typename Container, typename... Args> +void test_transparent_count(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + assert(c.count(SearchedType<int>(1, &conversions)) > 0); + assert(c.count(SearchedType<int>(2, &conversions)) > 0); + assert(conversions == 0); + assert(c.count(SearchedType<int>(3, &conversions)) == 0); + assert(conversions == 0); +} + +template <typename Container, typename... Args> +void test_non_transparent_count(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + assert(c.count(SearchedType<int>(1, &conversions)) > 0); + assert(conversions > 0); + conversions = 0; + assert(c.count(SearchedType<int>(2, &conversions)) > 0); + assert(conversions > 0); + conversions = 0; + assert(c.count(SearchedType<int>(3, &conversions)) == 0); + assert(conversions > 0); +} + +template <typename Container, typename... Args> +void test_transparent_contains(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + assert(c.contains(SearchedType<int>(1, &conversions))); + assert(c.contains(SearchedType<int>(2, &conversions))); + assert(conversions == 0); + assert(!c.contains(SearchedType<int>(3, &conversions))); + assert(conversions == 0); +} + +template <typename Container, typename... Args> +void test_non_transparent_contains(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + assert(c.contains(SearchedType<int>(1, &conversions))); + assert(conversions > 0); + conversions = 0; + assert(c.contains(SearchedType<int>(2, &conversions))); + assert(conversions > 0); + conversions = 0; + assert(!c.contains(SearchedType<int>(3, &conversions))); + assert(conversions > 0); +} + +template <typename Container, typename... Args> +void test_transparent_equal_range(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + auto iters = c.equal_range(SearchedType<int>(1, &conversions)); + assert(std::distance(iters.first, iters.second) > 0); + iters = c.equal_range(SearchedType<int>(2, &conversions)); + assert(std::distance(iters.first, iters.second) > 0); + assert(conversions == 0); + iters = c.equal_range(SearchedType<int>(3, &conversions)); + assert(std::distance(iters.first, iters.second) == 0); + assert(conversions == 0); +} + +template <typename Container, typename... Args> +void test_non_transparent_equal_range(Args&&... args) { + Container c{std::forward<Args>(args)...}; + int conversions = 0; + auto iters = c.equal_range(SearchedType<int>(1, &conversions)); + assert(std::distance(iters.first, iters.second) > 0); + assert(conversions > 0); + conversions = 0; + iters = c.equal_range(SearchedType<int>(2, &conversions)); + assert(std::distance(iters.first, iters.second) > 0); + assert(conversions > 0); + conversions = 0; + iters = c.equal_range(SearchedType<int>(3, &conversions)); + assert(std::distance(iters.first, iters.second) == 0); + assert(conversions > 0); +} + +#endif // TEST_STD_VER > 17 + +#endif // TEST_TRANSPARENT_UNORDERED_H diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 6fef8ea85606..06eb57d8b3fc 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -393,7 +393,6 @@ feature_test_macros = sorted([ add_version_header(x) for x in [ "name": "__cpp_lib_generic_unordered_lookup", "values": { "c++2a": int(201811) }, "headers": ["unordered_map", "unordered_set"], - "unimplemented": True, }, { "name": "__cpp_lib_ranges", "values": { "c++2a": int(201811) }, diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html index a038ef4c1f0a..254eb9a05d38 100644 --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -120,7 +120,7 @@ <tr><td><a href="https://wg21.link/P0771R1">P0771R1</a></td><td>LWG</td><td>std::function move constructor should be noexcept</td><td>San Diego</td><td>Complete</td><td>6.0</td></tr> <tr><td><a href="https://wg21.link/P0896R4">P0896R4</a></td><td>LWG</td><td>The One Ranges Proposal</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0899R1">P0899R1</a></td><td>LWG</td><td>P0899R1 - LWG 3016 is not a defect</td><td>San Diego</td><td><i>Nothing to do</i></td><td></td></tr> - <tr><td><a href="https://wg21.link/P0919R3">P0919R3</a></td><td>LWG</td><td>Heterogeneous lookup for unordered containers</td><td>San Diego</td><td><i> </i></td><td></td></tr> + <tr><td><a href="https://wg21.link/P0919R3">P0919R3</a></td><td>LWG</td><td>Heterogeneous lookup for unordered containers</td><td>San Diego</td><td>Complete</td><td>12.0</td></tr> <tr><td><a href="https://wg21.link/P0972R0">P0972R0</a></td><td>LWG</td><td><chrono> <tt>zero()</tt>, <tt>min()</tt>, and <tt>max()</tt> should be noexcept</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P1006R1">P1006R1</a></td><td>LWG</td><td>Constexpr in std::pointer_traits</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P1007R3">P1007R3</a></td><td>LWG</td><td><tt>std::assume_aligned</tt></td><td>San Diego</td><td><i> </i></td><td></td></tr> @@ -201,7 +201,7 @@ <tr><td><a href="https://wg21.link/P1645">P1645</a></td><td>LWG</td><td>constexpr for numeric algorithms </td><td>Belfast</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1664">P1664</a></td><td>LWG</td><td>reconstructible_range - a concept for putting ranges back together </td><td>Belfast</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1686">P1686</a></td><td>LWG</td><td>Mandating the Standard Library: Clause 27 - Time library </td><td>Belfast</td><td><i> </i></td><td></td></tr> - <tr><td><a href="https://wg21.link/P1690">P1690</a></td><td>LWG</td><td>Refinement Proposal for P0919 Heterogeneous lookup for unordered containers </td><td>Belfast</td><td><i> </i></td><td></td></tr> + <tr><td><a href="https://wg21.link/P1690">P1690</a></td><td>LWG</td><td>Refinement Proposal for P0919 Heterogeneous lookup for unordered containers </td><td>Belfast</td><td>Complete</td><td>12.0</td></tr> <tr><td><a href="https://wg21.link/P1716">P1716</a></td><td>LWG</td><td>ranges compare algorithm are over-constrained </td><td>Belfast</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1718">P1718</a></td><td>LWG</td><td>Mandating the Standard Library: Clause 25 - Algorithms library </td><td>Belfast</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P1719">P1719</a></td><td>LWG</td><td>Mandating the Standard Library: Clause 26 - Numerics library </td><td>Belfast</td><td><i> </i></td><td></td></tr>