1 // Copyright (c) 2011 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.
5 #ifndef BASE_CALLBACK_OLD_H_
6 #define BASE_CALLBACK_OLD_H_
9 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
10 #include "base/tuple.h"
12 // Callback --------------------------------------------------------------------
14 // A Callback is like a Task but with unbound parameters. It is basically an
15 // object-oriented function pointer.
17 // Callbacks are designed to work with Tuples. A set of helper functions and
18 // classes is provided to hide the Tuple details from the consumer. Client
19 // code will generally work with the CallbackRunner base class, which merely
20 // provides a Run method and is returned by the New* functions. This allows
21 // users to not care which type of class implements the callback, only that it
22 // has a certain number and type of arguments.
24 // The implementation of this is done by CallbackImpl, which inherits
25 // CallbackStorage to store the data. This allows the storage of the data
26 // (requiring the class type T) to be hidden from users, who will want to call
27 // this regardless of the implementor's type T.
29 // Note that callbacks currently have no facility for cancelling or abandoning
30 // them. We currently handle this at a higher level for cases where this is
31 // necessary. The pointer in a callback must remain valid until the callback
34 // Like Task, the callback executor is responsible for deleting the callback
35 // pointer once the callback has executed.
37 // Example client usage:
38 // void Object::DoStuff(int, string);
39 // Callback2<int, string>::Type* callback =
40 // NewCallback(obj, &Object::DoStuff);
41 // callback->Run(5, string("hello"));
43 // or, equivalently, using tuples directly:
44 // CallbackRunner<Tuple2<int, string> >* callback =
45 // NewCallback(obj, &Object::DoStuff);
46 // callback->RunWithParams(MakeTuple(5, string("hello")));
48 // There is also a 0-args version that returns a value. Example:
49 // int Object::GetNextInt();
50 // CallbackWithReturnValue<int>::Type* callback =
51 // NewCallbackWithReturnValue(obj, &Object::GetNextInt);
52 // int next_int = callback->Run();
55 // Base for all Callbacks that handles storage of the pointers.
56 template <class T
, typename Method
>
57 class CallbackStorage
{
59 CallbackStorage(T
* obj
, Method meth
) : obj_(obj
), meth_(meth
) {
67 // Interface that is exposed to the consumer, that does the actual calling
69 template <typename Params
>
70 class CallbackRunner
{
72 typedef Params TupleType
;
74 virtual ~CallbackRunner() {}
75 virtual void RunWithParams(const Params
& params
) = 0;
77 // Convenience functions so callers don't have to deal with Tuples.
79 RunWithParams(Tuple0());
82 template <typename Arg1
>
83 inline void Run(const Arg1
& a
) {
84 RunWithParams(Params(a
));
87 template <typename Arg1
, typename Arg2
>
88 inline void Run(const Arg1
& a
, const Arg2
& b
) {
89 RunWithParams(Params(a
, b
));
92 template <typename Arg1
, typename Arg2
, typename Arg3
>
93 inline void Run(const Arg1
& a
, const Arg2
& b
, const Arg3
& c
) {
94 RunWithParams(Params(a
, b
, c
));
97 template <typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
>
98 inline void Run(const Arg1
& a
, const Arg2
& b
, const Arg3
& c
, const Arg4
& d
) {
99 RunWithParams(Params(a
, b
, c
, d
));
102 template <typename Arg1
, typename Arg2
, typename Arg3
,
103 typename Arg4
, typename Arg5
>
104 inline void Run(const Arg1
& a
, const Arg2
& b
, const Arg3
& c
,
105 const Arg4
& d
, const Arg5
& e
) {
106 RunWithParams(Params(a
, b
, c
, d
, e
));
110 template <class T
, typename Method
, typename Params
>
111 class CallbackImpl
: public CallbackStorage
<T
, Method
>,
112 public CallbackRunner
<Params
> {
114 CallbackImpl(T
* obj
, Method meth
) : CallbackStorage
<T
, Method
>(obj
, meth
) {
116 virtual void RunWithParams(const Params
& params
) {
117 // use "this->" to force C++ to look inside our templatized base class; see
118 // Effective C++, 3rd Ed, item 43, p210 for details.
119 DispatchToMethod(this->obj_
, this->meth_
, params
);
123 // 0-arg implementation
125 typedef CallbackRunner
<Tuple0
> Type
;
129 typename
Callback0::Type
* NewCallback(T
* object
, void (T::*method
)()) {
130 return new CallbackImpl
<T
, void (T::*)(), Tuple0
>(object
, method
);
133 // 1-arg implementation
134 template <typename Arg1
>
136 typedef CallbackRunner
<Tuple1
<Arg1
> > Type
;
139 template <class T
, typename Arg1
>
140 typename Callback1
<Arg1
>::Type
* NewCallback(T
* object
,
141 void (T::*method
)(Arg1
)) {
142 return new CallbackImpl
<T
, void (T::*)(Arg1
), Tuple1
<Arg1
> >(object
, method
);
145 // 2-arg implementation
146 template <typename Arg1
, typename Arg2
>
148 typedef CallbackRunner
<Tuple2
<Arg1
, Arg2
> > Type
;
151 template <class T
, typename Arg1
, typename Arg2
>
152 typename Callback2
<Arg1
, Arg2
>::Type
* NewCallback(
154 void (T::*method
)(Arg1
, Arg2
)) {
155 return new CallbackImpl
<T
, void (T::*)(Arg1
, Arg2
),
156 Tuple2
<Arg1
, Arg2
> >(object
, method
);
159 // 3-arg implementation
160 template <typename Arg1
, typename Arg2
, typename Arg3
>
162 typedef CallbackRunner
<Tuple3
<Arg1
, Arg2
, Arg3
> > Type
;
165 template <class T
, typename Arg1
, typename Arg2
, typename Arg3
>
166 typename Callback3
<Arg1
, Arg2
, Arg3
>::Type
* NewCallback(
168 void (T::*method
)(Arg1
, Arg2
, Arg3
)) {
169 return new CallbackImpl
<T
, void (T::*)(Arg1
, Arg2
, Arg3
),
170 Tuple3
<Arg1
, Arg2
, Arg3
> >(object
, method
);
173 // 4-arg implementation
174 template <typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
>
176 typedef CallbackRunner
<Tuple4
<Arg1
, Arg2
, Arg3
, Arg4
> > Type
;
179 template <class T
, typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
>
180 typename Callback4
<Arg1
, Arg2
, Arg3
, Arg4
>::Type
* NewCallback(
182 void (T::*method
)(Arg1
, Arg2
, Arg3
, Arg4
)) {
183 return new CallbackImpl
<T
, void (T::*)(Arg1
, Arg2
, Arg3
, Arg4
),
184 Tuple4
<Arg1
, Arg2
, Arg3
, Arg4
> >(object
, method
);
187 // 5-arg implementation
188 template <typename Arg1
, typename Arg2
, typename Arg3
,
189 typename Arg4
, typename Arg5
>
191 typedef CallbackRunner
<Tuple5
<Arg1
, Arg2
, Arg3
, Arg4
, Arg5
> > Type
;
194 template <class T
, typename Arg1
, typename Arg2
,
195 typename Arg3
, typename Arg4
, typename Arg5
>
196 typename Callback5
<Arg1
, Arg2
, Arg3
, Arg4
, Arg5
>::Type
* NewCallback(
198 void (T::*method
)(Arg1
, Arg2
, Arg3
, Arg4
, Arg5
)) {
199 return new CallbackImpl
<T
, void (T::*)(Arg1
, Arg2
, Arg3
, Arg4
, Arg5
),
200 Tuple5
<Arg1
, Arg2
, Arg3
, Arg4
, Arg5
> >(object
, method
);
203 // An UnboundMethod is a wrapper for a method where the actual object is
204 // provided at Run dispatch time.
205 template <class T
, class Method
, class Params
>
206 class UnboundMethod
{
208 UnboundMethod(Method m
, const Params
& p
) : m_(m
), p_(p
) {
210 (base::internal::ParamsUseScopedRefptrCorrectly
<Params
>::value
),
211 badunboundmethodparams
);
213 void Run(T
* obj
) const {
214 DispatchToMethod(obj
, m_
, p_
);
221 // Return value implementation with no args.
222 template <typename ReturnValue
>
223 struct CallbackWithReturnValue
{
227 virtual ReturnValue
Run() = 0;
231 template <class T
, typename Method
, typename ReturnValue
>
232 class CallbackWithReturnValueImpl
233 : public CallbackStorage
<T
, Method
>,
234 public CallbackWithReturnValue
<ReturnValue
>::Type
{
236 CallbackWithReturnValueImpl(T
* obj
, Method meth
)
237 : CallbackStorage
<T
, Method
>(obj
, meth
) {}
239 virtual ReturnValue
Run() {
240 return (this->obj_
->*(this->meth_
))();
244 virtual ~CallbackWithReturnValueImpl() {}
247 template <class T
, typename ReturnValue
>
248 typename CallbackWithReturnValue
<ReturnValue
>::Type
*
249 NewCallbackWithReturnValue(T
* object
, ReturnValue (T::*method
)()) {
250 return new CallbackWithReturnValueImpl
<T
, ReturnValue (T::*)(), ReturnValue
>(
254 #endif // BASE_CALLBACK_OLD_H_