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