diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2009-11-19 16:55:25 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2009-11-19 16:55:25 +0000 |
commit | 4a85780b75143fa28bc26ce508eafa95c5f5b3e8 (patch) | |
tree | c2be9169ddada0db0f1c418fab39fb8d3c3ea0a6 /libstdc++-v3 | |
parent | d95ba652abbbfda10f29ca8b80c2126825a65eeb (diff) | |
download | gcc-4a85780b75143fa28bc26ce508eafa95c5f5b3e8.zip gcc-4a85780b75143fa28bc26ce508eafa95c5f5b3e8.tar.gz gcc-4a85780b75143fa28bc26ce508eafa95c5f5b3e8.tar.bz2 |
re PR libstdc++/41622 ([DR 1245] [c++0x] std::hash<std::string>::operator() copies its argument)
2009-11-19 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/41622
* include/bits/functional_hash.h: Implement inline the various
std::hash specializations, using, when appropriate, pass by
const ref too, per DR 1245.
* include/tr1_impl/functional_hash.h: Remove, move its contents...
* include/tr1/functional_hash.h: ... here.
* include/std/functional: Tweak includes.
* src/hash_c++0x: Rename to...
* src/compatibility-c++0x.cc: ... this, implementing compatibility
std::hash<>::operator() specializations.
* src/hash.cc: Do not mark specializations as throw().
* src/Makefile.am: Adjust.
* include/Makefile.am: Likewise.
* src/Makefile.in: Regenerate.
* include/Makefile.in: Likewise.
* testsuite/util/testsuite_api.h: Define a dummy hash for
NonDefaultConstructible.
* testsuite/23_containers/unordered_map/requirements/
explicit_instantiation/2.cc: Use it.
* testsuite/23_containers/unordered_multimap/requirements/
explicit_instantiation/2.cc: Likewise.
* testsuite/23_containers/unordered_set/requirements/
explicit_instantiation/2.cc: Likewise.
* testsuite/23_containers/unordered_multiset/requirements/
explicit_instantiation/2.cc: Likewise.
From-SVN: r154335
Diffstat (limited to 'libstdc++-v3')
16 files changed, 468 insertions, 257 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index db8246e..380b6d5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,31 @@ +2009-11-19 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/41622 + * include/bits/functional_hash.h: Implement inline the various + std::hash specializations, using, when appropriate, pass by + const ref too, per DR 1245. + * include/tr1_impl/functional_hash.h: Remove, move its contents... + * include/tr1/functional_hash.h: ... here. + * include/std/functional: Tweak includes. + * src/hash_c++0x: Rename to... + * src/compatibility-c++0x.cc: ... this, implementing compatibility + std::hash<>::operator() specializations. + * src/hash.cc: Do not mark specializations as throw(). + * src/Makefile.am: Adjust. + * include/Makefile.am: Likewise. + * src/Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/util/testsuite_api.h: Define a dummy hash for + NonDefaultConstructible. + * testsuite/23_containers/unordered_map/requirements/ + explicit_instantiation/2.cc: Use it. + * testsuite/23_containers/unordered_multimap/requirements/ + explicit_instantiation/2.cc: Likewise. + * testsuite/23_containers/unordered_set/requirements/ + explicit_instantiation/2.cc: Likewise. + * testsuite/23_containers/unordered_multiset/requirements/ + explicit_instantiation/2.cc: Likewise. + 2009-11-19 Johannes Singler <singler@kit.edu> * include/parallel/partition.h (__parallel_partition): Correctly @@ -8,7 +36,7 @@ 2009-11-17 Benjamin Kosnik <bkoz@redhat.com> * include/profile/impl/profiler.h: Remove namespace markup. - + 2009-11-17 Benjamin Kosnik <bkoz@redhat.com> * include/profile/bitset: Tweak doxygen markup. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 1cea8a2..47253e6 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -610,7 +610,6 @@ tr1_impl_headers = \ ${tr1_impl_srcdir}/cwchar \ ${tr1_impl_srcdir}/cwctype \ ${tr1_impl_srcdir}/functional \ - ${tr1_impl_srcdir}/functional_hash.h \ ${tr1_impl_srcdir}/hashtable \ ${tr1_impl_srcdir}/hashtable_policy.h \ ${tr1_impl_srcdir}/regex \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index a1fab9a..71e7489 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -850,7 +850,6 @@ tr1_impl_headers = \ ${tr1_impl_srcdir}/cwchar \ ${tr1_impl_srcdir}/cwctype \ ${tr1_impl_srcdir}/functional \ - ${tr1_impl_srcdir}/functional_hash.h \ ${tr1_impl_srcdir}/hashtable \ ${tr1_impl_srcdir}/hashtable_policy.h \ ${tr1_impl_srcdir}/regex \ diff --git a/libstdc++-v3/include/bits/functional_hash.h b/libstdc++-v3/include/bits/functional_hash.h index 78b0aa3..c045ba0 100644 --- a/libstdc++-v3/include/bits/functional_hash.h +++ b/libstdc++-v3/include/bits/functional_hash.h @@ -36,33 +36,232 @@ # include <c++0x_warning.h> #endif -#if defined(_GLIBCXX_INCLUDE_AS_TR1) -# error C++0x header cannot be included from TR1 header +#include <string> +#include <system_error> + +namespace std +{ + /// Class template hash. + template<typename _Tp> + struct hash; + + /// Partial specializations for pointer types. + template<typename _Tp> + struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> + { + size_t + operator()(_Tp* __p) const + { return reinterpret_cast<size_t>(__p); } + }; + + /// Explicit specializations for integer types. +#define _Cxx_hashtable_define_trivial_hash(_Tp) \ + template<> \ + struct hash<_Tp> : public std::unary_function<_Tp, size_t> \ + { \ + size_t \ + operator()(_Tp __val) const \ + { return static_cast<size_t>(__val); } \ + }; + + _Cxx_hashtable_define_trivial_hash(bool); + _Cxx_hashtable_define_trivial_hash(char); + _Cxx_hashtable_define_trivial_hash(signed char); + _Cxx_hashtable_define_trivial_hash(unsigned char); + _Cxx_hashtable_define_trivial_hash(wchar_t); +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + _Cxx_hashtable_define_trivial_hash(char16_t); + _Cxx_hashtable_define_trivial_hash(char32_t); #endif + _Cxx_hashtable_define_trivial_hash(short); + _Cxx_hashtable_define_trivial_hash(int); + _Cxx_hashtable_define_trivial_hash(long); + _Cxx_hashtable_define_trivial_hash(long long); + _Cxx_hashtable_define_trivial_hash(unsigned short); + _Cxx_hashtable_define_trivial_hash(unsigned int); + _Cxx_hashtable_define_trivial_hash(unsigned long); + _Cxx_hashtable_define_trivial_hash(unsigned long long); + +#undef _Cxx_hashtable_define_trivial_hash + + // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) + // (Used by the next specializations of std::tr1::hash.) + + /// Dummy generic implementation (for sizeof(size_t) != 4, 8). + template<size_t = sizeof(size_t)> + struct _Fnv_hash + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = 0; + for (; __length > 0; --__length) + __result = (__result * 131) + *__first++; + return __result; + } + }; + + template<> + struct _Fnv_hash<4> + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = static_cast<size_t>(2166136261UL); + for (; __length > 0; --__length) + { + __result ^= static_cast<size_t>(*__first++); + __result *= static_cast<size_t>(16777619UL); + } + return __result; + } + }; + + template<> + struct _Fnv_hash<8> + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = + static_cast<size_t>(14695981039346656037ULL); + for (; __length > 0; --__length) + { + __result ^= static_cast<size_t>(*__first++); + __result *= static_cast<size_t>(1099511628211ULL); + } + return __result; + } + }; + + /// Explicit specializations for float. + template<> + struct hash<float> + : public std::unary_function<float, size_t> + { + size_t + operator()(float __val) const + { + size_t __result = 0; + + // 0 and -0 both hash to zero. + if (__val != 0.0f) + __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), + sizeof(__val)); + return __result; + } + }; + + /// Explicit specializations for double. + template<> + struct hash<double> + : public std::unary_function<double, size_t> + { + size_t + operator()(double __val) const + { + size_t __result = 0; + + // 0 and -0 both hash to zero. + if (__val != 0.0) + __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), + sizeof(__val)); + return __result; + } + }; -#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) -# include <tr1_impl/functional_hash.h> -#else -# define _GLIBCXX_INCLUDE_AS_CXX0X -# define _GLIBCXX_BEGIN_NAMESPACE_TR1 -# define _GLIBCXX_END_NAMESPACE_TR1 -# define _GLIBCXX_TR1 -# include <tr1_impl/functional_hash.h> -# undef _GLIBCXX_TR1 -# undef _GLIBCXX_END_NAMESPACE_TR1 -# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 -# undef _GLIBCXX_INCLUDE_AS_CXX0X + /// Explicit specializations for long double. + template<> + struct hash<long double> + : public std::unary_function<long double, size_t> + { + size_t + operator()(long double __val) const + { + size_t __result = 0; + + int __exponent; + __val = __builtin_frexpl(__val, &__exponent); + __val = __val < 0.0l ? -(__val + 0.5l) : __val; + + const long double __mult = + __gnu_cxx::__numeric_traits<size_t>::__max + 1.0l; + __val *= __mult; + + // Try to use all the bits of the mantissa (really necessary only + // on 32-bit targets, at least for 80-bit floating point formats). + const size_t __hibits = (size_t)__val; + __val = (__val - (long double)__hibits) * __mult; + + const size_t __coeff = + __gnu_cxx::__numeric_traits<size_t>::__max / __LDBL_MAX_EXP__; + + __result = __hibits + (size_t)__val + __coeff * __exponent; + + return __result; + } + }; + + template<> + struct hash<string> + : public std::unary_function<string, size_t> + { + size_t + operator()(const string& __s) const + { return _Fnv_hash<>::hash(__s.data(), __s.length()); } + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct hash<wstring> + : public std::unary_function<wstring, size_t> + { + size_t + operator()(const wstring& __s) const + { + const char* __p = reinterpret_cast<const char*>(__s.data()); + return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t)); + } + }; #endif +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + template<> + struct hash<u16string> + : public std::unary_function<u16string, size_t> + { + size_t + operator()(const u16string& __s) const + { + const char* __p = reinterpret_cast<const char*>(__s.data()); + return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char16_t)); + } + }; -namespace std -{ - struct error_code; + template<> + struct hash<u32string> + : public std::unary_function<u32string, size_t> + { + size_t + operator()(const u32string& __s) const + { + const char* __p = reinterpret_cast<const char*>(__s.data()); + return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char32_t)); + } + }; +#endif template<> - _GLIBCXX_PURE size_t - hash<error_code>::operator()(error_code) const; + struct hash<error_code> + : public std::unary_function<error_code, size_t> + { + size_t + operator()(const error_code& __e) const + { + const char* __p = reinterpret_cast<const char*>(&__e); + return _Fnv_hash<>::hash(__p, sizeof(__e)); + } + }; } #endif // _FUNCTIONAL_HASH_H - diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 8f4f42c..e46a27d 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -57,7 +57,6 @@ # include <new> # include <tuple> # include <type_traits> -# include <bits/stringfwd.h> # include <bits/functional_hash.h> # include <ext/type_traits.h> # if defined(_GLIBCXX_INCLUDE_AS_CXX0X) diff --git a/libstdc++-v3/include/tr1/functional_hash.h b/libstdc++-v3/include/tr1/functional_hash.h index 933ded9..d684930 100644 --- a/libstdc++-v3/include/tr1/functional_hash.h +++ b/libstdc++-v3/include/tr1/functional_hash.h @@ -1,6 +1,6 @@ // TR1 functional_hash.h header -*- C++ -*- -// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009 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 @@ -32,22 +32,154 @@ #pragma GCC system_header -#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) -# error TR1 header cannot be included from C++0x header -#endif +namespace std +{ +namespace tr1 +{ + /// Class template hash. + // Declaration of default hash functor std::tr1::hash. The types for + // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR. + template<typename _Tp> + struct hash : public std::unary_function<_Tp, size_t> + { + size_t + operator()(_Tp __val) const; + }; + + /// Partial specializations for pointer types. + template<typename _Tp> + struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> + { + size_t + operator()(_Tp* __p) const + { return reinterpret_cast<size_t>(__p); } + }; + + /// Explicit specializations for integer types. +#define _TR1_hashtable_define_trivial_hash(_Tp) \ + template<> \ + inline size_t \ + hash<_Tp>::operator()(_Tp __val) const \ + { return static_cast<size_t>(__val); } + + _TR1_hashtable_define_trivial_hash(bool); + _TR1_hashtable_define_trivial_hash(char); + _TR1_hashtable_define_trivial_hash(signed char); + _TR1_hashtable_define_trivial_hash(unsigned char); + _TR1_hashtable_define_trivial_hash(wchar_t); + _TR1_hashtable_define_trivial_hash(short); + _TR1_hashtable_define_trivial_hash(int); + _TR1_hashtable_define_trivial_hash(long); + _TR1_hashtable_define_trivial_hash(long long); + _TR1_hashtable_define_trivial_hash(unsigned short); + _TR1_hashtable_define_trivial_hash(unsigned int); + _TR1_hashtable_define_trivial_hash(unsigned long); + _TR1_hashtable_define_trivial_hash(unsigned long long); + +#undef _TR1_hashtable_define_trivial_hash + + // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) + // (Used by the next specializations of std::tr1::hash.) + + /// Dummy generic implementation (for sizeof(size_t) != 4, 8). + template<size_t = sizeof(size_t)> + struct _Fnv_hash + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = 0; + for (; __length > 0; --__length) + __result = (__result * 131) + *__first++; + return __result; + } + }; + + template<> + struct _Fnv_hash<4> + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = static_cast<size_t>(2166136261UL); + for (; __length > 0; --__length) + { + __result ^= static_cast<size_t>(*__first++); + __result *= static_cast<size_t>(16777619UL); + } + return __result; + } + }; + + template<> + struct _Fnv_hash<8> + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = + static_cast<size_t>(14695981039346656037ULL); + for (; __length > 0; --__length) + { + __result ^= static_cast<size_t>(*__first++); + __result *= static_cast<size_t>(1099511628211ULL); + } + return __result; + } + }; + + /// Explicit specializations for float. + template<> + inline size_t + hash<float>::operator()(float __val) const + { + size_t __result = 0; + + // 0 and -0 both hash to zero. + if (__val != 0.0f) + __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), + sizeof(__val)); + return __result; + }; + + /// Explicit specializations for double. + template<> + inline size_t + hash<double>::operator()(double __val) const + { + size_t __result = 0; + + // 0 and -0 both hash to zero. + if (__val != 0.0) + __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), + sizeof(__val)); + return __result; + }; + + /// Explicit specializations for long double. + template<> + _GLIBCXX_PURE size_t + hash<long double>::operator()(long double __val) const; + + /// Explicit specialization of member operator for non-builtin types. + template<> + _GLIBCXX_PURE size_t + hash<string>::operator()(string) const; + + template<> + _GLIBCXX_PURE size_t + hash<const string&>::operator()(const string&) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + _GLIBCXX_PURE size_t + hash<wstring>::operator()(wstring) const; -#if defined(_GLIBCXX_INCLUDE_AS_TR1) -# include <tr1_impl/functional_hash.h> -#else -# define _GLIBCXX_INCLUDE_AS_TR1 -# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 { -# define _GLIBCXX_END_NAMESPACE_TR1 } -# define _GLIBCXX_TR1 tr1:: -# include <tr1_impl/functional_hash.h> -# undef _GLIBCXX_TR1 -# undef _GLIBCXX_END_NAMESPACE_TR1 -# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 -# undef _GLIBCXX_INCLUDE_AS_TR1 + template<> + _GLIBCXX_PURE size_t + hash<const wstring&>::operator()(const wstring&) const; #endif +} +} #endif // _GLIBCXX_TR1_FUNCTIONAL_HASH_H diff --git a/libstdc++-v3/include/tr1_impl/functional_hash.h b/libstdc++-v3/include/tr1_impl/functional_hash.h deleted file mode 100644 index 0b963e0..0000000 --- a/libstdc++-v3/include/tr1_impl/functional_hash.h +++ /dev/null @@ -1,183 +0,0 @@ -// TR1 functional -*- C++ -*- - -// Copyright (C) 2007, 2008, 2009 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 even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// <http://www.gnu.org/licenses/>. - -/** @file tr1_impl/functional_hash.h - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. - */ - -namespace std -{ -_GLIBCXX_BEGIN_NAMESPACE_TR1 - - /// Class template hash. - // Declaration of default hash functor std::tr1::hash. The types for - // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR. - template<typename _Tp> - struct hash : public std::unary_function<_Tp, size_t> - { - size_t - operator()(_Tp __val) const; - }; - - /// Partial specializations for pointer types. - template<typename _Tp> - struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> - { - size_t - operator()(_Tp* __p) const - { return reinterpret_cast<size_t>(__p); } - }; - - /// Explicit specializations for integer types. -#define _TR1_hashtable_define_trivial_hash(_Tp) \ - template<> \ - inline size_t \ - hash<_Tp>::operator()(_Tp __val) const \ - { return static_cast<size_t>(__val); } - - _TR1_hashtable_define_trivial_hash(bool); - _TR1_hashtable_define_trivial_hash(char); - _TR1_hashtable_define_trivial_hash(signed char); - _TR1_hashtable_define_trivial_hash(unsigned char); - _TR1_hashtable_define_trivial_hash(wchar_t); -#ifdef _GLIBCXX_INCLUDE_AS_CXX0X - _TR1_hashtable_define_trivial_hash(char16_t); - _TR1_hashtable_define_trivial_hash(char32_t); -#endif - _TR1_hashtable_define_trivial_hash(short); - _TR1_hashtable_define_trivial_hash(int); - _TR1_hashtable_define_trivial_hash(long); - _TR1_hashtable_define_trivial_hash(long long); - _TR1_hashtable_define_trivial_hash(unsigned short); - _TR1_hashtable_define_trivial_hash(unsigned int); - _TR1_hashtable_define_trivial_hash(unsigned long); - _TR1_hashtable_define_trivial_hash(unsigned long long); - -#undef _TR1_hashtable_define_trivial_hash - - // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) - // (Used by the next specializations of std::tr1::hash.) - - /// Dummy generic implementation (for sizeof(size_t) != 4, 8). - template<size_t = sizeof(size_t)> - struct _Fnv_hash - { - static size_t - hash(const char* __first, size_t __length) - { - size_t __result = 0; - for (; __length > 0; --__length) - __result = (__result * 131) + *__first++; - return __result; - } - }; - - template<> - struct _Fnv_hash<4> - { - static size_t - hash(const char* __first, size_t __length) - { - size_t __result = static_cast<size_t>(2166136261UL); - for (; __length > 0; --__length) - { - __result ^= static_cast<size_t>(*__first++); - __result *= static_cast<size_t>(16777619UL); - } - return __result; - } - }; - - template<> - struct _Fnv_hash<8> - { - static size_t - hash(const char* __first, size_t __length) - { - size_t __result = - static_cast<size_t>(14695981039346656037ULL); - for (; __length > 0; --__length) - { - __result ^= static_cast<size_t>(*__first++); - __result *= static_cast<size_t>(1099511628211ULL); - } - return __result; - } - }; - - /// Explicit specializations for float. - template<> - inline size_t - hash<float>::operator()(float __val) const - { - size_t __result = 0; - - // 0 and -0 both hash to zero. - if (__val != 0.0f) - __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), - sizeof(__val)); - return __result; - }; - - /// Explicit specializations for double. - template<> - inline size_t - hash<double>::operator()(double __val) const - { - size_t __result = 0; - - // 0 and -0 both hash to zero. - if (__val != 0.0) - __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), - sizeof(__val)); - return __result; - }; - - /// Explicit specializations for long double. - template<> - _GLIBCXX_PURE size_t - hash<long double>::operator()(long double __val) const; - - /// Explicit specialization of member operator for non-builtin types. - template<> - _GLIBCXX_PURE size_t - hash<string>::operator()(string) const; - - template<> - _GLIBCXX_PURE size_t - hash<const string&>::operator()(const string&) const; - -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - _GLIBCXX_PURE size_t - hash<wstring>::operator()(wstring) const; - - template<> - _GLIBCXX_PURE size_t - hash<const wstring&>::operator()(const wstring&) const; -#endif - -_GLIBCXX_END_NAMESPACE_TR1 -} diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index 9513bd5..4306dd5 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -140,12 +140,12 @@ sources = \ mt_allocator.cc \ codecvt.cc \ compatibility.cc \ + compatibility-c++0x.cc \ complex_io.cc \ ctype.cc \ debug.cc \ functexcept.cc \ hash_tr1.cc \ - hash_c++0x.cc \ globals_io.cc \ hashtable_tr1.cc \ hashtable_c++0x.cc \ @@ -260,9 +260,9 @@ condition_variable.lo: condition_variable.cc condition_variable.o: condition_variable.cc $(CXXCOMPILE) -std=gnu++0x -c $< -hash_c++0x.lo: hash_c++0x.cc +compatibility-c++0x.lo: compatibility-c++0x.cc $(LTCXXCOMPILE) -std=gnu++0x -c $< -hash_c++0x.o: hash_c++0x.cc +compatibility-c++0x.o: compatibility-c++0x.cc $(CXXCOMPILE) -std=gnu++0x -c $< hashtable_c++0x.lo: hashtable_c++0x.cc diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index 9c03ac4..8cc950f 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -87,8 +87,8 @@ LTLIBRARIES = $(toolexeclib_LTLIBRARIES) am__DEPENDENCIES_1 = am__libstdc___la_SOURCES_DIST = atomic.cc bitmap_allocator.cc \ pool_allocator.cc mt_allocator.cc codecvt.cc compatibility.cc \ - complex_io.cc ctype.cc debug.cc functexcept.cc hash_tr1.cc \ - hash_c++0x.cc globals_io.cc hashtable_tr1.cc \ + compatibility-c++0x.cc complex_io.cc ctype.cc debug.cc \ + functexcept.cc hash_tr1.cc globals_io.cc hashtable_tr1.cc \ hashtable_c++0x.cc ios.cc ios_failure.cc ios_init.cc \ ios_locale.cc limits.cc limits_c++0x.cc list.cc debug_list.cc \ locale.cc locale_init.cc locale_facets.cc localename.cc \ @@ -113,18 +113,18 @@ am__objects_1 = atomicity.lo codecvt_members.lo collate_members.lo \ am__objects_4 = basic_file.lo c++locale.lo $(am__objects_2) \ $(am__objects_3) am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \ - mt_allocator.lo codecvt.lo compatibility.lo complex_io.lo \ - ctype.lo debug.lo functexcept.lo hash_tr1.lo hash_c++0x.lo \ - globals_io.lo hashtable_tr1.lo hashtable_c++0x.lo ios.lo \ - ios_failure.lo ios_init.lo ios_locale.lo limits.lo \ - limits_c++0x.lo list.lo debug_list.lo locale.lo locale_init.lo \ - locale_facets.lo localename.lo math_stubs_float.lo \ - math_stubs_long_double.lo stdexcept.lo strstream.lo \ - system_error.lo tree.lo allocator-inst.lo concept-inst.lo \ - fstream-inst.lo ext-inst.lo ios-inst.lo iostream-inst.lo \ - istream-inst.lo istream.lo locale-inst.lo misc-inst.lo \ - ostream-inst.lo sstream-inst.lo streambuf-inst.lo streambuf.lo \ - string-inst.lo valarray-inst.lo wlocale-inst.lo \ + mt_allocator.lo codecvt.lo compatibility.lo \ + compatibility-c++0x.lo complex_io.lo ctype.lo debug.lo \ + functexcept.lo hash_tr1.lo globals_io.lo hashtable_tr1.lo \ + hashtable_c++0x.lo ios.lo ios_failure.lo ios_init.lo \ + ios_locale.lo limits.lo limits_c++0x.lo list.lo debug_list.lo \ + locale.lo locale_init.lo locale_facets.lo localename.lo \ + math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \ + strstream.lo system_error.lo tree.lo allocator-inst.lo \ + concept-inst.lo fstream-inst.lo ext-inst.lo ios-inst.lo \ + iostream-inst.lo istream-inst.lo istream.lo locale-inst.lo \ + misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo \ + streambuf.lo string-inst.lo valarray-inst.lo wlocale-inst.lo \ wstring-inst.lo mutex.lo condition_variable.lo chrono.lo \ thread.lo future.lo $(am__objects_1) $(am__objects_4) am_libstdc___la_OBJECTS = $(am__objects_5) @@ -382,12 +382,12 @@ sources = \ mt_allocator.cc \ codecvt.cc \ compatibility.cc \ + compatibility-c++0x.cc \ complex_io.cc \ ctype.cc \ debug.cc \ functexcept.cc \ hash_tr1.cc \ - hash_c++0x.cc \ globals_io.cc \ hashtable_tr1.cc \ hashtable_c++0x.cc \ @@ -891,9 +891,9 @@ condition_variable.lo: condition_variable.cc condition_variable.o: condition_variable.cc $(CXXCOMPILE) -std=gnu++0x -c $< -hash_c++0x.lo: hash_c++0x.cc +compatibility-c++0x.lo: compatibility-c++0x.cc $(LTCXXCOMPILE) -std=gnu++0x -c $< -hash_c++0x.o: hash_c++0x.cc +compatibility-c++0x.o: compatibility-c++0x.cc $(CXXCOMPILE) -std=gnu++0x -c $< hashtable_c++0x.lo: hashtable_c++0x.cc diff --git a/libstdc++-v3/src/hash_c++0x.cc b/libstdc++-v3/src/compatibility-c++0x.cc index 5bdbf0c..0e92135 100644 --- a/libstdc++-v3/src/hash_c++0x.cc +++ b/libstdc++-v3/src/compatibility-c++0x.cc @@ -1,6 +1,6 @@ -// std::hash definitions -*- C++ -*- +// Compatibility symbols for previous versions, C++0x bits -*- C++ -*- -// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2009 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 @@ -25,15 +25,38 @@ #include <cstddef> #include <string> #include <cmath> -#include <functional> #include <system_error> #ifndef __GXX_EXPERIMENTAL_CXX0X__ -# error "hash_c++0x.cc must be compiled with -std=gnu++0x" +# error "compatibility-c++0x.cc must be compiled with -std=gnu++0x" #endif namespace std { + // We need these due to the symbols exported since GLIBCXX_3.4.10. + // See libstdc++/41662 for details. + + template<typename _Tp> + struct hash : public std::unary_function<_Tp, size_t> + { + size_t + operator()(_Tp __val) const; + }; + + /// Dummy generic implementation (for sizeof(size_t) != 4, 8). + template<size_t = sizeof(size_t)> + struct _Fnv_hash + { + static size_t + hash(const char* __first, size_t __length) + { + size_t __result = 0; + for (; __length > 0; --__length) + __result = (__result * 131) + *__first++; + return __result; + } + }; + #include "hash.cc" template<> diff --git a/libstdc++-v3/src/hash.cc b/libstdc++-v3/src/hash.cc index c776ed5..cc23858 100644 --- a/libstdc++-v3/src/hash.cc +++ b/libstdc++-v3/src/hash.cc @@ -26,7 +26,7 @@ // 10 bytes -> 12 bytes) and resort to frexp. template<> size_t - hash<long double>::operator()(long double __val) const throw () + hash<long double>::operator()(long double __val) const { size_t __result = 0; @@ -59,7 +59,7 @@ template<> size_t - hash<const string&>::operator()(const string& __s) const throw () + hash<const string&>::operator()(const string& __s) const { return _Fnv_hash<>::hash(__s.data(), __s.length()); } #ifdef _GLIBCXX_USE_WCHAR_T @@ -73,7 +73,7 @@ template<> size_t - hash<const wstring&>::operator()(const wstring& __s) const throw () + hash<const wstring&>::operator()(const wstring& __s) const { const char* __p = reinterpret_cast<const char*>(__s.data()); return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t)); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/2.cc index f6b5fe3..8517908 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/2.cc @@ -24,5 +24,6 @@ #include <testsuite_hooks.h> #include <testsuite_api.h> -typedef __gnu_test::NonDefaultConstructible inst_type; -template class std::unordered_map<inst_type, inst_type>; +typedef __gnu_test::NonDefaultConstructible inst_type; +typedef __gnu_test::NonDefaultConstructible_hash hash_type; +template class std::unordered_map<inst_type, inst_type, hash_type>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/2.cc index e26428d..2eef371 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/2.cc @@ -24,5 +24,6 @@ #include <testsuite_hooks.h> #include <testsuite_api.h> -typedef __gnu_test::NonDefaultConstructible inst_type; -template class std::unordered_multimap<inst_type, inst_type>; +typedef __gnu_test::NonDefaultConstructible inst_type; +typedef __gnu_test::NonDefaultConstructible_hash hash_type; +template class std::unordered_multimap<inst_type, inst_type, hash_type>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/2.cc index d2a120a..5764e92 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/2.cc @@ -24,4 +24,6 @@ #include <testsuite_hooks.h> #include <testsuite_api.h> -template class std::unordered_multiset<__gnu_test::NonDefaultConstructible>; +typedef __gnu_test::NonDefaultConstructible inst_type; +typedef __gnu_test::NonDefaultConstructible_hash hash_type; +template class std::unordered_multiset<inst_type, hash_type>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/2.cc index 13e9e37..e227604 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/2.cc @@ -24,4 +24,6 @@ #include <testsuite_hooks.h> #include <testsuite_api.h> -template class std::unordered_set<__gnu_test::NonDefaultConstructible>; +typedef __gnu_test::NonDefaultConstructible inst_type; +typedef __gnu_test::NonDefaultConstructible_hash hash_type; +template class std::unordered_set<inst_type, hash_type>; diff --git a/libstdc++-v3/testsuite/util/testsuite_api.h b/libstdc++-v3/testsuite/util/testsuite_api.h index 772349b..4dc4a6f 100644 --- a/libstdc++-v3/testsuite/util/testsuite_api.h +++ b/libstdc++-v3/testsuite/util/testsuite_api.h @@ -19,6 +19,7 @@ // <http://www.gnu.org/licenses/>. // +#include <cstddef> #include <exception> #include <testsuite_hooks.h> @@ -103,6 +104,14 @@ namespace __gnu_test operator<(const NonDefaultConstructible&, const NonDefaultConstructible&) { return false; } + // For 23 unordered_* requirements. + struct NonDefaultConstructible_hash + { + size_t + operator()(NonDefaultConstructible) const + { return 1; } + }; + // For 26 numeric algorithms requirements, need addable, // subtractable, multiplicable. inline NonDefaultConstructible @@ -141,6 +150,6 @@ namespace __gnu_test operator()() const { return result_type(2); } }; - } + #endif |