libstdc++
functional_hash.h
Go to the documentation of this file.
00001 // functional_hash.h header -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/functional_hash.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{functional}
00028  */
00029 
00030 #ifndef _FUNCTIONAL_HASH_H
00031 #define _FUNCTIONAL_HASH_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #include <bits/hash_bytes.h>
00036 
00037 namespace std _GLIBCXX_VISIBILITY(default)
00038 {
00039 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00040 
00041   /** @defgroup hashes Hashes
00042    *  @ingroup functors
00043    *
00044    *   Hashing functors taking a variable type and returning a @c std::size_t.
00045    *
00046    *  @{
00047    */
00048 
00049   template<typename _Result, typename _Arg>
00050     struct __hash_base
00051     {
00052       typedef _Result     result_type;
00053       typedef _Arg      argument_type;
00054     };
00055 
00056   /// Primary class template hash.
00057   template<typename _Tp>
00058     struct hash : public __hash_base<size_t, _Tp>
00059     {
00060       size_t
00061       operator()(_Tp __val) const;
00062     };
00063 
00064   /// Partial specializations for pointer types.
00065   template<typename _Tp>
00066     struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
00067     {
00068       size_t
00069       operator()(_Tp* __p) const
00070       { return reinterpret_cast<size_t>(__p); }
00071     };
00072 
00073   // Explicit specializations for integer types.
00074 #define _Cxx_hashtable_define_trivial_hash(_Tp)     \
00075   template<>                        \
00076     inline size_t                   \
00077     hash<_Tp>::operator()(_Tp __val) const      \
00078     { return static_cast<size_t>(__val); }
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     inline size_t
00166     hash<float>::operator()(float __val) const
00167     {
00168       // 0 and -0 both hash to zero.
00169       return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0;
00170     }
00171 
00172   /// Specialization for double.
00173   template<>
00174     inline size_t
00175     hash<double>::operator()(double __val) const
00176     {
00177       // 0 and -0 both hash to zero.
00178       return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0;
00179     }
00180 
00181   /// Specialization for long double.
00182   template<>
00183     _GLIBCXX_PURE size_t
00184     hash<long double>::operator()(long double __val) const;
00185 
00186   // @} group hashes
00187 
00188 _GLIBCXX_END_NAMESPACE_VERSION
00189 } // namespace
00190 
00191 #endif // _FUNCTIONAL_HASH_H