1// TR1 functional -*- C++ -*- 2 3// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file tr1_impl/functional_hash.h 26 * This is an internal header file, included by other library headers. 27 * You should not attempt to use it directly. 28 */ 29 30namespace std 31{ 32_GLIBCXX_BEGIN_NAMESPACE_TR1 33 34 /// Class template hash. 35 // Declaration of default hash functor std::tr1::hash. The types for 36 // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR. 37 template<typename _Tp> 38 struct hash : public std::unary_function<_Tp, size_t> 39 { 40 size_t 41 operator()(_Tp __val) const; 42 }; 43 44 /// Partial specializations for pointer types. 45 template<typename _Tp> 46 struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> 47 { 48 size_t 49 operator()(_Tp* __p) const 50 { return reinterpret_cast<size_t>(__p); } 51 }; 52 53 /// Explicit specializations for integer types. 54#define _TR1_hashtable_define_trivial_hash(_Tp) \ 55 template<> \ 56 inline size_t \ 57 hash<_Tp>::operator()(_Tp __val) const \ 58 { return static_cast<size_t>(__val); } 59 60 _TR1_hashtable_define_trivial_hash(bool); 61 _TR1_hashtable_define_trivial_hash(char); 62 _TR1_hashtable_define_trivial_hash(signed char); 63 _TR1_hashtable_define_trivial_hash(unsigned char); 64 _TR1_hashtable_define_trivial_hash(wchar_t); 65#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 66 _TR1_hashtable_define_trivial_hash(char16_t); 67 _TR1_hashtable_define_trivial_hash(char32_t); 68#endif 69 _TR1_hashtable_define_trivial_hash(short); 70 _TR1_hashtable_define_trivial_hash(int); 71 _TR1_hashtable_define_trivial_hash(long); 72 _TR1_hashtable_define_trivial_hash(long long); 73 _TR1_hashtable_define_trivial_hash(unsigned short); 74 _TR1_hashtable_define_trivial_hash(unsigned int); 75 _TR1_hashtable_define_trivial_hash(unsigned long); 76 _TR1_hashtable_define_trivial_hash(unsigned long long); 77 78#undef _TR1_hashtable_define_trivial_hash 79 80 // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) 81 // (Used by the next specializations of std::tr1::hash.) 82 83 /// Dummy generic implementation (for sizeof(size_t) != 4, 8). 84 template<size_t = sizeof(size_t)> 85 struct _Fnv_hash 86 { 87 static size_t 88 hash(const char* __first, size_t __length) 89 { 90 size_t __result = 0; 91 for (; __length > 0; --__length) 92 __result = (__result * 131) + *__first++; 93 return __result; 94 } 95 }; 96 97 template<> 98 struct _Fnv_hash<4> 99 { 100 static size_t 101 hash(const char* __first, size_t __length) 102 { 103 size_t __result = static_cast<size_t>(2166136261UL); 104 for (; __length > 0; --__length) 105 { 106 __result ^= static_cast<size_t>(*__first++); 107 __result *= static_cast<size_t>(16777619UL); 108 } 109 return __result; 110 } 111 }; 112 113 template<> 114 struct _Fnv_hash<8> 115 { 116 static size_t 117 hash(const char* __first, size_t __length) 118 { 119 size_t __result = 120 static_cast<size_t>(14695981039346656037ULL); 121 for (; __length > 0; --__length) 122 { 123 __result ^= static_cast<size_t>(*__first++); 124 __result *= static_cast<size_t>(1099511628211ULL); 125 } 126 return __result; 127 } 128 }; 129 130 /// Explicit specializations for float. 131 template<> 132 inline size_t 133 hash<float>::operator()(float __val) const 134 { 135 size_t __result = 0; 136 137 // 0 and -0 both hash to zero. 138 if (__val != 0.0f) 139 __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), 140 sizeof(__val)); 141 return __result; 142 }; 143 144 /// Explicit specializations for double. 145 template<> 146 inline size_t 147 hash<double>::operator()(double __val) const 148 { 149 size_t __result = 0; 150 151 // 0 and -0 both hash to zero. 152 if (__val != 0.0) 153 __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val), 154 sizeof(__val)); 155 return __result; 156 }; 157 158 /// Explicit specializations for long double. 159 template<> 160 size_t 161 hash<long double>::operator()(long double __val) const; 162 163 /// Explicit specialization of member operator for non-builtin types. 164 template<> 165 size_t 166 hash<string>::operator()(string) const; 167 168 template<> 169 size_t 170 hash<const string&>::operator()(const string&) const; 171 172#ifdef _GLIBCXX_USE_WCHAR_T 173 template<> 174 size_t 175 hash<wstring>::operator()(wstring) const; 176 177 template<> 178 size_t 179 hash<const wstring&>::operator()(const wstring&) const; 180#endif 181 182_GLIBCXX_END_NAMESPACE_TR1 183} 184