xref: /aosp_15_r20/external/cronet/base/containers/unique_ptr_adapters.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 = std::default_delete<T>>
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 = std::default_delete<T>>
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 = std::default_delete<T>>
operatorUniquePtrComparator44   bool operator()(const std::unique_ptr<T, Deleter>& lhs, const T* rhs) const {
45     return lhs.get() < rhs;
46   }
47 };
48 
49 // UniquePtrMatcher is useful for finding an element in a container of
50 // unique_ptrs when you have the raw pointer.
51 //
52 // Example usage:
53 //   std::vector<std::unique_ptr<Foo>> vector;
54 //   Foo* element = ...
55 //   auto iter = base::ranges::find_if(vector, MatchesUniquePtr(element));
56 //
57 // Example of erasing from container:
58 //   EraseIf(v, MatchesUniquePtr(element));
59 //
60 template <class T, class Deleter = std::default_delete<T>>
61 struct UniquePtrMatcher {
UniquePtrMatcherUniquePtrMatcher62   explicit UniquePtrMatcher(T* t) : t_(t) {}
63 
operatorUniquePtrMatcher64   bool operator()(const std::unique_ptr<T, Deleter>& o) {
65     return o.get() == t_;
66   }
67 
68  private:
69   const raw_ptr<T, DanglingUntriaged> t_;
70 };
71 
72 template <class T, class Deleter = std::default_delete<T>>
MatchesUniquePtr(T * t)73 UniquePtrMatcher<T, Deleter> MatchesUniquePtr(T* t) {
74   return UniquePtrMatcher<T, Deleter>(t);
75 }
76 
77 }  // namespace base
78 
79 #endif  // BASE_CONTAINERS_UNIQUE_PTR_ADAPTERS_H_
80