pion-net
4.0.9
|
00001 // ----------------------------------------------------------------------- 00002 // pion-common: a collection of common libraries used by the Pion Platform 00003 // ----------------------------------------------------------------------- 00004 // Copyright (C) 2007-2008 Atomic Labs, Inc. (http://www.atomiclabs.com) 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_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 { // begin 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 00106 00107 struct CaseInsensitiveHashCompare : public stdext::hash_compare<std::string, CaseInsensitiveLess> { 00108 // makes operator() with two arguments visible, otherwise it would be hidden by the operator() defined here 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 //typedef PION_HASH_MULTIMAP<std::string, std::string, PION_HASH_STRING > StringDictionary; 00127 00128 00129 } // end namespace pion 00130 00131 #endif