| Index: base/containers/scoped_ptr_hash_map.h
|
| diff --git a/base/containers/scoped_ptr_hash_map.h b/base/containers/scoped_ptr_hash_map.h
|
| index dedf21365bee5eea44d1a4522d777e05736df558..8fe550e7317f7e79201c7ef801f01bc39cfd69ab 100644
|
| --- a/base/containers/scoped_ptr_hash_map.h
|
| +++ b/base/containers/scoped_ptr_hash_map.h
|
| @@ -16,12 +16,12 @@
|
|
|
| namespace base {
|
|
|
| -// This type acts like a hash_map<K, scoped_ptr<V> >, based on top of
|
| +// This type acts like a hash_map<K, scoped_ptr<V, D> >, based on top of
|
| // base::hash_map. The ScopedPtrHashMap has ownership of all values in the data
|
| // structure.
|
| -template <typename Key, typename Value>
|
| +template <typename Key, typename ScopedPtr>
|
| class ScopedPtrHashMap {
|
| - typedef base::hash_map<Key, Value*> Container;
|
| + typedef base::hash_map<Key, typename ScopedPtr::element_type*> Container;
|
|
|
| public:
|
| typedef typename Container::key_type key_type;
|
| @@ -34,15 +34,17 @@ class ScopedPtrHashMap {
|
|
|
| ~ScopedPtrHashMap() { clear(); }
|
|
|
| - void swap(ScopedPtrHashMap<Key, Value>& other) {
|
| + void swap(ScopedPtrHashMap<Key, ScopedPtr>& other) {
|
| data_.swap(other.data_);
|
| }
|
|
|
| // Replaces value but not key if key is already present.
|
| - iterator set(const Key& key, scoped_ptr<Value> data) {
|
| + iterator set(const Key& key, ScopedPtr data) {
|
| iterator it = find(key);
|
| if (it != end()) {
|
| - delete it->second;
|
| + // Let ScopedPtr decide how to delete. For example, it may use custom
|
| + // deleter.
|
| + ScopedPtr(it->second).reset();
|
| it->second = data.release();
|
| return it;
|
| }
|
| @@ -51,7 +53,7 @@ class ScopedPtrHashMap {
|
| }
|
|
|
| // Does nothing if key is already present
|
| - std::pair<iterator, bool> add(const Key& key, scoped_ptr<Value> data) {
|
| + std::pair<iterator, bool> add(const Key& key, ScopedPtr data) {
|
| std::pair<iterator, bool> result =
|
| data_.insert(std::make_pair(key, data.get()));
|
| if (result.second)
|
| @@ -60,7 +62,8 @@ class ScopedPtrHashMap {
|
| }
|
|
|
| void erase(iterator it) {
|
| - delete it->second;
|
| + // Let ScopedPtr decide how to delete.
|
| + ScopedPtr(it->second).reset();
|
| data_.erase(it);
|
| }
|
|
|
| @@ -72,45 +75,45 @@ class ScopedPtrHashMap {
|
| return 1;
|
| }
|
|
|
| - scoped_ptr<Value> take(iterator it) {
|
| + ScopedPtr take(iterator it) {
|
| DCHECK(it != data_.end());
|
| if (it == data_.end())
|
| - return scoped_ptr<Value>();
|
| + return ScopedPtr();
|
|
|
| - scoped_ptr<Value> ret(it->second);
|
| + ScopedPtr ret(it->second);
|
| it->second = NULL;
|
| return ret.Pass();
|
| }
|
|
|
| - scoped_ptr<Value> take(const Key& k) {
|
| + ScopedPtr take(const Key& k) {
|
| iterator it = find(k);
|
| if (it == data_.end())
|
| - return scoped_ptr<Value>();
|
| + return ScopedPtr();
|
|
|
| return take(it);
|
| }
|
|
|
| - scoped_ptr<Value> take_and_erase(iterator it) {
|
| + ScopedPtr take_and_erase(iterator it) {
|
| DCHECK(it != data_.end());
|
| if (it == data_.end())
|
| - return scoped_ptr<Value>();
|
| + return ScopedPtr();
|
|
|
| - scoped_ptr<Value> ret(it->second);
|
| + ScopedPtr ret(it->second);
|
| data_.erase(it);
|
| return ret.Pass();
|
| }
|
|
|
| - scoped_ptr<Value> take_and_erase(const Key& k) {
|
| + ScopedPtr take_and_erase(const Key& k) {
|
| iterator it = find(k);
|
| if (it == data_.end())
|
| - return scoped_ptr<Value>();
|
| + return ScopedPtr();
|
|
|
| return take_and_erase(it);
|
| }
|
|
|
| // Returns the element in the hash_map that matches the given key.
|
| // If no such element exists it returns NULL.
|
| - Value* get(const Key& k) const {
|
| + typename ScopedPtr::element_type* get(const Key& k) const {
|
| const_iterator it = find(k);
|
| if (it == end())
|
| return NULL;
|
| @@ -119,7 +122,19 @@ class ScopedPtrHashMap {
|
|
|
| inline bool contains(const Key& k) const { return data_.count(k) > 0; }
|
|
|
| - inline void clear() { STLDeleteValues(&data_); }
|
| + inline void clear() {
|
| + auto it = data_.begin();
|
| + while (it != data_.end()) {
|
| + // NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
|
| + // Deleting the value does not always invalidate the iterator, but it may
|
| + // do so if the key is a pointer into the value object.
|
| + auto temp = it;
|
| + ++it;
|
| + // Let ScopedPtr decide how to delete.
|
| + ScopedPtr(temp->second).reset();
|
| + }
|
| + data_.clear();
|
| + }
|
|
|
| inline const_iterator find(const Key& k) const { return data_.find(k); }
|
| inline iterator find(const Key& k) { return data_.find(k); }
|
|
|