1// TR1 functional_hash.h header -*- C++ -*- 2 3// Copyright (C) 2007, 2008, 2009, 2010 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/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 30#ifndef _GLIBCXX_TR1_FUNCTIONAL_HASH_H 31#define _GLIBCXX_TR1_FUNCTIONAL_HASH_H 1 32 33#pragma GCC system_header 34 35namespace std 36{ 37namespace tr1 38{ 39 /// Class template hash. 40 // Declaration of default hash functor std::tr1::hash. The types for 41 // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR. 42 template<typename _Tp> 43 struct hash : public std::unary_function<_Tp, size_t> 44 { 45 size_t 46 operator()(_Tp __val) const; 47 }; 48 49 /// Partial specializations for pointer types. 50 template<typename _Tp> 51 struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> 52 { 53 size_t 54 operator()(_Tp* __p) const 55 { return reinterpret_cast<size_t>(__p); } 56 }; 57 58 /// Explicit specializations for integer types. 59#define _TR1_hashtable_define_trivial_hash(_Tp) \ 60 template<> \ 61 inline size_t \ 62 hash<_Tp>::operator()(_Tp __val) const \ 63 { return static_cast<size_t>(__val); } 64 65 _TR1_hashtable_define_trivial_hash(bool); 66 _TR1_hashtable_define_trivial_hash(char); 67 _TR1_hashtable_define_trivial_hash(signed char); 68 _TR1_hashtable_define_trivial_hash(unsigned char); 69 _TR1_hashtable_define_trivial_hash(wchar_t); 70 _TR1_hashtable_define_trivial_hash(short); 71 _TR1_hashtable_define_trivial_hash(int); 72 _TR1_hashtable_define_trivial_hash(long); 73 _TR1_hashtable_define_trivial_hash(long long); 74 _TR1_hashtable_define_trivial_hash(unsigned short); 75 _TR1_hashtable_define_trivial_hash(unsigned int); 76 _TR1_hashtable_define_trivial_hash(unsigned long); 77 _TR1_hashtable_define_trivial_hash(unsigned long long); 78 79#undef _TR1_hashtable_define_trivial_hash 80 81 // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) 82 // (Used by the next specializations of std::tr1::hash.) 83 84 /// Dummy generic implementation (for sizeof(size_t) != 4, 8). 85 template<size_t> 86 struct _Fnv_hash_base 87 { 88 template<typename _Tp> 89 static size_t 90 hash(const _Tp* __ptr, size_t __clength) 91 { 92 size_t __result = 0; 93 const char* __cptr = reinterpret_cast<const char*>(__ptr); 94 for (; __clength; --__clength) 95 __result = (__result * 131) + *__cptr++; 96 return __result; 97 } 98 }; 99 100 template<> 101 struct _Fnv_hash_base<4> 102 { 103 template<typename _Tp> 104 static size_t 105 hash(const _Tp* __ptr, size_t __clength) 106 { 107 size_t __result = static_cast<size_t>(2166136261UL); 108 const char* __cptr = reinterpret_cast<const char*>(__ptr); 109 for (; __clength; --__clength) 110 { 111 __result ^= static_cast<size_t>(*__cptr++); 112 __result *= static_cast<size_t>(16777619UL); 113 } 114 return __result; 115 } 116 }; 117 118 template<> 119 struct _Fnv_hash_base<8> 120 { 121 template<typename _Tp> 122 static size_t 123 hash(const _Tp* __ptr, size_t __clength) 124 { 125 size_t __result 126 = static_cast<size_t>(14695981039346656037ULL); 127 const char* __cptr = reinterpret_cast<const char*>(__ptr); 128 for (; __clength; --__clength) 129 { 130 __result ^= static_cast<size_t>(*__cptr++); 131 __result *= static_cast<size_t>(1099511628211ULL); 132 } 133 return __result; 134 } 135 }; 136 137 struct _Fnv_hash 138 : public _Fnv_hash_base<sizeof(size_t)> 139 { 140 using _Fnv_hash_base<sizeof(size_t)>::hash; 141 142 template<typename _Tp> 143 static size_t 144 hash(const _Tp& __val) 145 { return hash(&__val, sizeof(__val)); } 146 }; 147 148 /// Explicit specializations for float. 149 template<> 150 inline size_t 151 hash<float>::operator()(float __val) const 152 { 153 // 0 and -0 both hash to zero. 154 return __val != 0.0f ? std::tr1::_Fnv_hash::hash(__val) : 0; 155 } 156 157 /// Explicit specializations for double. 158 template<> 159 inline size_t 160 hash<double>::operator()(double __val) const 161 { 162 // 0 and -0 both hash to zero. 163 return __val != 0.0 ? std::tr1::_Fnv_hash::hash(__val) : 0; 164 } 165 166 /// Explicit specializations for long double. 167 template<> 168 _GLIBCXX_PURE size_t 169 hash<long double>::operator()(long double __val) const; 170 171 /// Explicit specialization of member operator for non-builtin types. 172 template<> 173 _GLIBCXX_PURE size_t 174 hash<string>::operator()(string) const; 175 176 template<> 177 _GLIBCXX_PURE size_t 178 hash<const string&>::operator()(const string&) const; 179 180#ifdef _GLIBCXX_USE_WCHAR_T 181 template<> 182 _GLIBCXX_PURE size_t 183 hash<wstring>::operator()(wstring) const; 184 185 template<> 186 _GLIBCXX_PURE size_t 187 hash<const wstring&>::operator()(const wstring&) const; 188#endif 189} 190} 191 192#endif // _GLIBCXX_TR1_FUNCTIONAL_HASH_H 193