# tr1_impl/functional_hash.h

Go to the documentation of this file.

    00001 // TR1 functional -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file tr1_impl/functional_hash.h
    00031  *  This is an internal header file, included by other library headers.
    00032  *  You should not attempt to use it directly.
    00033  */
    00034
    00035 namespace std
    00036 {
    00037 _GLIBCXX_BEGIN_NAMESPACE_TR1
    00038
    00039   /// Class template hash.
    00040   // Declaration of default hash functor std::tr1::hash.  The types for
    00041   // which std::tr1::hash<T> is well-defined is in clause 6.3.3. of the PDTR.
    00042   template<typename _Tp>
    00043     struct hash : public std::unary_function<_Tp, size_t>
    00044     {
    00045       size_t
    00046       operator()(_Tp __val) const;
    00047     };
    00048
    00049   /// Partial specializations for pointer types.
    00050   template<typename _Tp>
    00051     struct hash<_Tp*> : public std::unary_function<_Tp*, size_t>
    00052     {
    00053       size_t
    00054       operator()(_Tp* __p) const
    00055       { return reinterpret_cast<size_t>(__p); }
    00056     };
    00057
    00058   /// Explicit specializations for integer types.
    00059 #define _TR1_hashtable_define_trivial_hash(_Tp)     \
    00060   template<>                        \
    00061     inline size_t                   \
    00062     hash<_Tp>::operator()(_Tp __val) const      \
    00063     { return static_cast<size_t>(__val); }
    00064
    00065   _TR1_hashtable_define_trivial_hash(bool);
    00066   _TR1_hashtable_define_trivial_hash(char);
    00067   _TR1_hashtable_define_trivial_hash(signed char);
    00068   _TR1_hashtable_define_trivial_hash(unsigned char);
    00069   _TR1_hashtable_define_trivial_hash(wchar_t);
    00070   _TR1_hashtable_define_trivial_hash(short);
    00071   _TR1_hashtable_define_trivial_hash(int);
    00072   _TR1_hashtable_define_trivial_hash(long);
    00073   _TR1_hashtable_define_trivial_hash(long long);
    00074   _TR1_hashtable_define_trivial_hash(unsigned short);
    00075   _TR1_hashtable_define_trivial_hash(unsigned int);
    00076   _TR1_hashtable_define_trivial_hash(unsigned long);
    00077   _TR1_hashtable_define_trivial_hash(unsigned long long);
    00078
    00079 #undef _TR1_hashtable_define_trivial_hash
    00080
    00081   // Fowler / Noll / Vo (FNV) Hash (type FNV-1a)
    00082   // (Used by the next specializations of std::tr1::hash.)
    00083
    00084   /// Dummy generic implementation (for sizeof(size_t) != 4, 8).
    00085   template<size_t = sizeof(size_t)>
    00086     struct _Fnv_hash
    00087     {
    00088       static size_t
    00089       hash(const char* __first, size_t __length)
    00090       {
    00091     size_t __result = 0;
    00092     for (; __length > 0; --__length)
    00093       __result = (__result * 131) + *__first++;
    00094     return __result;
    00095       }
    00096     };
    00097
    00098   template<>
    00099     struct _Fnv_hash<4>
    00100     {
    00101       static size_t
    00102       hash(const char* __first, size_t __length)
    00103       {
    00104     size_t __result = static_cast<size_t>(2166136261UL);
    00105     for (; __length > 0; --__length)
    00106       {
    00107         __result ^= static_cast<size_t>(*__first++);
    00108         __result *= static_cast<size_t>(16777619UL);
    00109       }
    00110     return __result;
    00111       }
    00112     };
    00113
    00114   template<>
    00115     struct _Fnv_hash<8>
    00116     {
    00117       static size_t
    00118       hash(const char* __first, size_t __length)
    00119       {
    00120     size_t __result =
    00121       static_cast<size_t>(14695981039346656037ULL);
    00122     for (; __length > 0; --__length)
    00123       {
    00124         __result ^= static_cast<size_t>(*__first++);
    00125         __result *= static_cast<size_t>(1099511628211ULL);
    00126       }
    00127     return __result;
    00128       }
    00129     };
    00130
    00131   /// Explicit specializations for float.
    00132   template<>
    00133     inline size_t
    00134     hash<float>::operator()(float __val) const
    00135     {
    00136       size_t __result = 0;
    00137
    00138       // 0 and -0 both hash to zero.
    00139       if (__val != 0.0f)
    00140     __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
    00141                      sizeof(__val));
    00142       return __result;
    00143     };
    00144
    00145   /// Explicit specializations for double.
    00146   template<>
    00147     inline size_t
    00148     hash<double>::operator()(double __val) const
    00149     {
    00150     size_t __result = 0;
    00151
    00152     // 0 and -0 both hash to zero.
    00153     if (__val != 0.0)
    00154       __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__val),
    00155                        sizeof(__val));
    00156     return __result;
    00157     };
    00158
    00159   /// Explicit specializations for long double.
    00160   template<>
    00161     size_t
    00162     hash<long double>::operator()(long double __val) const;
    00163
    00164   /// Explicit specialization of member operator for non-builtin types.
    00165   template<>
    00166     size_t
    00167     hash<string>::operator()(string) const;
    00168
    00169   template<>
    00170     size_t
    00171     hash<const string&>::operator()(const string&) const;
    00172
    00173 #ifdef _GLIBCXX_USE_WCHAR_T
    00174   template<>
    00175     size_t
    00176     hash<wstring>::operator()(wstring) const;
    00177
    00178   template<>
    00179     size_t
    00180     hash<const wstring&>::operator()(const wstring&) const;
    00181 #endif
    00182
    00183 _GLIBCXX_END_NAMESPACE_TR1
    00184 }