owned_objects.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2020 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. #ifndef COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_
  6. #include <memory>
  7. #include "base/check_op.h"
  8. #include "base/containers/contains.h"
  9. #include "base/containers/flat_set.h"
  10. #include "base/containers/unique_ptr_adapters.h"
  11. namespace performance_manager {
  12. namespace internal {
  13. // Builds the callback type from the ObjectType and CallbackArgType.
  14. template <typename ObjectType, typename CallbackArgType>
  15. struct CallbackType {
  16. typedef void (ObjectType::*Type)(CallbackArgType);
  17. };
  18. // Specialization for void CallbackArgType.
  19. template <typename ObjectType>
  20. struct CallbackType<ObjectType, void> {
  21. typedef void (ObjectType::*Type)();
  22. };
  23. } // namespace internal
  24. // Helper class defining storage for a collection of "owned" objects. These
  25. // are objects whose ownership has explicitly been passed to the container.
  26. // The objects can be taken back from the container, or will be torn down
  27. // with the container. Note that the owner of this container should
  28. // explicitly call ReleaseObjects prior to the object being torn down; the
  29. // container expects to be empty at destruction.
  30. // TODO: Once C++17 is available, use "auto" here and simply accept the 2
  31. // member function pointers, deducing all other type info.
  32. template <typename OwnedType,
  33. typename CallbackArgType,
  34. typename internal::CallbackType<OwnedType, CallbackArgType>::Type
  35. OnPassedMemberFunction,
  36. typename internal::CallbackType<OwnedType, CallbackArgType>::Type
  37. OnTakenMemberFunction>
  38. class OwnedObjects {
  39. public:
  40. OwnedObjects() = default;
  41. ~OwnedObjects() { DCHECK(objects_.empty()); }
  42. OwnedObjects(const OwnedObjects&) = delete;
  43. OwnedObjects& operator=(const OwnedObjects&) = delete;
  44. // Passes an object into this container, and invokes the OnPassedFunctionPtr.
  45. template <typename... ArgTypes>
  46. void PassObject(std::unique_ptr<OwnedType> object, ArgTypes... args) {
  47. auto* raw = object.get();
  48. DCHECK(!base::Contains(objects_, raw));
  49. objects_.insert(std::move(object));
  50. // We should stop using a flat_set at this point.
  51. DCHECK_GE(100u, objects_.size());
  52. ((raw)->*(OnPassedMemberFunction))(std::forward<ArgTypes>(args)...);
  53. }
  54. // Takes an object back from this container, and invokes the
  55. // OnTakenFunctionPtr (if the object is found).
  56. template <typename... ArgTypes>
  57. std::unique_ptr<OwnedType> TakeObject(OwnedType* raw, ArgTypes... args) {
  58. std::unique_ptr<OwnedType> object;
  59. auto it = objects_.find(raw);
  60. if (it != objects_.end()) {
  61. DCHECK_EQ(raw, it->get());
  62. // base::flat_set doesn't yet support "extract", but this is the approved
  63. // way of doing this for now.
  64. object = std::move(*it);
  65. objects_.erase(it);
  66. ((raw)->*(OnTakenMemberFunction))(std::forward<ArgTypes>(args)...);
  67. }
  68. return object;
  69. }
  70. // Releases all the objects owned by this container, invoking their
  71. // OnTakenFunctionPtr as they are released.
  72. template <typename... ArgTypes>
  73. void ReleaseObjects(ArgTypes... args) {
  74. // Release the last object first to be friendly with base::flat_set, which
  75. // is actually a std::vector.
  76. while (!objects_.empty())
  77. TakeObject(objects_.rbegin()->get(), std::forward<ArgTypes>(args)...);
  78. }
  79. // Returns the current size of this container.
  80. size_t size() const { return objects_.size(); }
  81. // Returns true if this container is empty.
  82. bool empty() const { return objects_.empty(); }
  83. private:
  84. // If this ever uses an STL compliant set with "extract", then modify
  85. // TakeObject to use that instead!
  86. base::flat_set<std::unique_ptr<OwnedType>, base::UniquePtrComparator>
  87. objects_;
  88. };
  89. } // namespace performance_manager
  90. #endif // COMPONENTS_PERFORMANCE_MANAGER_OWNED_OBJECTS_H_