|
libstdc++
|
00001 // functional_hash.h header -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file bits/functional_hash.h 00027 * This is an internal header file, included by other library headers. 00028 * Do not attempt to use it directly. @headername{functional} 00029 */ 00030 00031 #ifndef _FUNCTIONAL_HASH_H 00032 #define _FUNCTIONAL_HASH_H 1 00033 00034 #pragma GCC system_header 00035 00036 #include <bits/hash_bytes.h> 00037 00038 namespace std _GLIBCXX_VISIBILITY(default) 00039 { 00040 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00041 00042 /** @defgroup hashes Hashes 00043 * @ingroup functors 00044 * 00045 * Hashing functors taking a variable type and returning a @c std::size_t. 00046 * 00047 * @{ 00048 */ 00049 00050 template<typename _Result, typename _Arg> 00051 struct __hash_base 00052 { 00053 typedef _Result result_type; 00054 typedef _Arg argument_type; 00055 }; 00056 00057 /// Primary class template hash. 00058 template<typename _Tp> 00059 struct hash; 00060 00061 /// Partial specializations for pointer types. 00062 template<typename _Tp> 00063 struct hash<_Tp*> : public __hash_base<size_t, _Tp*> 00064 { 00065 size_t 00066 operator()(_Tp* __p) const noexcept 00067 { return reinterpret_cast<size_t>(__p); } 00068 }; 00069 00070 // Explicit specializations for integer types. 00071 #define _Cxx_hashtable_define_trivial_hash(_Tp) \ 00072 template<> \ 00073 struct hash<_Tp> : public __hash_base<size_t, _Tp> \ 00074 { \ 00075 size_t \ 00076 operator()(_Tp __val) const noexcept \ 00077 { return static_cast<size_t>(__val); } \ 00078 }; 00079 00080 /// Explicit specialization for bool. 00081 _Cxx_hashtable_define_trivial_hash(bool) 00082 00083 /// Explicit specialization for char. 00084 _Cxx_hashtable_define_trivial_hash(char) 00085 00086 /// Explicit specialization for signed char. 00087 _Cxx_hashtable_define_trivial_hash(signed char) 00088 00089 /// Explicit specialization for unsigned char. 00090 _Cxx_hashtable_define_trivial_hash(unsigned char) 00091 00092 /// Explicit specialization for wchar_t. 00093 _Cxx_hashtable_define_trivial_hash(wchar_t) 00094 00095 /// Explicit specialization for char16_t. 00096 _Cxx_hashtable_define_trivial_hash(char16_t) 00097 00098 /// Explicit specialization for char32_t. 00099 _Cxx_hashtable_define_trivial_hash(char32_t) 00100 00101 /// Explicit specialization for short. 00102 _Cxx_hashtable_define_trivial_hash(short) 00103 00104 /// Explicit specialization for int. 00105 _Cxx_hashtable_define_trivial_hash(int) 00106 00107 /// Explicit specialization for long. 00108 _Cxx_hashtable_define_trivial_hash(long) 00109 00110 /// Explicit specialization for long long. 00111 _Cxx_hashtable_define_trivial_hash(long long) 00112 00113 /// Explicit specialization for unsigned short. 00114 _Cxx_hashtable_define_trivial_hash(unsigned short) 00115 00116 /// Explicit specialization for unsigned int. 00117 _Cxx_hashtable_define_trivial_hash(unsigned int) 00118 00119 /// Explicit specialization for unsigned long. 00120 _Cxx_hashtable_define_trivial_hash(unsigned long) 00121 00122 /// Explicit specialization for unsigned long long. 00123 _Cxx_hashtable_define_trivial_hash(unsigned long long) 00124 00125 #undef _Cxx_hashtable_define_trivial_hash 00126 00127 struct _Hash_impl 00128 { 00129 static size_t 00130 hash(const void* __ptr, size_t __clength, 00131 size_t __seed = static_cast<size_t>(0xc70f6907UL)) 00132 { return _Hash_bytes(__ptr, __clength, __seed); } 00133 00134 template<typename _Tp> 00135 static size_t 00136 hash(const _Tp& __val) 00137 { return hash(&__val, sizeof(__val)); } 00138 00139 template<typename _Tp> 00140 static size_t 00141 __hash_combine(const _Tp& __val, size_t __hash) 00142 { return hash(&__val, sizeof(__val), __hash); } 00143 }; 00144 00145 struct _Fnv_hash_impl 00146 { 00147 static size_t 00148 hash(const void* __ptr, size_t __clength, 00149 size_t __seed = static_cast<size_t>(2166136261UL)) 00150 { return _Fnv_hash_bytes(__ptr, __clength, __seed); } 00151 00152 template<typename _Tp> 00153 static size_t 00154 hash(const _Tp& __val) 00155 { return hash(&__val, sizeof(__val)); } 00156 00157 template<typename _Tp> 00158 static size_t 00159 __hash_combine(const _Tp& __val, size_t __hash) 00160 { return hash(&__val, sizeof(__val), __hash); } 00161 }; 00162 00163 /// Specialization for float. 00164 template<> 00165 struct hash<float> : public __hash_base<size_t, float> 00166 { 00167 size_t 00168 operator()(float __val) const noexcept 00169 { 00170 // 0 and -0 both hash to zero. 00171 return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0; 00172 } 00173 }; 00174 00175 /// Specialization for double. 00176 template<> 00177 struct hash<double> : public __hash_base<size_t, double> 00178 { 00179 size_t 00180 operator()(double __val) const noexcept 00181 { 00182 // 0 and -0 both hash to zero. 00183 return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0; 00184 } 00185 }; 00186 00187 /// Specialization for long double. 00188 template<> 00189 struct hash<long double> 00190 : public __hash_base<size_t, long double> 00191 { 00192 _GLIBCXX_PURE size_t 00193 operator()(long double __val) const noexcept; 00194 }; 00195 00196 // @} group hashes 00197 00198 _GLIBCXX_END_NAMESPACE_VERSION 00199 } // namespace 00200 00201 #endif // _FUNCTIONAL_HASH_H