• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
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 #include "base/memory/raw_ptr.h"
11 
12 namespace base {
13 
14 // This transparent comparator allows to lookup by raw pointer in
15 // a container of unique pointers. This functionality is based on C++14
16 // extensions to std::set/std::map interface, and can also be used
17 // with base::flat_set/base::flat_map.
18 //
19 // Example usage:
20 //   Foo* foo = ...
21 //   std::set<std::unique_ptr<Foo>, base::UniquePtrComparator> set;
22 //   set.insert(std::unique_ptr<Foo>(foo));
23 //   ...
24 //   auto it = set.find(foo);
25 //   EXPECT_EQ(foo, it->get());
26 //
27 // You can find more information about transparent comparisons here:
28 // http://en.cppreference.com/w/cpp/utility/functional/less_void
29 struct UniquePtrComparator {
30   using is_transparent = int;
31 
32   template <typename T, class Deleter>
operatorUniquePtrComparator33   bool operator()(const std::unique_ptr<T, Deleter>& lhs,
34                   const std::unique_ptr<T, Deleter>& rhs) const {
35     return lhs < rhs;
36   }
37 
38   template <typename T, class Deleter>
operatorUniquePtrComparator39   bool operator()(const T* lhs, const std::unique_ptr<T, Deleter>& rhs) const {
40     return lhs < rhs.get();
41   }
42 
43   template <typename T, class Deleter, base::RawPtrTraits Traits>
operatorUniquePtrComparator44   bool operator()(const raw_ptr<T, Traits>& lhs,
45                   const std::unique_ptr<T, Deleter>& rhs) const {
46     return lhs < rhs.get();
47   }
48 
49   template <typename T, class Deleter>
operatorUniquePtrComparator50   bool operator()(const std::unique_ptr<T, Deleter>& lhs, const T* rhs) const {
51     return lhs.get() < rhs;
52   }
53 
54   template <typename T, class Deleter, base::RawPtrTraits Traits>
operatorUniquePtrComparator55   bool operator()(const std::unique_ptr<T, Deleter>& lhs,
56                   const raw_ptr<T, Traits>& rhs) const {
57     return lhs.get() < rhs;
58   }
59 };
60 
61 // UniquePtrMatcher is useful for finding an element in a container of
62 // unique_ptrs when you have the raw pointer.
63 //
64 // Example usage:
65 //   std::vector<std::unique_ptr<Foo>> vector;
66 //   Foo* element = ...
67 //   auto iter = base::ranges::find_if(vector, MatchesUniquePtr(element));
68 //
69 // Example of erasing from container:
70 //   EraseIf(v, MatchesUniquePtr(element));
71 //
72 template <class T, class Deleter = std::default_delete<T>>
73 struct UniquePtrMatcher {
UniquePtrMatcherUniquePtrMatcher74   explicit UniquePtrMatcher(T* t) : t_(t) {}
75 
operatorUniquePtrMatcher76   bool operator()(const std::unique_ptr<T, Deleter>& o) {
77     return o.get() == t_;
78   }
79 
80  private:
81   const raw_ptr<T, DanglingUntriaged> t_;
82 };
83 
84 template <class T, class Deleter = std::default_delete<T>>
MatchesUniquePtr(T * t)85 UniquePtrMatcher<T, Deleter> MatchesUniquePtr(T* t) {
86   return UniquePtrMatcher<T, Deleter>(t);
87 }
88 
89 template <class T,
90           class Deleter = std::default_delete<T>,
91           base::RawPtrTraits Traits = base::RawPtrTraits::kEmpty>
MatchesUniquePtr(const raw_ptr<T,Traits> & t)92 UniquePtrMatcher<T, Deleter> MatchesUniquePtr(const raw_ptr<T, Traits>& t) {
93   return UniquePtrMatcher<T, Deleter>(t.get());
94 }
95 
96 }  // namespace base
97 
98 #endif  // BASE_CONTAINERS_UNIQUE_PTR_ADAPTERS_H_
99