xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/functional_hash.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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