diff options
author | stoyan@google.com <stoyan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-19 16:11:24 +0000 |
---|---|---|
committer | stoyan@google.com <stoyan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-19 16:11:24 +0000 |
commit | b01784ab0881e7c2925d20150b72949cdf9bcf6a (patch) | |
tree | bb23e535feb28923b7d40827db333c5484c50561 /chrome_frame/test | |
parent | b2c9a1e325d47e4b098972485b6c00db8f35d94f (diff) | |
download | chromium_src-b01784ab0881e7c2925d20150b72949cdf9bcf6a.zip chromium_src-b01784ab0881e7c2925d20150b72949cdf9bcf6a.tar.gz chromium_src-b01784ab0881e7c2925d20150b72949cdf9bcf6a.tar.bz2 |
Simplification, generalization (and perhaps additional mystification) of gmock helpers.
Leak fixed - when gmock call is not satisfied, the callback that was set was leaked.
Suggestion for better names here and there are very welcome (though MF seems nice to me).
TEST=mocked tests runs
Review URL: http://codereview.chromium.org/285007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29402 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/test')
-rw-r--r-- | chrome_frame/test/chrome_frame_unittests.cc | 31 | ||||
-rw-r--r-- | chrome_frame/test/helper_gmock.h | 924 |
2 files changed, 495 insertions, 460 deletions
diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc index 8e1ad92..ed8f71d 100644 --- a/chrome_frame/test/chrome_frame_unittests.cc +++ b/chrome_frame/test/chrome_frame_unittests.cc @@ -1026,8 +1026,8 @@ template <> struct RunnableMethodTraits<TimedMsgLoop> { // Saves typing. It's somewhat hard to create a wrapper around // testing::InvokeWithoutArgs since it returns a // non-public (testing::internal) type. -#define QUIT_LOOP(loop) testing::InvokeWithoutArgs(TaskHolder(\ - NewRunnableMethod(&loop, &TimedMsgLoop::Quit))) +#define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\ + CreateFunctor(&loop, &TimedMsgLoop::Quit)) // We mock ChromeFrameDelegate only. The rest is with real AutomationProxy TEST(CFACWithChrome, CreateTooFast) { @@ -1099,7 +1099,7 @@ TEST(CFACWithChrome, NavigateOk) { client.reset(new ChromeFrameAutomationClient); EXPECT_CALL(cfd, OnAutomationServerReady()) - .WillOnce(testing::InvokeWithoutArgs(TaskHolder(NewRunnableMethod( + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor( client.get(), &ChromeFrameAutomationClient::InitiateNavigation, url, false)))); @@ -1139,7 +1139,7 @@ TEST(CFACWithChrome, DISABLED_NavigateFailed) { client.reset(new ChromeFrameAutomationClient); EXPECT_CALL(cfd, OnAutomationServerReady()) - .WillOnce(testing::InvokeWithoutArgs(TaskHolder(NewRunnableMethod( + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor( client.get(), &ChromeFrameAutomationClient::InitiateNavigation, url, false)))); @@ -1197,7 +1197,7 @@ TEST(CFACWithChrome, UseHostNetworkStack) { cfd.SetAutomationSender(client.get()); EXPECT_CALL(cfd, OnAutomationServerReady()) - .WillOnce(testing::InvokeWithoutArgs(TaskHolder(NewRunnableMethod( + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor( client.get(), &ChromeFrameAutomationClient::InitiateNavigation, url, false)))); @@ -1219,16 +1219,18 @@ TEST(CFACWithChrome, UseHostNetworkStack) { EXPECT_CALL(cfd, OnRequestStart(tab_id, request_id, EqUrlGet(url + '/'))) .Times(1) - .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::ReplyStarted, - &found))); + .WillOnce(testing::Invoke(CreateFunctor(&cfd, + &MockCFDelegate::ReplyStarted, + &found))); // Return some trivial page, that have a link to a "logo.gif" image const std::string data = "<!DOCTYPE html><title>Hello</title>" "<img src=\"logo.gif\">"; EXPECT_CALL(cfd, OnRequestRead(tab_id, request_id, testing::Ge(0))) .Times(2) - .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::ReplyData, &data))) - .WillOnce(testing::WithArgs<0, 1>(testing::Invoke(CBF(&cfd, + .WillOnce(testing::Invoke(CreateFunctor(&cfd, &MockCFDelegate::ReplyData, + &data))) + .WillOnce(testing::WithArgs<0, 1>(testing::Invoke(CreateFunctor(&cfd, &MockCFDelegate::ReplyEOF)))); EXPECT_CALL(cfd, OnDidNavigate(tab_id, EqNavigationInfoUrl(GURL(url)))) @@ -1241,7 +1243,8 @@ TEST(CFACWithChrome, UseHostNetworkStack) { EXPECT_CALL(cfd, OnRequestStart(tab_id, request_id, EqUrlGet(url + "/logo.gif"))) .Times(1) - .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::Reply404))); + .WillOnce(testing::Invoke(CreateFunctor(&cfd, + &MockCFDelegate::Reply404))); EXPECT_CALL(cfd, OnRequestRead(tab_id, request_id, testing::_)) .Times(testing::AtMost(1)); @@ -1251,7 +1254,8 @@ TEST(CFACWithChrome, UseHostNetworkStack) { EXPECT_CALL(cfd, OnRequestStart(tab_id, request_id, EqUrlGet(url + "/favicon.ico"))) .Times(1) - .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::Reply404))); + .WillOnce(testing::Invoke(CreateFunctor(&cfd, + &MockCFDelegate::Reply404))); EXPECT_CALL(cfd, OnRequestRead(tab_id, request_id, testing::_)) .Times(testing::AtMost(1)); @@ -1315,8 +1319,9 @@ class CFACMockTest : public testing::Test { .Times(1) .WillOnce(testing::DoAll( testing::WithArgs<0, 4>( - testing::Invoke(CBF(&factory_, &MockProxyFactory::GetServerImpl, - get_proxy(), AUTOMATION_SUCCESS))), + testing::Invoke(CreateFunctor(&factory_, + &MockProxyFactory::GetServerImpl, + get_proxy(), AUTOMATION_SUCCESS))), testing::Return(id_))); EXPECT_CALL(factory_, ReleaseAutomationServer(testing::Eq(id_))).Times(1); diff --git a/chrome_frame/test/helper_gmock.h b/chrome_frame/test/helper_gmock.h index 7f6d0a7..2475186 100644 --- a/chrome_frame/test/helper_gmock.h +++ b/chrome_frame/test/helper_gmock.h @@ -3,595 +3,625 @@ // found in the LICENSE file. #ifndef CHROME_FRAME_TEST_HELPER_GMOCK_H_ #define CHROME_FRAME_TEST_HELPER_GMOCK_H_ -// This intention of this file is to make possible gmock WithArgs<> in -// Chromium code base. -// MutantImpl is like CallbackImpl, but also has prebound arguments (like Task) -// There is also functor wrapper around it that should be used with -// testing::Invoke, for example: -// testing::WithArgs<0, 2>( -// testing::Invoke(CBF(&mock_object, &MockObject::Something, &tmp_obj, 12))); -// This will invoke MockObject::Something(tmp_obj, 12, arg_0, arg_2) - +// The intention of this file is to make possible using GMock actions in +// all of its syntactic beauty. Classes and helper functions could be used as +// more generic variants of Task and Callback classes (see base/task.h) +// Mutant supports both pre-bound arguments (like Task) and call-time arguments +// (like Callback) - hence the name. :-) // DispatchToMethod supporting two sets of arguments - -// prebound (P) and calltime (C) -// 1 - 1 -template <class ObjT, class Method, class P1, class C1> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<P1>& p, - const Tuple1<C1>& c) { - (obj->*method)(p.a, c.a); -} -// 2 - 1 -template <class ObjT, class Method, class P1, class P2, class C1> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<P1, P2>& p, - const Tuple1<C1>& c) { - (obj->*method)(p.a, p.b, c.a); -} -// 3 - 1 -template <class ObjT, class Method, class P1, class P2, class P3, class C1> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<P1, P2, P3>& p, - const Tuple1<C1>& c) { - (obj->*method)(p.a, p.b, p.c, c.a); -} -// 4 - 1 -template <class ObjT, class Method, class P1, class P2, class P3, - class P4, class C1> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<P1, P2, P3, P4>& p, - const Tuple1<C1>& c) { - (obj->*method)(p.a, p.b, p.c, p.d, c.a); -} +// pre-bound (P) and call-time (C) as well as return value type is templatized +// It will also try to call the selected method even if provided pre-bound args +// does not match exactly with the function signature - hence the X1, X2 +// parameters in CreateFunctor. -// 1 - 2 -template <class ObjT, class Method, class P1, class C1, class C2> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<P1>& p, - const Tuple2<C1, C2>& c) { - (obj->*method)(p.a, c.a, c.b); -} +#include "base/linked_ptr.h" +#include "base/task.h" // for CallBackStorage +#include "base/tuple.h" // for Tuple -// 2 - 2 -template <class ObjT, class Method, class P1, class P2, class C1, class C2> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<P1, P2>& p, - const Tuple2<C1, C2>& c) { - (obj->*method)(p.a, p.b, c.a, c.b); -} -// 3 - 2 -template <class ObjT, class Method, class P1, class P2, class P3, class C1, - class C2> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<P1, P2, P3>& p, - const Tuple2<C1, C2>& c) { - (obj->*method)(p.a, p.b, p.c, c.a, c.b); -} - -// 4 - 2 -template <class ObjT, class Method, class P1, class P2, class P3, class P4, - class C1, class C2> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<P1, P2, P3, P4>& p, - const Tuple2<C1, C2>& c) { - (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b); -} - -// 1 - 3 -template <class ObjT, class Method, class P1, class C1, class C2, class C3> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<P1>& p, - const Tuple3<C1, C2, C3>& c) { - (obj->*method)(p.a, c.a, c.b, c.c); -} - -// 2 - 3 -template <class ObjT, class Method, class P1, class P2, class C1, class C2, - class C3> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<P1, P2>& p, - const Tuple3<C1, C2, C3>& c) { - (obj->*method)(p.a, p.b, c.a, c.b, c.c); +// 0 - 0 +template <typename R, typename T, typename Method> +inline R DispatchToMethod(T* obj, Method method, + const Tuple0& p, + const Tuple0& c) { + return (obj->*method)(); } -// 3 - 3 -template <class ObjT, class Method, class P1, class P2, class P3, class C1, - class C2, class C3> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<P1, P2, P3>& p, - const Tuple3<C1, C2, C3>& c) { - (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c); -} - -// 4 - 3 -template <class ObjT, class Method, class P1, class P2, class P3, class P4, - class C1, class C2, class C3> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<P1, P2, P3, P4>& p, - const Tuple3<C1, C2, C3>& c) { - (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c); +// 0 - 1 +template <typename R, typename T, typename Method, typename C1> +inline R DispatchToMethod(T* obj, Method method, + const Tuple0& p, + const Tuple1<C1>& c) { + return (obj->*method)(c.a); } -// 1 - 4 -template <class ObjT, class Method, class P1, class C1, class C2, class C3, - class C4> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<P1>& p, - const Tuple4<C1, C2, C3, C4>& c) { - (obj->*method)(p.a, c.a, c.b, c.c, c.d); +// 0 - 2 +template <typename R, typename T, typename Method, typename C1, typename C2> +inline R DispatchToMethod(T* obj, Method method, + const Tuple0& p, + const Tuple2<C1, C2>& c) { + return (obj->*method)(c.a, c.b); } -// 2 - 4 -template <class ObjT, class Method, class P1, class P2, class C1, class C2, - class C3, class C4> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<P1, P2>& p, - const Tuple4<C1, C2, C3, C4>& c) { - (obj->*method)(p.a, p.b, c.a, c.b, c.c, c.d); +// 0 - 3 +template <typename R, typename T, typename Method, typename C1, typename C2, + typename C3> +inline R DispatchToMethod(T* obj, Method method, + const Tuple0& p, + const Tuple3<C1, C2, C3>& c) { + return (obj->*method)(c.a, c.b, c.c); } -// 3 - 4 -template <class ObjT, class Method, class P1, class P2, class P3, - class C1, class C2, class C3, class C4> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<P1, P2, P3>& p, - const Tuple4<C1, C2, C3, C4>& c) { - (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c, c.d); +// 0 - 4 +template <typename R, typename T, typename Method, typename C1, typename C2, + typename C3, typename C4> +inline R DispatchToMethod(T* obj, Method method, + const Tuple0& p, + const Tuple4<C1, C2, C3, C4>& c) { + return (obj->*method)(c.a, c.b, c.c, c.d); } -// 4 - 4 -template <class ObjT, class Method, class P1, class P2, class P3, class P4, - class C1, class C2, class C3, class C4> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<P1, P2, P3, P4>& p, - const Tuple4<C1, C2, C3, C4>& c) { - (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d); +// 1 - 0 +template <typename R, typename T, typename Method, typename P1> +inline R DispatchToMethod(T* obj, Method method, + const Tuple1<P1>& p, + const Tuple0& c) { + return (obj->*method)(p.a); } - -//////////////////////////////////////////////////////////////////////////////// - -// Like CallbackImpl but has prebound arguments (like Task) -template <class T, typename Method, typename PreBound, typename Params> -class MutantImpl : public CallbackStorage<T, Method>, - public CallbackRunner<Params> { - public: - MutantImpl(T* obj, Method meth, const PreBound& pb) - : CallbackStorage<T, Method>(obj, meth), - pb_(pb) { - } - - virtual void RunWithParams(const Params& params) { - // use "this->" to force C++ to look inside our templatized base class; see - // Effective C++, 3rd Ed, item 43, p210 for details. - DispatchToMethod(this->obj_, this->meth_, pb_, params); - } - - PreBound pb_; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Mutant creation simplification // 1 - 1 -template <class T, typename P1, typename A1> -inline typename Callback1<A1>::Type* NewMutant(T* obj, - void (T::*method)(P1, A1), - P1 p1) { - return new MutantImpl<T, void (T::*)(P1, A1), P1, A1>(obj, method, - MakeTuple(p1)); +template <typename R, typename T, typename Method, typename P1, typename C1> +inline R DispatchToMethod(T* obj, Method method, + const Tuple1<P1>& p, + const Tuple1<C1>& c) { + return (obj->*method)(p.a, c.a); } // 1 - 2 -template <class T, typename P1, typename A1, typename A2> -inline typename Callback2<A1, A2>::Type* NewMutant(T* obj, - void (T::*method)(P1, A1, A2), - P1 p1) { - return new MutantImpl<T, void (T::*)(P1, A1, A2), Tuple1<P1>, Tuple2<A1, A2> > - (obj, method, MakeTuple(p1)); +template <typename R, typename T, typename Method, typename P1, typename C1, + typename C2> +inline R DispatchToMethod(T* obj, Method method, + const Tuple1<P1>& p, + const Tuple2<C1, C2>& c) { + return (obj->*method)(p.a, c.a, c.b); } // 1 - 3 -template <class T, typename P1, typename A1, typename A2, typename A3> -inline typename Callback3<A1, A2, A3>::Type* -NewMutant(T* obj, void (T::*method)(P1, A1, A2, A3), P1 p1) { - return new MutantImpl<T, void (T::*)(P1, A1, A2, A3), Tuple1<P1>, - Tuple3<A1, A2, A3> >(obj, method, MakeTuple(p1)); +template <typename R, typename T, typename Method, typename P1, typename C1, + typename C2, typename C3> +inline R DispatchToMethod(T* obj, Method method, + const Tuple1<P1>& p, + const Tuple3<C1, C2, C3>& c) { + return (obj->*method)(p.a, c.a, c.b, c.c); } // 1 - 4 -template <class T, typename P1, typename A1, typename A2, typename A3, - typename A4> -inline typename Callback4<A1, A2, A3, A4>::Type* -NewMutant(T* obj, void (T::*method)(P1, A1, A2, A3, A4), P1 p1) { - return new MutantImpl<T, void (T::*)(P1, A1, A2, A3, A4), Tuple1<P1>, - Tuple4<A1, A2, A3, A4> >(obj, method, MakeTuple(p1)); +template <typename R, typename T, typename Method, typename P1, typename C1, + typename C2, typename C3, typename C4> +inline R DispatchToMethod(T* obj, Method method, + const Tuple1<P1>& p, + const Tuple4<C1, C2, C3, C4>& c) { + return (obj->*method)(p.a, c.a, c.b, c.c, c.d); } +// 2 - 0 +template <typename R, typename T, typename Method, typename P1, typename P2> +inline R DispatchToMethod(T* obj, Method method, + const Tuple2<P1, P2>& p, + const Tuple0& c) { + return (obj->*method)(p.a, p.b); +} // 2 - 1 -template <class T, typename P1, typename P2, typename A1> -inline typename Callback1<A1>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, A1), P1 p1, P2 p2) { - return new MutantImpl<T, void (T::*)(P1, P2, A1), Tuple2<P1, P2>, - Tuple1<A1> >(obj, method, MakeTuple(p1, p2)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename C1> +inline R DispatchToMethod(T* obj, Method method, + const Tuple2<P1, P2>& p, + const Tuple1<C1>& c) { + return (obj->*method)(p.a, p.b, c.a); } // 2 - 2 -template <class T, typename P1, typename P2, typename A1, typename A2> -inline typename Callback2<A1, A2>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, A1, A2), P1 p1, P2 p2) { - return new MutantImpl<T, void (T::*)(P1, P2, A1, A2), Tuple2<P1, P2>, - Tuple2<A1, A2> >(obj, method, MakeTuple(p1, p2)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename C1, typename C2> +inline R DispatchToMethod(T* obj, Method method, + const Tuple2<P1, P2>& p, + const Tuple2<C1, C2>& c) { + return (obj->*method)(p.a, p.b, c.a, c.b); } // 2 - 3 -template <class T, typename P1, typename P2, typename A1, typename A2, - typename A3> -inline typename Callback3<A1, A2, A3>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, A1, A2, A3), P1 p1, P2 p2) { - return new MutantImpl<T, void (T::*)(P1, P2, A1, A2, A3), Tuple2<P1, P2>, - Tuple3<A1, A2, A3> >(obj, method, MakeTuple(p1, p2)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename C1, typename C2, typename C3> +inline R DispatchToMethod(T* obj, Method method, + const Tuple2<P1, P2>& p, + const Tuple3<C1, C2, C3>& c) { + return (obj->*method)(p.a, p.b, c.a, c.b, c.c); } // 2 - 4 -template <class T, typename P1, typename P2, typename A1, typename A2, - typename A3, typename A4> -inline typename Callback4<A1, A2, A3, A4>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, A1, A2, A3, A4), P1 p1, P2 p2) { - return new MutantImpl<T, void (T::*)(P1, P2, A1, A2, A3, A4), Tuple2<P1, P2>, - Tuple3<A1, A2, A3, A4> >(obj, method, MakeTuple(p1, p2)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename C1, typename C2, typename C3, typename C4> +inline R DispatchToMethod(T* obj, Method method, + const Tuple2<P1, P2>& p, + const Tuple4<C1, C2, C3, C4>& c) { + return (obj->*method)(p.a, p.b, c.a, c.b, c.c, c.d); +} + +// 3 - 0 +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3> +inline R DispatchToMethod(T* obj, Method method, + const Tuple3<P1, P2, P3>& p, + const Tuple0& c) { + return (obj->*method)(p.a, p.b, p.c); } // 3 - 1 -template <class T, typename P1, typename P2, typename P3, typename A1> -inline typename Callback1<A1>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, A1), P1 p1, P2 p2, P3 p3) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, A1), Tuple3<P1, P2, P3>, - Tuple1<A1> >(obj, method, MakeTuple(p1, p2, p3)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename C1> +inline R DispatchToMethod(T* obj, Method method, + const Tuple3<P1, P2, P3>& p, + const Tuple1<C1>& c) { + return (obj->*method)(p.a, p.b, p.c, c.a); } // 3 - 2 -template <class T, typename P1, typename P2, typename P3, typename A1, - typename A2> -inline typename Callback2<A1, A2>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, A1, A2), P1 p1, P2 p2, P3 p3) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, A1, A2), Tuple3<P1, P2, P3>, - Tuple2<A1, A2> >(obj, method, MakeTuple(p1, p2, p3)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename C1, typename C2> +inline R DispatchToMethod(T* obj, Method method, + const Tuple3<P1, P2, P3>& p, + const Tuple2<C1, C2>& c) { + return (obj->*method)(p.a, p.b, p.c, c.a, c.b); } // 3 - 3 -template <class T, typename P1, typename P2, typename P3, typename A1, - typename A2, typename A3> -inline typename Callback3<A1, A2, A3>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, A1, A2, A3), P1 p1, P2 p2, - P3 p3) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, A1, A2, A3), - Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >(obj, method, - MakeTuple(p1, p2, p3)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename C1, typename C2, typename C3> +inline R DispatchToMethod(T* obj, Method method, + const Tuple3<P1, P2, P3>& p, + const Tuple3<C1, C2, C3>& c) { + return (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c); } // 3 - 4 -template <class T, typename P1, typename P2, typename P3, typename A1, - typename A2, typename A3, typename A4> -inline typename Callback4<A1, A2, A3, A4>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, A1, A2, A3, A4), P1 p1, P2 p2, - P3 p3) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, A1, A2, A3, A4), - Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3, A4> >(obj, method, - MakeTuple(p1, p2, p3)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename C1, typename C2, typename C3, typename C4> +inline R DispatchToMethod(T* obj, Method method, + const Tuple3<P1, P2, P3>& p, + const Tuple4<C1, C2, C3, C4>& c) { + return (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c, c.d); +} + +// 4 - 0 +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename P4> +inline R DispatchToMethod(T* obj, Method method, + const Tuple4<P1, P2, P3, P4>& p, + const Tuple0& c) { + return (obj->*method)(p.a, p.b, p.c, p.d); } // 4 - 1 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1> -inline typename Callback1<A1>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, P4, A1), P1 p1, P2 p2, P3 p3, - P4 p4) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1), - Tuple4<P1, P2, P3, P4>, Tuple1<A1> >(obj, method, - MakeTuple(p1, p2, p3, p4)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename P4, typename C1> +inline R DispatchToMethod(T* obj, Method method, + const Tuple4<P1, P2, P3, P4>& p, + const Tuple1<C1>& c) { + return (obj->*method)(p.a, p.b, p.c, p.d, c.a); } // 4 - 2 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1, typename A2> -inline typename Callback2<A1, A2>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, P4, A1, A2), P1 p1, P2 p2, - P3 p3, P4 p4) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1, A2), - Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >(obj, method, - MakeTuple(p1, p2, p3, p4)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename P4, typename C1, typename C2> +inline R DispatchToMethod(T* obj, Method method, + const Tuple4<P1, P2, P3, P4>& p, + const Tuple2<C1, C2>& c) { + return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b); } // 4 - 3 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1, typename A2, typename A3> -inline typename Callback3<A1, A2, A3>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, P4, A1, A2, A3), P1 p1, P2 p2, - P3 p3, P4 p4) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1, A2, A3), - Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >(obj, method, - MakeTuple(p1, p2, p3, p4)); +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename P4, typename C1, typename C2, typename C3> +inline R DispatchToMethod(T* obj, Method method, + const Tuple4<P1, P2, P3, P4>& p, + const Tuple3<C1, C2, C3>& c) { + return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c); } // 4 - 4 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1, typename A2, typename A3, typename A4> -inline typename Callback4<A1, A2, A3, A4>::Type* -NewMutant(T* obj, void (T::*method)(P1, P2, P3, P4, A1, A2, A3, A4), - P1 p1, P2 p2, P3 p3, P4 p4) { - return new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1, A2, A3, A4), - Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3, A4> >(obj, method, - MakeTuple(p1, p2, p3, p4)); -} - -//////////////////////////////////////////////////////////////////////////////// -// Simple callback wrapper acting as a functor. -// Redirects operator() to CallbackRunner<Params>::Run -// We cannot delete the inner impl_ in object's destructor because -// this object is copied few times inside from GMock machinery. -template <typename Params> -struct CallbackFunctor { - explicit CallbackFunctor(CallbackRunner<Params>* cb) : impl_(cb) {} +template <typename R, typename T, typename Method, typename P1, typename P2, + typename P3, typename P4, typename C1, typename C2, typename C3, + typename C4> +inline R DispatchToMethod(T* obj, Method method, + const Tuple4<P1, P2, P3, P4>& p, + const Tuple4<C1, C2, C3, C4>& c) { + return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d); +} + +// Interface that is exposed to the consumer, that does the actual calling +// of the method. +template <typename R, typename Params> +class MutantRunner { + public: + virtual R RunWithParams(const Params& params) = 0; + virtual ~MutantRunner() {} +}; + +// MutantImpl holds pre-bound arguments (like Task) and like Callback +// allows call-time arguments. +template <typename R, typename T, typename Method, + typename PreBound, typename Params> +class MutantImpl : public CallbackStorage<T, Method>, + public MutantRunner<R, Params> { + public: + MutantImpl(T* obj, Method meth, const PreBound& pb) + : CallbackStorage<T, Method>(obj, meth), + pb_(pb) { + } + + // MutantRunner implementation + virtual R RunWithParams(const Params& params) { + return DispatchToMethod<R>(this->obj_, this->meth_, pb_, params); + } + + PreBound pb_; +}; + +// Simple MutantRunner<> wrapper acting as a functor. +// Redirects operator() to MutantRunner<Params>::Run() +template <typename R, typename Params> +struct MutantFunctor { + explicit MutantFunctor(MutantRunner<R, Params>* cb) : impl_(cb) { + } + + ~MutantFunctor() { + } + + inline R operator()() { + return impl_->RunWithParams(Tuple0()); + } template <typename Arg1> - inline void operator()(const Arg1& a) { - impl_->Run(a); - delete impl_; - impl_ = NULL; + inline R operator()(const Arg1& a) { + return impl_->RunWithParams(Params(a)); } template <typename Arg1, typename Arg2> - inline void operator()(const Arg1& a, const Arg2& b) { - impl_->Run(a, b); - delete impl_; - impl_ = NULL; + inline R operator()(const Arg1& a, const Arg2& b) { + return impl_->RunWithParams(Params(a, b)); } template <typename Arg1, typename Arg2, typename Arg3> - inline void operator()(const Arg1& a, const Arg2& b, const Arg3& c) { - impl_->Run(a, b, c); - delete impl_; - impl_ = NULL; + inline R operator()(const Arg1& a, const Arg2& b, const Arg3& c) { + return impl_->RunWithParams(Params(a, b, c)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> - inline void operator()(const Arg1& a, const Arg2& b, const Arg3& c, + inline R operator()(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) { - impl_->Run(a, b, c, d); - delete impl_; - impl_ = NULL; + return impl_->RunWithParams(Params(a, b, c, d)); } private: - CallbackFunctor(); - CallbackRunner<Params>* impl_; + // We need copy constructor since MutantFunctor is copied few times + // inside GMock machinery, hence no DISALLOW_EVIL_CONTRUCTORS + MutantFunctor(); + linked_ptr<MutantRunner<R, Params> > impl_; }; -/////////////////////////////////////////////////////////////////////////////// -// CallbackFunctors creation + +// 0 - 0 +template <typename R, typename T> +inline MutantFunctor<R, Tuple0> +CreateFunctor(T* obj, R (T::*method)()) { + MutantRunner<R, Tuple0> *t = new MutantImpl<R, T, + R (T::*)(), + Tuple0, Tuple0> + (obj, method, MakeTuple()); + return MutantFunctor<R, Tuple0>(t); +} // 0 - 1 -template <class T, typename A1> -inline CallbackFunctor<Tuple1<A1> > -CBF(T* obj, void (T::*method)(A1)) { - return CallbackFunctor<Tuple1<A1> >(NewCallback(obj, method)); +template <typename R, typename T, typename A1> +inline MutantFunctor<R, Tuple1<A1> > +CreateFunctor(T* obj, R (T::*method)(A1)) { + MutantRunner<R, Tuple1<A1> > *t = new MutantImpl<R, T, + R (T::*)(A1), + Tuple0, Tuple1<A1> > + (obj, method, MakeTuple()); + return MutantFunctor<R, Tuple1<A1> >(t); } // 0 - 2 -template <class T, typename A1, typename A2> -inline CallbackFunctor<Tuple2<A1, A2> > -CBF(T* obj, void (T::*method)(A1, A2)) { - return CallbackFunctor<Tuple2<A1, A2> >(NewCallback(obj, method)); +template <typename R, typename T, typename A1, typename A2> +inline MutantFunctor<R, Tuple2<A1, A2> > +CreateFunctor(T* obj, R (T::*method)(A1, A2)) { + MutantRunner<R, Tuple2<A1, A2> > *t = new MutantImpl<R, T, + R (T::*)(A1, A2), + Tuple0, Tuple2<A1, A2> > + (obj, method, MakeTuple()); + return MutantFunctor<R, Tuple2<A1, A2> >(t); } // 0 - 3 -template <class T, typename A1, typename A2, typename A3> -inline CallbackFunctor<Tuple3<A1, A2, A3> > -CBF(T* obj, void (T::*method)(A1, A2, A3)) { - return CallbackFunctor<Tuple3<A1, A2, A3> >(NewCallback(obj, method)); +template <typename R, typename T, typename A1, typename A2, typename A3> +inline MutantFunctor<R, Tuple3<A1, A2, A3> > +CreateFunctor(T* obj, R (T::*method)(A1, A2, A3)) { + MutantRunner<R, Tuple3<A1, A2, A3> > *t = new MutantImpl<R, T, + R (T::*)(A1, A2, A3), + Tuple0, Tuple3<A1, A2, A3> > + (obj, method, MakeTuple()); + return MutantFunctor<R, Tuple3<A1, A2, A3> >(t); } // 0 - 4 -template <class T, typename A1, typename A2, typename A3, typename A4> -inline CallbackFunctor<Tuple4<A1, A2, A3, A4> > -CBF(T* obj, void (T::*method)(A1, A2, A3, A4)) { - return CallbackFunctor<Tuple4<A1, A2, A3, A4> >(NewCallback(obj, method)); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4> +inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> > +CreateFunctor(T* obj, R (T::*method)(A1, A2, A3, A4)) { + MutantRunner<R, Tuple4<A1, A2, A3, A4> > *t = new MutantImpl<R, T, + R (T::*)(A1, A2, A3, A4), + Tuple0, Tuple4<A1, A2, A3, A4> > + (obj, method, MakeTuple()); + return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t); +} + +// 1 - 0 +template <typename R, typename T, typename P1, typename X1> +inline MutantFunctor<R, Tuple0> +CreateFunctor(T* obj, R (T::*method)(X1), const P1& p1) { + MutantRunner<R, Tuple0> *t = new MutantImpl<R, T, + R (T::*)(X1), + Tuple1<P1>, Tuple0> + (obj, method, MakeTuple(p1)); + return MutantFunctor<R, Tuple0>(t); } // 1 - 1 -template <class T, typename P1, typename A1> -inline CallbackFunctor<Tuple1<A1> > -CBF(T* obj, void (T::*method)(P1, A1), P1 p1) { - Callback1<A1>::Type* t = new MutantImpl<T, void (T::*)(P1, A1), Tuple1<P1>, - Tuple1<A1> >(obj, method, MakeTuple(p1)); - return CallbackFunctor<Tuple1<A1> >(t); +template <typename R, typename T, typename P1, typename A1, typename X1> +inline MutantFunctor<R, Tuple1<A1> > +CreateFunctor(T* obj, R (T::*method)(X1, A1), const P1& p1) { + MutantRunner<R, Tuple1<A1> > *t = new MutantImpl<R, T, + R (T::*)(X1, A1), + Tuple1<P1>, Tuple1<A1> > + (obj, method, MakeTuple(p1)); + return MutantFunctor<R, Tuple1<A1> >(t); } // 1 - 2 -template <class T, typename P1, typename A1, typename A2> -inline CallbackFunctor<Tuple2<A1, A2> > -CBF(T* obj, void (T::*method)(P1, A1, A2), P1 p1) { - Callback2<A1, A2>::Type* t = new MutantImpl<T, void (T::*)(P1, A1, A2), - Tuple1<P1>, Tuple2<A1, A2> >(obj, method, MakeTuple(p1)); - return CallbackFunctor<Tuple2<A1, A2> >(t); +template <typename R, typename T, typename P1, typename A1, typename A2, + typename X1> +inline MutantFunctor<R, Tuple2<A1, A2> > +CreateFunctor(T* obj, R (T::*method)(X1, A1, A2), const P1& p1) { + MutantRunner<R, Tuple2<A1, A2> > *t = new MutantImpl<R, T, + R (T::*)(X1, A1, A2), + Tuple1<P1>, Tuple2<A1, A2> > + (obj, method, MakeTuple(p1)); + return MutantFunctor<R, Tuple2<A1, A2> >(t); } // 1 - 3 -template <class T, typename P1, typename A1, typename A2, typename A3> -inline CallbackFunctor<Tuple3<A1, A2, A3> > -CBF(T* obj, void (T::*method)(P1, A1, A2, A3), P1 p1) { - Callback3<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, A1, A2, A3), Tuple1<P1>, - Tuple3<A1, A2, A3> >(obj, method, MakeTuple(p1)); - return CallbackFunctor<Tuple3<A1, A2, A3> >(t); +template <typename R, typename T, typename P1, typename A1, typename A2, + typename A3, typename X1> +inline MutantFunctor<R, Tuple3<A1, A2, A3> > +CreateFunctor(T* obj, R (T::*method)(X1, A1, A2, A3), const P1& p1) { + MutantRunner<R, Tuple3<A1, A2, A3> > *t = new MutantImpl<R, T, + R (T::*)(X1, A1, A2, A3), + Tuple1<P1>, Tuple3<A1, A2, A3> > + (obj, method, MakeTuple(p1)); + return MutantFunctor<R, Tuple3<A1, A2, A3> >(t); } // 1 - 4 -template <class T, typename P1, typename A1, typename A2, typename A3, - typename A4> -inline CallbackFunctor<Tuple4<A1, A2, A3, A4> > -CBF(T* obj, void (T::*method)(P1, A1, A2, A3, A4), P1 p1) { - Callback4<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, A1, A2, A3, A4), Tuple1<P1>, - Tuple4<A1, A2, A3, A4> >(obj, method, MakeTuple(p1)); - return CallbackFunctor<Tuple4<A1, A2, A3, A4> >(t); +template <typename R, typename T, typename P1, typename A1, typename A2, + typename A3, typename A4, typename X1> +inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> > +CreateFunctor(T* obj, R (T::*method)(X1, A1, A2, A3, A4), const P1& p1) { + MutantRunner<R, Tuple4<A1, A2, A3, A4> > *t = new MutantImpl<R, T, + R (T::*)(X1, A1, A2, A3, A4), + Tuple1<P1>, Tuple4<A1, A2, A3, A4> > + (obj, method, MakeTuple(p1)); + return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t); +} + +// 2 - 0 +template <typename R, typename T, typename P1, typename P2, typename X1, + typename X2> +inline MutantFunctor<R, Tuple0> +CreateFunctor(T* obj, R (T::*method)(X1, X2), const P1& p1, const P2& p2) { + MutantRunner<R, Tuple0> *t = new MutantImpl<R, T, + R (T::*)(X1, X2), + Tuple2<P1, P2>, Tuple0> + (obj, method, MakeTuple(p1, p2)); + return MutantFunctor<R, Tuple0>(t); } // 2 - 1 -template <class T, typename P1, typename P2, typename A1> -inline CallbackFunctor<Tuple1<A1> > -CBF(T* obj, void (T::*method)(P1, P2, A1), P1 p1, P2 p2) { - Callback1<A1>::Type* t = new MutantImpl<T, void (T::*)(P1, P2, A1), - Tuple2<P1, P2>, Tuple1<A1> >(obj, method, MakeTuple(p1, p2)); - return CallbackFunctor<Tuple1<A1> >(t); +template <typename R, typename T, typename P1, typename P2, typename A1, + typename X1, typename X2> +inline MutantFunctor<R, Tuple1<A1> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, A1), const P1& p1, const P2& p2) { + MutantRunner<R, Tuple1<A1> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, A1), + Tuple2<P1, P2>, Tuple1<A1> > + (obj, method, MakeTuple(p1, p2)); + return MutantFunctor<R, Tuple1<A1> >(t); } // 2 - 2 -template <class T, typename P1, typename P2, typename A1, typename A2> -inline CallbackFunctor<Tuple2<A1, A2> > -CBF(T* obj, void (T::*method)(P1, P2, A1, A2), P1 p1, P2 p2) { - Callback2<A1, A2>::Type* t = new MutantImpl<T, void (T::*)(P1, P2, A1, A2), - Tuple2<P1, P2>, Tuple2<A1, A2> >(obj, method, MakeTuple(p1, p2)); - return CallbackFunctor<Tuple2<A1, A2> >(t); +template <typename R, typename T, typename P1, typename P2, typename A1, + typename A2, typename X1, typename X2> +inline MutantFunctor<R, Tuple2<A1, A2> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, A1, A2), const P1& p1, + const P2& p2) { + MutantRunner<R, Tuple2<A1, A2> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, A1, A2), + Tuple2<P1, P2>, Tuple2<A1, A2> > + (obj, method, MakeTuple(p1, p2)); + return MutantFunctor<R, Tuple2<A1, A2> >(t); } // 2 - 3 -template <class T, typename P1, typename P2, typename A1, typename A2, - typename A3> inline CallbackFunctor<Tuple3<A1, A2, A3> > -CBF(T* obj, void (T::*method)(P1, P2, A1, A2, A3), P1 p1, P2 p2) { - Callback3<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, A1, A2, A3), Tuple2<P1, P2>, - Tuple3<A1, A2, A3> >(obj, method, MakeTuple(p1, p2)); - return CallbackFunctor<Tuple3<A1, A2, A3> >(t); +template <typename R, typename T, typename P1, typename P2, typename A1, + typename A2, typename A3, typename X1, typename X2> +inline MutantFunctor<R, Tuple3<A1, A2, A3> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, A1, A2, A3), const P1& p1, + const P2& p2) { + MutantRunner<R, Tuple3<A1, A2, A3> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, A1, A2, A3), + Tuple2<P1, P2>, Tuple3<A1, A2, A3> > + (obj, method, MakeTuple(p1, p2)); + return MutantFunctor<R, Tuple3<A1, A2, A3> >(t); } // 2 - 4 -template <class T, typename P1, typename P2, typename A1, typename A2, - typename A3, typename A4> -inline CallbackFunctor<Tuple4<A1, A2, A3, A4> > -CBF(T* obj, void (T::*method)(P1, P2, A1, A2, A3, A4), P1 p1, P2 p2) { - Callback4<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, A1, A2, A3, A4), Tuple2<P1, P2>, - Tuple4<A1, A2, A3, A4> >(obj, method, MakeTuple(p1, p2)); - return CallbackFunctor<Tuple4<A1, A2, A3, A4> >(t); +template <typename R, typename T, typename P1, typename P2, typename A1, + typename A2, typename A3, typename A4, typename X1, typename X2> +inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, A1, A2, A3, A4), const P1& p1, + const P2& p2) { + MutantRunner<R, Tuple4<A1, A2, A3, A4> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, A1, A2, A3, A4), + Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> > + (obj, method, MakeTuple(p1, p2)); + return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t); +} + +// 3 - 0 +template <typename R, typename T, typename P1, typename P2, typename P3, + typename X1, typename X2, typename X3> +inline MutantFunctor<R, Tuple0> +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3), const P1& p1, const P2& p2, + const P3& p3) { + MutantRunner<R, Tuple0> *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3), + Tuple3<P1, P2, P3>, Tuple0> + (obj, method, MakeTuple(p1, p2, p3)); + return MutantFunctor<R, Tuple0>(t); } - // 3 - 1 -template <class T, typename P1, typename P2, typename P3, typename A1> -inline CallbackFunctor<Tuple1<A1> > -CBF(T* obj, void (T::*method)(P1, P2, P3, A1), P1 p1, P2 p2, P3 p3) { - Callback1<A1>::Type* t = new MutantImpl<T, void (T::*)(P1, P2, P3, A1), - Tuple3<P1, P2, P3>, Tuple1<A1> >(obj, method, MakeTuple(p1, p2, p3)); - return CallbackFunctor<Tuple1<A1> >(t); +template <typename R, typename T, typename P1, typename P2, typename P3, + typename A1, typename X1, typename X2, typename X3> +inline MutantFunctor<R, Tuple1<A1> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, A1), const P1& p1, + const P2& p2, const P3& p3) { + MutantRunner<R, Tuple1<A1> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, A1), + Tuple3<P1, P2, P3>, Tuple1<A1> > + (obj, method, MakeTuple(p1, p2, p3)); + return MutantFunctor<R, Tuple1<A1> >(t); } - // 3 - 2 -template <class T, typename P1, typename P2, typename P3, typename A1, - typename A2> inline CallbackFunctor<Tuple2<A1, A2> > -CBF(T* obj, void (T::*method)(P1, P2, P3, A1, A2), P1 p1, P2 p2, P3 p3) { - Callback2<A1, A2>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, P3, A1, A2), Tuple3<P1, P2, P3>, - Tuple2<A1, A2> >(obj, method, MakeTuple(p1, p2, p3)); - return CallbackFunctor<Tuple2<A1, A2> >(t); +template <typename R, typename T, typename P1, typename P2, typename P3, + typename A1, typename A2, typename X1, typename X2, typename X3> +inline MutantFunctor<R, Tuple2<A1, A2> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, A1, A2), const P1& p1, + const P2& p2, const P3& p3) { + MutantRunner<R, Tuple2<A1, A2> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, A1, A2), + Tuple3<P1, P2, P3>, Tuple2<A1, A2> > + (obj, method, MakeTuple(p1, p2, p3)); + return MutantFunctor<R, Tuple2<A1, A2> >(t); } // 3 - 3 -template <class T, typename P1, typename P2, typename P3, typename A1, - typename A2, typename A3> -inline CallbackFunctor<Tuple3<A1, A2, A3> > -CBF(T* obj, void (T::*method)(P1, P2, P3, A1, A2, A3), P1 p1, P2 p2, P3 p3) { - Callback3<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, P3, A1, A2, A3), Tuple3<P1, P2, P3>, - Tuple3<A1, A2, A3> >(obj, method, MakeTuple(p1, p2, p3)); - return CallbackFunctor<Tuple3<A1, A2, A3> >(t); +template <typename R, typename T, typename P1, typename P2, typename P3, + typename A1, typename A2, typename A3, typename X1, typename X2, + typename X3> +inline MutantFunctor<R, Tuple3<A1, A2, A3> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, A1, A2, A3), const P1& p1, + const P2& p2, const P3& p3) { + MutantRunner<R, Tuple3<A1, A2, A3> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, A1, A2, A3), + Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> > + (obj, method, MakeTuple(p1, p2, p3)); + return MutantFunctor<R, Tuple3<A1, A2, A3> >(t); } // 3 - 4 -template <class T, typename P1, typename P2, typename P3, typename A1, - typename A2, typename A3, typename A4> -inline CallbackFunctor<Tuple4<A1, A2, A3, A4> > -CBF(T* obj, void (T::*method)(P1, P2, P3, A1, A2, A3, A4), - P1 p1, P2 p2, P3 p3) { - Callback4<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, P3, A1, A2, A3, A4), - Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >(obj, method, - MakeTuple(p1, p2, p3)); - return CallbackFunctor<Tuple4<A1, A2, A3, A4> >(t); +template <typename R, typename T, typename P1, typename P2, typename P3, + typename A1, typename A2, typename A3, typename A4, typename X1, + typename X2, typename X3> +inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, A1, A2, A3, A4), const P1& p1, + const P2& p2, const P3& p3) { + MutantRunner<R, Tuple4<A1, A2, A3, A4> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, A1, A2, A3, A4), + Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> > + (obj, method, MakeTuple(p1, p2, p3)); + return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t); +} + +// 4 - 0 +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename X1, typename X2, typename X3, typename X4> +inline MutantFunctor<R, Tuple0> +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, X4), const P1& p1, + const P2& p2, const P3& p3, const P4& p4) { + MutantRunner<R, Tuple0> *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, X4), + Tuple4<P1, P2, P3, P4>, Tuple0> + (obj, method, MakeTuple(p1, p2, p3, p4)); + return MutantFunctor<R, Tuple0>(t); } - - // 4 - 1 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1> -inline CallbackFunctor<Tuple1<A1> > -CBF(T* obj, void (T::*method)(P1, P2, P3, P4, A1), P1 p1, P2 p2, P3 p3, P4 p4) { - Callback1<A1>::Type* t = new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1), +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename A1, typename X1, typename X2, typename X3, + typename X4> +inline MutantFunctor<R, Tuple1<A1> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, X4, A1), const P1& p1, + const P2& p2, const P3& p3, const P4& p4) { + MutantRunner<R, Tuple1<A1> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, X4, A1), Tuple4<P1, P2, P3, P4>, Tuple1<A1> > (obj, method, MakeTuple(p1, p2, p3, p4)); - return CallbackFunctor<Tuple1<A1> >(t); + return MutantFunctor<R, Tuple1<A1> >(t); } - // 4 - 2 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1, typename A2> -inline CallbackFunctor<Tuple2<A1, A2> > -CBF(T* obj, void (T::*method)(P1, P2, P3, P4, A1, A2), - P1 p1, P2 p2, P3 p3, P4 p4) { - Callback2<A1, A2>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1, A2), - Tuple4<P1, P2, P3, P4>, - Tuple2<A1, A2> >(obj, method, MakeTuple(p1, p2, p3, p4)); - return CallbackFunctor<Tuple2<A1, A2> >(t); +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename A1, typename A2, typename X1, typename X2, + typename X3, typename X4> +inline MutantFunctor<R, Tuple2<A1, A2> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, X4, A1, A2), const P1& p1, + const P2& p2, const P3& p3, const P4& p4) { + MutantRunner<R, Tuple2<A1, A2> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, X4, A1, A2), + Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> > + (obj, method, MakeTuple(p1, p2, p3, p4)); + return MutantFunctor<R, Tuple2<A1, A2> >(t); } // 4 - 3 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1, typename A2, typename A3> -inline CallbackFunctor<Tuple3<A1, A2, A3> > -CBF(T* obj, void (T::*method)(P1, P2, P3, P4, A1, A2, A3), - P1 p1, P2 p2, P3 p3, P4 p4) { - Callback3<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1, A2, A3), +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename A1, typename A2, typename A3, typename X1, + typename X2, typename X3, typename X4> +inline MutantFunctor<R, Tuple3<A1, A2, A3> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, X4, A1, A2, A3), const P1& p1, + const P2& p2, const P3& p3, const P4& p4) { + MutantRunner<R, Tuple3<A1, A2, A3> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, X4, A1, A2, A3), Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> > (obj, method, MakeTuple(p1, p2, p3, p4)); - return CallbackFunctor<Tuple3<A1, A2, A3> >(t); + return MutantFunctor<R, Tuple3<A1, A2, A3> >(t); } // 4 - 4 -template <class T, typename P1, typename P2, typename P3, typename P4, - typename A1, typename A2, typename A3, typename A4> -inline CallbackFunctor<Tuple4<A1, A2, A3, A4> > -CBF(T* obj, void (T::*method)(P1, P2, P3, P4, A1, A2, A3, A4), - P1 p1, P2 p2, P3 p3, P4 p4) { - Callback4<A1, A2, A3>::Type* t = - new MutantImpl<T, void (T::*)(P1, P2, P3, P4, A1, A2, A3, A4), - Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >(obj, method, - MakeTuple(p1, p2, p3, p4)); - return CallbackFunctor<Tuple4<A1, A2, A3, A4> >(t); -} - - -// Simple task wrapper acting as a functor. -// Redirects operator() to Task::Run. We cannot delete the inner impl_ object -// in object's destructor because this object is copied few times inside -// from GMock machinery. -struct TaskHolder { - explicit TaskHolder(Task* impl) : impl_(impl) {} - void operator()() { - impl_->Run(); - delete impl_; - impl_ = NULL; - } - private: - TaskHolder(); - Task* impl_; -}; - +template <typename R, typename T, typename P1, typename P2, typename P3, + typename P4, typename A1, typename A2, typename A3, typename A4, + typename X1, typename X2, typename X3, typename X4> +inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> > +CreateFunctor(T* obj, R (T::*method)(X1, X2, X3, X4, A1, A2, A3, A4), + const P1& p1, const P2& p2, const P3& p3, const P4& p4) { + MutantRunner<R, Tuple4<A1, A2, A3, A4> > *t = new MutantImpl<R, T, + R (T::*)(X1, X2, X3, X4, A1, A2, A3, A4), + Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> > + (obj, method, MakeTuple(p1, p2, p3, p4)); + return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t); +} #endif // CHROME_FRAME_TEST_HELPER_GMOCK_H_ |