blob: 5c1c7e945f6ec17577476d3759b54027e5c79d17 [file] [log] [blame]
[email protected]ea8e1812012-02-15 22:07:341// 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
10#include "base/base_export.h"
avi9b6f42932015-12-26 22:15:1411#include "base/macros.h"
[email protected]ea8e1812012-02-15 22:07:3412#include "base/memory/linked_ptr.h"
[email protected]314c3e22012-02-21 03:57:4213#include "base/memory/ref_counted.h"
[email protected]7d2e5f7622012-09-10 19:18:5314#include "base/threading/thread_checker.h"
[email protected]ea8e1812012-02-15 22:07:3415
16namespace base {
17
18// This is a helper for classes that want to allow users to stash random data by
19// key. At destruction all the objects will be destructed.
20class BASE_EXPORT SupportsUserData {
21 public:
22 SupportsUserData();
[email protected]ea8e1812012-02-15 22:07:3423
24 // Derive from this class and add your own data members to associate extra
[email protected]5b9f0b52012-08-20 22:58:2125 // information with this object. Alternatively, add this as a public base
26 // class to any class with a virtual destructor.
[email protected]ea8e1812012-02-15 22:07:3427 class BASE_EXPORT Data {
28 public:
29 virtual ~Data() {}
30 };
31
32 // The user data allows the clients to associate data with this object.
33 // Multiple user data values can be stored under different keys.
34 // This object will TAKE OWNERSHIP of the given data pointer, and will
35 // delete the object if it is changed or the object is destroyed.
36 Data* GetUserData(const void* key) const;
37 void SetUserData(const void* key, Data* data);
[email protected]27ee16f2012-08-12 02:25:1338 void RemoveUserData(const void* key);
[email protected]ea8e1812012-02-15 22:07:3439
[email protected]7d2e5f7622012-09-10 19:18:5340 // SupportsUserData is not thread-safe, and on debug build will assert it is
41 // only used on one thread. Calling this method allows the caller to hand
42 // the SupportsUserData instance across threads. Use only if you are taking
43 // full control of the synchronization of that hand over.
44 void DetachUserDataThread();
45
[email protected]cb932482012-06-26 06:23:0046 protected:
47 virtual ~SupportsUserData();
48
[email protected]ea8e1812012-02-15 22:07:3449 private:
50 typedef std::map<const void*, linked_ptr<Data> > DataMap;
51
[email protected]5b9f0b52012-08-20 22:58:2152 // Externally-defined data accessible by key.
[email protected]ea8e1812012-02-15 22:07:3453 DataMap user_data_;
[email protected]7d2e5f7622012-09-10 19:18:5354 // Guards usage of |user_data_|
55 ThreadChecker thread_checker_;
[email protected]ea8e1812012-02-15 22:07:3456
57 DISALLOW_COPY_AND_ASSIGN(SupportsUserData);
58};
59
[email protected]314c3e22012-02-21 03:57:4260// Adapter class that releases a refcounted object when the
61// SupportsUserData::Data object is deleted.
62template <typename T>
63class UserDataAdapter : public base::SupportsUserData::Data {
64 public:
horod5560432014-12-12 06:20:1365 static T* Get(const SupportsUserData* supports_user_data, const void* key) {
[email protected]55370992012-10-08 21:08:5466 UserDataAdapter* data =
[email protected]314c3e22012-02-21 03:57:4267 static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key));
[email protected]55370992012-10-08 21:08:5468 return data ? static_cast<T*>(data->object_.get()) : NULL;
[email protected]314c3e22012-02-21 03:57:4269 }
70
71 UserDataAdapter(T* object) : object_(object) {}
[email protected]c1fff072012-02-24 23:38:1272 T* release() { return object_.release(); }
[email protected]314c3e22012-02-21 03:57:4273
74 private:
75 scoped_refptr<T> object_;
76
77 DISALLOW_COPY_AND_ASSIGN(UserDataAdapter);
78};
79
[email protected]ea8e1812012-02-15 22:07:3480} // namespace base
81
82#endif // BASE_SUPPORTS_USER_DATA_H_