diff options
author | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-02-23 15:23:37 +0000 |
---|---|---|
committer | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-02-23 15:23:37 +0000 |
commit | 3103d73cdcd9f75c792c1213d242371410ea4fb7 (patch) | |
tree | 5a389c42914e410ce5375c1480147999b90aeb07 /libstdc++-v3 | |
parent | d96f9313aeb7cc7816eb9abfabb5ee1dcd5499ef (diff) | |
download | ppe42-gcc-3103d73cdcd9f75c792c1213d242371410ea4fb7.tar.gz ppe42-gcc-3103d73cdcd9f75c792c1213d242371410ea4fb7.zip |
2010-02-23 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/functional_hash.h (struct _Fnv_hash): Rename
to _Fnv_hash_base.
(struct _Fnv_hash): Add, derives from the latter.
(__hash_combine): Add.
(hash<float>::operator()(float), hash<double>::operator()(double)):
Adjust.
* include/bits/basic_string.h (hash<string>, hash<wstring>,
hash<u16string>, hash<u32string>): Adjust.
* src/hash-string-aux.cc: Adjust.
* src/compatibility-c++0x.cc (hash<error_code>): Use __hash_combine.
* include/std/system_error (hash<error_code>): Likewise.
* include/std/thread (struct hash<thread::id>): Add.
* include/tr1/functional_hash.h : Rename to _Fnv_hash_base.
(struct _Fnv_hash): Add, derives from the latter.
(hash<float>::operator()(float), hash<double>::operator()(double)):
Adjust.
* testsuite/30_threads/thread/id/hash.cc: New.
* testsuite/30_threads/thread/cons/assign_neg.cc: Adjust dg-error
line number.
* testsuite/30_threads/thread/cons/copy_neg.cc: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157005 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 23 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/basic_string.h | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/functional_hash.h | 45 | ||||
-rw-r--r-- | libstdc++-v3/include/std/system_error | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/std/thread | 16 | ||||
-rw-r--r-- | libstdc++-v3/include/tr1/functional_hash.h | 38 | ||||
-rw-r--r-- | libstdc++-v3/src/compatibility-c++0x.cc | 6 | ||||
-rw-r--r-- | libstdc++-v3/src/hash-string-aux.cc | 8 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/thread/id/hash.cc | 26 |
11 files changed, 133 insertions, 54 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 63171f98610..96006bcb4cc 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2010-02-23 Paolo Carlini <paolo.carlini@oracle.com> + + * include/bits/functional_hash.h (struct _Fnv_hash): Rename + to _Fnv_hash_base. + (struct _Fnv_hash): Add, derives from the latter. + (__hash_combine): Add. + (hash<float>::operator()(float), hash<double>::operator()(double)): + Adjust. + * include/bits/basic_string.h (hash<string>, hash<wstring>, + hash<u16string>, hash<u32string>): Adjust. + * src/hash-string-aux.cc: Adjust. + * src/compatibility-c++0x.cc (hash<error_code>): Use __hash_combine. + * include/std/system_error (hash<error_code>): Likewise. + * include/std/thread (struct hash<thread::id>): Add. + * include/tr1/functional_hash.h : Rename to _Fnv_hash_base. + (struct _Fnv_hash): Add, derives from the latter. + (hash<float>::operator()(float), hash<double>::operator()(double)): + Adjust. + * testsuite/30_threads/thread/id/hash.cc: New. + * testsuite/30_threads/thread/cons/assign_neg.cc: Adjust dg-error + line number. + * testsuite/30_threads/thread/cons/copy_neg.cc: Likewise. + 2010-02-22 Janis Johnson <janis187@us.ibm.com> * src/compatibility-ldbl.cc: Include new hash-long-double-aux.cc. diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 399f29a8c82..4c1c427f142 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -2887,7 +2887,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { size_t operator()(const string& __s) const - { return _Fnv_hash<>::hash(__s.data(), __s.length()); } + { return std::_Fnv_hash::hash(__s.data(), __s.length()); } }; #ifdef _GLIBCXX_USE_WCHAR_T @@ -2900,7 +2900,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator()(const wstring& __s) const { const char* __p = reinterpret_cast<const char*>(__s.data()); - return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t)); + return std::_Fnv_hash::hash(__p, __s.length() * sizeof(wchar_t)); } }; #endif @@ -2916,7 +2916,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator()(const u16string& __s) const { const char* __p = reinterpret_cast<const char*>(__s.data()); - return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char16_t)); + return std::_Fnv_hash::hash(__p, __s.length() * sizeof(char16_t)); } }; @@ -2929,7 +2929,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator()(const u32string& __s) const { const char* __p = reinterpret_cast<const char*>(__s.data()); - return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char32_t)); + return std::_Fnv_hash::hash(__p, __s.length() * sizeof(char32_t)); } }; #endif diff --git a/libstdc++-v3/include/bits/functional_hash.h b/libstdc++-v3/include/bits/functional_hash.h index 231d5430d23..8a291899798 100644 --- a/libstdc++-v3/include/bits/functional_hash.h +++ b/libstdc++-v3/include/bits/functional_hash.h @@ -117,14 +117,10 @@ namespace std #undef _Cxx_hashtable_define_trivial_hash // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) - // (Used by the next specializations of std::hash.) - - template<size_t = sizeof(size_t)> - struct _Fnv_hash; // Dummy generic implementation (for sizeof(size_t) != 4, 8). template<size_t> - struct _Fnv_hash + struct _Fnv_hash_base { static size_t hash(const char* __first, size_t __length) @@ -137,7 +133,7 @@ namespace std }; template<> - struct _Fnv_hash<4> + struct _Fnv_hash_base<4> { static size_t hash(const char* __first, size_t __length) @@ -153,7 +149,7 @@ namespace std }; template<> - struct _Fnv_hash<8> + struct _Fnv_hash_base<8> { static size_t hash(const char* __first, size_t __length) @@ -169,18 +165,34 @@ namespace std } }; + struct _Fnv_hash + : public _Fnv_hash_base<sizeof(size_t)> + { + using _Fnv_hash_base<sizeof(size_t)>::hash; + + template<typename _Tp> + static size_t + hash(const _Tp& __val) + { return hash(reinterpret_cast<const char*>(&__val), + sizeof(__val)); } + }; + + // Inspired by the Boost facility hash_combine. + template<typename _Tp> + inline size_t + __hash_combine(size_t __hash, const _Tp& __val) + { + const size_t __tmp = std::_Fnv_hash::hash(__val); + return __hash ^ (__tmp + 0x9e3779b9 + (__hash << 6) + (__hash >> 2)); + } + /// Specialization 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; + return __val != 0.0f ? std::_Fnv_hash::hash(__val) : 0; } /// Specialization for double. @@ -188,13 +200,8 @@ namespace std 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; + return __val != 0.0 ? std::_Fnv_hash::hash(__val) : 0; } /// Specialization for long double. diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error index 3199d461be4..9b6eff8e836 100644 --- a/libstdc++-v3/include/std/system_error +++ b/libstdc++-v3/include/std/system_error @@ -108,6 +108,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) error_code make_error_code(errc); + template<typename _Tp> + struct hash; + /// error_code // Implementation-specific error identification struct error_code @@ -159,6 +162,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // DR 804. private: + friend class hash<error_code>; + int _M_value; const error_category* _M_cat; }; @@ -350,8 +355,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) size_t operator()(const error_code& __e) const { - const char* __p = reinterpret_cast<const char*>(&__e); - return _Fnv_hash<>::hash(__p, sizeof(__e)); + const size_t __tmp = std::_Fnv_hash::hash(__e._M_value); + return std::__hash_combine(__tmp, __e._M_cat); } }; diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index f72f5e5a3a6..470f2c0f35c 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -42,6 +42,7 @@ #include <condition_variable> #include <cstddef> #include <bits/functexcept.h> +#include <bits/functional_hash.h> #include <bits/gthr.h> #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) @@ -56,6 +57,9 @@ namespace std * @{ */ + template<typename _Tp> + struct hash; + /// thread class thread { @@ -77,6 +81,7 @@ namespace std private: friend class thread; + friend class hash<thread::id>; friend bool operator==(thread::id __x, thread::id __y) @@ -215,6 +220,17 @@ namespace std operator>=(thread::id __x, thread::id __y) { return !(__x < __y); } + // DR 889. + /// std::hash specialization for thread::id. + template<> + struct hash<thread::id> + : public std::unary_function<thread::id, size_t> + { + size_t + operator()(const thread::id& __id) const + { return std::_Fnv_hash::hash(__id._M_thread); } + }; + template<class _CharT, class _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id) diff --git a/libstdc++-v3/include/tr1/functional_hash.h b/libstdc++-v3/include/tr1/functional_hash.h index d944fa9ff0f..98fb1878695 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, 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010 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 @@ -82,8 +82,8 @@ namespace tr1 // (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 + template<size_t> + struct _Fnv_hash_base { static size_t hash(const char* __first, size_t __length) @@ -96,7 +96,7 @@ namespace tr1 }; template<> - struct _Fnv_hash<4> + struct _Fnv_hash_base<4> { static size_t hash(const char* __first, size_t __length) @@ -112,7 +112,7 @@ namespace tr1 }; template<> - struct _Fnv_hash<8> + struct _Fnv_hash_base<8> { static size_t hash(const char* __first, size_t __length) @@ -128,18 +128,25 @@ namespace tr1 } }; + struct _Fnv_hash + : public _Fnv_hash_base<sizeof(size_t)> + { + using _Fnv_hash_base<sizeof(size_t)>::hash; + + template<typename _Tp> + static size_t + hash(const _Tp& __val) + { return hash(reinterpret_cast<const char*>(&__val), + sizeof(__val)); } + }; + /// 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; + return __val != 0.0f ? std::tr1::_Fnv_hash::hash(__val) : 0; } /// Explicit specializations for double. @@ -147,13 +154,8 @@ namespace tr1 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; + // 0 and -0 both hash to zero. + return __val != 0.0 ? std::tr1::_Fnv_hash::hash(__val) : 0; } /// Explicit specializations for long double. diff --git a/libstdc++-v3/src/compatibility-c++0x.cc b/libstdc++-v3/src/compatibility-c++0x.cc index abdc72c0832..7dd57680484 100644 --- a/libstdc++-v3/src/compatibility-c++0x.cc +++ b/libstdc++-v3/src/compatibility-c++0x.cc @@ -55,8 +55,8 @@ namespace std template<> size_t hash<error_code>::operator()(error_code __e) const - { - const char* __p = reinterpret_cast<const char*>(&__e); - return _Fnv_hash<>::hash(__p, sizeof(__e)); + { + const size_t __tmp = std::_Fnv_hash::hash(__e._M_value); + return std::__hash_combine(__tmp, __e._M_cat); } } diff --git a/libstdc++-v3/src/hash-string-aux.cc b/libstdc++-v3/src/hash-string-aux.cc index 1da015c1fd5..b5a2c6ddc3d 100644 --- a/libstdc++-v3/src/hash-string-aux.cc +++ b/libstdc++-v3/src/hash-string-aux.cc @@ -26,12 +26,12 @@ template<> size_t hash<string>::operator()(string __s) const - { return _Fnv_hash<>::hash(__s.data(), __s.length()); } + { return _Fnv_hash::hash(__s.data(), __s.length()); } template<> size_t hash<const string&>::operator()(const string& __s) const - { return _Fnv_hash<>::hash(__s.data(), __s.length()); } + { return _Fnv_hash::hash(__s.data(), __s.length()); } #ifdef _GLIBCXX_USE_WCHAR_T template<> @@ -39,7 +39,7 @@ hash<wstring>::operator()(wstring __s) const { const char* __p = reinterpret_cast<const char*>(__s.data()); - return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t)); + return _Fnv_hash::hash(__p, __s.length() * sizeof(wchar_t)); } template<> @@ -47,7 +47,7 @@ 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)); + return _Fnv_hash::hash(__p, __s.length() * sizeof(wchar_t)); } #endif diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc index 1ea66ec9c81..f45b9f203ae 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc @@ -3,7 +3,7 @@ // { dg-require-cstdint "" } // { dg-require-gthreads "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010 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,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 144 } +// { dg-error "deleted function" "" { target *-*-* } 149 } diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc index d7fbc485293..ce5034bf502 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc @@ -3,7 +3,7 @@ // { dg-require-cstdint "" } // { dg-require-gthreads "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010 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 @@ -31,5 +31,5 @@ void test01() } // { dg-error "here" "" { target *-*-* } 30 } -// { dg-error "deleted function" "" { target *-*-* } 122 } +// { dg-error "deleted function" "" { target *-*-* } 127 } // { dg-excess-errors "In file included from" } diff --git a/libstdc++-v3/testsuite/30_threads/thread/id/hash.cc b/libstdc++-v3/testsuite/30_threads/thread/id/hash.cc new file mode 100644 index 00000000000..86acac84ca2 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/thread/id/hash.cc @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 2010 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. + +// 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 <thread> + +// thread::id hash +std::hash<std::thread::id> h1; |