pion  5.0.6
hash_map.hpp
1 // ---------------------------------------------------------------------
2 // pion: a Boost C++ framework for building lightweight HTTP interfaces
3 // ---------------------------------------------------------------------
4 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_HASH_MAP_HEADER__
11 #define __PION_HASH_MAP_HEADER__
12 
13 #include <string>
14 #include <locale>
15 #include <boost/algorithm/string.hpp>
16 #include <boost/functional/hash.hpp>
17 #include <pion/config.hpp>
18 
19 #if defined(PION_HAVE_UNORDERED_MAP) && defined(PION_CMAKE_BUILD)
20  // cmake will search for unordered_map without tr1
21  #include <unordered_map>
22 #elif defined(PION_HAVE_UNORDERED_MAP)
23  #include <tr1/unordered_map>
24 #elif defined(PION_HAVE_EXT_HASH_MAP)
25  #include <ext/hash_map>
26 #elif defined(PION_HAVE_HASH_MAP)
27  #include <hash_map>
28 #endif
29 
30 
31 namespace pion { // begin namespace pion
32 
33 #if defined(PION_HAVE_UNORDERED_MAP) && defined(PION_CMAKE_BUILD)
34  #define PION_HASH_MAP std::unordered_map
35  #define PION_HASH_MULTIMAP std::unordered_multimap
36  #define PION_HASH_STRING boost::hash<std::string>
37  #define PION_HASH(TYPE) boost::hash<TYPE>
38 #elif defined(PION_HAVE_UNORDERED_MAP)
39  #define PION_HASH_MAP std::tr1::unordered_map
40  #define PION_HASH_MULTIMAP std::tr1::unordered_multimap
41  #define PION_HASH_STRING boost::hash<std::string>
42  #define PION_HASH(TYPE) boost::hash<TYPE>
43 #elif defined(PION_HAVE_EXT_HASH_MAP)
44  #if __GNUC__ >= 3
45  #define PION_HASH_MAP __gnu_cxx::hash_map
46  #define PION_HASH_MULTIMAP __gnu_cxx::hash_multimap
47  #else
48  #define PION_HASH_MAP hash_map
49  #define PION_HASH_MULTIMAP hash_multimap
50  #endif
51  #define PION_HASH_STRING boost::hash<std::string>
52  #define PION_HASH(TYPE) boost::hash<TYPE>
53 #elif defined(PION_HAVE_HASH_MAP)
54  #ifdef _MSC_VER
55  #define PION_HASH_MAP stdext::hash_map
56  #define PION_HASH_MULTIMAP stdext::hash_multimap
57  #define PION_HASH_STRING stdext::hash_compare<std::string, std::less<std::string> >
58  #define PION_HASH(TYPE) stdext::hash_compare<TYPE, std::less<TYPE> >
59  #else
60  #define PION_HASH_MAP hash_map
61  #define PION_HASH_MULTIMAP hash_multimap
62  #define PION_HASH_STRING boost::hash<std::string>
63  #define PION_HASH(TYPE) boost::hash<TYPE>
64  #endif
65 #endif
66 
70  struct iequal_to
71  : std::binary_function<std::string, std::string, bool>
72  {
73  bool operator()(std::string const& x,
74  std::string const& y) const
75  {
76  return boost::algorithm::iequals(x, y, std::locale());
77  }
78  };
79 
83  struct ihash
84  : std::unary_function<std::string, std::size_t>
85  {
86  std::size_t operator()(std::string const& x) const
87  {
88  std::size_t seed = 0;
89  std::locale locale;
90 
91  for(std::string::const_iterator it = x.begin();
92  it != x.end(); ++it)
93  {
94  boost::hash_combine(seed, std::toupper(*it, locale));
95  }
96 
97  return seed;
98  }
99  };
100 
101 #ifdef _MSC_VER
102  template<class _Ty> struct is_iless : public std::binary_function<_Ty, _Ty, bool>
104  {
106  is_iless( const std::locale& Loc=std::locale() ) : m_Loc( Loc ) {}
107 
109  bool operator()( const _Ty& Arg1, const _Ty& Arg2 ) const
110  {
111  return _Ty(boost::algorithm::to_upper_copy(Arg1, m_Loc)) < _Ty(boost::algorithm::to_upper_copy(Arg2, m_Loc));
112  }
113 
114  private:
115  std::locale m_Loc;
116  };
117 
119  struct ihash_windows : public stdext::hash_compare<std::string, is_iless<std::string> > {
120  // makes operator() with two arguments visible, otherwise it would be hidden by the operator() defined here
121  using stdext::hash_compare<std::string, is_iless<std::string> >::operator();
122 
123  inline size_t operator()(const std::string& str) const {
124  return ihash()(str);
125  }
126  };
127 
129  typedef PION_HASH_MULTIMAP<std::string, std::string, ihash_windows > ihash_multimap;
130 #else
131  typedef PION_HASH_MULTIMAP<std::string, std::string, ihash, iequal_to > ihash_multimap;
133 #endif
134 
135 
136 } // end namespace pion
137 
138 #endif