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