registered_objects.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2019 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_REGISTERED_OBJECTS_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_REGISTERED_OBJECTS_H_
  6. #include <type_traits>
  7. #include "base/check_op.h"
  8. #include "base/containers/flat_set.h"
  9. namespace performance_manager {
  10. // Container for holding registered objects. The objects are stored as raw
  11. // pointers. At most a single instance of an object of a given type may exist
  12. // at a moment. It is expected that RegisteredType satisfies the following
  13. // interface:
  14. //
  15. // // Returns the type id of the derived type.
  16. // uintptr_t GetTypeId() const;
  17. //
  18. // The container is expected to be empty by the time of its destruction.
  19. template <typename RegisteredType>
  20. class RegisteredObjects {
  21. public:
  22. RegisteredObjects() = default;
  23. ~RegisteredObjects() { DCHECK(objects_.empty()); }
  24. RegisteredObjects(const RegisteredObjects&) = delete;
  25. RegisteredObjects& operator=(const RegisteredObjects&) = delete;
  26. // Registers an object with this container. No more than one object of a given
  27. // type may be registered at once.
  28. void RegisterObject(RegisteredType* object) {
  29. DCHECK_EQ(nullptr, GetRegisteredObject(object->GetTypeId()));
  30. objects_.insert(object);
  31. // If there are ever so many registered objects we should consider changing
  32. // data structures.
  33. DCHECK_GT(100u, objects_.size());
  34. }
  35. // Unregisters an object from this container. The object must previously have
  36. // been registered.
  37. void UnregisterObject(RegisteredType* object) {
  38. DCHECK_EQ(object, GetRegisteredObject(object->GetTypeId()));
  39. objects_.erase(object);
  40. }
  41. // Returns the object with the registered type, nullptr if none exists.
  42. RegisteredType* GetRegisteredObject(uintptr_t type_id) {
  43. auto it = objects_.find(type_id);
  44. if (it == objects_.end())
  45. return nullptr;
  46. DCHECK_EQ((*it)->GetTypeId(), type_id);
  47. return *it;
  48. }
  49. // Returns the current size of this container.
  50. size_t size() const { return objects_.size(); }
  51. // Returns true if this container is empty.
  52. bool empty() const { return objects_.empty(); }
  53. private:
  54. // Comparator for registered objects. They are stored by raw pointers but
  55. // sorted by their type IDs. This is a transparent comparator that also allows
  56. // comparing with type IDs directly.
  57. struct RegisteredComparator {
  58. using is_transparent = void;
  59. bool operator()(const RegisteredType* r1, const RegisteredType* r2) const {
  60. return r1->GetTypeId() < r2->GetTypeId();
  61. }
  62. bool operator()(const RegisteredType* r1, uintptr_t type_id) const {
  63. return r1->GetTypeId() < type_id;
  64. }
  65. bool operator()(uintptr_t type_id, const RegisteredType* r2) const {
  66. return type_id < r2->GetTypeId();
  67. }
  68. };
  69. base::flat_set<RegisteredType*, RegisteredComparator> objects_;
  70. };
  71. } // namespace performance_manager
  72. #endif // COMPONENTS_PERFORMANCE_MANAGER_REGISTERED_OBJECTS_H_