blob: 9808f7a6dfe31b212734ef155f6f6a9af9045461 [file] [log] [blame]
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: gee@google.com (Adam Gee)
#ifndef PAGESPEED_KERNEL_BASE_CALLBACK_H_
#define PAGESPEED_KERNEL_BASE_CALLBACK_H_
namespace net_instaweb {
// Base class for a single argument callback. Currently we have a single
// implementation that handles single argument member functions, which are
// to be invoked at some point in the future with the parameter.
// Example Usage:
//
// class MyClass {
// public:
// void MyMethod(int x);
// };
//
// void Foo(MyClass* my_class) {
// Callback1<int>* cb = NewCallback(my_class, &MyClass::MyMethod);
// Bar(cb);
// }
//
// void Bar(Callback1<int>* cb) {
// cb->Run(1234);
// }
//
template<class A1>
class Callback1 {
public:
Callback1() {}
virtual ~Callback1() {}
virtual void Run(A1) = 0;
};
// Naming convention is:
// (Member)?Callback_<num-pre-bound-args>_<num-runtime-args>
// TODO(gee): Fill out other useful specializations.
template<class C, class A1, bool DeleteAfterRun>
class _MemberCallback_0_1 : public Callback1<A1> {
public:
typedef void (C::*MemberSignature)(A1);
typedef Callback1<A1> base;
_MemberCallback_0_1(C* object, MemberSignature member)
: object_(object),
member_(member) {
}
void Run(A1 t) {
(object_->*member_)(t);
if (DeleteAfterRun) {
delete this;
}
}
private:
C* object_;
MemberSignature member_;
};
// Creates a callback that automatically gets deleted after being run.
template <class T1, class T2, class A1>
typename _MemberCallback_0_1<T1, A1, true>::base*
NewCallback(T1* obj, void (T2::*member)(A1)) {
return new _MemberCallback_0_1<T1, A1, true>(obj, member);
}
// Creates a callback that does not get deleted after being run.
template <class T1, class T2, class A1>
typename _MemberCallback_0_1<T1, A1, false>::base*
NewPermanentCallback(T1* obj, void (T2::*member)(A1)) {
return new _MemberCallback_0_1<T1, A1, false>(obj, member);
}
// Specified by TR1 [4.7.2] Reference modifications.
template<typename T> struct remove_reference { typedef T type; };
template<typename T> struct remove_reference<T&> { typedef T type; };
template <typename T>
struct ConstRef {
typedef typename remove_reference<T>::type base_type;
typedef const base_type& type;
};
template <class T, class P1, class A1, bool DeleteAfterRun>
class _MemberCallback_1_1 : public Callback1<A1> {
public:
typedef Callback1<A1> base;
typedef void (T::*MemberSignature)(P1, A1);
private:
T* object_;
MemberSignature member_;
typename remove_reference<P1>::type p1_;
public:
_MemberCallback_1_1(T* object,
MemberSignature member,
typename ConstRef<P1>::type p1)
: object_(object),
member_(member),
p1_(p1) { }
virtual void Run(A1 a1) {
(object_->*member_)(p1_, a1);
if (DeleteAfterRun) {
delete this;
}
}
};
// Creates a callback that automatically gets deleted after being run.
template <class T1, class T2, class P1, class A1>
inline typename _MemberCallback_1_1<T1, P1, A1, true>::base*
NewCallback(T1* obj,
void (T2::*member)(P1, A1),
typename ConstRef<P1>::type p1) {
return new _MemberCallback_1_1<T1, P1, A1, true>(obj, member, p1);
}
// Creates a callback that does not get deleted after being run.
template <class T1, class T2, class P1, class A1>
inline typename _MemberCallback_1_1<T1, P1, A1, false>::base*
NewPermanentCallback(T1* obj,
void (T2::*member)(P1, A1),
typename ConstRef<P1>::type p1) {
return new _MemberCallback_1_1<T1, P1, A1, false>(obj, member, p1);
}
// Base class for a two-argument callback. Currently we have a single
// implementation that handles single argument member functions, which are
// to be invoked at some point in the future with the parameter.
// Example Usage:
//
// class MyClass {
// public:
// void MyMethod(int x, double y);
// };
//
// void Foo(MyClass* my_class) {
// Callback<int, double>* cb = NewCallback(my_class, &MyClass::MyMethod);
// Bar(cb);
// }
//
// void Bar(Callback1<int, double>* cb) {
// cb->Run(1234, 2.7182818);
// }
//
template<class A1, class A2>
class Callback2 {
public:
Callback2() {}
virtual ~Callback2() {}
virtual void Run(A1, A2) = 0;
};
// Naming convention is:
// (Member)?Callback_<num-pre-bound-args>_<num-runtime-args>
// TODO(gee): Fill out other useful specializations.
template<class C, class A1, class A2, bool DeleteAfterRun>
class _MemberCallback_0_2 : public Callback2<A1, A2> {
public:
typedef void (C::*MemberSignature)(A1, A2);
typedef Callback2<A1, A2> base;
_MemberCallback_0_2(C* object, MemberSignature member)
: object_(object),
member_(member) {
}
void Run(A1 t1, A2 t2) {
(object_->*member_)(t1, t2);
if (DeleteAfterRun) {
delete this;
}
}
private:
C* object_;
MemberSignature member_;
};
// Creates a callback that automatically gets deleted after being run.
template <class T1, class T2, class A1, class A2>
typename _MemberCallback_0_2<T1, A1, A2, true>::base*
NewCallback(T1* obj, void (T2::*member)(A1, A2)) {
return new _MemberCallback_0_2<T1, A1, A2, true>(obj, member);
}
// Creates a callback that does not get deleted after being run.
template <class T1, class T2, class A1, class A2>
typename _MemberCallback_0_2<T1, A1, A2, false>::base*
NewPermanentCallback(T1* obj, void (T2::*member)(A1, A2)) {
return new _MemberCallback_0_2<T1, A1, A2, false>(obj, member);
}
template <class T, class P1, class A1, class A2, bool DeleteAfterRun>
class _MemberCallback_2_1 : public Callback2<A1, A2> {
public:
typedef Callback2<A1, A2> base;
typedef void (T::*MemberSignature)(P1, A1, A2);
private:
T* object_;
MemberSignature member_;
typename remove_reference<P1>::type p1_;
public:
_MemberCallback_2_1(T* object,
MemberSignature member,
typename ConstRef<P1>::type p1)
: object_(object),
member_(member),
p1_(p1) { }
virtual void Run(A1 a1, A2 a2) {
(object_->*member_)(p1_, a1, a2);
if (DeleteAfterRun) {
delete this;
}
}
};
// Creates a callback that automatically gets deleted after being run.
template <class T1, class T2, class P1, class A1, class A2>
inline typename _MemberCallback_2_1<T1, P1, A1, A2, true>::base*
NewCallback(T1* obj,
void (T2::*member)(P1, A1, A2),
typename ConstRef<P1>::type p1) {
return new _MemberCallback_2_1<T1, P1, A1, A2, true>(obj, member, p1);
}
// Creates a callback that does not get deleted after being run.
template <class T1, class T2, class P1, class A1, class A2>
inline typename _MemberCallback_2_1<T1, P1, A1, A2, false>::base*
NewPermanentCallback(T1* obj,
void (T2::*member)(P1, A1, A2),
typename ConstRef<P1>::type p1) {
return new _MemberCallback_2_1<T1, P1, A1, A2, false>(obj, member, p1);
}
} // namespace net_instaweb
#endif // PAGESPEED_KERNEL_BASE_CALLBACK_H_