1// 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 bits/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 _FUNCTIONAL_HASH_H 31#define _FUNCTIONAL_HASH_H 1 32 33#pragma GCC system_header 34 35#include <cstddef> 36#include <bits/stl_function.h> 37 38namespace std 39{ 40 /** @defgroup hashes Hashes 41 * @ingroup functors 42 * 43 * Hashing functors taking a variable type and returning a @c std::size_t. 44 * 45 * @{ 46 */ 47 48 /// Primary class template hash. 49 template<typename _Tp> 50 struct hash : public std::unary_function<_Tp, size_t> 51 { 52 size_t 53 operator()(_Tp __val) const; 54 }; 55 56 /// Partial specializations for pointer types. 57 template<typename _Tp> 58 struct hash<_Tp*> : public std::unary_function<_Tp*, size_t> 59 { 60 size_t 61 operator()(_Tp* __p) const 62 { return reinterpret_cast<size_t>(__p); } 63 }; 64 65 // Explicit specializations for integer types. 66#define _Cxx_hashtable_define_trivial_hash(_Tp) \ 67 template<> \ 68 inline size_t \ 69 hash<_Tp>::operator()(_Tp __val) const \ 70 { return static_cast<size_t>(__val); } 71 72 /// Explicit specialization for bool. 73 _Cxx_hashtable_define_trivial_hash(bool); 74 75 /// Explicit specialization for char. 76 _Cxx_hashtable_define_trivial_hash(char); 77 78 /// Explicit specialization for signed char. 79 _Cxx_hashtable_define_trivial_hash(signed char); 80 81 /// Explicit specialization for unsigned char. 82 _Cxx_hashtable_define_trivial_hash(unsigned char); 83 84 /// Explicit specialization for wchar_t. 85 _Cxx_hashtable_define_trivial_hash(wchar_t); 86 87 /// Explicit specialization for char16_t. 88 _Cxx_hashtable_define_trivial_hash(char16_t); 89 90 /// Explicit specialization for char32_t. 91 _Cxx_hashtable_define_trivial_hash(char32_t); 92 93 /// Explicit specialization for short. 94 _Cxx_hashtable_define_trivial_hash(short); 95 96 /// Explicit specialization for int. 97 _Cxx_hashtable_define_trivial_hash(int); 98 99 /// Explicit specialization for long. 100 _Cxx_hashtable_define_trivial_hash(long); 101 102 /// Explicit specialization for long long. 103 _Cxx_hashtable_define_trivial_hash(long long); 104 105 /// Explicit specialization for unsigned short. 106 _Cxx_hashtable_define_trivial_hash(unsigned short); 107 108 /// Explicit specialization for unsigned int. 109 _Cxx_hashtable_define_trivial_hash(unsigned int); 110 111 /// Explicit specialization for unsigned long. 112 _Cxx_hashtable_define_trivial_hash(unsigned long); 113 114 /// Explicit specialization for unsigned long long. 115 _Cxx_hashtable_define_trivial_hash(unsigned long long); 116 117#undef _Cxx_hashtable_define_trivial_hash 118 119 // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) 120 121 // Dummy generic implementation (for sizeof(size_t) != 4, 8). 122 template<size_t> 123 struct _Fnv_hash_base 124 { 125 template<typename _Tp> 126 static size_t 127 hash(const _Tp* __ptr, size_t __clength, size_t __hash = 0) 128 { 129 const char* __cptr = reinterpret_cast<const char*>(__ptr); 130 for (; __clength; --__clength) 131 __hash = (__hash * 131) + *__cptr++; 132 return __hash; 133 } 134 }; 135 136 template<> 137 struct _Fnv_hash_base<4> 138 { 139 template<typename _Tp> 140 static size_t 141 hash(const _Tp* __ptr, size_t __clength, 142 size_t __hash = static_cast<size_t>(2166136261UL)) 143 { 144 const char* __cptr = reinterpret_cast<const char*>(__ptr); 145 for (; __clength; --__clength) 146 { 147 __hash ^= static_cast<size_t>(*__cptr++); 148 __hash *= static_cast<size_t>(16777619UL); 149 } 150 return __hash; 151 } 152 }; 153 154 template<> 155 struct _Fnv_hash_base<8> 156 { 157 template<typename _Tp> 158 static size_t 159 hash(const _Tp* __ptr, size_t __clength, 160 size_t __hash = static_cast<size_t>(14695981039346656037ULL)) 161 { 162 const char* __cptr = reinterpret_cast<const char*>(__ptr); 163 for (; __clength; --__clength) 164 { 165 __hash ^= static_cast<size_t>(*__cptr++); 166 __hash *= static_cast<size_t>(1099511628211ULL); 167 } 168 return __hash; 169 } 170 }; 171 172 struct _Fnv_hash 173 : public _Fnv_hash_base<sizeof(size_t)> 174 { 175 using _Fnv_hash_base<sizeof(size_t)>::hash; 176 177 template<typename _Tp> 178 static size_t 179 hash(const _Tp& __val) 180 { return hash(&__val, sizeof(__val)); } 181 182 template<typename _Tp> 183 static size_t 184 __hash_combine(const _Tp& __val, size_t __hash) 185 { return hash(&__val, sizeof(__val), __hash); } 186 }; 187 188 /// Specialization for float. 189 template<> 190 inline size_t 191 hash<float>::operator()(float __val) const 192 { 193 // 0 and -0 both hash to zero. 194 return __val != 0.0f ? std::_Fnv_hash::hash(__val) : 0; 195 } 196 197 /// Specialization for double. 198 template<> 199 inline size_t 200 hash<double>::operator()(double __val) const 201 { 202 // 0 and -0 both hash to zero. 203 return __val != 0.0 ? std::_Fnv_hash::hash(__val) : 0; 204 } 205 206 /// Specialization for long double. 207 template<> 208 _GLIBCXX_PURE size_t 209 hash<long double>::operator()(long double __val) const; 210 211 // @} group hashes 212} 213 214#endif // _FUNCTIONAL_HASH_H 215