File: owned_objects.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (108 lines) | stat: -rw-r--r-- 3,952 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_
#define COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_

#include <memory>

#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"

namespace performance_manager {

namespace internal {

// Builds the callback type from the ObjectType and CallbackArgType.
template <typename ObjectType, typename CallbackArgType>
struct CallbackType {
  typedef void (ObjectType::*Type)(CallbackArgType);
};

// Specialization for void CallbackArgType.
template <typename ObjectType>
struct CallbackType<ObjectType, void> {
  typedef void (ObjectType::*Type)();
};

}  // namespace internal

// Helper class defining storage for a collection of "owned" objects. These
// are objects whose ownership has explicitly been passed to the container.
// The objects can be taken back from the container, or will be torn down
// with the container. Note that the owner of this container should
// explicitly call ReleaseObjects prior to the object being torn down; the
// container expects to be empty at destruction.
// TODO: Once C++17 is available, use "auto" here and simply accept the 2
// member function pointers, deducing all other type info.
template <typename OwnedType,
          typename CallbackArgType,
          typename internal::CallbackType<OwnedType, CallbackArgType>::Type
              OnPassedMemberFunction,
          typename internal::CallbackType<OwnedType, CallbackArgType>::Type
              OnTakenMemberFunction>
class OwnedObjects {
 public:
  OwnedObjects() = default;
  ~OwnedObjects() { CHECK(objects_.empty()); }

  OwnedObjects(const OwnedObjects&) = delete;
  OwnedObjects& operator=(const OwnedObjects&) = delete;

  // Passes an object into this container, and invokes the OnPassedFunctionPtr.
  template <typename... ArgTypes>
  void PassObject(std::unique_ptr<OwnedType> object, ArgTypes... args) {
    auto* raw = object.get();
    CHECK(!base::Contains(objects_, raw));
    objects_.insert(std::move(object));
    // We should stop using a flat_set at this point.
    CHECK_GE(100u, objects_.size());
    ((raw)->*(OnPassedMemberFunction))(std::forward<ArgTypes>(args)...);
  }

  // Takes an object back from this container, and invokes the
  // OnTakenFunctionPtr (if the object is found).
  template <typename... ArgTypes>
  std::unique_ptr<OwnedType> TakeObject(OwnedType* raw, ArgTypes... args) {
    std::unique_ptr<OwnedType> object;
    auto it = objects_.find(raw);
    if (it != objects_.end()) {
      CHECK_EQ(raw, it->get());
      // base::flat_set doesn't yet support "extract", but this is the approved
      // way of doing this for now.
      object = std::move(*it);
      objects_.erase(it);
      ((raw)->*(OnTakenMemberFunction))(std::forward<ArgTypes>(args)...);
    }
    return object;
  }

  // Releases all the objects owned by this container, invoking their
  // OnTakenFunctionPtr as they are released.
  template <typename... ArgTypes>
  void ReleaseObjects(ArgTypes... args) {
    // Release the last object first to be friendly with base::flat_set, which
    // is actually a std::vector.
    while (!objects_.empty())
      TakeObject(objects_.rbegin()->get(), std::forward<ArgTypes>(args)...);
  }

  // Returns the current size of this container.
  size_t size() const { return objects_.size(); }

  // Returns true if this container is empty.
  bool empty() const { return objects_.empty(); }

 private:
  // If this ever uses an STL compliant set with "extract", then modify
  // TakeObject to use that instead!
  base::flat_set<std::unique_ptr<OwnedType>, base::UniquePtrComparator>
      objects_;
};

}  // namespace performance_manager

#endif  // COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_