diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index cce4e2844cf..4a89d0ee1c8 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -125,15 +125,15 @@ namespace __detail { return std::forward<_Kt>(__k); } }; - template - struct _ConvertToValueType<_Select1st, _Value> + template + struct _ConvertToValueType<_Select1st, std::pair<_Key, _Value>> { - constexpr _Value&& - operator()(_Value&& __x) const noexcept + constexpr std::pair<_Key, _Value>&& + operator()(std::pair<_Key, _Value>&& __x) const noexcept { return std::move(__x); } - constexpr const _Value& - operator()(const _Value& __x) const noexcept + constexpr const std::pair<_Key, _Value>& + operator()(const std::pair<_Key, _Value>& __x) const noexcept { return __x; } template @@ -145,6 +145,26 @@ namespace __detail constexpr const std::pair<_Kt, _Val>& operator()(const std::pair<_Kt, _Val>& __x) const noexcept { return __x; } + + template + using __is_cons = std::is_constructible<_Key, _Kt&&>; + + template + using _IFcons = std::enable_if<__is_cons<_Kt>::value>; + + template + using _IFconsp = typename _IFcons<_Kt>::type; + + template> + std::pair<_Kt, _Value> + operator()(_Kt&& __kt) const + { + return { + std::piecewise_construct, + std::forward_as_tuple(std::forward<_Kt>(__kt)), + std::tuple<>() + }; + } }; template diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc index 754b529c67c..a3bf6ce5307 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc @@ -264,6 +264,28 @@ test03() } } +void +test04() +{ + const std::initializer_list strlst = + { "long_str_for_dynamic_allocating" }; + __gnu_test::counter::reset(); + std::unordered_map> um; + um.insert(strlst.begin(), strlst.end()); + VERIFY( um.size() == 1 ); + + VERIFY( __gnu_test::counter::count() == 3 ); + VERIFY( __gnu_test::counter::get()._M_increments == 3 ); + + um.insert(strlst.begin(), strlst.end()); + VERIFY( um.size() == 1 ); + + VERIFY( __gnu_test::counter::count() == 3 ); + VERIFY( __gnu_test::counter::get()._M_increments == 3 ); +} + int main() { @@ -274,5 +296,6 @@ main() test21(); test22(); test03(); + test04(); return 0; }