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.
5 #ifndef BASE_CONTAINERS_SCOPED_PTR_MAP_H_
6 #define BASE_CONTAINERS_SCOPED_PTR_MAP_H_
12 #include "base/basictypes.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/move.h"
15 #include "base/stl_util.h"
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.
23 // |ScopedPtr| must be a type scoped_ptr<T>. This is for compatibility with
25 template <class Key
, class ScopedPtr
, class Compare
= std::less
<Key
>>
27 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(ScopedPtrMap
)
29 using Container
= std::map
<Key
, typename
ScopedPtr::element_type
*, Compare
>;
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
;
44 ~ScopedPtrMap() { clear(); }
45 ScopedPtrMap(ScopedPtrMap
<Key
, ScopedPtr
>&& other
) { swap(other
); }
47 ScopedPtrMap
& operator=(ScopedPtrMap
<Key
, ScopedPtr
>&& rhs
) {
52 const_iterator
find(const Key
& k
) const { return data_
.find(k
); }
53 size_type
count(const Key
& k
) const { return data_
.count(k
); }
55 bool empty() const { return data_
.empty(); }
56 size_t size() const { return data_
.size(); }
58 const_reverse_iterator
rbegin() const { return data_
.rbegin(); }
59 const_reverse_iterator
rend() const { return data_
.rend(); }
61 const_iterator
begin() const { return data_
.begin(); }
62 const_iterator
end() const { return data_
.end(); }
64 void swap(ScopedPtrMap
<Key
, ScopedPtr
>& other
) { data_
.swap(other
.data_
); }
66 void clear() { STLDeleteValues(&data_
); }
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()));
72 ignore_result(val
.release());
76 // Inserts |val| into the map, associated with |key|. Overwrites any existing
78 void set(const Key
& key
, ScopedPtr val
) {
79 typename
ScopedPtr::element_type
*& val_ref
= data_
[key
];
81 val_ref
= val
.release();
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
);
91 size_type
erase(const Key
& k
) {
92 typename
Container::iterator it
= data_
.find(k
);
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
));
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())
113 ScopedPtr
ret(position
->second
);
114 // Key-based lookup (cannot use const_iterator overload in C++03 library).
115 data_
.erase(position
->first
);
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
);
125 ScopedPtr
ret(it
->second
);
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())
138 return data_
.find(it
->first
);
144 #endif // BASE_CONTAINERS_SCOPED_PTR_MAP_H_