• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_
6 #define GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_
7 
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/callback.h"
11 
12 #define INVALIDATION_CALLBACK1_TYPE(Arg1) ::base::Callback<void(Arg1)>
13 
14 // Below are a collection of types and functions that adapt base::Callback's
15 // pass-by-value semantics to the pointer-based callback system that
16 // cacheinvalidation needs.
17 
18 namespace invalidation {
19 
20 typedef ::base::Closure Closure;
21 
22 template <class T>
IsCallbackRepeatable(const T * callback)23 bool IsCallbackRepeatable(const T* callback) {
24   // The default cacheinvalidation Callbacks may be self-deleting. We don't
25   // support this behave, so we already return true to indicate that the
26   // cacheinvalidation implementation should delete our Callbacks.
27   return true;
28 }
29 
30 namespace internal {
31 
32 // Identity<T>::type is a typedef of T. Useful for preventing the
33 // compiler from inferring the type of an argument in templates.
34 template <typename T>
35 struct Identity {
36   typedef T type;
37 };
38 
39 }  // namespace internal
40 
41 // The cacheinvalidation callback system expects to take the callback by
42 // pointer and handle the ownership semantics itself.  Adapting the
43 // Chromium Callback system requires returning a dynamically allocated
44 // copy of the result of Bind().
45 
NewPermanentCallback(void (* fn)())46 inline Closure* NewPermanentCallback(void (*fn)()) {
47   return new ::base::Closure(::base::Bind(fn));
48 }
49 
50 template <class T1, class T2>
NewPermanentCallback(T1 * object,void (T2::* method)())51 Closure* NewPermanentCallback(
52     T1* object, void (T2::*method)()) {
53   return new ::base::Closure(::base::Bind(method, base::Unretained(object)));
54 }
55 
56 template <class T1, class T2, typename Arg1>
NewPermanentCallback(T1 * object,void (T2::* method)(Arg1))57 ::base::Callback<void(Arg1)>* NewPermanentCallback(
58     T1* object, void (T2::*method)(Arg1)) {
59   return new ::base::Callback<void(Arg1)>(
60       ::base::Bind(method, base::Unretained(object)));
61 }
62 
63 template <class T1, class T2, typename Arg1>
NewPermanentCallback(T1 * object,void (T2::* method)(Arg1),typename internal::Identity<Arg1>::type arg1)64 Closure* NewPermanentCallback(
65     T1* object,
66     void (T2::*method)(Arg1),
67     typename internal::Identity<Arg1>::type arg1) {
68   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
69                                           arg1));
70 }
71 
72 template <typename Arg1, typename Arg2>
NewPermanentCallback(void (* fn)(Arg1,Arg2),typename internal::Identity<Arg1>::type arg1,typename internal::Identity<Arg2>::type arg2)73 Closure* NewPermanentCallback(
74     void (*fn)(Arg1, Arg2),
75     typename internal::Identity<Arg1>::type arg1,
76     typename internal::Identity<Arg2>::type arg2) {
77   return new ::base::Closure(::base::Bind(fn, arg1, arg2));
78 }
79 
80 template <class T1, class T2, typename Arg1, typename Arg2>
NewPermanentCallback(T1 * object,void (T2::* method)(Arg1,Arg2),typename internal::Identity<Arg1>::type arg1,typename internal::Identity<Arg2>::type arg2)81 Closure* NewPermanentCallback(
82     T1* object,
83     void (T2::*method)(Arg1, Arg2),
84     typename internal::Identity<Arg1>::type arg1,
85     typename internal::Identity<Arg2>::type arg2) {
86   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
87                                           arg1, arg2));
88 }
89 
90 template <class T1, class T2, typename Arg1, typename Arg2>
NewPermanentCallback(T1 * object,void (T2::* method)(Arg1,Arg2),typename internal::Identity<Arg1>::type arg1)91 ::base::Callback<void(Arg2)>* NewPermanentCallback(
92     T1* object,
93     void (T2::*method)(Arg1, Arg2),
94     typename internal::Identity<Arg1>::type arg1) {
95   return new ::base::Callback<void(Arg2)>(
96       ::base::Bind(method, base::Unretained(object), arg1));
97 }
98 
99 template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3>
NewPermanentCallback(T1 * object,void (T2::* method)(Arg1,Arg2,Arg3),typename internal::Identity<Arg1>::type arg1,typename internal::Identity<Arg2>::type arg2,typename internal::Identity<Arg3>::type arg3)100 Closure* NewPermanentCallback(
101     T1* object,
102     void (T2::*method)(Arg1, Arg2, Arg3),
103     typename internal::Identity<Arg1>::type arg1,
104     typename internal::Identity<Arg2>::type arg2,
105     typename internal::Identity<Arg3>::type arg3) {
106   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
107                                           arg1, arg2, arg3));
108 }
109 
110 template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3,
111           typename Arg4>
NewPermanentCallback(T1 * object,void (T2::* method)(Arg1,Arg2,Arg3,Arg4),typename internal::Identity<Arg1>::type arg1,typename internal::Identity<Arg2>::type arg2,typename internal::Identity<Arg3>::type arg3,typename internal::Identity<Arg4>::type arg4)112 Closure* NewPermanentCallback(
113     T1* object,
114     void (T2::*method)(Arg1, Arg2, Arg3, Arg4),
115     typename internal::Identity<Arg1>::type arg1,
116     typename internal::Identity<Arg2>::type arg2,
117     typename internal::Identity<Arg3>::type arg3,
118     typename internal::Identity<Arg4>::type arg4) {
119   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
120                                           arg1, arg2, arg3, arg4));
121 }
122 
123 // Creates a Closure that runs |callback| on |arg|. The returned Closure owns
124 // |callback|.
125 template <typename ArgType>
NewPermanentCallback(INVALIDATION_CALLBACK1_TYPE (ArgType)* callback,typename internal::Identity<ArgType>::type arg)126 Closure* NewPermanentCallback(
127     INVALIDATION_CALLBACK1_TYPE(ArgType)* callback,
128     typename internal::Identity<ArgType>::type arg) {
129   return new ::base::Closure(::base::Bind(
130       &::base::Callback<void(ArgType)>::Run, base::Owned(callback), arg));
131 }
132 
133 }  // namespace invalidation
134 
135 #endif  // GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_
136