00001 // TR1 functional -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 /** @file tr1_impl/functional_hash.h 00031 * This is an internal header file, included by other library headers. 00032 * You should not attempt to use it directly. 00033 */ 00034 00035 namespace std 00036 { 00037 _GLIBCXX_BEGIN_NAMESPACE_TR1 00038 00039 /// Class template hash. 00040 // Declaration of default hash functor std::tr1::hash. The types for 00041 // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR. 00042 template<typename _Tp> 00043 struct hash : public std::unary_function<_Tp, size_t> 00044 { 00045 size_t 00046 operator()(_Tp __val) const; 00047 }; 00048 00049 /// Partial specializations for pointer types. 00050 template<typename _Tp> 00051 struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> 00052 { 00053 size_t 00054 operator()(_Tp* __p) const 00055 { return reinterpret_cast<size_t>(__p); } 00056 }; 00057 00058 /// Explicit specializations for integer types. 00059 #define _TR1_hashtable_define_trivial_hash(_Tp) \ 00060 template<> \ 00061 inline size_t \ 00062 hash<_Tp>::operator()(_Tp __val) const \ 00063 { return static_cast<size_t>(__val); } 00064 00065 _TR1_hashtable_define_trivial_hash(bool); 00066 _TR1_hashtable_define_trivial_hash(char); 00067 _TR1_hashtable_define_trivial_hash(signed char); 00068 _TR1_hashtable_define_trivial_hash(unsigned char); 00069 _TR1_hashtable_define_trivial_hash(wchar_t); 00070 _TR1_hashtable_define_trivial_hash(short); 00071 _TR1_hashtable_define_trivial_hash(int); 00072 _TR1_hashtable_define_trivial_hash(long); 00073 _TR1_hashtable_define_trivial_hash(long long); 00074 _TR1_hashtable_define_trivial_hash(unsigned short); 00075 _TR1_hashtable_define_trivial_hash(unsigned int); 00076 _TR1_hashtable_define_trivial_hash(unsigned long); 00077 _TR1_hashtable_define_trivial_hash(unsigned long long); 00078 00079 #undef _TR1_hashtable_define_trivial_hash 00080 00081 // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) 00082 // (Used by the next specializations of std::tr1::hash.) 00083 00084 /// Dummy generic implementation (for sizeof(size_t) != 4, 8). 00085 template<size_t = sizeof(size_t)> 00086 struct _Fnv_hash 00087 { 00088 static size_t 00089 hash(const char* __first, size_t __length) 00090 { 00091 size_t __result = 0; 00092 for (; __length > 0; --__length) 00093 __result = (__result * 131) + *__first++; 00094 return __result; 00095 } 00096 }; 00097 00098 template<> 00099 struct _Fnv_hash<4> 00100 { 00101 static size_t 00102 hash(const char* __first, size_t __length) 00103 { 00104 size_t __result = static_cast<size_t>(2166136261UL); 00105 for (; __length > 0; --__length) 00106 { 00107 __result ^= static_cast<size_t>(*__first++); 00108 __result *= static_cast<size_t>(16777619UL); 00109 } 00110 return __result; 00111 } 00112 }; 00113 00114 template<> 00115 struct _Fnv_hash<8> 00116 { 00117 static size_t 00118 hash(const char* __first, size_t __length) 00119 { 00120 size_t __result = 00121 static_cast<size_t>(14695981039346656037ULL); 00122 for (; __length > 0; --__length) 00123 { 00124 __result ^= static_cast<size_t>(*__first++); 00125 __result *= static_cast<size_t>(1099511628211ULL); 00126 } 00127 return __result; 00128 } 00129 }; 00130 00131 /// Explicit specializations for float. 00132 template<> 00133 inline size_t 00134 hash<float>::operator()(float __val) const 00135 { 00136 size_t __result = 0; 00137 00138 // 0 and -0 both hash to zero. 00139 if (__val != 0.0f) 00140 __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), 00141 sizeof(__val)); 00142 return __result; 00143 }; 00144 00145 /// Explicit specializations for double. 00146 template<> 00147 inline size_t 00148 hash<double>::operator()(double __val) const 00149 { 00150 size_t __result = 0; 00151 00152 // 0 and -0 both hash to zero. 00153 if (__val != 0.0) 00154 __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), 00155 sizeof(__val)); 00156 return __result; 00157 }; 00158 00159 /// Explicit specializations for long double. 00160 template<> 00161 size_t 00162 hash<long double>::operator()(long double __val) const; 00163 00164 /// Explicit specialization of member operator for non-builtin types. 00165 template<> 00166 size_t 00167 hash<string>::operator()(string) const; 00168 00169 template<> 00170 size_t 00171 hash<const string&>::operator()(const string&) const; 00172 00173 #ifdef _GLIBCXX_USE_WCHAR_T 00174 template<> 00175 size_t 00176 hash<wstring>::operator()(wstring) const; 00177 00178 template<> 00179 size_t 00180 hash<const wstring&>::operator()(const wstring&) const; 00181 #endif 00182 00183 _GLIBCXX_END_NAMESPACE_TR1 00184 }