1*e4b17023SJohn Marino // functional_hash.h header -*- C++ -*-
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9*e4b17023SJohn Marino // any later version.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*e4b17023SJohn Marino // GNU General Public License for more details.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino /** @file bits/functional_hash.h
26*e4b17023SJohn Marino * This is an internal header file, included by other library headers.
27*e4b17023SJohn Marino * Do not attempt to use it directly. @headername{functional}
28*e4b17023SJohn Marino */
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino #ifndef _FUNCTIONAL_HASH_H
31*e4b17023SJohn Marino #define _FUNCTIONAL_HASH_H 1
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino #pragma GCC system_header
34*e4b17023SJohn Marino
35*e4b17023SJohn Marino #include <bits/hash_bytes.h>
36*e4b17023SJohn Marino
_GLIBCXX_VISIBILITY(default)37*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
40*e4b17023SJohn Marino
41*e4b17023SJohn Marino /** @defgroup hashes Hashes
42*e4b17023SJohn Marino * @ingroup functors
43*e4b17023SJohn Marino *
44*e4b17023SJohn Marino * Hashing functors taking a variable type and returning a @c std::size_t.
45*e4b17023SJohn Marino *
46*e4b17023SJohn Marino * @{
47*e4b17023SJohn Marino */
48*e4b17023SJohn Marino
49*e4b17023SJohn Marino template<typename _Result, typename _Arg>
50*e4b17023SJohn Marino struct __hash_base
51*e4b17023SJohn Marino {
52*e4b17023SJohn Marino typedef _Result result_type;
53*e4b17023SJohn Marino typedef _Arg argument_type;
54*e4b17023SJohn Marino };
55*e4b17023SJohn Marino
56*e4b17023SJohn Marino /// Primary class template hash.
57*e4b17023SJohn Marino template<typename _Tp>
58*e4b17023SJohn Marino struct hash : public __hash_base<size_t, _Tp>
59*e4b17023SJohn Marino {
60*e4b17023SJohn Marino static_assert(sizeof(_Tp) < 0,
61*e4b17023SJohn Marino "std::hash is not specialized for this type");
62*e4b17023SJohn Marino size_t operator()(const _Tp&) const noexcept;
63*e4b17023SJohn Marino };
64*e4b17023SJohn Marino
65*e4b17023SJohn Marino /// Partial specializations for pointer types.
66*e4b17023SJohn Marino template<typename _Tp>
67*e4b17023SJohn Marino struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
68*e4b17023SJohn Marino {
69*e4b17023SJohn Marino size_t
70*e4b17023SJohn Marino operator()(_Tp* __p) const noexcept
71*e4b17023SJohn Marino { return reinterpret_cast<size_t>(__p); }
72*e4b17023SJohn Marino };
73*e4b17023SJohn Marino
74*e4b17023SJohn Marino // Explicit specializations for integer types.
75*e4b17023SJohn Marino #define _Cxx_hashtable_define_trivial_hash(_Tp) \
76*e4b17023SJohn Marino template<> \
77*e4b17023SJohn Marino struct hash<_Tp> : public __hash_base<size_t, _Tp> \
78*e4b17023SJohn Marino { \
79*e4b17023SJohn Marino size_t \
80*e4b17023SJohn Marino operator()(_Tp __val) const noexcept \
81*e4b17023SJohn Marino { return static_cast<size_t>(__val); } \
82*e4b17023SJohn Marino };
83*e4b17023SJohn Marino
84*e4b17023SJohn Marino /// Explicit specialization for bool.
85*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(bool)
86*e4b17023SJohn Marino
87*e4b17023SJohn Marino /// Explicit specialization for char.
88*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(char)
89*e4b17023SJohn Marino
90*e4b17023SJohn Marino /// Explicit specialization for signed char.
91*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(signed char)
92*e4b17023SJohn Marino
93*e4b17023SJohn Marino /// Explicit specialization for unsigned char.
94*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(unsigned char)
95*e4b17023SJohn Marino
96*e4b17023SJohn Marino /// Explicit specialization for wchar_t.
97*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(wchar_t)
98*e4b17023SJohn Marino
99*e4b17023SJohn Marino /// Explicit specialization for char16_t.
100*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(char16_t)
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino /// Explicit specialization for char32_t.
103*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(char32_t)
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino /// Explicit specialization for short.
106*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(short)
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino /// Explicit specialization for int.
109*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(int)
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino /// Explicit specialization for long.
112*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(long)
113*e4b17023SJohn Marino
114*e4b17023SJohn Marino /// Explicit specialization for long long.
115*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(long long)
116*e4b17023SJohn Marino
117*e4b17023SJohn Marino /// Explicit specialization for unsigned short.
118*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(unsigned short)
119*e4b17023SJohn Marino
120*e4b17023SJohn Marino /// Explicit specialization for unsigned int.
121*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(unsigned int)
122*e4b17023SJohn Marino
123*e4b17023SJohn Marino /// Explicit specialization for unsigned long.
124*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(unsigned long)
125*e4b17023SJohn Marino
126*e4b17023SJohn Marino /// Explicit specialization for unsigned long long.
127*e4b17023SJohn Marino _Cxx_hashtable_define_trivial_hash(unsigned long long)
128*e4b17023SJohn Marino
129*e4b17023SJohn Marino #undef _Cxx_hashtable_define_trivial_hash
130*e4b17023SJohn Marino
131*e4b17023SJohn Marino struct _Hash_impl
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino static size_t
134*e4b17023SJohn Marino hash(const void* __ptr, size_t __clength,
135*e4b17023SJohn Marino size_t __seed = static_cast<size_t>(0xc70f6907UL))
136*e4b17023SJohn Marino { return _Hash_bytes(__ptr, __clength, __seed); }
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino template<typename _Tp>
139*e4b17023SJohn Marino static size_t
140*e4b17023SJohn Marino hash(const _Tp& __val)
141*e4b17023SJohn Marino { return hash(&__val, sizeof(__val)); }
142*e4b17023SJohn Marino
143*e4b17023SJohn Marino template<typename _Tp>
144*e4b17023SJohn Marino static size_t
145*e4b17023SJohn Marino __hash_combine(const _Tp& __val, size_t __hash)
146*e4b17023SJohn Marino { return hash(&__val, sizeof(__val), __hash); }
147*e4b17023SJohn Marino };
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino struct _Fnv_hash_impl
150*e4b17023SJohn Marino {
151*e4b17023SJohn Marino static size_t
152*e4b17023SJohn Marino hash(const void* __ptr, size_t __clength,
153*e4b17023SJohn Marino size_t __seed = static_cast<size_t>(2166136261UL))
154*e4b17023SJohn Marino { return _Fnv_hash_bytes(__ptr, __clength, __seed); }
155*e4b17023SJohn Marino
156*e4b17023SJohn Marino template<typename _Tp>
157*e4b17023SJohn Marino static size_t
158*e4b17023SJohn Marino hash(const _Tp& __val)
159*e4b17023SJohn Marino { return hash(&__val, sizeof(__val)); }
160*e4b17023SJohn Marino
161*e4b17023SJohn Marino template<typename _Tp>
162*e4b17023SJohn Marino static size_t
163*e4b17023SJohn Marino __hash_combine(const _Tp& __val, size_t __hash)
164*e4b17023SJohn Marino { return hash(&__val, sizeof(__val), __hash); }
165*e4b17023SJohn Marino };
166*e4b17023SJohn Marino
167*e4b17023SJohn Marino /// Specialization for float.
168*e4b17023SJohn Marino template<>
169*e4b17023SJohn Marino struct hash<float> : public __hash_base<size_t, float>
170*e4b17023SJohn Marino {
171*e4b17023SJohn Marino size_t
172*e4b17023SJohn Marino operator()(float __val) const noexcept
173*e4b17023SJohn Marino {
174*e4b17023SJohn Marino // 0 and -0 both hash to zero.
175*e4b17023SJohn Marino return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0;
176*e4b17023SJohn Marino }
177*e4b17023SJohn Marino };
178*e4b17023SJohn Marino
179*e4b17023SJohn Marino /// Specialization for double.
180*e4b17023SJohn Marino template<>
181*e4b17023SJohn Marino struct hash<double> : public __hash_base<size_t, double>
182*e4b17023SJohn Marino {
183*e4b17023SJohn Marino size_t
184*e4b17023SJohn Marino operator()(double __val) const noexcept
185*e4b17023SJohn Marino {
186*e4b17023SJohn Marino // 0 and -0 both hash to zero.
187*e4b17023SJohn Marino return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0;
188*e4b17023SJohn Marino }
189*e4b17023SJohn Marino };
190*e4b17023SJohn Marino
191*e4b17023SJohn Marino /// Specialization for long double.
192*e4b17023SJohn Marino template<>
193*e4b17023SJohn Marino struct hash<long double>
194*e4b17023SJohn Marino : public __hash_base<size_t, long double>
195*e4b17023SJohn Marino {
196*e4b17023SJohn Marino _GLIBCXX_PURE size_t
197*e4b17023SJohn Marino operator()(long double __val) const noexcept;
198*e4b17023SJohn Marino };
199*e4b17023SJohn Marino
200*e4b17023SJohn Marino // @} group hashes
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
203*e4b17023SJohn Marino } // namespace
204*e4b17023SJohn Marino
205*e4b17023SJohn Marino #endif // _FUNCTIONAL_HASH_H
206