1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file.
472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#ifndef BASE_CALLBACK_OLD_H_
672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define BASE_CALLBACK_OLD_H_
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#pragma once
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/tuple.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Callback --------------------------------------------------------------------
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// A Callback is like a Task but with unbound parameters. It is basically an
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// object-oriented function pointer.
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Callbacks are designed to work with Tuples.  A set of helper functions and
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// classes is provided to hide the Tuple details from the consumer.  Client
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// code will generally work with the CallbackRunner base class, which merely
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// provides a Run method and is returned by the New* functions. This allows
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// users to not care which type of class implements the callback, only that it
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// has a certain number and type of arguments.
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The implementation of this is done by CallbackImpl, which inherits
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// CallbackStorage to store the data. This allows the storage of the data
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// (requiring the class type T) to be hidden from users, who will want to call
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// this regardless of the implementor's type T.
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Note that callbacks currently have no facility for cancelling or abandoning
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// them. We currently handle this at a higher level for cases where this is
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// necessary. The pointer in a callback must remain valid until the callback
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// is made.
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Like Task, the callback executor is responsible for deleting the callback
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// pointer once the callback has executed.
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Example client usage:
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   void Object::DoStuff(int, string);
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   Callback2<int, string>::Type* callback =
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//       NewCallback(obj, &Object::DoStuff);
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   callback->Run(5, string("hello"));
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   delete callback;
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// or, equivalently, using tuples directly:
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   CallbackRunner<Tuple2<int, string> >* callback =
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//       NewCallback(obj, &Object::DoStuff);
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   callback->RunWithParams(MakeTuple(5, string("hello")));
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// There is also a 0-args version that returns a value.  Example:
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   int Object::GetNextInt();
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   CallbackWithReturnValue<int>::Type* callback =
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//       NewCallbackWithReturnValue(obj, &Object::GetNextInt);
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   int next_int = callback->Run();
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//   delete callback;
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Base for all Callbacks that handles storage of the pointers.
5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Method>
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass CallbackStorage {
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) {
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen protected:
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  T* obj_;
6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Method meth_;
6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Interface that is exposed to the consumer, that does the actual calling
6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// of the method.
6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename Params>
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass CallbackRunner {
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef Params TupleType;
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual ~CallbackRunner() {}
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void RunWithParams(const Params& params) = 0;
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Convenience functions so callers don't have to deal with Tuples.
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  inline void Run() {
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    RunWithParams(Tuple0());
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  template <typename Arg1>
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  inline void Run(const Arg1& a) {
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    RunWithParams(Params(a));
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  template <typename Arg1, typename Arg2>
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  inline void Run(const Arg1& a, const Arg2& b) {
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    RunWithParams(Params(a, b));
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  template <typename Arg1, typename Arg2, typename Arg3>
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  inline void Run(const Arg1& a, const Arg2& b, const Arg3& c) {
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    RunWithParams(Params(a, b, c));
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) {
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    RunWithParams(Params(a, b, c, d));
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  template <typename Arg1, typename Arg2, typename Arg3,
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            typename Arg4, typename Arg5>
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  inline void Run(const Arg1& a, const Arg2& b, const Arg3& c,
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  const Arg4& d, const Arg5& e) {
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    RunWithParams(Params(a, b, c, d, e));
10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Method, typename Params>
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass CallbackImpl : public CallbackStorage<T, Method>,
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                     public CallbackRunner<Params> {
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CallbackImpl(T* obj, Method meth) : CallbackStorage<T, Method>(obj, meth) {
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void RunWithParams(const Params& params) {
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // use "this->" to force C++ to look inside our templatized base class; see
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Effective C++, 3rd Ed, item 43, p210 for details.
11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DispatchToMethod(this->obj_, this->meth_, params);
12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 0-arg implementation
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct Callback0 {
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef CallbackRunner<Tuple0> Type;
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T>
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename Callback0::Type* NewCallback(T* object, void (T::*method)()) {
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackImpl<T, void (T::*)(), Tuple0 >(object, method);
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1-arg implementation
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename Arg1>
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct Callback1 {
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef CallbackRunner<Tuple1<Arg1> > Type;
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Arg1>
14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename Callback1<Arg1>::Type* NewCallback(T* object,
14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                            void (T::*method)(Arg1)) {
14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackImpl<T, void (T::*)(Arg1), Tuple1<Arg1> >(object, method);
14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 2-arg implementation
14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename Arg1, typename Arg2>
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct Callback2 {
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type;
14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Arg1, typename Arg2>
15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename Callback2<Arg1, Arg2>::Type* NewCallback(
15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    T* object,
15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void (T::*method)(Arg1, Arg2)) {
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackImpl<T, void (T::*)(Arg1, Arg2),
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Tuple2<Arg1, Arg2> >(object, method);
15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3-arg implementation
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename Arg1, typename Arg2, typename Arg3>
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct Callback3 {
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef CallbackRunner<Tuple3<Arg1, Arg2, Arg3> > Type;
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Arg1, typename Arg2, typename Arg3>
16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback(
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    T* object,
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void (T::*method)(Arg1, Arg2, Arg3)) {
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackImpl<T,  void (T::*)(Arg1, Arg2, Arg3),
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Tuple3<Arg1, Arg2, Arg3> >(object, method);
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4-arg implementation
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct Callback4 {
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef CallbackRunner<Tuple4<Arg1, Arg2, Arg3, Arg4> > Type;
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback(
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    T* object,
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void (T::*method)(Arg1, Arg2, Arg3, Arg4)) {
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4),
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Tuple4<Arg1, Arg2, Arg3, Arg4> >(object, method);
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 5-arg implementation
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename Arg1, typename Arg2, typename Arg3,
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          typename Arg4, typename Arg5>
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct Callback5 {
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef CallbackRunner<Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> > Type;
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Arg1, typename Arg2,
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          typename Arg3, typename Arg4, typename Arg5>
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback(
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    T* object,
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) {
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5),
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >(object, method);
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// An UnboundMethod is a wrapper for a method where the actual object is
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// provided at Run dispatch time.
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, class Method, class Params>
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass UnboundMethod {
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UnboundMethod(Method m, const Params& p) : m_(m), p_(p) {
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    COMPILE_ASSERT(
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value),
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        badunboundmethodparams);
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void Run(T* obj) const {
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DispatchToMethod(obj, m_, p_);
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private:
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Method m_;
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Params p_;
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Return value implementation with no args.
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename ReturnValue>
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct CallbackWithReturnValue {
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  class Type {
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen   public:
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual ~Type() {}
22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual ReturnValue Run() = 0;
22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename Method, typename ReturnValue>
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass CallbackWithReturnValueImpl
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : public CallbackStorage<T, Method>,
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      public CallbackWithReturnValue<ReturnValue>::Type {
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CallbackWithReturnValueImpl(T* obj, Method meth)
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      : CallbackStorage<T, Method>(obj, meth) {}
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual ReturnValue Run() {
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return (this->obj_->*(this->meth_))();
24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen protected:
24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual ~CallbackWithReturnValueImpl() {}
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T, typename ReturnValue>
24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypename CallbackWithReturnValue<ReturnValue>::Type*
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenNewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) {
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return new CallbackWithReturnValueImpl<T, ReturnValue (T::*)(), ReturnValue>(
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      object, method);
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif  // BASE_CALLBACK_OLD_H_
255