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::iterator iterator; 28 typedef typename Container::const_iterator const_iterator; 29 30 ScopedPtrHashMap() {} 31 32 ~ScopedPtrHashMap() { clear(); } 33 34 void swap(ScopedPtrHashMap<Key, Value>& other) { 35 data_.swap(other.data_); 36 } 37 38 std::pair<iterator, bool> insert( 39 std::pair<Key, const scoped_ptr<Value> > pair) { 40 return data_.insert( 41 std::pair<Key, Value*>(pair.first, pair.second.release())); 42 } 43 44 // Replaces value but not key if key is already present. 45 std::pair<iterator, bool> set(Key key, scoped_ptr<Value> data) { 46 iterator it = find(key); 47 if (it != end()) 48 erase(it); 49 Value* raw_ptr = data.release(); 50 return data_.insert(std::pair<Key, Value*>(key, raw_ptr)); 51 } 52 53 // Does nothing if key is already present 54 std::pair<iterator, bool> add(Key key, scoped_ptr<Value> data) { 55 Value* raw_ptr = data.release(); 56 return data_.insert(std::pair<Key, Value*>(key, raw_ptr)); 57 } 58 59 void erase(iterator it) { 60 if (it->second) 61 delete it->second; 62 data_.erase(it); 63 } 64 65 size_t erase(const Key& k) { 66 iterator it = data_.find(k); 67 if (it == data_.end()) 68 return 0; 69 erase(it); 70 return 1; 71 } 72 73 scoped_ptr<Value> take(iterator it) { 74 DCHECK(it != data_.end()); 75 if (it == data_.end()) 76 return scoped_ptr<Value>(); 77 78 Key key = it->first; 79 scoped_ptr<Value> ret(it->second); 80 data_.erase(it); 81 data_.insert(std::pair<Key, Value*>(key, static_cast<Value*>(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 first 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 0; 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