Hi, tested x86_64-linux, committed to mainline (see audit trail for details)
Thanks, Paolo. /////////////////////////////
2012-05-15 Paolo Carlini <paolo.carl...@oracle.com> PR libstdc++/53339 * include/bits/hashtable_policy.h (__detail::_Identity, __detail::_Select1st): Add. (_Map_base, _Hashtable_base): Use the latter, adjust parameters. * include/bits/hashtable.h (_Hashtable::__key_extract): Adjust. * include/bits/unordered_set.h (__uset_hashtable, __umset_hashtable): Likewise. * include/bits/unordered_map.h (__umap_hashtable, __ummap_hashtable): Likewise. * include/bits/stl_function.h (_Identity, _Select1st, _Select2nd) Unconditionally derive from unary_function. * include/ext/functional (identity, select1st, select2nd): Remove #ifdef __GXX_EXPERIMENTAL_CXX0X__ bits. * testsuite/23_containers/unordered_map/requirements/53339.cc: New. * testsuite/23_containers/unordered_multimap/requirements/ 53339.cc: Likewise.
Index: include/ext/functional =================================================================== --- include/ext/functional (revision 187501) +++ include/ext/functional (working copy) @@ -184,12 +184,7 @@ */ template <class _Tp> struct identity -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - : public std::unary_function<_Tp,_Tp>, - public std::_Identity<_Tp> {}; -#else : public std::_Identity<_Tp> {}; -#endif /** @c select1st and @c select2nd are extensions provided by SGI. Their * @c operator()s @@ -204,22 +199,13 @@ /// An \link SGIextensions SGI extension \endlink. template <class _Pair> struct select1st -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - : public std::unary_function<_Pair, typename _Pair::first_type>, - public std::_Select1st<_Pair> {}; -#else : public std::_Select1st<_Pair> {}; -#endif /// An \link SGIextensions SGI extension \endlink. template <class _Pair> struct select2nd -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - : public std::unary_function<_Pair, typename _Pair::second_type>, - public std::_Select2nd<_Pair> {}; -#else : public std::_Select2nd<_Pair> {}; -#endif + /** @} */ // extension documented next Index: include/bits/hashtable.h =================================================================== --- include/bits/hashtable.h (revision 187501) +++ include/bits/hashtable.h (working copy) @@ -203,8 +203,8 @@ using __key_extract = typename std::conditional< __constant_iterators::value, - std::_Identity<value_type>, - std::_Select1st<value_type>>::type; + __detail::_Identity, + __detail::_Select1st>::type; using __hashtable_base = __detail:: _Hashtable_base<_Key, _Value, _ExtractKey, Index: include/bits/hashtable_policy.h =================================================================== --- include/bits/hashtable_policy.h (revision 187501) +++ include/bits/hashtable_policy.h (working copy) @@ -86,6 +86,23 @@ noexcept(declval<const _Hash&>()(declval<const _Key&>()))> { }; + struct _Identity + { + template<typename _Tp> + _Tp&& + operator()(_Tp&& __x) const + { return std::forward<_Tp>(__x); } + }; + + struct _Select1st + { + template<typename _Tp> + auto + operator()(_Tp&& __x) const + -> decltype(std::get<0>(std::forward<_Tp>(__x))) + { return std::get<0>(std::forward<_Tp>(__x)); } + }; + // Auxiliary types used for all instantiations of _Hashtable nodes // and iterators. @@ -497,27 +514,27 @@ template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> - struct _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, false> { - using mapped_type = typename _Pair::second_type; + using mapped_type = typename std::tuple_element<1, _Pair>::type; }; /// Partial specialization, __unique_keys set to true. template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> - struct _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> { private: using __hashtable_base = __detail::_Hashtable_base<_Key, _Pair, - std::_Select1st<_Pair>, + _Select1st, _Equal, _H1, _H2, _Hash, _Traits>; using __hashtable = _Hashtable<_Key, _Pair, _Alloc, - std::_Select1st<_Pair>, _Equal, + _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __hash_code = typename __hashtable_base::__hash_code; @@ -526,7 +543,7 @@ public: using key_type = typename __hashtable_base::key_type; using iterator = typename __hashtable_base::iterator; - using mapped_type = typename _Pair::second_type; + using mapped_type = typename std::tuple_element<1, _Pair>::type; mapped_type& operator[](const key_type& __k); @@ -546,10 +563,10 @@ template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> - typename _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> ::mapped_type& - _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: operator[](const key_type& __k) { @@ -567,10 +584,10 @@ template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> - typename _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> ::mapped_type& - _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: operator[](key_type&& __k) { @@ -589,10 +606,10 @@ template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> - typename _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> ::mapped_type& - _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: at(const key_type& __k) { @@ -609,11 +626,10 @@ template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> - const typename _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, - _Equal, - _H1, _H2, _Hash, _RehashPolicy, _Traits, true> - ::mapped_type& - _Map_base<_Key, _Pair, _Alloc, std::_Select1st<_Pair>, _Equal, + const typename _Map_base<_Key, _Pair, _Alloc, _Select1st, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + _Traits, true>::mapped_type& + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: at(const key_type& __k) const { @@ -1492,8 +1508,7 @@ iterator>::type; using __iconv_type = typename std::conditional<__unique_keys::value, - std::_Select1st<__ireturn_type>, - std::_Identity<__ireturn_type> + _Select1st, _Identity >::type; private: using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>; Index: include/bits/unordered_map.h =================================================================== --- include/bits/unordered_map.h (revision 187501) +++ include/bits/unordered_map.h (working copy) @@ -45,12 +45,11 @@ typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >, typename _Tr = __umap_traits<__cache_default<_Key, _Hash>::value>> using __umap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>, - _Alloc, - std::_Select1st<std::pair<const _Key, _Tp>>, - _Pred, _Hash, - __detail::_Mod_range_hashing, - __detail::_Default_ranged_hash, - __detail::_Prime_rehash_policy, _Tr>; + _Alloc, __detail::_Select1st, + _Pred, _Hash, + __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, _Tr>; /// Base types for unordered_multimap. template<bool _Cache> @@ -63,8 +62,7 @@ typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >, typename _Tr = __ummap_traits<__cache_default<_Key, _Hash>::value>> using __ummap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>, - _Alloc, - std::_Select1st<std::pair<const _Key, _Tp>>, + _Alloc, __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, Index: include/bits/unordered_set.h =================================================================== --- include/bits/unordered_set.h (revision 187501) +++ include/bits/unordered_set.h (working copy) @@ -44,7 +44,7 @@ typename _Alloc = std::allocator<_Value>, typename _Tr = __uset_traits<__cache_default<_Value, _Hash>::value>> using __uset_hashtable = _Hashtable<_Value, _Value, _Alloc, - std::_Identity<_Value>, _Pred, _Hash, + __detail::_Identity, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, _Tr>; @@ -59,7 +59,7 @@ typename _Alloc = std::allocator<_Value>, typename _Tr = __umset_traits<__cache_default<_Value, _Hash>::value>> using __umset_hashtable = _Hashtable<_Value, _Value, _Alloc, - std::_Identity<_Value>, + __detail::_Identity, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, Index: include/bits/stl_function.h =================================================================== --- include/bits/stl_function.h (revision 187501) +++ include/bits/stl_function.h (working copy) @@ -473,11 +473,7 @@ template<typename _Tp> struct _Identity -#ifndef __GXX_EXPERIMENTAL_CXX0X__ - // unary_function itself is deprecated in C++11 and deriving from - // it can even be a nuisance (see PR 52942). : public unary_function<_Tp,_Tp> -#endif { _Tp& operator()(_Tp& __x) const @@ -490,9 +486,7 @@ template<typename _Pair> struct _Select1st -#ifndef __GXX_EXPERIMENTAL_CXX0X__ : public unary_function<_Pair, typename _Pair::first_type> -#endif { typename _Pair::first_type& operator()(_Pair& __x) const @@ -517,9 +511,7 @@ template<typename _Pair> struct _Select2nd -#ifndef __GXX_EXPERIMENTAL_CXX0X__ : public unary_function<_Pair, typename _Pair::second_type> -#endif { typename _Pair::second_type& operator()(_Pair& __x) const Index: testsuite/23_containers/unordered_map/requirements/53339.cc =================================================================== --- testsuite/23_containers/unordered_map/requirements/53339.cc (revision 0) +++ testsuite/23_containers/unordered_map/requirements/53339.cc (revision 0) @@ -0,0 +1,34 @@ +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without Pred the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <unordered_map> + +struct LinkedHashMap +{ + struct Entry; + + typedef std::unordered_map<int, Entry> Storage; + typedef Storage::iterator EntryPtr; + + struct Entry + { + EntryPtr prev, next; + }; +}; Index: testsuite/23_containers/unordered_multimap/requirements/53339.cc =================================================================== --- testsuite/23_containers/unordered_multimap/requirements/53339.cc (revision 0) +++ testsuite/23_containers/unordered_multimap/requirements/53339.cc (revision 0) @@ -0,0 +1,34 @@ +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without Pred the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <unordered_map> + +struct LinkedHashMap +{ + struct Entry; + + typedef std::unordered_multimap<int, Entry> Storage; + typedef Storage::iterator EntryPtr; + + struct Entry + { + EntryPtr prev, next; + }; +};