00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_
00016 #define ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_
00017
00018 #include <tuple>
00019 #include <type_traits>
00020 #include <utility>
00021
00022 #include "absl/container/internal/container_memory.h"
00023 #include "absl/container/internal/raw_hash_set.h"
00024
00025 namespace absl {
00026 namespace container_internal {
00027
00028 template <class Policy, class Hash, class Eq, class Alloc>
00029 class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> {
00030
00031
00032
00033 template <class P>
00034 using MappedReference = decltype(P::value(
00035 std::addressof(std::declval<typename raw_hash_map::reference>())));
00036
00037
00038 template <class P>
00039 using MappedConstReference = decltype(P::value(
00040 std::addressof(std::declval<typename raw_hash_map::const_reference>())));
00041
00042 using KeyArgImpl =
00043 KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>;
00044
00045 public:
00046 using key_type = typename Policy::key_type;
00047 using mapped_type = typename Policy::mapped_type;
00048 template <class K>
00049 using key_arg = typename KeyArgImpl::template type<K, key_type>;
00050
00051 static_assert(!std::is_reference<key_type>::value, "");
00052
00053
00054 static_assert(!std::is_reference<mapped_type>::value, "");
00055
00056 using iterator = typename raw_hash_map::raw_hash_set::iterator;
00057 using const_iterator = typename raw_hash_map::raw_hash_set::const_iterator;
00058
00059 raw_hash_map() {}
00060 using raw_hash_map::raw_hash_set::raw_hash_set;
00061
00062
00063
00064
00065
00066
00067
00068
00069 template <class K = key_type, class V = mapped_type, K* = nullptr,
00070 V* = nullptr>
00071 std::pair<iterator, bool> insert_or_assign(key_arg<K>&& k, V&& v) {
00072 return insert_or_assign_impl(std::forward<K>(k), std::forward<V>(v));
00073 }
00074
00075 template <class K = key_type, class V = mapped_type, K* = nullptr>
00076 std::pair<iterator, bool> insert_or_assign(key_arg<K>&& k, const V& v) {
00077 return insert_or_assign_impl(std::forward<K>(k), v);
00078 }
00079
00080 template <class K = key_type, class V = mapped_type, V* = nullptr>
00081 std::pair<iterator, bool> insert_or_assign(const key_arg<K>& k, V&& v) {
00082 return insert_or_assign_impl(k, std::forward<V>(v));
00083 }
00084
00085 template <class K = key_type, class V = mapped_type>
00086 std::pair<iterator, bool> insert_or_assign(const key_arg<K>& k, const V& v) {
00087 return insert_or_assign_impl(k, v);
00088 }
00089
00090 template <class K = key_type, class V = mapped_type, K* = nullptr,
00091 V* = nullptr>
00092 iterator insert_or_assign(const_iterator, key_arg<K>&& k, V&& v) {
00093 return insert_or_assign(std::forward<K>(k), std::forward<V>(v)).first;
00094 }
00095
00096 template <class K = key_type, class V = mapped_type, K* = nullptr>
00097 iterator insert_or_assign(const_iterator, key_arg<K>&& k, const V& v) {
00098 return insert_or_assign(std::forward<K>(k), v).first;
00099 }
00100
00101 template <class K = key_type, class V = mapped_type, V* = nullptr>
00102 iterator insert_or_assign(const_iterator, const key_arg<K>& k, V&& v) {
00103 return insert_or_assign(k, std::forward<V>(v)).first;
00104 }
00105
00106 template <class K = key_type, class V = mapped_type>
00107 iterator insert_or_assign(const_iterator, const key_arg<K>& k, const V& v) {
00108 return insert_or_assign(k, v).first;
00109 }
00110
00111 template <class K = key_type, class... Args,
00112 typename std::enable_if<
00113 !std::is_convertible<K, const_iterator>::value, int>::type = 0,
00114 K* = nullptr>
00115 std::pair<iterator, bool> try_emplace(key_arg<K>&& k, Args&&... args) {
00116 return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...);
00117 }
00118
00119 template <class K = key_type, class... Args,
00120 typename std::enable_if<
00121 !std::is_convertible<K, const_iterator>::value, int>::type = 0>
00122 std::pair<iterator, bool> try_emplace(const key_arg<K>& k, Args&&... args) {
00123 return try_emplace_impl(k, std::forward<Args>(args)...);
00124 }
00125
00126 template <class K = key_type, class... Args, K* = nullptr>
00127 iterator try_emplace(const_iterator, key_arg<K>&& k, Args&&... args) {
00128 return try_emplace(std::forward<K>(k), std::forward<Args>(args)...).first;
00129 }
00130
00131 template <class K = key_type, class... Args>
00132 iterator try_emplace(const_iterator, const key_arg<K>& k, Args&&... args) {
00133 return try_emplace(k, std::forward<Args>(args)...).first;
00134 }
00135
00136 template <class K = key_type, class P = Policy>
00137 MappedReference<P> at(const key_arg<K>& key) {
00138 auto it = this->find(key);
00139 if (it == this->end()) std::abort();
00140 return Policy::value(&*it);
00141 }
00142
00143 template <class K = key_type, class P = Policy>
00144 MappedConstReference<P> at(const key_arg<K>& key) const {
00145 auto it = this->find(key);
00146 if (it == this->end()) std::abort();
00147 return Policy::value(&*it);
00148 }
00149
00150 template <class K = key_type, class P = Policy, K* = nullptr>
00151 MappedReference<P> operator[](key_arg<K>&& key) {
00152 return Policy::value(&*try_emplace(std::forward<K>(key)).first);
00153 }
00154
00155 template <class K = key_type, class P = Policy>
00156 MappedReference<P> operator[](const key_arg<K>& key) {
00157 return Policy::value(&*try_emplace(key).first);
00158 }
00159
00160 private:
00161 template <class K, class V>
00162 std::pair<iterator, bool> insert_or_assign_impl(K&& k, V&& v) {
00163 auto res = this->find_or_prepare_insert(k);
00164 if (res.second)
00165 this->emplace_at(res.first, std::forward<K>(k), std::forward<V>(v));
00166 else
00167 Policy::value(&*this->iterator_at(res.first)) = std::forward<V>(v);
00168 return {this->iterator_at(res.first), res.second};
00169 }
00170
00171 template <class K = key_type, class... Args>
00172 std::pair<iterator, bool> try_emplace_impl(K&& k, Args&&... args) {
00173 auto res = this->find_or_prepare_insert(k);
00174 if (res.second)
00175 this->emplace_at(res.first, std::piecewise_construct,
00176 std::forward_as_tuple(std::forward<K>(k)),
00177 std::forward_as_tuple(std::forward<Args>(args)...));
00178 return {this->iterator_at(res.first), res.second};
00179 }
00180 };
00181
00182 }
00183 }
00184
00185 #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_