00001
00002
00003
00004
00005
00006
00007
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 <tr1/unordered_map>
00021 #elif defined(PION_HAVE_EXT_HASH_MAP)
00022 #include <ext/hash_map>
00023 #elif defined(PION_HAVE_HASH_MAP)
00024 #include <hash_map>
00025 #endif
00026
00027
00028 namespace pion {
00029
00030
00031 #if defined(PION_HAVE_UNORDERED_MAP)
00032 #define PION_HASH_MAP std::tr1::unordered_map
00033 #define PION_HASH_MULTIMAP std::tr1::unordered_multimap
00034 #define PION_HASH_STRING boost::hash<std::string>
00035 #define PION_HASH(TYPE) boost::hash<TYPE>
00036 #elif defined(PION_HAVE_EXT_HASH_MAP)
00037 #if __GNUC__ >= 3
00038 #define PION_HASH_MAP __gnu_cxx::hash_map
00039 #define PION_HASH_MULTIMAP __gnu_cxx::hash_multimap
00040 #else
00041 #define PION_HASH_MAP hash_map
00042 #define PION_HASH_MULTIMAP hash_multimap
00043 #endif
00044 #define PION_HASH_STRING boost::hash<std::string>
00045 #define PION_HASH(TYPE) boost::hash<TYPE>
00046 #elif defined(PION_HAVE_HASH_MAP)
00047 #ifdef _MSC_VER
00048 #define PION_HASH_MAP stdext::hash_map
00049 #define PION_HASH_MULTIMAP stdext::hash_multimap
00050 #define PION_HASH_STRING stdext::hash_compare<std::string, std::less<std::string> >
00051 #define PION_HASH(TYPE) stdext::hash_compare<TYPE, std::less<TYPE> >
00052 #else
00053 #define PION_HASH_MAP hash_map
00054 #define PION_HASH_MULTIMAP hash_multimap
00055 #define PION_HASH_STRING boost::hash<std::string>
00056 #define PION_HASH(TYPE) boost::hash<TYPE>
00057 #endif
00058 #endif
00059
00063 struct iequal_to
00064 : std::binary_function<std::string, std::string, bool>
00065 {
00066 bool operator()(std::string const& x,
00067 std::string const& y) const
00068 {
00069 return boost::algorithm::iequals(x, y, std::locale());
00070 }
00071 };
00072
00076 struct ihash
00077 : std::unary_function<std::string, std::size_t>
00078 {
00079 std::size_t operator()(std::string const& x) const
00080 {
00081 std::size_t seed = 0;
00082 std::locale locale;
00083
00084 for(std::string::const_iterator it = x.begin();
00085 it != x.end(); ++it)
00086 {
00087 boost::hash_combine(seed, std::toupper(*it, locale));
00088 }
00089
00090 return seed;
00091 }
00092 };
00093
00094 #ifdef _MSC_VER
00096 template<class _Ty> struct is_iless : public std::binary_function<_Ty, _Ty, bool>
00097 {
00099 is_iless( const std::locale& Loc=std::locale() ) : m_Loc( Loc ) {}
00100
00102 bool operator()( const _Ty& Arg1, const _Ty& Arg2 ) const
00103 {
00104 return _Ty(boost::algorithm::to_upper_copy(Arg1, m_Loc)) < _Ty(boost::algorithm::to_upper_copy(Arg2, m_Loc));
00105 }
00106
00107 private:
00108 std::locale m_Loc;
00109 };
00110
00112 struct ihash_windows : public stdext::hash_compare<std::string, is_iless<std::string> > {
00113
00114 using stdext::hash_compare<std::string, is_iless<std::string> >::operator();
00115
00116 inline size_t operator()(const std::string& str) const {
00117 return ihash()(str);
00118 }
00119 };
00120
00122 typedef PION_HASH_MULTIMAP<std::string, std::string, ihash_windows > ihash_multimap;
00123 #else
00125 typedef PION_HASH_MULTIMAP<std::string, std::string, ihash, iequal_to > ihash_multimap;
00126 #endif
00127
00128
00129 }
00130
00131 #endif