OSDN Git Service

2010-02-23 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Feb 2010 15:23:37 +0000 (15:23 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Feb 2010 15:23:37 +0000 (15:23 +0000)
* 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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/functional_hash.h
libstdc++-v3/include/std/system_error
libstdc++-v3/include/std/thread
libstdc++-v3/include/tr1/functional_hash.h
libstdc++-v3/src/compatibility-c++0x.cc
libstdc++-v3/src/hash-string-aux.cc
libstdc++-v3/testsuite/30_threads/thread/cons/assign_neg.cc
libstdc++-v3/testsuite/30_threads/thread/cons/copy_neg.cc
libstdc++-v3/testsuite/30_threads/thread/id/hash.cc [new file with mode: 0644]

index 63171f9..96006bc 100644 (file)
@@ -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.
index 399f29a..4c1c427 100644 (file)
@@ -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
index 231d543..8a29189 100644 (file)
@@ -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.
index 3199d46..9b6eff8 100644 (file)
@@ -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);
       }
     };
 
index f72f5e5..470f2c0 100644 (file)
@@ -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)
index d944fa9..98fb187 100644 (file)
@@ -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.
index abdc72c..7dd5768 100644 (file)
@@ -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);
     }
 }
index 1da015c..b5a2c6d 100644 (file)
   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
 
index 1ea66ec..f45b9f2 100644 (file)
@@ -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 }
index d7fbc48..ce5034b 100644 (file)
@@ -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 (file)
index 0000000..86acac8
--- /dev/null
@@ -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;