00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __PION_PIONHASHMAP_HEADER__
00011 #define __PION_PIONHASHMAP_HEADER__
00012
00013 #include <string>
00014 #include <cctype>
00015 #include <boost/functional/hash.hpp>
00016 #include <pion/PionConfig.hpp>
00017
00018 #if defined(PION_HAVE_UNORDERED_MAP)
00019 #include <tr1/unordered_map>
00020 #elif defined(PION_HAVE_EXT_HASH_MAP)
00021 #include <ext/hash_map>
00022 #elif defined(PION_HAVE_HASH_MAP)
00023 #include <hash_map>
00024 #endif
00025
00026
00027 namespace pion {
00028
00029
00030 #if defined(PION_HAVE_UNORDERED_MAP)
00031 #define PION_HASH_MAP std::tr1::unordered_map
00032 #define PION_HASH_MULTIMAP std::tr1::unordered_multimap
00033 #define PION_HASH_STRING boost::hash<std::string>
00034 #define PION_HASH(TYPE) boost::hash<TYPE>
00035 #elif defined(PION_HAVE_EXT_HASH_MAP)
00036 #if __GNUC__ >= 3
00037 #define PION_HASH_MAP __gnu_cxx::hash_map
00038 #define PION_HASH_MULTIMAP __gnu_cxx::hash_multimap
00039 #else
00040 #define PION_HASH_MAP hash_map
00041 #define PION_HASH_MULTIMAP hash_multimap
00042 #endif
00043 #define PION_HASH_STRING boost::hash<std::string>
00044 #define PION_HASH(TYPE) boost::hash<TYPE>
00045 #elif defined(PION_HAVE_HASH_MAP)
00046 #ifdef _MSC_VER
00047 #define PION_HASH_MAP stdext::hash_map
00048 #define PION_HASH_MULTIMAP stdext::hash_multimap
00049 #define PION_HASH_STRING stdext::hash_compare<std::string, std::less<std::string> >
00050 #define PION_HASH(TYPE) stdext::hash_compare<TYPE, std::less<TYPE> >
00051 #else
00052 #define PION_HASH_MAP hash_map
00053 #define PION_HASH_MULTIMAP hash_multimap
00054 #define PION_HASH_STRING boost::hash<std::string>
00055 #define PION_HASH(TYPE) boost::hash<TYPE>
00056 #endif
00057 #endif
00058
00059
00061 struct CaseInsensitiveEqual {
00062 inline bool operator()(const std::string& str1, const std::string& str2) const {
00063 if (str1.size() != str2.size())
00064 return false;
00065 std::string::const_iterator it1 = str1.begin();
00066 std::string::const_iterator it2 = str2.begin();
00067 while ( (it1!=str1.end()) && (it2!=str2.end()) ) {
00068 if (tolower(*it1) != tolower(*it2))
00069 return false;
00070 ++it1;
00071 ++it2;
00072 }
00073 return true;
00074 }
00075 };
00076
00077
00079 struct CaseInsensitiveHash {
00080 inline unsigned long operator()(const std::string& str) const {
00081 unsigned long value = 0;
00082 for (std::string::const_iterator i = str.begin(); i!= str.end(); ++i)
00083 value = static_cast<unsigned char>(tolower(*i)) + (value << 6) + (value << 16) - value;
00084 return value;
00085 }
00086 };
00087
00088
00090 struct CaseInsensitiveLess {
00091 inline bool operator()(const std::string& str1, const std::string& str2) const {
00092 std::string::const_iterator it1 = str1.begin();
00093 std::string::const_iterator it2 = str2.begin();
00094 while ( (it1 != str1.end()) && (it2 != str2.end()) ) {
00095 if (tolower(*it1) != tolower(*it2))
00096 return (tolower(*it1) < tolower(*it2));
00097 ++it1;
00098 ++it2;
00099 }
00100 return (str1.size() < str2.size());
00101 }
00102 };
00103
00104
00105 #ifdef _MSC_VER
00107 struct CaseInsensitiveHashCompare : public stdext::hash_compare<std::string, CaseInsensitiveLess> {
00108
00109 using stdext::hash_compare<std::string, CaseInsensitiveLess>::operator();
00110
00111 inline size_t operator()(const std::string& str) const {
00112 return CaseInsensitiveHash()(str);
00113 }
00114 };
00115 #endif
00116
00117
00119 #ifdef _MSC_VER
00120 typedef PION_HASH_MULTIMAP<std::string, std::string, CaseInsensitiveHashCompare> StringDictionary;
00121 #else
00122 typedef PION_HASH_MULTIMAP<std::string, std::string, CaseInsensitiveHash, CaseInsensitiveEqual > StringDictionary;
00123 #endif
00124
00126
00127
00128
00129 }
00130
00131 #endif