1 // Copyright (c) 2012 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 5 #ifndef BASE_SUPPORTS_USER_DATA_H_ 6 #define BASE_SUPPORTS_USER_DATA_H_ 7 8 #include <map> 9 #include <memory> 10 11 #include "base/base_export.h" 12 #include "base/macros.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/sequence_checker.h" 15 16 // TODO(gab): Removing this include causes IWYU failures in other headers, 17 // remove it in a follow- up CL. 18 #include "base/threading/thread_checker.h" 19 20 namespace base { 21 22 // This is a helper for classes that want to allow users to stash random data by 23 // key. At destruction all the objects will be destructed. 24 class BASE_EXPORT SupportsUserData { 25 public: 26 SupportsUserData(); 27 28 // Derive from this class and add your own data members to associate extra 29 // information with this object. Alternatively, add this as a public base 30 // class to any class with a virtual destructor. 31 class BASE_EXPORT Data { 32 public: 33 virtual ~Data() = default; 34 }; 35 36 // The user data allows the clients to associate data with this object. 37 // Multiple user data values can be stored under different keys. 38 // This object will TAKE OWNERSHIP of the given data pointer, and will 39 // delete the object if it is changed or the object is destroyed. 40 // |key| must not be null--that value is too vulnerable for collision. 41 Data* GetUserData(const void* key) const; 42 void SetUserData(const void* key, std::unique_ptr<Data> data); 43 void RemoveUserData(const void* key); 44 45 // SupportsUserData is not thread-safe, and on debug build will assert it is 46 // only used on one execution sequence. Calling this method allows the caller 47 // to hand the SupportsUserData instance across execution sequences. Use only 48 // if you are taking full control of the synchronization of that hand over. 49 void DetachFromSequence(); 50 51 protected: 52 virtual ~SupportsUserData(); 53 54 private: 55 using DataMap = std::map<const void*, std::unique_ptr<Data>>; 56 57 // Externally-defined data accessible by key. 58 DataMap user_data_; 59 // Guards usage of |user_data_| 60 SequenceChecker sequence_checker_; 61 62 DISALLOW_COPY_AND_ASSIGN(SupportsUserData); 63 }; 64 65 // Adapter class that releases a refcounted object when the 66 // SupportsUserData::Data object is deleted. 67 template <typename T> 68 class UserDataAdapter : public base::SupportsUserData::Data { 69 public: Get(const SupportsUserData * supports_user_data,const void * key)70 static T* Get(const SupportsUserData* supports_user_data, const void* key) { 71 UserDataAdapter* data = 72 static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key)); 73 return data ? static_cast<T*>(data->object_.get()) : NULL; 74 } 75 UserDataAdapter(T * object)76 UserDataAdapter(T* object) : object_(object) {} release()77 T* release() { return object_.release(); } 78 79 private: 80 scoped_refptr<T> object_; 81 82 DISALLOW_COPY_AND_ASSIGN(UserDataAdapter); 83 }; 84 85 } // namespace base 86 87 #endif // BASE_SUPPORTS_USER_DATA_H_ 88