// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_PERFORMANCE_MANAGER_REGISTERED_OBJECTS_H_ #define COMPONENTS_PERFORMANCE_MANAGER_REGISTERED_OBJECTS_H_ #include #include "base/check_op.h" #include "base/containers/flat_set.h" namespace performance_manager { // Container for holding registered objects. The objects are stored as raw // pointers. At most a single instance of an object of a given type may exist // at a moment. It is expected that RegisteredType satisfies the following // interface: // // // Returns the type id of the derived type. // uintptr_t GetTypeId() const; // // The container is expected to be empty by the time of its destruction. template class RegisteredObjects { public: RegisteredObjects() = default; ~RegisteredObjects() { DCHECK(objects_.empty()); } RegisteredObjects(const RegisteredObjects&) = delete; RegisteredObjects& operator=(const RegisteredObjects&) = delete; // Registers an object with this container. No more than one object of a given // type may be registered at once. void RegisterObject(RegisteredType* object) { DCHECK_EQ(nullptr, GetRegisteredObject(object->GetTypeId())); objects_.insert(object); // If there are ever so many registered objects we should consider changing // data structures. DCHECK_GT(100u, objects_.size()); } // Unregisters an object from this container. The object must previously have // been registered. void UnregisterObject(RegisteredType* object) { DCHECK_EQ(object, GetRegisteredObject(object->GetTypeId())); objects_.erase(object); } // Returns the object with the registered type, nullptr if none exists. RegisteredType* GetRegisteredObject(uintptr_t type_id) { auto it = objects_.find(type_id); if (it == objects_.end()) return nullptr; DCHECK_EQ((*it)->GetTypeId(), type_id); return *it; } // 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: // Comparator for registered objects. They are stored by raw pointers but // sorted by their type IDs. This is a transparent comparator that also allows // comparing with type IDs directly. struct RegisteredComparator { using is_transparent = void; bool operator()(const RegisteredType* r1, const RegisteredType* r2) const { return r1->GetTypeId() < r2->GetTypeId(); } bool operator()(const RegisteredType* r1, uintptr_t type_id) const { return r1->GetTypeId() < type_id; } bool operator()(uintptr_t type_id, const RegisteredType* r2) const { return type_id < r2->GetTypeId(); } }; base::flat_set objects_; }; } // namespace performance_manager #endif // COMPONENTS_PERFORMANCE_MANAGER_REGISTERED_OBJECTS_H_