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