| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_SUPPORTS_USER_DATA_H_ |
| #define BASE_SUPPORTS_USER_DATA_H_ |
| |
| #include<map> |
| #include<memory> |
| |
| #include"base/base_export.h" |
| #include"base/memory/scoped_refptr.h" |
| #include"base/sequence_checker.h" |
| |
| namespacebase{ |
| |
| // This is a helper for classes that want to allow users to stash random data by |
| // key. At destruction all the objects will be destructed. |
| class BASE_EXPORTSupportsUserData{ |
| public: |
| SupportsUserData(); |
| SupportsUserData(SupportsUserData&&); |
| SupportsUserData&operator=(SupportsUserData&&); |
| SupportsUserData(constSupportsUserData&)=delete; |
| SupportsUserData&operator=(constSupportsUserData&)=delete; |
| |
| // Derive from this class and add your own data members to associate extra |
| // information with this object. Alternatively, add this as a public base |
| // class to any class with a virtual destructor. |
| class BASE_EXPORTData{ |
| public: |
| virtual~Data()=default; |
| |
| // Returns a copy of |this|; null if copy is not supported. |
| virtual std::unique_ptr<Data>Clone(); |
| }; |
| |
| // The user data allows the clients to associate data with this object. |
| // |key| must not be null--that value is too vulnerable for collision. |
| // NOTE: SetUserData() with an empty unique_ptr behaves the same as |
| // RemoveUserData(). |
| Data*GetUserData(constvoid* key)const; |
| [[nodiscard]] std::unique_ptr<Data>TakeUserData(constvoid* key); |
| voidSetUserData(constvoid* key, std::unique_ptr<Data> data); |
| voidRemoveUserData(constvoid* key); |
| |
| // Adds all data from |other|, that is clonable, to |this|. That is, this |
| // iterates over the data in |other|, and any data that returns non-null from |
| // Clone() is added to |this|. |
| voidCloneDataFrom(constSupportsUserData& other); |
| |
| // SupportsUserData is not thread-safe, and on debug build will assert it is |
| // only used on one execution sequence. Calling this method allows the caller |
| // to hand the SupportsUserData instance across execution sequences. Use only |
| // if you are taking full control of the synchronization of that hand over. |
| voidDetachFromSequence(); |
| |
| protected: |
| virtual~SupportsUserData(); |
| |
| // Clear all user data from this object. This can be used if the subclass |
| // needs to provide reset functionality. |
| voidClearAllUserData(); |
| |
| // Returns the number of Data objects attached to this object. |
| size_tUserDataCount()const; |
| |
| private: |
| structImpl; |
| std::unique_ptr<Impl> impl_; |
| bool in_clear_=false; |
| // Guards usage of |impl_| |
| SEQUENCE_CHECKER(sequence_checker_); |
| }; |
| |
| // Adapter class that releases a refcounted object when the |
| // SupportsUserData::Data object is deleted. |
| template<typename T> |
| classUserDataAdapter:publicSupportsUserData::Data{ |
| public: |
| static T*Get(constSupportsUserData* supports_user_data,constvoid* key){ |
| UserDataAdapter* data= |
| static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key)); |
| return data?static_cast<T*>(data->object_.get()):nullptr; |
| } |
| |
| explicitUserDataAdapter(T*object): object_(object){} |
| UserDataAdapter(constUserDataAdapter&)=delete; |
| UserDataAdapter&operator=(constUserDataAdapter&)=delete; |
| ~UserDataAdapter()override=default; |
| |
| T* release(){return object_.release();} |
| |
| private: |
| scoped_refptr<T>const object_; |
| }; |
| |
| }// namespace base |
| |
| #endif// BASE_SUPPORTS_USER_DATA_H_ |