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 }

Generated on Wed Mar 26 00:42:58 2008 for libstdc++ by  doxygen 1.5.1