00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_DETAIL_HASH_MAP_HPP
00012 #define ASIO_DETAIL_HASH_MAP_HPP
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017
00018 #include "asio/detail/push_options.hpp"
00019
00020 #include "asio/detail/push_options.hpp"
00021 #include <cassert>
00022 #include <list>
00023 #include <utility>
00024 #include <boost/functional/hash.hpp>
00025 #include "asio/detail/pop_options.hpp"
00026
00027 #include "asio/detail/noncopyable.hpp"
00028 #include "asio/detail/socket_types.hpp"
00029
00030 namespace asio {
00031 namespace detail {
00032
00033 template <typename T>
00034 inline std::size_t calculate_hash_value(const T& t)
00035 {
00036 return boost::hash_value(t);
00037 }
00038
00039 #if defined(_WIN64)
00040 inline std::size_t calculate_hash_value(SOCKET s)
00041 {
00042 return static_cast<std::size_t>(s);
00043 }
00044 #endif // defined(_WIN64)
00045
00046 template <typename K, typename V>
00047 class hash_map
00048 : private noncopyable
00049 {
00050 public:
00051
00052 typedef std::pair<K, V> value_type;
00053
00054
00055 typedef typename std::list<value_type>::iterator iterator;
00056
00057
00058 typedef typename std::list<value_type>::const_iterator const_iterator;
00059
00060
00061 hash_map()
00062 {
00063
00064 for (size_t i = 0; i < num_buckets; ++i)
00065 buckets_[i].first = buckets_[i].last = values_.end();
00066 }
00067
00068
00069 iterator begin()
00070 {
00071 return values_.begin();
00072 }
00073
00074
00075 const_iterator begin() const
00076 {
00077 return values_.begin();
00078 }
00079
00080
00081 iterator end()
00082 {
00083 return values_.end();
00084 }
00085
00086
00087 const_iterator end() const
00088 {
00089 return values_.end();
00090 }
00091
00092
00093 bool empty() const
00094 {
00095 return values_.empty();
00096 }
00097
00098
00099 iterator find(const K& k)
00100 {
00101 size_t bucket = calculate_hash_value(k) % num_buckets;
00102 iterator it = buckets_[bucket].first;
00103 if (it == values_.end())
00104 return values_.end();
00105 iterator end = buckets_[bucket].last;
00106 ++end;
00107 while (it != end)
00108 {
00109 if (it->first == k)
00110 return it;
00111 ++it;
00112 }
00113 return values_.end();
00114 }
00115
00116
00117 const_iterator find(const K& k) const
00118 {
00119 size_t bucket = calculate_hash_value(k) % num_buckets;
00120 const_iterator it = buckets_[bucket].first;
00121 if (it == values_.end())
00122 return it;
00123 const_iterator end = buckets_[bucket].last;
00124 ++end;
00125 while (it != end)
00126 {
00127 if (it->first == k)
00128 return it;
00129 ++it;
00130 }
00131 return values_.end();
00132 }
00133
00134
00135 std::pair<iterator, bool> insert(const value_type& v)
00136 {
00137 size_t bucket = calculate_hash_value(v.first) % num_buckets;
00138 iterator it = buckets_[bucket].first;
00139 if (it == values_.end())
00140 {
00141 buckets_[bucket].first = buckets_[bucket].last =
00142 values_.insert(values_.end(), v);
00143 return std::pair<iterator, bool>(buckets_[bucket].last, true);
00144 }
00145 iterator end = buckets_[bucket].last;
00146 ++end;
00147 while (it != end)
00148 {
00149 if (it->first == v.first)
00150 return std::pair<iterator, bool>(it, false);
00151 ++it;
00152 }
00153 buckets_[bucket].last = values_.insert(end, v);
00154 return std::pair<iterator, bool>(buckets_[bucket].last, true);
00155 }
00156
00157
00158 void erase(iterator it)
00159 {
00160 assert(it != values_.end());
00161
00162 size_t bucket = calculate_hash_value(it->first) % num_buckets;
00163 bool is_first = (it == buckets_[bucket].first);
00164 bool is_last = (it == buckets_[bucket].last);
00165 if (is_first && is_last)
00166 buckets_[bucket].first = buckets_[bucket].last = values_.end();
00167 else if (is_first)
00168 ++buckets_[bucket].first;
00169 else if (is_last)
00170 --buckets_[bucket].last;
00171
00172 values_.erase(it);
00173 }
00174
00175
00176 void clear()
00177 {
00178
00179 values_.clear();
00180
00181
00182 for (size_t i = 0; i < num_buckets; ++i)
00183 buckets_[i].first = buckets_[i].last = values_.end();
00184 }
00185
00186 private:
00187
00188 std::list<value_type> values_;
00189
00190
00191 struct bucket_type
00192 {
00193 iterator first;
00194 iterator last;
00195 };
00196
00197
00198 enum { num_buckets = 1021 };
00199
00200
00201 bucket_type buckets_[num_buckets];
00202 };
00203
00204 }
00205 }
00206
00207 #include "asio/detail/pop_options.hpp"
00208
00209 #endif // ASIO_DETAIL_HASH_MAP_HPP