libstdc++
|
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 }