OLD | NEW |
| (Empty) |
1 // Copyright 2015 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_MAP_H_ | |
6 #define BASE_CONTAINERS_SCOPED_PTR_MAP_H_ | |
7 | |
8 #include <functional> | |
9 #include <map> | |
10 #include <utility> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/macros.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/stl_util.h" | |
16 | |
17 namespace base { | |
18 | |
19 // ScopedPtrMap provides a std::map that supports scoped_ptr values. It ensures | |
20 // that the map's values are properly deleted when removed from the map, or when | |
21 // the map is destroyed. | |
22 // | |
23 // |ScopedPtr| must be a type scoped_ptr<T>. This is for compatibility with | |
24 // std::map in C++11. | |
25 // | |
26 // TODO(http://crbug.com/554291): DEPRECATED: Use std::map instead (now that we | |
27 // have support for moveable types inside containers). | |
28 template <class Key, class ScopedPtr, class Compare = std::less<Key>> | |
29 class ScopedPtrMap { | |
30 using Container = std::map<Key, typename ScopedPtr::element_type*, Compare>; | |
31 public: | |
32 using allocator_type = typename Container::allocator_type; | |
33 using size_type = typename Container::size_type; | |
34 using difference_type = typename Container::difference_type; | |
35 using reference = typename Container::reference; | |
36 using const_reference = typename Container::const_reference; | |
37 using key_type = typename Container::key_type; | |
38 using mapped_type = ScopedPtr; | |
39 using key_compare = typename Container::key_compare; | |
40 using const_iterator = typename Container::const_iterator; | |
41 using const_reverse_iterator = typename Container::const_reverse_iterator; | |
42 | |
43 ScopedPtrMap() {} | |
44 ~ScopedPtrMap() { clear(); } | |
45 ScopedPtrMap(ScopedPtrMap&& other) { swap(other); } | |
46 | |
47 ScopedPtrMap& operator=(ScopedPtrMap&& rhs) { | |
48 swap(rhs); | |
49 return *this; | |
50 } | |
51 | |
52 const_iterator find(const Key& k) const { return data_.find(k); } | |
53 size_type count(const Key& k) const { return data_.count(k); } | |
54 | |
55 bool empty() const { return data_.empty(); } | |
56 size_t size() const { return data_.size(); } | |
57 | |
58 const_reverse_iterator rbegin() const { return data_.rbegin(); } | |
59 const_reverse_iterator rend() const { return data_.rend(); } | |
60 | |
61 const_iterator begin() const { return data_.begin(); } | |
62 const_iterator end() const { return data_.end(); } | |
63 | |
64 void swap(ScopedPtrMap& other) { data_.swap(other.data_); } | |
65 | |
66 void clear() { STLDeleteValues(&data_); } | |
67 | |
68 // Inserts |val| into the map, associated with |key|. | |
69 std::pair<const_iterator, bool> insert(const Key& key, ScopedPtr val) { | |
70 auto result = data_.insert(std::make_pair(key, val.get())); | |
71 if (result.second) | |
72 ::ignore_result(val.release()); | |
73 return result; | |
74 } | |
75 | |
76 // Inserts |val| into the map, associated with |key|. Overwrites any existing | |
77 // element at |key|. | |
78 void set(const Key& key, ScopedPtr val) { | |
79 typename ScopedPtr::element_type*& val_ref = data_[key]; | |
80 delete val_ref; | |
81 val_ref = val.release(); | |
82 } | |
83 | |
84 void erase(const_iterator position) { | |
85 DCHECK(position != end()); | |
86 delete position->second; | |
87 // Key-based lookup (cannot use const_iterator overload in C++03 library). | |
88 data_.erase(position->first); | |
89 } | |
90 | |
91 size_type erase(const Key& k) { | |
92 typename Container::iterator it = data_.find(k); | |
93 if (it == end()) | |
94 return 0; | |
95 | |
96 delete it->second; | |
97 data_.erase(it); | |
98 return 1; | |
99 } | |
100 | |
101 void erase(const_iterator first, const_iterator last) { | |
102 STLDeleteContainerPairSecondPointers(first, last); | |
103 // Need non-const iterators as required by the C++03 library. | |
104 data_.erase(ConstIteratorToIterator(first), ConstIteratorToIterator(last)); | |
105 } | |
106 | |
107 // Like |erase()|, but returns the element instead of deleting it. | |
108 ScopedPtr take_and_erase(const_iterator position) { | |
109 DCHECK(position != end()); | |
110 if (position == end()) | |
111 return ScopedPtr(); | |
112 | |
113 ScopedPtr ret(position->second); | |
114 // Key-based lookup (cannot use const_iterator overload in C++03 library). | |
115 data_.erase(position->first); | |
116 return ret; | |
117 } | |
118 | |
119 // Like |erase()|, but returns the element instead of deleting it. | |
120 ScopedPtr take_and_erase(const Key& k) { | |
121 typename Container::iterator it = data_.find(k); | |
122 if (it == end()) | |
123 return ScopedPtr(); | |
124 | |
125 ScopedPtr ret(it->second); | |
126 data_.erase(it); | |
127 return ret; | |
128 } | |
129 | |
130 private: | |
131 Container data_; | |
132 | |
133 typename Container::iterator ConstIteratorToIterator(const_iterator it) { | |
134 // This is the only way to convert a const iterator to a non-const iterator | |
135 // in C++03 (get the key and do the lookup again). | |
136 if (it == data_.end()) | |
137 return data_.end(); | |
138 return data_.find(it->first); | |
139 }; | |
140 | |
141 DISALLOW_COPY_AND_ASSIGN(ScopedPtrMap); | |
142 }; | |
143 | |
144 } // namespace base | |
145 | |
146 #endif // BASE_CONTAINERS_SCOPED_PTR_MAP_H_ | |
OLD | NEW |