1 // Copyright 2017 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_UNIQUE_PTR_ADAPTERS_H_
6 #define BASE_CONTAINERS_UNIQUE_PTR_ADAPTERS_H_
7
8 #include <memory>
9
10 namespace base {
11
12 // This transparent comparator allows to lookup by raw pointer in
13 // a container of unique pointers. This functionality is based on C++14
14 // extensions to std::set/std::map interface, and can also be used
15 // with base::flat_set/base::flat_map.
16 //
17 // Example usage:
18 // Foo* foo = ...
19 // std::set<std::unique_ptr<Foo>, base::UniquePtrComparator> set;
20 // set.insert(std::unique_ptr<Foo>(foo));
21 // ...
22 // auto it = set.find(foo);
23 // EXPECT_EQ(foo, it->get());
24 //
25 // You can find more information about transparent comparisons here:
26 // http://en.cppreference.com/w/cpp/utility/functional/less_void
27 struct UniquePtrComparator {
28 using is_transparent = int;
29
30 template <typename T>
operatorUniquePtrComparator31 bool operator()(const std::unique_ptr<T>& lhs,
32 const std::unique_ptr<T>& rhs) const {
33 return lhs < rhs;
34 }
35
36 template <typename T>
operatorUniquePtrComparator37 bool operator()(const T* lhs, const std::unique_ptr<T>& rhs) const {
38 return lhs < rhs.get();
39 }
40
41 template <typename T>
operatorUniquePtrComparator42 bool operator()(const std::unique_ptr<T>& lhs, const T* rhs) const {
43 return lhs.get() < rhs;
44 }
45 };
46
47 // UniquePtrMatcher is useful for finding an element in a container of
48 // unique_ptrs when you have the raw pointer.
49 //
50 // Example usage:
51 // std::vector<std::unique_ptr<Foo>> vector;
52 // Foo* element = ...
53 // auto iter = std::find_if(vector.begin(), vector.end(),
54 // MatchesUniquePtr(element));
55 //
56 // Example of erasing from container:
57 // EraseIf(v, MatchesUniquePtr(element));
58 //
59 template <class T, class Deleter = std::default_delete<T>>
60 struct UniquePtrMatcher {
UniquePtrMatcherUniquePtrMatcher61 explicit UniquePtrMatcher(T* t) : t_(t) {}
62
operatorUniquePtrMatcher63 bool operator()(const std::unique_ptr<T, Deleter>& o) {
64 return o.get() == t_;
65 }
66
67 private:
68 T* const t_;
69 };
70
71 template <class T, class Deleter = std::default_delete<T>>
MatchesUniquePtr(T * t)72 UniquePtrMatcher<T, Deleter> MatchesUniquePtr(T* t) {
73 return UniquePtrMatcher<T, Deleter>(t);
74 }
75
76 } // namespace base
77
78 #endif // BASE_CONTAINERS_UNIQUE_PTR_ADAPTERS_H_
79