diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index b4e8e4d3fb25a03f66b73f3d88f8edda71789163..efc155bdfa4b6e09218246fb91bc864009b18004 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -930,10 +930,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_insert_unique(_Kt&&, _Arg&&, _NodeGenerator&); template<typename _Kt> - static __conditional_t< - __and_<__is_nothrow_invocable<_Hash&, const key_type&>, - __not_<__is_nothrow_invocable<_Hash&, _Kt>>>::value, - key_type, _Kt&&> + key_type _S_forward_key(_Kt&& __k) { return std::forward<_Kt>(__k); } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc index 2065caab6c5c1082d9d89f7c0af6016ac8052d61..b5be7d06aa0348e2b667953109b2e5795fa65682 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc @@ -29,46 +29,45 @@ #include <testsuite_hooks.h> #include <replacement_memory_operators.h> -static constexpr std::initializer_list<std::pair<const char*, int>> lst = { - {"long_str_for_dynamic_allocating", 1} -}; +static constexpr std::initializer_list<std::pair<const char*, const char*>> lst = + { { "long_str_for_dynamic_allocation", "long_str_for_dynamic_allocation" } }; void test01() { __gnu_test::counter::reset(); - std::unordered_map<std::string, int> um; + std::unordered_map<std::string, std::string> um; um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 4 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } void test02() { __gnu_test::counter::reset(); - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, std::hash<std::string_view>, std::equal_to<std::string_view>> um; um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } std::size_t @@ -84,20 +83,20 @@ test11() typedef std::size_t (*hash_string_t)(const std::string&) noexcept; __gnu_test::counter::reset(); hash_string_t hasher = &hash_string_f; - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, hash_string_t, std::equal_to<std::string>> um(0, hasher); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 4 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } std::size_t @@ -113,19 +112,19 @@ test12() typedef std::size_t (*hash_stringview_t) (const std::string_view&) noexcept; __gnu_test::counter::reset(); hash_stringview_t hasher = &hash_string_view_f; - std::unordered_map<std::string, int, hash_stringview_t, + std::unordered_map<std::string, std::string, hash_stringview_t, std::equal_to<std::string_view>> um(0, hasher); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } struct hash_string_functor @@ -142,20 +141,20 @@ void test21() { __gnu_test::counter::reset(); - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, hash_string_functor, std::equal_to<std::string>> um; um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 4 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } struct hash_string_view_noexcept_functor @@ -172,20 +171,20 @@ void test22() { __gnu_test::counter::reset(); - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, hash_string_view_noexcept_functor, std::equal_to<std::string_view>> um; um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } struct hash_string_view_functor @@ -202,40 +201,41 @@ void test23() { __gnu_test::counter::reset(); - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, hash_string_view_functor, std::equal_to<std::string_view>> um; um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); um.insert(lst.begin(), lst.end()); VERIFY( um.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 5 ); } void test03() { - std::vector<std::pair<std::string, int>> v; + std::vector<std::pair<std::string, std::string>> v; v.insert(v.end(), lst.begin(), lst.end()); const auto origin = __gnu_test::counter::count(); { __gnu_test::counter::reset(); - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, std::hash<std::string_view>, std::equal_to<std::string_view>> um; um.insert(v.begin(), v.end()); VERIFY( um.size() == 1 ); - // Allocate array of buckets, a node, and the std::string (unless COW). - constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 3 : 2; + // Allocate array of buckets, a node, the std::string value and the + // std::string key (unless COW). + constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 4 : 3; VERIFY( __gnu_test::counter::count() == origin + increments ); VERIFY( __gnu_test::counter::get()._M_increments == increments ); @@ -250,7 +250,7 @@ test03() { __gnu_test::counter::reset(); - std::unordered_map<std::string, int, + std::unordered_map<std::string, std::string, std::hash<std::string_view>, std::equal_to<std::string_view>> um; um.insert(std::make_move_iterator(v.begin()), diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc index b1b33708cde8bb406d3dff68d3532fe295e9b7b7..562ec76e69744bbc1a2cb312168e09ca7e6a53e4 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc @@ -28,34 +28,33 @@ #include <testsuite_hooks.h> #include <replacement_memory_operators.h> -static constexpr std::initializer_list<std::pair<const char*, int>> lst = { - {"long_str_for_dynamic_allocating", 1} -}; +static constexpr std::initializer_list<std::pair<const char*, const char*>> lst = + { { "long_str_for_dynamic_allocation", "long_str_for_dynamic_allocation" } }; void test01() { __gnu_test::counter::reset(); - std::unordered_multimap<std::string, int, + std::unordered_multimap<std::string, std::string, std::hash<std::string_view>, std::equal_to<std::string_view>> foo; foo.insert(lst.begin(), lst.end()); VERIFY( foo.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); } void test02() { __gnu_test::counter::reset(); - std::unordered_multimap<std::string, int> foo; + std::unordered_multimap<std::string, std::string> foo; foo.insert(lst.begin(), lst.end()); VERIFY( foo.size() == 1 ); - VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::count() == 4 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); } int diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc index d525bd532beb9aaf77e1522dbb81152763f44435..1efd5be7f104d1c5411d8a661f66b6789e918bf0 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc @@ -28,9 +28,8 @@ #include <testsuite_hooks.h> #include <replacement_memory_operators.h> -static constexpr std::initializer_list<const char*> lst = { - "long_str_for_dynamic_allocating" -}; +static constexpr std::initializer_list<const char*> lst = + { "long_str_for_dynamic_allocation" }; void test01() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc index f9ef94eac5311c64bf427a7f10a4ef0392bd63c0..bc2f093f47c33dabb739815f423548e36d1838fe 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc @@ -29,9 +29,8 @@ #include <testsuite_hooks.h> #include <replacement_memory_operators.h> -static constexpr std::initializer_list<const char*> lst = { - "long_str_for_dynamic_allocating" -}; +static constexpr std::initializer_list<const char*> lst = + { "long_str_for_dynamic_allocation" }; void test01() @@ -68,7 +67,7 @@ test02() VERIFY( us.size() == 1 ); VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); } std::size_t @@ -126,7 +125,7 @@ test12() VERIFY( us.size() == 1 ); VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); } struct hash_string_functor @@ -186,7 +185,7 @@ test22() VERIFY( us.size() == 1 ); VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); } struct hash_string_view_functor @@ -216,7 +215,7 @@ test23() VERIFY( us.size() == 1 ); VERIFY( __gnu_test::counter::count() == 3 ); - VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + VERIFY( __gnu_test::counter::get()._M_increments == 4 ); } void @@ -245,7 +244,7 @@ test03() VERIFY( us.size() == 1 ); VERIFY( __gnu_test::counter::count() == origin + increments ); - VERIFY( __gnu_test::counter::get()._M_increments == increments ); + VERIFY( __gnu_test::counter::get()._M_increments == increments + 1 ); } VERIFY( __gnu_test::counter::count() == origin ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc new file mode 100644 index 0000000000000000000000000000000000000000..6c5cc24930ce294f7ba1b3630d3a8030d1193fa4 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc @@ -0,0 +1,40 @@ +// { dg-do run { target c++11 } } + +// libstdc++/115285 + +#include <string> +#include <unordered_set> + +#include <testsuite_hooks.h> + +class TrimmedStr : public std::string +{ + static std::string trim_str(std::string const &str) + { + auto start = str.find_first_not_of(" \r\n\t"); + + return start == std::string::npos + ? str + : str.substr(start, str.find_last_not_of(" \r\n\t") - start + 1); + } + +public: + TrimmedStr(std::string const &arg) + : std::string{trim_str(arg)} {} + TrimmedStr(char const *arg) + : TrimmedStr{std::string{arg}} {} +}; + +int main() +{ + std::unordered_set<TrimmedStr, std::hash<std::string>, std::equal_to<std::string>> + set_from_initializer_list{ "foo", "bar", " foo ", " bar " }; + + VERIFY( set_from_initializer_list.size() == 2 ); + + std::vector<std::string> args{ "foo", "bar", " foo ", " bar " }; + std::unordered_set<TrimmedStr, std::hash<std::string>, std::equal_to<std::string>> + set_from_iterators; + set_from_iterators.insert(args.begin(), args.end()); + VERIFY( set_from_iterators.size() == 2 ); +}