blob: cad8045ea2c4460ba41681e9c0dcb3598ecf3b9d [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
[email protected]ea8e1812012-02-15 22:07:342// 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>
dcheng093de9b2016-04-04 21:25:519#include <memory>
[email protected]ea8e1812012-02-15 22:07:3410
11#include "base/base_export.h"
David Sanders174b3472022-04-13 07:38:3312#include "base/memory/scoped_refptr.h"
gab7b1d6772016-12-22 14:05:1713#include "base/sequence_checker.h"
14
[email protected]ea8e1812012-02-15 22:07:3415namespace 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.
19class BASE_EXPORT SupportsUserData {
20 public:
21 SupportsUserData();
Matt Mueller39fc01f92019-08-10 02:24:0822 SupportsUserData(SupportsUserData&&);
23 SupportsUserData& operator=(SupportsUserData&&);
David Bienvenu5f4d4f02020-09-27 16:55:0324 SupportsUserData(const SupportsUserData&) = delete;
25 SupportsUserData& operator=(const SupportsUserData&) = delete;
[email protected]ea8e1812012-02-15 22:07:3426
27 // Derive from this class and add your own data members to associate extra
[email protected]5b9f0b52012-08-20 22:58:2128 // information with this object. Alternatively, add this as a public base
29 // class to any class with a virtual destructor.
[email protected]ea8e1812012-02-15 22:07:3430 class BASE_EXPORT Data {
31 public:
gab7b1d6772016-12-22 14:05:1732 virtual ~Data() = default;
Scott Violetf4eec902019-04-04 21:20:3433
34 // Returns a copy of |this|; null if copy is not supported.
35 virtual std::unique_ptr<Data> Clone();
[email protected]ea8e1812012-02-15 22:07:3436 };
37
38 // The user data allows the clients to associate data with this object.
Randy Smith4cd4d36a2017-08-24 01:01:0939 // |key| must not be null--that value is too vulnerable for collision.
Scott Violetf4eec902019-04-04 21:20:3440 // NOTE: SetUserData() with an empty unique_ptr behaves the same as
41 // RemoveUserData().
[email protected]ea8e1812012-02-15 22:07:3442 Data* GetUserData(const void* key) const;
William Liu055a3542023-04-02 17:21:1943 [[nodiscard]] std::unique_ptr<Data> TakeUserData(const void* key);
sdefresneae5e2d22017-02-13 11:49:2644 void SetUserData(const void* key, std::unique_ptr<Data> data);
[email protected]27ee16f2012-08-12 02:25:1345 void RemoveUserData(const void* key);
[email protected]ea8e1812012-02-15 22:07:3446
Scott Violetf4eec902019-04-04 21:20:3447 // 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]7d2e5f7622012-09-10 19:18:5352 // SupportsUserData is not thread-safe, and on debug build will assert it is
gab7b1d6772016-12-22 14:05:1753 // 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]7d2e5f7622012-09-10 19:18:5357
[email protected]cb932482012-06-26 06:23:0058 protected:
59 virtual ~SupportsUserData();
60
Matt Muellere74f61772019-08-13 20:00:5961 // 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]ea8e1812012-02-15 22:07:3465 private:
Nico Weberd0e8dc12024-05-23 15:12:3666 struct Impl;
67 std::unique_ptr<Impl> impl_;
Daniel Cheng80a7cdf2024-06-10 05:30:3968 bool in_clear_ = false;
Nico Weberd0e8dc12024-05-23 15:12:3669 // Guards usage of |impl_|
Daniel Chenga5700b32021-10-13 18:19:0070 SEQUENCE_CHECKER(sequence_checker_);
[email protected]ea8e1812012-02-15 22:07:3471};
72
[email protected]314c3e22012-02-21 03:57:4273// Adapter class that releases a refcounted object when the
74// SupportsUserData::Data object is deleted.
75template <typename T>
Lei Zhangfdfe3b62019-04-03 05:29:2676class UserDataAdapter : public SupportsUserData::Data {
[email protected]314c3e22012-02-21 03:57:4277 public:
horod5560432014-12-12 06:20:1378 static T* Get(const SupportsUserData* supports_user_data, const void* key) {
[email protected]55370992012-10-08 21:08:5479 UserDataAdapter* data =
Peter Kasting134ef9af2024-12-28 02:30:0980 static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key));
Lei Zhangfdfe3b62019-04-03 05:29:2681 return data ? static_cast<T*>(data->object_.get()) : nullptr;
[email protected]314c3e22012-02-21 03:57:4282 }
83
Lei Zhangfdfe3b62019-04-03 05:29:2684 explicit UserDataAdapter(T* object) : object_(object) {}
David Bienvenu5f4d4f02020-09-27 16:55:0385 UserDataAdapter(const UserDataAdapter&) = delete;
86 UserDataAdapter& operator=(const UserDataAdapter&) = delete;
Lei Zhangfdfe3b62019-04-03 05:29:2687 ~UserDataAdapter() override = default;
88
[email protected]c1fff072012-02-24 23:38:1289 T* release() { return object_.release(); }
[email protected]314c3e22012-02-21 03:57:4290
91 private:
Lei Zhangfdfe3b62019-04-03 05:29:2692 scoped_refptr<T> const object_;
[email protected]314c3e22012-02-21 03:57:4293};
94
[email protected]ea8e1812012-02-15 22:07:3495} // namespace base
96
97#endif // BASE_SUPPORTS_USER_DATA_H_