# tr1_impl/functional_hash.h

Go to the documentation of this file.

    00001 // TR1 functional -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 3, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // Under Section 7 of GPL version 3, you are granted additional
    00017 // permissions described in the GCC Runtime Library Exception, version
    00018 // 3.1, as published by the Free Software Foundation.
    00019
    00020 // You should have received a copy of the GNU General Public License and
    00021 // a copy of the GCC Runtime Library Exception along with this program;
    00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00023 // <http://www.gnu.org/licenses/>.
    00024
    00025 /** @file tr1_impl/functional_hash.h
    00026  *  This is an internal header file, included by other library headers.
    00027  *  You should not attempt to use it directly.
    00028  */
    00029
    00030 namespace std
    00031 {
    00032 _GLIBCXX_BEGIN_NAMESPACE_TR1
    00033
    00034   /// Class template hash.
    00035   // Declaration of default hash functor std::tr1::hash.  The types for
    00036   // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR.
    00037   template<typename _Tp>
    00038     struct hash : public std::unary_function<_Tp, size_t>
    00039     {
    00040       size_t
    00041       operator()(_Tp __val) const;
    00042     };
    00043
    00044   /// Partial specializations for pointer types.
    00045   template<typename _Tp>
    00046     struct hash<_Tp*> : public std::unary_function<_Tp*, size_t>
    00047     {
    00048       size_t
    00049       operator()(_Tp* __p) const
    00050       { return reinterpret_cast<size_t>(__p); }
    00051     };
    00052
    00053   /// Explicit specializations for integer types.
    00054 #define _TR1_hashtable_define_trivial_hash(_Tp)     \
    00055   template<>                        \
    00056     inline size_t                   \
    00057     hash<_Tp>::operator()(_Tp __val) const      \
    00058     { return static_cast<size_t>(__val); }
    00059
    00060   _TR1_hashtable_define_trivial_hash(bool);
    00061   _TR1_hashtable_define_trivial_hash(char);
    00062   _TR1_hashtable_define_trivial_hash(signed char);
    00063   _TR1_hashtable_define_trivial_hash(unsigned char);
    00064   _TR1_hashtable_define_trivial_hash(wchar_t);
    00065 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    00066   _TR1_hashtable_define_trivial_hash(char16_t);
    00067   _TR1_hashtable_define_trivial_hash(char32_t);
    00068 #endif
    00069   _TR1_hashtable_define_trivial_hash(short);
    00070   _TR1_hashtable_define_trivial_hash(int);
    00071   _TR1_hashtable_define_trivial_hash(long);
    00072   _TR1_hashtable_define_trivial_hash(long long);
    00073   _TR1_hashtable_define_trivial_hash(unsigned short);
    00074   _TR1_hashtable_define_trivial_hash(unsigned int);
    00075   _TR1_hashtable_define_trivial_hash(unsigned long);
    00076   _TR1_hashtable_define_trivial_hash(unsigned long long);
    00077
    00078 #undef _TR1_hashtable_define_trivial_hash
    00079
    00080   // Fowler / Noll / Vo (FNV) Hash (type FNV-1a)
    00081   // (Used by the next specializations of std::tr1::hash.)
    00082
    00083   /// Dummy generic implementation (for sizeof(size_t) != 4, 8).
    00084   template<size_t = sizeof(size_t)>
    00085     struct _Fnv_hash
    00086     {
    00087       static size_t
    00088       hash(const char* __first, size_t __length)
    00089       {
    00090     size_t __result = 0;
    00091     for (; __length > 0; --__length)
    00092       __result = (__result * 131) + *__first++;
    00093     return __result;
    00094       }
    00095     };
    00096
    00097   template<>
    00098     struct _Fnv_hash<4>
    00099     {
    00100       static size_t
    00101       hash(const char* __first, size_t __length)
    00102       {
    00103     size_t __result = static_cast<size_t>(2166136261UL);
    00104     for (; __length > 0; --__length)
    00105       {
    00106         __result ^= static_cast<size_t>(*__first++);
    00107         __result *= static_cast<size_t>(16777619UL);
    00108       }
    00109     return __result;
    00110       }
    00111     };
    00112
    00113   template<>
    00114     struct _Fnv_hash<8>
    00115     {
    00116       static size_t
    00117       hash(const char* __first, size_t __length)
    00118       {
    00119     size_t __result =
    00120       static_cast<size_t>(14695981039346656037ULL);
    00121     for (; __length > 0; --__length)
    00122       {
    00123         __result ^= static_cast<size_t>(*__first++);
    00124         __result *= static_cast<size_t>(1099511628211ULL);
    00125       }
    00126     return __result;
    00127       }
    00128     };
    00129
    00130   /// Explicit specializations for float.
    00131   template<>
    00132     inline size_t
    00133     hash<float>::operator()(float __val) const
    00134     {
    00135       size_t __result = 0;
    00136
    00137       // 0 and -0 both hash to zero.
    00138       if (__val != 0.0f)
    00139     __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
    00140                      sizeof(__val));
    00141       return __result;
    00142     };
    00143
    00144   /// Explicit specializations for double.
    00145   template<>
    00146     inline size_t
    00147     hash<double>::operator()(double __val) const
    00148     {
    00149     size_t __result = 0;
    00150
    00151     // 0 and -0 both hash to zero.
    00152     if (__val != 0.0)
    00153       __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
    00154                        sizeof(__val));
    00155     return __result;
    00156     };
    00157
    00158   /// Explicit specializations for long double.
    00159   template<>
    00160     size_t
    00161     hash<long double>::operator()(long double __val) const;
    00162
    00163   /// Explicit specialization of member operator for non-builtin types.
    00164   template<>
    00165     size_t
    00166     hash<string>::operator()(string) const;
    00167
    00168   template<>
    00169     size_t
    00170     hash<const string&>::operator()(const string&) const;
    00171
    00172 #ifdef _GLIBCXX_USE_WCHAR_T
    00173   template<>
    00174     size_t
    00175     hash<wstring>::operator()(wstring) const;
    00176
    00177   template<>
    00178     size_t
    00179     hash<const wstring&>::operator()(const wstring&) const;
    00180 #endif
    00181
    00182 _GLIBCXX_END_NAMESPACE_TR1
    00183 }