functional_hash.h

Go to the documentation of this file.
00001 // functional_hash.h header -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010 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 bits/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 #ifndef _FUNCTIONAL_HASH_H
00031 #define _FUNCTIONAL_HASH_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00036 # include <c++0x_warning.h>
00037 #endif
00038 
00039 #include <string>
00040 #include <system_error>
00041 
00042 namespace std
00043 {
00044   /** @defgroup hashes Hashes
00045    *  @ingroup functors
00046    *
00047    *   Hashing functors taking a variable type and returning a @c std::size_t.
00048    *
00049    *  @{
00050    */
00051  
00052   /// Primary class template hash.
00053   template<typename _Tp>
00054     struct hash;
00055 
00056   /// Partial specializations for pointer types.
00057   template<typename _Tp>
00058     struct hash<_Tp*> : public std::unary_function<_Tp*, size_t>
00059     {
00060       size_t
00061       operator()(_Tp* __p) const
00062       { return reinterpret_cast<size_t>(__p); }
00063     };
00064 
00065   // Explicit specializations for integer types.
00066 #define _Cxx_hashtable_define_trivial_hash(_Tp)            \
00067   template<>                               \
00068     struct hash<_Tp> : public std::unary_function<_Tp, size_t> \
00069     {                                                          \
00070       size_t                                                   \
00071       operator()(_Tp __val) const                      \
00072       { return static_cast<size_t>(__val); }               \
00073     };
00074 
00075   /// Explicit specialization for bool.
00076   _Cxx_hashtable_define_trivial_hash(bool);
00077 
00078   /// Explicit specialization for char.
00079   _Cxx_hashtable_define_trivial_hash(char);
00080 
00081   /// Explicit specialization for signed char.
00082   _Cxx_hashtable_define_trivial_hash(signed char);
00083 
00084   /// Explicit specialization for unsigned char.
00085   _Cxx_hashtable_define_trivial_hash(unsigned char);
00086 
00087   /// Explicit specialization for wchar_t.
00088   _Cxx_hashtable_define_trivial_hash(wchar_t);
00089 
00090 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
00091   /// Explicit specialization for char16_t.
00092   _Cxx_hashtable_define_trivial_hash(char16_t);
00093 
00094   /// Explicit specialization for char32_t.
00095   _Cxx_hashtable_define_trivial_hash(char32_t);
00096 #endif
00097 
00098   /// Explicit specialization for short.
00099   _Cxx_hashtable_define_trivial_hash(short);
00100 
00101   /// Explicit specialization for int.
00102   _Cxx_hashtable_define_trivial_hash(int);
00103 
00104   /// Explicit specialization for long.
00105   _Cxx_hashtable_define_trivial_hash(long);
00106 
00107   /// Explicit specialization for long long.
00108   _Cxx_hashtable_define_trivial_hash(long long);
00109 
00110   /// Explicit specialization for unsigned short.
00111   _Cxx_hashtable_define_trivial_hash(unsigned short);
00112 
00113   /// Explicit specialization for unsigned int.
00114   _Cxx_hashtable_define_trivial_hash(unsigned int);
00115 
00116   /// Explicit specialization for unsigned long.
00117   _Cxx_hashtable_define_trivial_hash(unsigned long);
00118 
00119   /// Explicit specialization for unsigned long long.
00120   _Cxx_hashtable_define_trivial_hash(unsigned long long);
00121 
00122 #undef _Cxx_hashtable_define_trivial_hash
00123 
00124   // Fowler / Noll / Vo (FNV) Hash (type FNV-1a)
00125   // (Used by the next specializations of std::tr1::hash.)
00126 
00127   // Dummy generic implementation (for sizeof(size_t) != 4, 8).
00128   template<size_t = sizeof(size_t)>
00129     struct _Fnv_hash
00130     {
00131       static size_t
00132       hash(const char* __first, size_t __length)
00133       {
00134     size_t __result = 0;
00135     for (; __length > 0; --__length)
00136       __result = (__result * 131) + *__first++;
00137     return __result;
00138       }
00139     };
00140 
00141   template<>
00142     struct _Fnv_hash<4>
00143     {
00144       static size_t
00145       hash(const char* __first, size_t __length)
00146       {
00147     size_t __result = static_cast<size_t>(2166136261UL);
00148     for (; __length > 0; --__length)
00149       {
00150         __result ^= static_cast<size_t>(*__first++);
00151         __result *= static_cast<size_t>(16777619UL);
00152       }
00153     return __result;
00154       }
00155     };
00156   
00157   template<>
00158     struct _Fnv_hash<8>
00159     {
00160       static size_t
00161       hash(const char* __first, size_t __length)
00162       {
00163     size_t __result =
00164       static_cast<size_t>(14695981039346656037ULL);
00165     for (; __length > 0; --__length)
00166       {
00167         __result ^= static_cast<size_t>(*__first++);
00168         __result *= static_cast<size_t>(1099511628211ULL);
00169       }
00170     return __result;
00171       }
00172     };
00173 
00174   /// Explicit specializations for float.
00175   template<>
00176     struct hash<float>
00177     : public std::unary_function<float, size_t>
00178     {
00179       size_t
00180       operator()(float __val) const
00181       {
00182     size_t __result = 0;
00183       
00184     // 0 and -0 both hash to zero.
00185     if (__val != 0.0f)
00186       __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
00187                        sizeof(__val));
00188     return __result;
00189       }
00190     };
00191 
00192   /// Explicit specializations for double.
00193   template<>
00194     struct hash<double>
00195     : public std::unary_function<double, size_t>
00196     {
00197       size_t
00198       operator()(double __val) const
00199       {
00200     size_t __result = 0;
00201 
00202     // 0 and -0 both hash to zero.
00203     if (__val != 0.0)
00204       __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
00205                        sizeof(__val));
00206     return __result;
00207       }
00208     };
00209 
00210   /// Explicit specializations for long double.
00211   template<>
00212     struct hash<long double>
00213     : public std::unary_function<long double, size_t>
00214     {
00215       size_t
00216       operator()(long double __val) const
00217       {
00218     size_t __result = 0;
00219 
00220     int __exponent;
00221     __val = __builtin_frexpl(__val, &__exponent);
00222     __val = __val < 0.0l ? -(__val + 0.5l) : __val;
00223 
00224     const long double __mult =
00225       __gnu_cxx::__numeric_traits<size_t>::__max + 1.0l;
00226     __val *= __mult;
00227 
00228     // Try to use all the bits of the mantissa (really necessary only
00229     // on 32-bit targets, at least for 80-bit floating point formats).
00230     const size_t __hibits = (size_t)__val;
00231     __val = (__val - (long double)__hibits) * __mult;
00232 
00233     const size_t __coeff =
00234       __gnu_cxx::__numeric_traits<size_t>::__max / __LDBL_MAX_EXP__;
00235 
00236     __result = __hibits + (size_t)__val + __coeff * __exponent;
00237 
00238     return __result;
00239       }
00240     };
00241 
00242   /// Explicit specializations for string.
00243   template<>
00244     struct hash<string>
00245     : public std::unary_function<string, size_t>
00246     {
00247       size_t
00248       operator()(const string& __s) const
00249       { return _Fnv_hash<>::hash(__s.data(), __s.length()); }
00250     };
00251 
00252 #ifdef _GLIBCXX_USE_WCHAR_T
00253   /// Explicit specializations for wstring.
00254   template<>
00255     struct hash<wstring>
00256     : public std::unary_function<wstring, size_t>
00257     {
00258       size_t
00259       operator()(const wstring& __s) const
00260       {
00261     const char* __p = reinterpret_cast<const char*>(__s.data());
00262     return _Fnv_hash<>::hash(__p, __s.length() * sizeof(wchar_t));
00263       }
00264     };
00265 #endif
00266 
00267 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
00268   /// Explicit specializations for u16string.
00269   template<>
00270     struct hash<u16string>
00271     : public std::unary_function<u16string, size_t>
00272     {
00273       size_t
00274       operator()(const u16string& __s) const
00275       {
00276     const char* __p = reinterpret_cast<const char*>(__s.data());
00277     return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char16_t));
00278       }
00279     };
00280 
00281   /// Explicit specializations for u32string.
00282   template<>
00283     struct hash<u32string>
00284     : public std::unary_function<u32string, size_t>
00285     {
00286       size_t
00287       operator()(const u32string& __s) const
00288       {
00289     const char* __p = reinterpret_cast<const char*>(__s.data());
00290     return _Fnv_hash<>::hash(__p, __s.length() * sizeof(char32_t));
00291       }
00292     };
00293 #endif
00294 
00295   /// Explicit specializations for error_code.
00296   template<>
00297     struct hash<error_code>
00298     : public std::unary_function<error_code, size_t>
00299     {
00300       size_t
00301       operator()(const error_code& __e) const
00302       {
00303     const char* __p = reinterpret_cast<const char*>(&__e);
00304     return _Fnv_hash<>::hash(__p, sizeof(__e));
00305       }
00306     };
00307   // @} group hashes
00308 }
00309 
00310 #endif // _FUNCTIONAL_HASH_H

Generated on 9 Feb 2010 for libstdc++ by  doxygen 1.6.1