DevTools: consistently use camel case for URL parameter names
[chromium-blink-merge.git] / base / callback_old.h
blob7719e6601f742979392750f693d9156075be3201
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_
7 #pragma once
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
32 // is made.
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"));
42 // delete callback;
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();
53 // delete callback;
55 // Base for all Callbacks that handles storage of the pointers.
56 template <class T, typename Method>
57 class CallbackStorage {
58 public:
59 CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) {
62 protected:
63 T* obj_;
64 Method meth_;
67 // Interface that is exposed to the consumer, that does the actual calling
68 // of the method.
69 template <typename Params>
70 class CallbackRunner {
71 public:
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.
78 inline void Run() {
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> {
113 public:
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
124 struct Callback0 {
125 typedef CallbackRunner<Tuple0> Type;
128 template <class T>
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>
135 struct Callback1 {
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>
147 struct Callback2 {
148 typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type;
151 template <class T, typename Arg1, typename Arg2>
152 typename Callback2<Arg1, Arg2>::Type* NewCallback(
153 T* object,
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>
161 struct Callback3 {
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(
167 T* object,
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>
175 struct Callback4 {
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(
181 T* object,
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>
190 struct Callback5 {
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(
197 T* object,
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 {
207 public:
208 UnboundMethod(Method m, const Params& p) : m_(m), p_(p) {
209 COMPILE_ASSERT(
210 (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value),
211 badunboundmethodparams);
213 void Run(T* obj) const {
214 DispatchToMethod(obj, m_, p_);
216 private:
217 Method m_;
218 Params p_;
221 // Return value implementation with no args.
222 template <typename ReturnValue>
223 struct CallbackWithReturnValue {
224 class Type {
225 public:
226 virtual ~Type() {}
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 {
235 public:
236 CallbackWithReturnValueImpl(T* obj, Method meth)
237 : CallbackStorage<T, Method>(obj, meth) {}
239 virtual ReturnValue Run() {
240 return (this->obj_->*(this->meth_))();
243 protected:
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>(
251 object, method);
254 #endif // BASE_CALLBACK_OLD_H_