common/include/pion/PionHashMap.hpp

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

Generated on Fri Apr 30 14:48:53 2010 for pion-net by  doxygen 1.4.7