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> >, 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 Value> 23 class ScopedPtrHashMap { 24 typedef base::hash_map<Key, Value*> 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, Value>& 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, scoped_ptr<Value> data) { 43 iterator it = find(key); 44 if (it != end()) { 45 delete it->second; 46 it->second = data.release(); 47 return it; 48 } 49 50 return data_.insert(std::make_pair(key, data.release())).first; 51 } 52 53 // Does nothing if key is already present 54 std::pair<iterator, bool> add(const Key& key, scoped_ptr<Value> data) { 55 std::pair<iterator, bool> result = 56 data_.insert(std::make_pair(key, data.get())); 57 if (result.second) 58 ignore_result(data.release()); 59 return result; 60 } 61 62 void erase(iterator it) { 63 delete it->second; 64 data_.erase(it); 65 } 66 67 size_t erase(const Key& k) { 68 iterator it = data_.find(k); 69 if (it == data_.end()) 70 return 0; 71 erase(it); 72 return 1; 73 } 74 75 scoped_ptr<Value> take(iterator it) { 76 DCHECK(it != data_.end()); 77 if (it == data_.end()) 78 return scoped_ptr<Value>(); 79 80 scoped_ptr<Value> ret(it->second); 81 it->second = NULL; 82 return ret.Pass(); 83 } 84 85 scoped_ptr<Value> take(const Key& k) { 86 iterator it = find(k); 87 if (it == data_.end()) 88 return scoped_ptr<Value>(); 89 90 return take(it); 91 } 92 93 scoped_ptr<Value> take_and_erase(iterator it) { 94 DCHECK(it != data_.end()); 95 if (it == data_.end()) 96 return scoped_ptr<Value>(); 97 98 scoped_ptr<Value> ret(it->second); 99 data_.erase(it); 100 return ret.Pass(); 101 } 102 103 scoped_ptr<Value> take_and_erase(const Key& k) { 104 iterator it = find(k); 105 if (it == data_.end()) 106 return scoped_ptr<Value>(); 107 108 return take_and_erase(it); 109 } 110 111 // Returns the element in the hash_map that matches the given key. 112 // If no such element exists it returns NULL. 113 Value* get(const Key& k) const { 114 const_iterator it = find(k); 115 if (it == end()) 116 return NULL; 117 return it->second; 118 } 119 120 inline bool contains(const Key& k) const { return data_.count(k) > 0; } 121 122 inline void clear() { STLDeleteValues(&data_); } 123 124 inline const_iterator find(const Key& k) const { return data_.find(k); } 125 inline iterator find(const Key& k) { return data_.find(k); } 126 127 inline size_t count(const Key& k) const { return data_.count(k); } 128 inline std::pair<const_iterator, const_iterator> equal_range( 129 const Key& k) const { 130 return data_.equal_range(k); 131 } 132 inline std::pair<iterator, iterator> equal_range(const Key& k) { 133 return data_.equal_range(k); 134 } 135 136 inline size_t size() const { return data_.size(); } 137 inline size_t max_size() const { return data_.max_size(); } 138 139 inline bool empty() const { return data_.empty(); } 140 141 inline size_t bucket_count() const { return data_.bucket_count(); } 142 inline void resize(size_t size) { return data_.resize(size); } 143 144 inline iterator begin() { return data_.begin(); } 145 inline const_iterator begin() const { return data_.begin(); } 146 inline iterator end() { return data_.end(); } 147 inline const_iterator end() const { return data_.end(); } 148 149 private: 150 Container data_; 151 152 DISALLOW_COPY_AND_ASSIGN(ScopedPtrHashMap); 153 }; 154 155 } // namespace base 156 157 #endif // BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_ 158