blob: fc8d0058099ba1410217274eda5f87d544c30701 [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2020 The Chromium Authors
Chris Hamiltonf7effeb2020-05-19 21:43:122// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_
6#define COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_
7
8#include <memory>
9
Hans Wennborg29c74d3f2020-06-24 13:46:3510#include "base/check_op.h"
Jan Wilken Dörrie986f0a62020-12-09 23:29:1211#include "base/containers/contains.h"
Chris Hamiltonf7effeb2020-05-19 21:43:1212#include "base/containers/flat_set.h"
13#include "base/containers/unique_ptr_adapters.h"
Chris Hamiltonf7effeb2020-05-19 21:43:1214
15namespace performance_manager {
16
17namespace internal {
18
19// Builds the callback type from the ObjectType and CallbackArgType.
20template <typename ObjectType, typename CallbackArgType>
21struct CallbackType {
22 typedef void (ObjectType::*Type)(CallbackArgType);
23};
24
25// Specialization for void CallbackArgType.
26template <typename ObjectType>
27struct CallbackType<ObjectType, void> {
28 typedef void (ObjectType::*Type)();
29};
30
31} // namespace internal
32
33// Helper class defining storage for a collection of "owned" objects. These
34// are objects whose ownership has explicitly been passed to the container.
35// The objects can be taken back from the container, or will be torn down
36// with the container. Note that the owner of this container should
37// explicitly call ReleaseObjects prior to the object being torn down; the
38// container expects to be empty at destruction.
39// TODO: Once C++17 is available, use "auto" here and simply accept the 2
40// member function pointers, deducing all other type info.
41template <typename OwnedType,
42 typename CallbackArgType,
43 typename internal::CallbackType<OwnedType, CallbackArgType>::Type
44 OnPassedMemberFunction,
45 typename internal::CallbackType<OwnedType, CallbackArgType>::Type
46 OnTakenMemberFunction>
47class OwnedObjects {
48 public:
49 OwnedObjects() = default;
Joe Masonbe3fb0f02024-06-14 15:45:2250 ~OwnedObjects() { CHECK(objects_.empty()); }
Chris Hamiltonf7effeb2020-05-19 21:43:1251
52 OwnedObjects(const OwnedObjects&) = delete;
53 OwnedObjects& operator=(const OwnedObjects&) = delete;
54
55 // Passes an object into this container, and invokes the OnPassedFunctionPtr.
56 template <typename... ArgTypes>
57 void PassObject(std::unique_ptr<OwnedType> object, ArgTypes... args) {
58 auto* raw = object.get();
Joe Masonbe3fb0f02024-06-14 15:45:2259 CHECK(!base::Contains(objects_, raw));
Chris Hamiltonf7effeb2020-05-19 21:43:1260 objects_.insert(std::move(object));
61 // We should stop using a flat_set at this point.
Joe Masonbe3fb0f02024-06-14 15:45:2262 CHECK_GE(100u, objects_.size());
Chris Hamiltonf7effeb2020-05-19 21:43:1263 ((raw)->*(OnPassedMemberFunction))(std::forward<ArgTypes>(args)...);
64 }
65
66 // Takes an object back from this container, and invokes the
67 // OnTakenFunctionPtr (if the object is found).
68 template <typename... ArgTypes>
69 std::unique_ptr<OwnedType> TakeObject(OwnedType* raw, ArgTypes... args) {
70 std::unique_ptr<OwnedType> object;
71 auto it = objects_.find(raw);
72 if (it != objects_.end()) {
Joe Masonbe3fb0f02024-06-14 15:45:2273 CHECK_EQ(raw, it->get());
Chris Hamiltonf7effeb2020-05-19 21:43:1274 // base::flat_set doesn't yet support "extract", but this is the approved
75 // way of doing this for now.
76 object = std::move(*it);
77 objects_.erase(it);
78 ((raw)->*(OnTakenMemberFunction))(std::forward<ArgTypes>(args)...);
79 }
80 return object;
81 }
82
83 // Releases all the objects owned by this container, invoking their
84 // OnTakenFunctionPtr as they are released.
85 template <typename... ArgTypes>
86 void ReleaseObjects(ArgTypes... args) {
87 // Release the last object first to be friendly with base::flat_set, which
88 // is actually a std::vector.
89 while (!objects_.empty())
90 TakeObject(objects_.rbegin()->get(), std::forward<ArgTypes>(args)...);
91 }
92
93 // Returns the current size of this container.
94 size_t size() const { return objects_.size(); }
95
96 // Returns true if this container is empty.
97 bool empty() const { return objects_.empty(); }
98
99 private:
100 // If this ever uses an STL compliant set with "extract", then modify
101 // TakeObject to use that instead!
102 base::flat_set<std::unique_ptr<OwnedType>, base::UniquePtrComparator>
103 objects_;
104};
105
106} // namespace performance_manager
107
108#endif // COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_