pion  5.0.6
include/pion/hash_map.hpp
00001 // ---------------------------------------------------------------------
00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
00003 // ---------------------------------------------------------------------
00004 // Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #ifndef __PION_HASH_MAP_HEADER__
00011 #define __PION_HASH_MAP_HEADER__
00012 
00013 #include <string>
00014 #include <locale>
00015 #include <boost/algorithm/string.hpp>
00016 #include <boost/functional/hash.hpp>
00017 #include <pion/config.hpp>
00018 
00019 #if defined(PION_HAVE_UNORDERED_MAP)
00020     #include <unordered_map>
00021 #elif defined(PION_HAVE_TR1_UNORDERED_MAP)
00022     #include <tr1/unordered_map>
00023 #elif defined(PION_HAVE_EXT_HASH_MAP)
00024     #include <ext/hash_map>
00025 #elif defined(PION_HAVE_HASH_MAP)
00026     #include <hash_map>
00027 #endif
00028 
00029 
00030 namespace pion {    // begin namespace pion
00031 
00032 #if defined(PION_HAVE_UNORDERED_MAP)
00033     #define PION_HASH_MAP std::unordered_map
00034     #define PION_HASH_MULTIMAP std::unordered_multimap
00035     #define PION_HASH_STRING boost::hash<std::string>
00036     #define PION_HASH(TYPE) boost::hash<TYPE>
00037 #elif defined(PION_HAVE_TR1_UNORDERED_MAP)
00038     #define PION_HASH_MAP std::tr1::unordered_map
00039     #define PION_HASH_MULTIMAP std::tr1::unordered_multimap
00040     #define PION_HASH_STRING boost::hash<std::string>
00041     #define PION_HASH(TYPE) boost::hash<TYPE>
00042 #elif defined(PION_HAVE_EXT_HASH_MAP)
00043     #if __GNUC__ >= 3
00044         #define PION_HASH_MAP __gnu_cxx::hash_map
00045         #define PION_HASH_MULTIMAP __gnu_cxx::hash_multimap
00046     #else
00047         #define PION_HASH_MAP hash_map
00048         #define PION_HASH_MULTIMAP hash_multimap
00049     #endif
00050     #define PION_HASH_STRING boost::hash<std::string>
00051     #define PION_HASH(TYPE) boost::hash<TYPE>
00052 #elif defined(PION_HAVE_HASH_MAP)
00053     #ifdef _MSC_VER
00054         #define PION_HASH_MAP stdext::hash_map
00055         #define PION_HASH_MULTIMAP stdext::hash_multimap
00056         #define PION_HASH_STRING stdext::hash_compare<std::string, std::less<std::string> >
00057         #define PION_HASH(TYPE) stdext::hash_compare<TYPE, std::less<TYPE> >
00058     #else
00059         #define PION_HASH_MAP hash_map
00060         #define PION_HASH_MULTIMAP hash_multimap
00061         #define PION_HASH_STRING boost::hash<std::string>
00062         #define PION_HASH(TYPE) boost::hash<TYPE>
00063     #endif
00064 #endif
00065 
00069     struct iequal_to
00070         : std::binary_function<std::string, std::string, bool>
00071     {
00072         bool operator()(std::string const& x,
00073                         std::string const& y) const
00074         {
00075             return boost::algorithm::iequals(x, y, std::locale());
00076         }
00077     };
00078     
00082     struct ihash
00083         : std::unary_function<std::string, std::size_t>
00084     {
00085         std::size_t operator()(std::string const& x) const
00086         {
00087             std::size_t seed = 0;
00088             std::locale locale;
00089             
00090             for(std::string::const_iterator it = x.begin();
00091                 it != x.end(); ++it)
00092             {
00093                 boost::hash_combine(seed, std::toupper(*it, locale));
00094             }
00095             
00096             return seed;
00097         }
00098     };
00099     
00100 #if defined(_MSC_VER) && !defined(PION_HAVE_UNORDERED_MAP)
00101 
00102     template<class _Ty> struct is_iless : public std::binary_function<_Ty, _Ty, bool>
00103     {
00105         is_iless( const std::locale& Loc=std::locale() ) : m_Loc( Loc ) {}
00106 
00108         bool operator()( const _Ty& Arg1, const _Ty& Arg2 ) const
00109         {
00110             return _Ty(boost::algorithm::to_upper_copy(Arg1, m_Loc)) < _Ty(boost::algorithm::to_upper_copy(Arg2, m_Loc));
00111         }
00112 
00113         private:
00114             std::locale m_Loc;
00115     };
00116 
00118     struct ihash_windows : public stdext::hash_compare<std::string, is_iless<std::string> > {
00119         // makes operator() with two arguments visible, otherwise it would be hidden by the operator() defined here
00120         using stdext::hash_compare<std::string, is_iless<std::string> >::operator();
00121         
00122         inline size_t operator()(const std::string& str) const {
00123             return ihash()(str);
00124         }
00125     };
00126 
00128     typedef PION_HASH_MULTIMAP<std::string, std::string, ihash_windows >    ihash_multimap;
00129 #else
00130 
00131     typedef PION_HASH_MULTIMAP<std::string, std::string, ihash, iequal_to >    ihash_multimap;
00132 #endif
00133 
00134 
00135 }   // end namespace pion
00136 
00137 #endif