pion
5.0.6
|
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