1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_SUPPORTS_USER_DATA_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_SUPPORTS_USER_DATA_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <map> 9*6777b538SAndroid Build Coastguard Worker #include <memory> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 14*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/container/flat_hash_map.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker namespace base { 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker // This is a helper for classes that want to allow users to stash random data by 19*6777b538SAndroid Build Coastguard Worker // key. At destruction all the objects will be destructed. 20*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT SupportsUserData { 21*6777b538SAndroid Build Coastguard Worker public: 22*6777b538SAndroid Build Coastguard Worker SupportsUserData(); 23*6777b538SAndroid Build Coastguard Worker SupportsUserData(SupportsUserData&&); 24*6777b538SAndroid Build Coastguard Worker SupportsUserData& operator=(SupportsUserData&&); 25*6777b538SAndroid Build Coastguard Worker SupportsUserData(const SupportsUserData&) = delete; 26*6777b538SAndroid Build Coastguard Worker SupportsUserData& operator=(const SupportsUserData&) = delete; 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker // Derive from this class and add your own data members to associate extra 29*6777b538SAndroid Build Coastguard Worker // information with this object. Alternatively, add this as a public base 30*6777b538SAndroid Build Coastguard Worker // class to any class with a virtual destructor. 31*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Data { 32*6777b538SAndroid Build Coastguard Worker public: 33*6777b538SAndroid Build Coastguard Worker virtual ~Data() = default; 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker // Returns a copy of |this|; null if copy is not supported. 36*6777b538SAndroid Build Coastguard Worker virtual std::unique_ptr<Data> Clone(); 37*6777b538SAndroid Build Coastguard Worker }; 38*6777b538SAndroid Build Coastguard Worker 39*6777b538SAndroid Build Coastguard Worker // The user data allows the clients to associate data with this object. 40*6777b538SAndroid Build Coastguard Worker // |key| must not be null--that value is too vulnerable for collision. 41*6777b538SAndroid Build Coastguard Worker // NOTE: SetUserData() with an empty unique_ptr behaves the same as 42*6777b538SAndroid Build Coastguard Worker // RemoveUserData(). 43*6777b538SAndroid Build Coastguard Worker Data* GetUserData(const void* key) const; 44*6777b538SAndroid Build Coastguard Worker [[nodiscard]] std::unique_ptr<Data> TakeUserData(const void* key); 45*6777b538SAndroid Build Coastguard Worker void SetUserData(const void* key, std::unique_ptr<Data> data); 46*6777b538SAndroid Build Coastguard Worker void RemoveUserData(const void* key); 47*6777b538SAndroid Build Coastguard Worker 48*6777b538SAndroid Build Coastguard Worker // Adds all data from |other|, that is clonable, to |this|. That is, this 49*6777b538SAndroid Build Coastguard Worker // iterates over the data in |other|, and any data that returns non-null from 50*6777b538SAndroid Build Coastguard Worker // Clone() is added to |this|. 51*6777b538SAndroid Build Coastguard Worker void CloneDataFrom(const SupportsUserData& other); 52*6777b538SAndroid Build Coastguard Worker 53*6777b538SAndroid Build Coastguard Worker // SupportsUserData is not thread-safe, and on debug build will assert it is 54*6777b538SAndroid Build Coastguard Worker // only used on one execution sequence. Calling this method allows the caller 55*6777b538SAndroid Build Coastguard Worker // to hand the SupportsUserData instance across execution sequences. Use only 56*6777b538SAndroid Build Coastguard Worker // if you are taking full control of the synchronization of that hand over. 57*6777b538SAndroid Build Coastguard Worker void DetachFromSequence(); 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Worker protected: 60*6777b538SAndroid Build Coastguard Worker virtual ~SupportsUserData(); 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker // Clear all user data from this object. This can be used if the subclass 63*6777b538SAndroid Build Coastguard Worker // needs to provide reset functionality. 64*6777b538SAndroid Build Coastguard Worker void ClearAllUserData(); 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker private: 67*6777b538SAndroid Build Coastguard Worker // Externally-defined data accessible by key. 68*6777b538SAndroid Build Coastguard Worker absl::flat_hash_map<const void*, std::unique_ptr<Data>> user_data_; 69*6777b538SAndroid Build Coastguard Worker bool in_destructor_ = false; 70*6777b538SAndroid Build Coastguard Worker // Guards usage of |user_data_| 71*6777b538SAndroid Build Coastguard Worker SEQUENCE_CHECKER(sequence_checker_); 72*6777b538SAndroid Build Coastguard Worker }; 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker // Adapter class that releases a refcounted object when the 75*6777b538SAndroid Build Coastguard Worker // SupportsUserData::Data object is deleted. 76*6777b538SAndroid Build Coastguard Worker template <typename T> 77*6777b538SAndroid Build Coastguard Worker class UserDataAdapter : public SupportsUserData::Data { 78*6777b538SAndroid Build Coastguard Worker public: Get(const SupportsUserData * supports_user_data,const void * key)79*6777b538SAndroid Build Coastguard Worker static T* Get(const SupportsUserData* supports_user_data, const void* key) { 80*6777b538SAndroid Build Coastguard Worker UserDataAdapter* data = 81*6777b538SAndroid Build Coastguard Worker static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key)); 82*6777b538SAndroid Build Coastguard Worker return data ? static_cast<T*>(data->object_.get()) : nullptr; 83*6777b538SAndroid Build Coastguard Worker } 84*6777b538SAndroid Build Coastguard Worker UserDataAdapter(T * object)85*6777b538SAndroid Build Coastguard Worker explicit UserDataAdapter(T* object) : object_(object) {} 86*6777b538SAndroid Build Coastguard Worker UserDataAdapter(const UserDataAdapter&) = delete; 87*6777b538SAndroid Build Coastguard Worker UserDataAdapter& operator=(const UserDataAdapter&) = delete; 88*6777b538SAndroid Build Coastguard Worker ~UserDataAdapter() override = default; 89*6777b538SAndroid Build Coastguard Worker release()90*6777b538SAndroid Build Coastguard Worker T* release() { return object_.release(); } 91*6777b538SAndroid Build Coastguard Worker 92*6777b538SAndroid Build Coastguard Worker private: 93*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> const object_; 94*6777b538SAndroid Build Coastguard Worker }; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker } // namespace base 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker #endif // BASE_SUPPORTS_USER_DATA_H_ 99