functional_hash.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00045 template<typename _Tp>
00046 struct hash;
00047
00048
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
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
00088
00089
00090
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
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
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
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
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
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
00192
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