callback.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef BASE_CALLBACK_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define BASE_CALLBACK_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/tuple.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/raw_scoped_refptr_mismatch_checker.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Callback -------------------------------------------------------------------- 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A Callback is like a Task but with unbound parameters. It is basically an 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// object-oriented function pointer. 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Callbacks are designed to work with Tuples. A set of helper functions and 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// classes is provided to hide the Tuple details from the consumer. Client 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// code will generally work with the CallbackRunner base class, which merely 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// provides a Run method and is returned by the New* functions. This allows 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// users to not care which type of class implements the callback, only that it 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// has a certain number and type of arguments. 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The implementation of this is done by CallbackImpl, which inherits 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CallbackStorage to store the data. This allows the storage of the data 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (requiring the class type T) to be hidden from users, who will want to call 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// this regardless of the implementor's type T. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note that callbacks currently have no facility for cancelling or abandoning 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// them. We currently handle this at a higher level for cases where this is 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// necessary. The pointer in a callback must remain valid until the callback 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is made. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Like Task, the callback executor is responsible for deleting the callback 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pointer once the callback has executed. 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Example client usage: 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// void Object::DoStuff(int, string); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Callback2<int, string>::Type* callback = 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NewCallback(obj, &Object::DoStuff); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// callback->Run(5, string("hello")); 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// delete callback; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// or, equivalently, using tuples directly: 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CallbackRunner<Tuple2<int, string> >* callback = 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NewCallback(obj, &Object::DoStuff); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// callback->RunWithParams(MakeTuple(5, string("hello"))); 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// There is also a 0-args version that returns a value. Example: 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// int Object::GetNextInt(); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CallbackWithReturnValue<int>::Type* callback = 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NewCallbackWithReturnValue(obj, &Object::GetNextInt); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// int next_int = callback->Run(); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// delete callback; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Base for all Callbacks that handles storage of the pointers. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Method> 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CallbackStorage { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch T* obj_; 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Method meth_; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Interface that is exposed to the consumer, that does the actual calling 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of the method. 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename Params> 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CallbackRunner { 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef Params TupleType; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~CallbackRunner() {} 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void RunWithParams(const Params& params) = 0; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Convenience functions so callers don't have to deal with Tuples. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inline void Run() { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunWithParams(Tuple0()); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <typename Arg1> 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inline void Run(const Arg1& a) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunWithParams(Params(a)); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <typename Arg1, typename Arg2> 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inline void Run(const Arg1& a, const Arg2& b) { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunWithParams(Params(a, b)); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <typename Arg1, typename Arg2, typename Arg3> 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inline void Run(const Arg1& a, const Arg2& b, const Arg3& c) { 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunWithParams(Params(a, b, c)); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) { 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunWithParams(Params(a, b, c, d)); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch template <typename Arg1, typename Arg2, typename Arg3, 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typename Arg4, typename Arg5> 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Arg4& d, const Arg5& e) { 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RunWithParams(Params(a, b, c, d, e)); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Method, typename Params> 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CallbackImpl : public CallbackStorage<T, Method>, 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public CallbackRunner<Params> { 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CallbackImpl(T* obj, Method meth) : CallbackStorage<T, Method>(obj, meth) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void RunWithParams(const Params& params) { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // use "this->" to force C++ to look inside our templatized base class; see 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Effective C++, 3rd Ed, item 43, p210 for details. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DispatchToMethod(this->obj_, this->meth_, params); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 0-arg implementation 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct Callback0 { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef CallbackRunner<Tuple0> Type; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T> 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename Callback0::Type* NewCallback(T* object, void (T::*method)()) { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackImpl<T, void (T::*)(), Tuple0 >(object, method); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 1-arg implementation 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename Arg1> 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct Callback1 { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef CallbackRunner<Tuple1<Arg1> > Type; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Arg1> 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename Callback1<Arg1>::Type* NewCallback(T* object, 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void (T::*method)(Arg1)) { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackImpl<T, void (T::*)(Arg1), Tuple1<Arg1> >(object, method); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 2-arg implementation 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename Arg1, typename Arg2> 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct Callback2 { 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Arg1, typename Arg2> 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename Callback2<Arg1, Arg2>::Type* NewCallback( 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch T* object, 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void (T::*method)(Arg1, Arg2)) { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackImpl<T, void (T::*)(Arg1, Arg2), 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Tuple2<Arg1, Arg2> >(object, method); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 3-arg implementation 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename Arg1, typename Arg2, typename Arg3> 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct Callback3 { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef CallbackRunner<Tuple3<Arg1, Arg2, Arg3> > Type; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Arg1, typename Arg2, typename Arg3> 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback( 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch T* object, 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void (T::*method)(Arg1, Arg2, Arg3)) { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3), 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Tuple3<Arg1, Arg2, Arg3> >(object, method); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 4-arg implementation 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct Callback4 { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef CallbackRunner<Tuple4<Arg1, Arg2, Arg3, Arg4> > Type; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4> 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback( 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch T* object, 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void (T::*method)(Arg1, Arg2, Arg3, Arg4)) { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4), 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Tuple4<Arg1, Arg2, Arg3, Arg4> >(object, method); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 5-arg implementation 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename Arg1, typename Arg2, typename Arg3, 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typename Arg4, typename Arg5> 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct Callback5 { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef CallbackRunner<Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> > Type; 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Arg1, typename Arg2, 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typename Arg3, typename Arg4, typename Arg5> 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback( 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch T* object, 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5), 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >(object, method); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// An UnboundMethod is a wrapper for a method where the actual object is 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// provided at Run dispatch time. 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, class Method, class Params> 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass UnboundMethod { 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnboundMethod(Method m, const Params& p) : m_(m), p_(p) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value), 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch badunboundmethodparams); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Run(T* obj) const { 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DispatchToMethod(obj, m_, p_); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Method m_; 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Params p_; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Return value implementation with no args. 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename ReturnValue> 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct CallbackWithReturnValue { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class Type { 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~Type() {} 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ReturnValue Run() = 0; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename Method, typename ReturnValue> 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CallbackWithReturnValueImpl 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public CallbackStorage<T, Method>, 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public CallbackWithReturnValue<ReturnValue>::Type { 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CallbackWithReturnValueImpl(T* obj, Method meth) 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : CallbackStorage<T, Method>(obj, meth) {} 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ReturnValue Run() { 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (this->obj_->*(this->meth_))(); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~CallbackWithReturnValueImpl() {} 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, typename ReturnValue> 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypename CallbackWithReturnValue<ReturnValue>::Type* 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new CallbackWithReturnValueImpl<T, ReturnValue (T::*)(), ReturnValue>( 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch object, method); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // BASE_CALLBACK_H 254