Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 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> | ||||
dcheng | 093de9b | 2016-04-04 21:25:51 | [diff] [blame] | 9 | #include <memory> |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 10 | |
11 | #include "base/base_export.h" | ||||
David Sanders | 174b347 | 2022-04-13 07:38:33 | [diff] [blame] | 12 | #include "base/memory/scoped_refptr.h" |
gab | 7b1d677 | 2016-12-22 14:05:17 | [diff] [blame] | 13 | #include "base/sequence_checker.h" |
14 | |||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 15 | namespace base { |
16 | |||||
17 | // This is a helper for classes that want to allow users to stash random data by | ||||
18 | // key. At destruction all the objects will be destructed. | ||||
19 | class BASE_EXPORT SupportsUserData { | ||||
20 | public: | ||||
21 | SupportsUserData(); | ||||
Matt Mueller | 39fc01f9 | 2019-08-10 02:24:08 | [diff] [blame] | 22 | SupportsUserData(SupportsUserData&&); |
23 | SupportsUserData& operator=(SupportsUserData&&); | ||||
David Bienvenu | 5f4d4f0 | 2020-09-27 16:55:03 | [diff] [blame] | 24 | SupportsUserData(const SupportsUserData&) = delete; |
25 | SupportsUserData& operator=(const SupportsUserData&) = delete; | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 26 | |
27 | // Derive from this class and add your own data members to associate extra | ||||
[email protected] | 5b9f0b5 | 2012-08-20 22:58:21 | [diff] [blame] | 28 | // information with this object. Alternatively, add this as a public base |
29 | // class to any class with a virtual destructor. | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 30 | class BASE_EXPORT Data { |
31 | public: | ||||
gab | 7b1d677 | 2016-12-22 14:05:17 | [diff] [blame] | 32 | virtual ~Data() = default; |
Scott Violet | f4eec90 | 2019-04-04 21:20:34 | [diff] [blame] | 33 | |
34 | // Returns a copy of |this|; null if copy is not supported. | ||||
35 | virtual std::unique_ptr<Data> Clone(); | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 36 | }; |
37 | |||||
38 | // The user data allows the clients to associate data with this object. | ||||
Randy Smith | 4cd4d36a | 2017-08-24 01:01:09 | [diff] [blame] | 39 | // |key| must not be null--that value is too vulnerable for collision. |
Scott Violet | f4eec90 | 2019-04-04 21:20:34 | [diff] [blame] | 40 | // NOTE: SetUserData() with an empty unique_ptr behaves the same as |
41 | // RemoveUserData(). | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 42 | Data* GetUserData(const void* key) const; |
William Liu | 055a354 | 2023-04-02 17:21:19 | [diff] [blame] | 43 | [[nodiscard]] std::unique_ptr<Data> TakeUserData(const void* key); |
sdefresne | ae5e2d2 | 2017-02-13 11:49:26 | [diff] [blame] | 44 | void SetUserData(const void* key, std::unique_ptr<Data> data); |
[email protected] | 27ee16f | 2012-08-12 02:25:13 | [diff] [blame] | 45 | void RemoveUserData(const void* key); |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 46 | |
Scott Violet | f4eec90 | 2019-04-04 21:20:34 | [diff] [blame] | 47 | // Adds all data from |other|, that is clonable, to |this|. That is, this |
48 | // iterates over the data in |other|, and any data that returns non-null from | ||||
49 | // Clone() is added to |this|. | ||||
50 | void CloneDataFrom(const SupportsUserData& other); | ||||
51 | |||||
[email protected] | 7d2e5f762 | 2012-09-10 19:18:53 | [diff] [blame] | 52 | // SupportsUserData is not thread-safe, and on debug build will assert it is |
gab | 7b1d677 | 2016-12-22 14:05:17 | [diff] [blame] | 53 | // only used on one execution sequence. Calling this method allows the caller |
54 | // to hand the SupportsUserData instance across execution sequences. Use only | ||||
55 | // if you are taking full control of the synchronization of that hand over. | ||||
56 | void DetachFromSequence(); | ||||
[email protected] | 7d2e5f762 | 2012-09-10 19:18:53 | [diff] [blame] | 57 | |
[email protected] | cb93248 | 2012-06-26 06:23:00 | [diff] [blame] | 58 | protected: |
59 | virtual ~SupportsUserData(); | ||||
60 | |||||
Matt Mueller | e74f6177 | 2019-08-13 20:00:59 | [diff] [blame] | 61 | // Clear all user data from this object. This can be used if the subclass |
62 | // needs to provide reset functionality. | ||||
63 | void ClearAllUserData(); | ||||
64 | |||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 65 | private: |
Nico Weber | d0e8dc1 | 2024-05-23 15:12:36 | [diff] [blame] | 66 | struct Impl; |
67 | std::unique_ptr<Impl> impl_; | ||||
Daniel Cheng | 80a7cdf | 2024-06-10 05:30:39 | [diff] [blame] | 68 | bool in_clear_ = false; |
Nico Weber | d0e8dc1 | 2024-05-23 15:12:36 | [diff] [blame] | 69 | // Guards usage of |impl_| |
Daniel Cheng | a5700b3 | 2021-10-13 18:19:00 | [diff] [blame] | 70 | SEQUENCE_CHECKER(sequence_checker_); |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 71 | }; |
72 | |||||
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 73 | // Adapter class that releases a refcounted object when the |
74 | // SupportsUserData::Data object is deleted. | ||||
75 | template <typename T> | ||||
Lei Zhang | fdfe3b6 | 2019-04-03 05:29:26 | [diff] [blame] | 76 | class UserDataAdapter : public SupportsUserData::Data { |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 77 | public: |
horo | d556043 | 2014-12-12 06:20:13 | [diff] [blame] | 78 | static T* Get(const SupportsUserData* supports_user_data, const void* key) { |
[email protected] | 5537099 | 2012-10-08 21:08:54 | [diff] [blame] | 79 | UserDataAdapter* data = |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 80 | static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key)); |
Lei Zhang | fdfe3b6 | 2019-04-03 05:29:26 | [diff] [blame] | 81 | return data ? static_cast<T*>(data->object_.get()) : nullptr; |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 82 | } |
83 | |||||
Lei Zhang | fdfe3b6 | 2019-04-03 05:29:26 | [diff] [blame] | 84 | explicit UserDataAdapter(T* object) : object_(object) {} |
David Bienvenu | 5f4d4f0 | 2020-09-27 16:55:03 | [diff] [blame] | 85 | UserDataAdapter(const UserDataAdapter&) = delete; |
86 | UserDataAdapter& operator=(const UserDataAdapter&) = delete; | ||||
Lei Zhang | fdfe3b6 | 2019-04-03 05:29:26 | [diff] [blame] | 87 | ~UserDataAdapter() override = default; |
88 | |||||
[email protected] | c1fff07 | 2012-02-24 23:38:12 | [diff] [blame] | 89 | T* release() { return object_.release(); } |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 90 | |
91 | private: | ||||
Lei Zhang | fdfe3b6 | 2019-04-03 05:29:26 | [diff] [blame] | 92 | scoped_refptr<T> const object_; |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 93 | }; |
94 | |||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 95 | } // namespace base |
96 | |||||
97 | #endif // BASE_SUPPORTS_USER_DATA_H_ |