| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_ | |
| 6 #define BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_ | |
| 7 | |
| 8 #include <algorithm> | |
| 9 #include <utility> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/containers/hash_tables.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/stl_util.h" | |
| 16 | |
| 17 namespace base { | |
| 18 | |
| 19 // This type acts like a hash_map<K, scoped_ptr<V, D> >, based on top of | |
| 20 // base::hash_map. The ScopedPtrHashMap has ownership of all values in the data | |
| 21 // structure. | |
| 22 template <typename Key, typename ScopedPtr> | |
| 23 class ScopedPtrHashMap { | |
| 24 typedef base::hash_map<Key, typename ScopedPtr::element_type*> Container; | |
| 25 | |
| 26 public: | |
| 27 typedef typename Container::key_type key_type; | |
| 28 typedef typename Container::mapped_type mapped_type; | |
| 29 typedef typename Container::value_type value_type; | |
| 30 typedef typename Container::iterator iterator; | |
| 31 typedef typename Container::const_iterator const_iterator; | |
| 32 | |
| 33 ScopedPtrHashMap() {} | |
| 34 | |
| 35 ~ScopedPtrHashMap() { clear(); } | |
| 36 | |
| 37 void swap(ScopedPtrHashMap<Key, ScopedPtr>& other) { | |
| 38 data_.swap(other.data_); | |
| 39 } | |
| 40 | |
| 41 // Replaces value but not key if key is already present. | |
| 42 iterator set(const Key& key, ScopedPtr data) { | |
| 43 iterator it = find(key); | |
| 44 if (it != end()) { | |
| 45 // Let ScopedPtr decide how to delete. For example, it may use custom | |
| 46 // deleter. | |
| 47 ScopedPtr(it->second).reset(); | |
| 48 it->second = data.release(); | |
| 49 return it; | |
| 50 } | |
| 51 | |
| 52 return data_.insert(std::make_pair(key, data.release())).first; | |
| 53 } | |
| 54 | |
| 55 // Does nothing if key is already present | |
| 56 std::pair<iterator, bool> add(const Key& key, ScopedPtr data) { | |
| 57 std::pair<iterator, bool> result = | |
| 58 data_.insert(std::make_pair(key, data.get())); | |
| 59 if (result.second) | |
| 60 ignore_result(data.release()); | |
| 61 return result; | |
| 62 } | |
| 63 | |
| 64 void erase(iterator it) { | |
| 65 // Let ScopedPtr decide how to delete. | |
| 66 ScopedPtr(it->second).reset(); | |
| 67 data_.erase(it); | |
| 68 } | |
| 69 | |
| 70 size_t erase(const Key& k) { | |
| 71 iterator it = data_.find(k); | |
| 72 if (it == data_.end()) | |
| 73 return 0; | |
| 74 erase(it); | |
| 75 return 1; | |
| 76 } | |
| 77 | |
| 78 ScopedPtr take(iterator it) { | |
| 79 DCHECK(it != data_.end()); | |
| 80 if (it == data_.end()) | |
| 81 return ScopedPtr(); | |
| 82 | |
| 83 ScopedPtr ret(it->second); | |
| 84 it->second = NULL; | |
| 85 return ret.Pass(); | |
| 86 } | |
| 87 | |
| 88 ScopedPtr take(const Key& k) { | |
| 89 iterator it = find(k); | |
| 90 if (it == data_.end()) | |
| 91 return ScopedPtr(); | |
| 92 | |
| 93 return take(it); | |
| 94 } | |
| 95 | |
| 96 ScopedPtr take_and_erase(iterator it) { | |
| 97 DCHECK(it != data_.end()); | |
| 98 if (it == data_.end()) | |
| 99 return ScopedPtr(); | |
| 100 | |
| 101 ScopedPtr ret(it->second); | |
| 102 data_.erase(it); | |
| 103 return ret.Pass(); | |
| 104 } | |
| 105 | |
| 106 ScopedPtr take_and_erase(const Key& k) { | |
| 107 iterator it = find(k); | |
| 108 if (it == data_.end()) | |
| 109 return ScopedPtr(); | |
| 110 | |
| 111 return take_and_erase(it); | |
| 112 } | |
| 113 | |
| 114 // Returns the element in the hash_map that matches the given key. | |
| 115 // If no such element exists it returns NULL. | |
| 116 typename ScopedPtr::element_type* get(const Key& k) const { | |
| 117 const_iterator it = find(k); | |
| 118 if (it == end()) | |
| 119 return NULL; | |
| 120 return it->second; | |
| 121 } | |
| 122 | |
| 123 inline bool contains(const Key& k) const { return data_.count(k) > 0; } | |
| 124 | |
| 125 inline void clear() { | |
| 126 auto it = data_.begin(); | |
| 127 while (it != data_.end()) { | |
| 128 // NOTE: Like STLDeleteContainerPointers, deleting behind the iterator. | |
| 129 // Deleting the value does not always invalidate the iterator, but it may | |
| 130 // do so if the key is a pointer into the value object. | |
| 131 auto temp = it; | |
| 132 ++it; | |
| 133 // Let ScopedPtr decide how to delete. | |
| 134 ScopedPtr(temp->second).reset(); | |
| 135 } | |
| 136 data_.clear(); | |
| 137 } | |
| 138 | |
| 139 inline const_iterator find(const Key& k) const { return data_.find(k); } | |
| 140 inline iterator find(const Key& k) { return data_.find(k); } | |
| 141 | |
| 142 inline size_t count(const Key& k) const { return data_.count(k); } | |
| 143 inline std::pair<const_iterator, const_iterator> equal_range( | |
| 144 const Key& k) const { | |
| 145 return data_.equal_range(k); | |
| 146 } | |
| 147 inline std::pair<iterator, iterator> equal_range(const Key& k) { | |
| 148 return data_.equal_range(k); | |
| 149 } | |
| 150 | |
| 151 inline size_t size() const { return data_.size(); } | |
| 152 inline size_t max_size() const { return data_.max_size(); } | |
| 153 | |
| 154 inline bool empty() const { return data_.empty(); } | |
| 155 | |
| 156 inline size_t bucket_count() const { return data_.bucket_count(); } | |
| 157 inline void resize(size_t size) { return data_.resize(size); } | |
| 158 | |
| 159 inline iterator begin() { return data_.begin(); } | |
| 160 inline const_iterator begin() const { return data_.begin(); } | |
| 161 inline iterator end() { return data_.end(); } | |
| 162 inline const_iterator end() const { return data_.end(); } | |
| 163 | |
| 164 private: | |
| 165 Container data_; | |
| 166 | |
| 167 DISALLOW_COPY_AND_ASSIGN(ScopedPtrHashMap); | |
| 168 }; | |
| 169 | |
| 170 } // namespace base | |
| 171 | |
| 172 #endif // BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_ | |
| OLD | NEW |