functional_hash.h

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

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1